mirror of
https://github.com/scottlamb/moonfire-nvr.git
synced 2025-12-05 07:12:34 -05:00
Merge branch 'master' (early part) into new-schema
Catch the new-schema branch up with everything up to (but not including) the big UI refactoring. I'll merge that separately.
This commit is contained in:
@@ -55,11 +55,15 @@ Options:
|
||||
--db-dir=DIR Set the directory holding the SQLite3 index database.
|
||||
This is typically on a flash device.
|
||||
[default: /var/lib/moonfire-nvr/db]
|
||||
--ui-dir=DIR Set the directory with the user interface files (.html, .js, etc).
|
||||
--ui-dir=DIR Set the directory with the user interface files
|
||||
(.html, .js, etc).
|
||||
[default: /usr/local/lib/moonfire-nvr/ui]
|
||||
--http-addr=ADDR Set the bind address for the unencrypted HTTP server.
|
||||
[default: 0.0.0.0:8080]
|
||||
--read-only Forces read-only mode / disables recording.
|
||||
--allow-origin=ORIGIN If present, adds a Access-Control-Allow-Origin:
|
||||
header to HTTP responses. This may be useful for
|
||||
Javascript development.
|
||||
"#;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
@@ -68,6 +72,7 @@ struct Args {
|
||||
flag_http_addr: String,
|
||||
flag_ui_dir: String,
|
||||
flag_read_only: bool,
|
||||
flag_allow_origin: Option<String>,
|
||||
}
|
||||
|
||||
fn setup_shutdown_future(h: &reactor::Handle) -> Box<Future<Item = (), Error = ()>> {
|
||||
@@ -111,7 +116,8 @@ pub fn run() -> Result<(), Error> {
|
||||
}
|
||||
info!("Directories are opened.");
|
||||
|
||||
let s = web::Service::new(db.clone(), Some(&args.flag_ui_dir), resolve_zone())?;
|
||||
let s = web::Service::new(db.clone(), Some(&args.flag_ui_dir), args.flag_allow_origin,
|
||||
resolve_zone())?;
|
||||
|
||||
// Start a streamer for each stream.
|
||||
let shutdown_streamers = Arc::new(AtomicBool::new(false));
|
||||
|
||||
24
src/web.rs
24
src/web.rs
@@ -40,7 +40,7 @@ use futures::{future, stream};
|
||||
use futures_cpupool;
|
||||
use json;
|
||||
use http_serve;
|
||||
use hyper::header;
|
||||
use hyper::header::{self, Header};
|
||||
use hyper::server::{self, Request, Response};
|
||||
use mime;
|
||||
use mp4;
|
||||
@@ -192,6 +192,7 @@ struct ServiceInner {
|
||||
db: Arc<db::Database>,
|
||||
dirs_by_stream_id: Arc<FnvHashMap<i32, Arc<SampleFileDir>>>,
|
||||
ui_files: HashMap<String, UiFile>,
|
||||
allow_origin: Option<header::AccessControlAllowOrigin>,
|
||||
pool: futures_cpupool::CpuPool,
|
||||
time_zone_name: String,
|
||||
}
|
||||
@@ -416,7 +417,8 @@ impl ServiceInner {
|
||||
pub struct Service(Arc<ServiceInner>);
|
||||
|
||||
impl Service {
|
||||
pub fn new(db: Arc<db::Database>, ui_dir: Option<&str>, zone: String) -> Result<Self, Error> {
|
||||
pub fn new(db: Arc<db::Database>, ui_dir: Option<&str>, allow_origin: Option<String>,
|
||||
zone: String) -> Result<Self, Error> {
|
||||
let mut ui_files = HashMap::new();
|
||||
if let Some(d) = ui_dir {
|
||||
Service::fill_ui_files(d, &mut ui_files);
|
||||
@@ -438,10 +440,15 @@ impl Service {
|
||||
}
|
||||
Arc::new(d)
|
||||
};
|
||||
let allow_origin = match allow_origin {
|
||||
None => None,
|
||||
Some(o) => Some(header::AccessControlAllowOrigin::parse_header(&header::Raw::from(o))?),
|
||||
};
|
||||
Ok(Service(Arc::new(ServiceInner {
|
||||
db,
|
||||
dirs_by_stream_id,
|
||||
ui_files,
|
||||
allow_origin,
|
||||
pool: futures_cpupool::Builder::new().pool_size(1).name_prefix("static").create(),
|
||||
time_zone_name: zone,
|
||||
})))
|
||||
@@ -466,8 +473,11 @@ impl Service {
|
||||
};
|
||||
let (p, mime) = match e.file_name().to_str() {
|
||||
Some(n) if n == "index.html" => ("/".to_owned(), mime::TEXT_HTML),
|
||||
Some(n) if n.ends_with(".js") => (format!("/{}", n), mime::TEXT_JAVASCRIPT),
|
||||
Some(n) if n.ends_with(".html") => (format!("/{}", n), mime::TEXT_HTML),
|
||||
Some(n) if n.ends_with(".ico") => (format!("/{}", n),
|
||||
"image/vnd.microsoft.icon".parse().unwrap()),
|
||||
Some(n) if n.ends_with(".js") => (format!("/{}", n), mime::TEXT_JAVASCRIPT),
|
||||
Some(n) if n.ends_with(".map") => (format!("/{}", n), mime::TEXT_JAVASCRIPT),
|
||||
Some(n) if n.ends_with(".png") => (format!("/{}", n), mime::IMAGE_PNG),
|
||||
Some(n) => {
|
||||
warn!("UI directory file {:?} has unknown extension; skipping", n);
|
||||
@@ -509,6 +519,11 @@ impl server::Service for Service {
|
||||
Path::NotFound => self.0.not_found(),
|
||||
Path::Static => self.0.static_file(&req),
|
||||
};
|
||||
let res = if let Some(ref o) = self.0.allow_origin {
|
||||
res.map(|resp| resp.with_header(o.clone()))
|
||||
} else {
|
||||
res
|
||||
};
|
||||
future::result(res.map_err(|e| {
|
||||
error!("error: {}", e);
|
||||
hyper::Error::Incomplete
|
||||
@@ -570,7 +585,8 @@ mod bench {
|
||||
let (tx, rx) = ::std::sync::mpsc::channel();
|
||||
::std::thread::spawn(move || {
|
||||
let addr = "127.0.0.1:0".parse().unwrap();
|
||||
let service = super::Service::new(db.db.clone(), None, "".to_owned()).unwrap();
|
||||
let service = super::Service::new(db.db.clone(), None, None,
|
||||
"".to_owned()).unwrap();
|
||||
let server = hyper::server::Http::new()
|
||||
.bind(&addr, move || Ok(service.clone()))
|
||||
.unwrap();
|
||||
|
||||
Reference in New Issue
Block a user