From 1b66569754f86bc3e56d1cc91e6d1fcd032da88c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Wed, 4 Jan 2017 15:31:30 +0100 Subject: [PATCH 1/3] Opening local dapp --- dapps/src/apps/fs.rs | 33 +++++++++++++++++++++++--------- dapps/src/apps/mod.rs | 8 ++++++++ dapps/src/lib.rs | 21 ++++++++++++++++++++- parity/cli/mod.rs | 2 ++ parity/cli/usage.txt | 13 +++++++------ parity/configuration.rs | 42 ++++++++++++++++++++++++++++++++++++++--- parity/dapps.rs | 14 +++++++++++++- parity/run.rs | 16 ++++++++++++++++ 8 files changed, 129 insertions(+), 20 deletions(-) diff --git a/dapps/src/apps/fs.rs b/dapps/src/apps/fs.rs index 12bad2e3d38..eec4e56228c 100644 --- a/dapps/src/apps/fs.rs +++ b/dapps/src/apps/fs.rs @@ -28,6 +28,16 @@ struct LocalDapp { info: EndpointInfo, } +fn local_dapp(name: String, path: PathBuf) -> LocalDapp { + // try to get manifest file + let info = read_manifest(&name, path.clone()); + LocalDapp { + id: name, + path: path, + info: info, + } +} + fn local_dapps(dapps_path: String) -> Vec { let files = fs::read_dir(dapps_path.as_str()); if let Err(e) = files { @@ -59,15 +69,7 @@ fn local_dapps(dapps_path: String) -> Vec { } m.ok() }) - .map(|(name, path)| { - // try to get manifest file - let info = read_manifest(&name, path.clone()); - LocalDapp { - id: name, - path: path, - info: info, - } - }) + .map(|(name, path)| local_dapp(name, path)) .collect() } @@ -97,6 +99,19 @@ fn read_manifest(name: &str, mut path: PathBuf) -> EndpointInfo { }) } +pub fn local_endpoint(path: String, signer_address: Option<(String, u16)>) -> Option<(String, Box)> { + let path = PathBuf::from(path); + path.canonicalize().ok().and_then(|path| { + let name = path.file_name().and_then(|name| name.to_str()); + name.map(|name| { + let dapp = local_dapp(name.into(), path.clone()); + (dapp.id, Box::new(LocalPageEndpoint::new( + dapp.path, dapp.info, PageCache::Disabled, signer_address.clone()) + )) + }) + }) +} + pub fn local_endpoints(dapps_path: String, signer_address: Option<(String, u16)>) -> Endpoints { let mut pages = Endpoints::new(); for dapp in local_dapps(dapps_path) { diff --git a/dapps/src/apps/mod.rs b/dapps/src/apps/mod.rs index 51f8f5572c1..f7ab6c67a66 100644 --- a/dapps/src/apps/mod.rs +++ b/dapps/src/apps/mod.rs @@ -44,6 +44,7 @@ pub fn utils() -> Box { pub fn all_endpoints( dapps_path: String, + extra_dapps: Vec, signer_address: Option<(String, u16)>, web_proxy_tokens: Arc, remote: Remote, @@ -51,6 +52,13 @@ pub fn all_endpoints( ) -> Endpoints { // fetch fs dapps at first to avoid overwriting builtins let mut pages = fs::local_endpoints(dapps_path, signer_address.clone()); + for path in extra_dapps { + if let Some((id, endpoint)) = fs::local_endpoint(path.clone(), signer_address.clone()) { + pages.insert(id, endpoint); + } else { + warn!(target: "dapps", "Ingoring invalid dapp at {}", path); + } + } // NOTE [ToDr] Dapps will be currently embeded on 8180 insert::(&mut pages, "ui", Embeddable::Yes(signer_address.clone())); diff --git a/dapps/src/lib.rs b/dapps/src/lib.rs index effa29fcc80..a22f8403b47 100644 --- a/dapps/src/lib.rs +++ b/dapps/src/lib.rs @@ -124,6 +124,7 @@ impl WebProxyTokens for F where F: Fn(String) -> bool + Send + Sync { /// Webapps HTTP+RPC server build. pub struct ServerBuilder { dapps_path: String, + extra_dapps: Vec, handler: Arc, registrar: Arc, sync_status: Arc, @@ -144,6 +145,7 @@ impl ServerBuilder { pub fn new(dapps_path: String, registrar: Arc, remote: Remote) -> Self { ServerBuilder { dapps_path: dapps_path, + extra_dapps: vec![], handler: Arc::new(IoHandler::new()), registrar: registrar, sync_status: Arc::new(|| false), @@ -160,6 +162,7 @@ impl ServerBuilder { pub fn fetch(self, fetch: X) -> ServerBuilder { ServerBuilder { dapps_path: self.dapps_path, + extra_dapps: vec![], handler: self.handler, registrar: self.registrar, sync_status: self.sync_status, @@ -188,6 +191,12 @@ impl ServerBuilder { self } + /// Change extra dapps paths (apart from `dapps_path`) + pub fn extra_dapps(mut self, extra_dapps: Vec) -> Self { + self.extra_dapps = extra_dapps; + self + } + /// Asynchronously start server with no authentication, /// returns result with `Server` handle on success or an error. pub fn start_unsecured_http(self, addr: &SocketAddr, hosts: Option>) -> Result { @@ -197,6 +206,7 @@ impl ServerBuilder { NoAuth, self.handler.clone(), self.dapps_path.clone(), + self.extra_dapps.clone(), self.signer_address.clone(), self.registrar.clone(), self.sync_status.clone(), @@ -215,6 +225,7 @@ impl ServerBuilder { HttpBasicAuth::single_user(username, password), self.handler.clone(), self.dapps_path.clone(), + self.extra_dapps.clone(), self.signer_address.clone(), self.registrar.clone(), self.sync_status.clone(), @@ -271,6 +282,7 @@ impl Server { authorization: A, handler: Arc, dapps_path: String, + extra_dapps: Vec, signer_address: Option<(String, u16)>, registrar: Arc, sync_status: Arc, @@ -287,7 +299,14 @@ impl Server { remote.clone(), fetch.clone(), )); - let endpoints = Arc::new(apps::all_endpoints(dapps_path, signer_address.clone(), web_proxy_tokens, remote.clone(), fetch.clone())); + let endpoints = Arc::new(apps::all_endpoints( + dapps_path, + extra_dapps, + signer_address.clone(), + web_proxy_tokens, + remote.clone(), + fetch.clone(), + )); let cors_domains = Self::cors_domains(signer_address.clone()); let special = Arc::new({ diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index 47a0af0bb3d..818c263d03b 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -37,6 +37,7 @@ usage! { cmd_snapshot: bool, cmd_restore: bool, cmd_ui: bool, + cmd_dapp: bool, cmd_tools: bool, cmd_hash: bool, cmd_kill: bool, @@ -525,6 +526,7 @@ mod tests { cmd_snapshot: false, cmd_restore: false, cmd_ui: false, + cmd_dapp: false, cmd_tools: false, cmd_hash: false, cmd_db: false, diff --git a/parity/cli/usage.txt b/parity/cli/usage.txt index dc7c487ffaf..11ebb744760 100644 --- a/parity/cli/usage.txt +++ b/parity/cli/usage.txt @@ -5,6 +5,7 @@ Parity. Ethereum Client. Usage: parity [options] parity ui [options] + parity dapp [options] parity daemon [options] parity account (new | list ) [options] parity account import ... [options] @@ -36,15 +37,15 @@ Operating Options: (default: {flag_mode_alarm}). --auto-update SET Set a releases set to automatically update and install. - all - All updates in the our release track. + all - All updates in the our release track. critical - Only consensus/security updates. - none - No updates will be auto-installed. + none - No updates will be auto-installed. (default: {flag_auto_update}). --release-track TRACK Set which release track we should use for updates. - stable - Stable releases. - beta - Beta releases. + stable - Stable releases. + beta - Beta releases. nightly - Nightly releases (unstable). - testing - Testing releases (do not use). + testing - Testing releases (do not use). current - Whatever track this executable was released on (default: {flag_release_track}). --no-download Normally new releases will be downloaded ready for @@ -362,7 +363,7 @@ Legacy Options: --cache MB Equivalent to --cache-size MB. Internal Options: - --can-restart Executable will auto-restart if exiting with 69. + --can-restart Executable will auto-restart if exiting with 69. Miscellaneous Options: -c --config CONFIG Specify a filename containing a configuration file. diff --git a/parity/configuration.rs b/parity/configuration.rs index 23adffe6616..3c79027f919 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -17,7 +17,7 @@ use std::time::Duration; use std::io::Read; use std::net::SocketAddr; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::cmp::max; use cli::{Args, ArgsError}; use util::{Hashable, U256, Uint, Bytes, version_data, Secret, Address}; @@ -335,6 +335,7 @@ impl Configuration { net_settings: self.network_settings(), dapps_conf: dapps_conf, signer_conf: signer_conf, + dapp: self.dapp_to_open()?, ui: self.args.cmd_ui, name: self.args.flag_identity, custom_bootnodes: self.args.flag_bootnodes.is_some(), @@ -508,7 +509,25 @@ impl Configuration { user: self.args.flag_dapps_user.clone(), pass: self.args.flag_dapps_pass.clone(), dapps_path: self.directories().dapps, + extra_dapps: if self.args.cmd_dapp { + self.args.arg_path.clone() + } else { + vec![] + }, + } + } + + fn dapp_to_open(&self) -> Result, String> { + if !self.args.cmd_dapp { + return Ok(None); } + let path = self.args.arg_path.get(0).map(String::as_str).unwrap_or("."); + let path = Path::new(path).canonicalize() + .map_err(|e| format!("Invalid path: {}. Error: {:?}", path, e))?; + let name = path.file_name() + .and_then(|name| name.to_str()) + .ok_or_else(|| "Root path is not supported.".to_owned())?; + Ok(Some(name.into())) } fn gas_pricer_config(&self) -> Result { @@ -690,7 +709,7 @@ impl Configuration { "none" => UpdateFilter::None, "critical" => UpdateFilter::Critical, "all" => UpdateFilter::All, - _ => return Err("Invalid value for `--auto-update`. See `--help` for more information.".into()), + _ => return Err("Invalid value for `--auto-update`. See `--help` for more information.".into()), }, track: match self.args.flag_release_track.as_ref() { "stable" => ReleaseTrack::Stable, @@ -698,7 +717,7 @@ impl Configuration { "nightly" => ReleaseTrack::Nightly, "testing" => ReleaseTrack::Testing, "current" => ReleaseTrack::Unknown, - _ => return Err("Invalid value for `--releases-track`. See `--help` for more information.".into()), + _ => return Err("Invalid value for `--releases-track`. See `--help` for more information.".into()), }, path: default_hypervisor_path(), }) @@ -1025,6 +1044,7 @@ mod tests { dapps_conf: Default::default(), signer_conf: Default::default(), ui: false, + dapp: None, name: "".into(), custom_bootnodes: false, fat_db: Default::default(), @@ -1219,6 +1239,22 @@ mod tests { }); } + #[test] + fn should_parse_dapp_opening() { + // given + let temp = RandomTempPath::new(); + let name = temp.file_name().unwrap().to_str().unwrap(); + create_dir(temp.as_str().to_owned()).unwrap(); + + // when + let conf0 = parse(&["parity", "dapp", temp.to_str().unwrap()]); + + // then + assert_eq!(conf0.dapp_to_open(), Ok(Some(name.into()))); + let extra_dapps = conf0.dapps_config().extra_dapps; + assert_eq!(extra_dapps, vec![temp.to_str().unwrap().to_owned()]); + } + #[test] fn should_not_bail_on_empty_line_in_reserved_peers() { let temp = RandomTempPath::new(); diff --git a/parity/dapps.rs b/parity/dapps.rs index 8ec526a0586..e61a722e635 100644 --- a/parity/dapps.rs +++ b/parity/dapps.rs @@ -34,6 +34,7 @@ pub struct Configuration { pub user: Option, pub pass: Option, pub dapps_path: String, + pub extra_dapps: Vec, } impl Default for Configuration { @@ -47,6 +48,7 @@ impl Default for Configuration { user: None, pass: None, dapps_path: replace_home(&data_dir, "$BASE/dapps"), + extra_dapps: vec![], } } } @@ -80,7 +82,14 @@ pub fn new(configuration: Configuration, deps: Dependencies) -> Result, _url: &SocketAddr, _allowed_hosts: Option>, _auth: Option<(String, String)>, @@ -123,6 +133,7 @@ mod server { pub fn setup_dapps_server( deps: Dependencies, dapps_path: String, + extra_dapps: Vec, url: &SocketAddr, allowed_hosts: Option>, auth: Option<(String, String)>, @@ -141,6 +152,7 @@ mod server { .fetch(deps.fetch.clone()) .sync_status(Arc::new(move || is_major_importing(Some(sync.status().state), client.queue_info()))) .web_proxy_tokens(Arc::new(move |token| signer.is_valid_web_proxy_access_token(&token))) + .extra_dapps(extra_dapps) .signer_address(deps.signer.address()); let server = rpc_apis::setup_rpc(server, deps.apis.clone(), rpc_apis::ApiSet::UnsafeContext); diff --git a/parity/run.rs b/parity/run.rs index 672c80fcf55..5e91e67fbb2 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -91,6 +91,7 @@ pub struct RunCmd { pub net_settings: NetworkSettings, pub dapps_conf: dapps::Configuration, pub signer_conf: signer::Configuration, + pub dapp: Option, pub ui: bool, pub name: String, pub custom_bootnodes: bool, @@ -117,6 +118,17 @@ pub fn open_ui(dapps_conf: &dapps::Configuration, signer_conf: &signer::Configur Ok(()) } +pub fn open_dapp(dapps_conf: &dapps::Configuration, dapp: &str) -> Result<(), String> { + if !dapps_conf.enabled { + return Err("Cannot use DAPP command with Dapps turned off.".into()) + } + + let url = format!("http://{}:{}/{}/", dapps_conf.interface, dapps_conf.port, dapp); + url::open(&url); + Ok(()) +} + + pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc) -> Result { if cmd.ui && cmd.dapps_conf.enabled { // Check if Parity is already running @@ -428,6 +440,10 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc) -> R open_ui(&cmd.dapps_conf, &cmd.signer_conf)?; } + if let Some(dapp) = cmd.dapp { + open_dapp(&cmd.dapps_conf, &dapp)?; + } + // Handle exit let restart = wait_for_exit( panic_handler, From d64ecff89485889ce588f0181d8f4e1f9dc64c63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Thu, 5 Jan 2017 14:52:45 +0100 Subject: [PATCH 2/3] Using Path/PathBuf instead of Strings --- dapps/src/apps/fs.rs | 16 ++++++++-------- dapps/src/apps/mod.rs | 7 ++++--- dapps/src/lib.rs | 17 +++++++++-------- dapps/src/tests/helpers/mod.rs | 4 ++-- parity/configuration.rs | 6 +++--- parity/dapps.rs | 20 +++++++++++--------- 6 files changed, 37 insertions(+), 33 deletions(-) diff --git a/dapps/src/apps/fs.rs b/dapps/src/apps/fs.rs index eec4e56228c..11c152940ef 100644 --- a/dapps/src/apps/fs.rs +++ b/dapps/src/apps/fs.rs @@ -17,7 +17,7 @@ use std::io; use std::io::Read; use std::fs; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use page::{LocalPageEndpoint, PageCache}; use endpoint::{Endpoints, EndpointInfo}; use apps::manifest::{MANIFEST_FILENAME, deserialize_manifest}; @@ -38,10 +38,10 @@ fn local_dapp(name: String, path: PathBuf) -> LocalDapp { } } -fn local_dapps(dapps_path: String) -> Vec { - let files = fs::read_dir(dapps_path.as_str()); +fn local_dapps(dapps_path: &Path) -> Vec { + let files = fs::read_dir(dapps_path); if let Err(e) = files { - warn!(target: "dapps", "Unable to load local dapps from: {}. Reason: {:?}", dapps_path, e); + warn!(target: "dapps", "Unable to load local dapps from: {}. Reason: {:?}", dapps_path.display(), e); return vec![]; } @@ -99,8 +99,8 @@ fn read_manifest(name: &str, mut path: PathBuf) -> EndpointInfo { }) } -pub fn local_endpoint(path: String, signer_address: Option<(String, u16)>) -> Option<(String, Box)> { - let path = PathBuf::from(path); +pub fn local_endpoint>(path: P, signer_address: Option<(String, u16)>) -> Option<(String, Box)> { + let path = path.as_ref().to_owned(); path.canonicalize().ok().and_then(|path| { let name = path.file_name().and_then(|name| name.to_str()); name.map(|name| { @@ -112,9 +112,9 @@ pub fn local_endpoint(path: String, signer_address: Option<(String, u16)>) -> Op }) } -pub fn local_endpoints(dapps_path: String, signer_address: Option<(String, u16)>) -> Endpoints { +pub fn local_endpoints>(dapps_path: P, signer_address: Option<(String, u16)>) -> Endpoints { let mut pages = Endpoints::new(); - for dapp in local_dapps(dapps_path) { + for dapp in local_dapps(dapps_path.as_ref()) { pages.insert( dapp.id, Box::new(LocalPageEndpoint::new(dapp.path, dapp.info, PageCache::Disabled, signer_address.clone())) diff --git a/dapps/src/apps/mod.rs b/dapps/src/apps/mod.rs index f7ab6c67a66..59f9aef94f2 100644 --- a/dapps/src/apps/mod.rs +++ b/dapps/src/apps/mod.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use std::path::PathBuf; use std::sync::Arc; use endpoint::{Endpoints, Endpoint}; use page::PageEndpoint; @@ -43,8 +44,8 @@ pub fn utils() -> Box { } pub fn all_endpoints( - dapps_path: String, - extra_dapps: Vec, + dapps_path: PathBuf, + extra_dapps: Vec, signer_address: Option<(String, u16)>, web_proxy_tokens: Arc, remote: Remote, @@ -56,7 +57,7 @@ pub fn all_endpoints( if let Some((id, endpoint)) = fs::local_endpoint(path.clone(), signer_address.clone()) { pages.insert(id, endpoint); } else { - warn!(target: "dapps", "Ingoring invalid dapp at {}", path); + warn!(target: "dapps", "Ingoring invalid dapp at {}", path.display()); } } diff --git a/dapps/src/lib.rs b/dapps/src/lib.rs index a22f8403b47..64ee0c3410a 100644 --- a/dapps/src/lib.rs +++ b/dapps/src/lib.rs @@ -88,6 +88,7 @@ mod web; #[cfg(test)] mod tests; +use std::path::{Path, PathBuf}; use std::sync::{Arc, Mutex}; use std::net::SocketAddr; use std::collections::HashMap; @@ -123,8 +124,8 @@ impl WebProxyTokens for F where F: Fn(String) -> bool + Send + Sync { /// Webapps HTTP+RPC server build. pub struct ServerBuilder { - dapps_path: String, - extra_dapps: Vec, + dapps_path: PathBuf, + extra_dapps: Vec, handler: Arc, registrar: Arc, sync_status: Arc, @@ -142,9 +143,9 @@ impl Extendable for ServerBuilder { impl ServerBuilder { /// Construct new dapps server - pub fn new(dapps_path: String, registrar: Arc, remote: Remote) -> Self { + pub fn new>(dapps_path: P, registrar: Arc, remote: Remote) -> Self { ServerBuilder { - dapps_path: dapps_path, + dapps_path: dapps_path.as_ref().to_owned(), extra_dapps: vec![], handler: Arc::new(IoHandler::new()), registrar: registrar, @@ -192,8 +193,8 @@ impl ServerBuilder { } /// Change extra dapps paths (apart from `dapps_path`) - pub fn extra_dapps(mut self, extra_dapps: Vec) -> Self { - self.extra_dapps = extra_dapps; + pub fn extra_dapps>(mut self, extra_dapps: &[P]) -> Self { + self.extra_dapps = extra_dapps.iter().map(|p| p.as_ref().to_owned()).collect(); self } @@ -281,8 +282,8 @@ impl Server { hosts: Option>, authorization: A, handler: Arc, - dapps_path: String, - extra_dapps: Vec, + dapps_path: PathBuf, + extra_dapps: Vec, signer_address: Option<(String, u16)>, registrar: Arc, sync_status: Arc, diff --git a/dapps/src/tests/helpers/mod.rs b/dapps/src/tests/helpers/mod.rs index d3f97b35bcf..5cc367fccf5 100644 --- a/dapps/src/tests/helpers/mod.rs +++ b/dapps/src/tests/helpers/mod.rs @@ -51,7 +51,7 @@ pub fn init_server(hosts: Option>, process: F, remote: Remote) let mut dapps_path = env::temp_dir(); dapps_path.push("non-existent-dir-to-prevent-fs-files-from-loading"); let server = process(ServerBuilder::new( - dapps_path.to_str().unwrap().into(), registrar.clone(), remote, + &dapps_path, registrar.clone(), remote, )) .signer_address(Some(("127.0.0.1".into(), SIGNER_PORT))) .start_unsecured_http(&"127.0.0.1:0".parse().unwrap(), hosts).unwrap(); @@ -66,7 +66,7 @@ pub fn serve_with_auth(user: &str, pass: &str) -> Server { let registrar = Arc::new(FakeRegistrar::new()); let mut dapps_path = env::temp_dir(); dapps_path.push("non-existent-dir-to-prevent-fs-files-from-loading"); - ServerBuilder::new(dapps_path.to_str().unwrap().into(), registrar.clone(), Remote::new_sync()) + ServerBuilder::new(&dapps_path, registrar.clone(), Remote::new_sync()) .signer_address(Some(("127.0.0.1".into(), SIGNER_PORT))) .start_basic_auth_http(&"127.0.0.1:0".parse().unwrap(), None, user, pass).unwrap() } diff --git a/parity/configuration.rs b/parity/configuration.rs index 3c79027f919..f388259d782 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -508,9 +508,9 @@ impl Configuration { hosts: self.dapps_hosts(), user: self.args.flag_dapps_user.clone(), pass: self.args.flag_dapps_pass.clone(), - dapps_path: self.directories().dapps, + dapps_path: PathBuf::from(self.directories().dapps), extra_dapps: if self.args.cmd_dapp { - self.args.arg_path.clone() + self.args.arg_path.iter().map(|path| PathBuf::from(path)).collect() } else { vec![] }, @@ -1252,7 +1252,7 @@ mod tests { // then assert_eq!(conf0.dapp_to_open(), Ok(Some(name.into()))); let extra_dapps = conf0.dapps_config().extra_dapps; - assert_eq!(extra_dapps, vec![temp.to_str().unwrap().to_owned()]); + assert_eq!(extra_dapps, vec![temp.to_owned()]); } #[test] diff --git a/parity/dapps.rs b/parity/dapps.rs index e61a722e635..711ba3a4974 100644 --- a/parity/dapps.rs +++ b/parity/dapps.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use std::path::PathBuf; use std::sync::Arc; use io::PanicHandler; use rpc_apis; @@ -33,8 +34,8 @@ pub struct Configuration { pub hosts: Option>, pub user: Option, pub pass: Option, - pub dapps_path: String, - pub extra_dapps: Vec, + pub dapps_path: PathBuf, + pub extra_dapps: Vec, } impl Default for Configuration { @@ -47,7 +48,7 @@ impl Default for Configuration { hosts: Some(Vec::new()), user: None, pass: None, - dapps_path: replace_home(&data_dir, "$BASE/dapps"), + dapps_path: replace_home(&data_dir, "$BASE/dapps").into(), extra_dapps: vec![], } } @@ -103,8 +104,8 @@ mod server { pub struct WebappServer; pub fn setup_dapps_server( _deps: Dependencies, - _dapps_path: String, - _extra_dapps: Vec, + _dapps_path: PathBuf, + _extra_dapps: Vec, _url: &SocketAddr, _allowed_hosts: Option>, _auth: Option<(String, String)>, @@ -116,6 +117,7 @@ mod server { #[cfg(feature = "dapps")] mod server { use super::Dependencies; + use std::path::PathBuf; use std::sync::Arc; use std::net::SocketAddr; use std::io; @@ -132,8 +134,8 @@ mod server { pub fn setup_dapps_server( deps: Dependencies, - dapps_path: String, - extra_dapps: Vec, + dapps_path: PathBuf, + extra_dapps: Vec, url: &SocketAddr, allowed_hosts: Option>, auth: Option<(String, String)>, @@ -141,7 +143,7 @@ mod server { use ethcore_dapps as dapps; let server = dapps::ServerBuilder::new( - dapps_path, + &dapps_path, Arc::new(Registrar { client: deps.client.clone() }), deps.remote.clone(), ); @@ -152,7 +154,7 @@ mod server { .fetch(deps.fetch.clone()) .sync_status(Arc::new(move || is_major_importing(Some(sync.status().state), client.queue_info()))) .web_proxy_tokens(Arc::new(move |token| signer.is_valid_web_proxy_access_token(&token))) - .extra_dapps(extra_dapps) + .extra_dapps(&extra_dapps) .signer_address(deps.signer.address()); let server = rpc_apis::setup_rpc(server, deps.apis.clone(), rpc_apis::ApiSet::UnsafeContext); From 8097b066a5ed7f3e17e5ccc47915d7d3e21b70ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Fri, 6 Jan 2017 11:15:30 +0100 Subject: [PATCH 3/3] Fixing typo and adding some docs to apps::fs functions --- dapps/src/apps/fs.rs | 99 +++++++++++++++++++++++-------------------- dapps/src/apps/mod.rs | 2 +- 2 files changed, 55 insertions(+), 46 deletions(-) diff --git a/dapps/src/apps/fs.rs b/dapps/src/apps/fs.rs index 11c152940ef..9984a112a09 100644 --- a/dapps/src/apps/fs.rs +++ b/dapps/src/apps/fs.rs @@ -28,51 +28,8 @@ struct LocalDapp { info: EndpointInfo, } -fn local_dapp(name: String, path: PathBuf) -> LocalDapp { - // try to get manifest file - let info = read_manifest(&name, path.clone()); - LocalDapp { - id: name, - path: path, - info: info, - } -} - -fn local_dapps(dapps_path: &Path) -> Vec { - let files = fs::read_dir(dapps_path); - if let Err(e) = files { - warn!(target: "dapps", "Unable to load local dapps from: {}. Reason: {:?}", dapps_path.display(), e); - return vec![]; - } - - let files = files.expect("Check is done earlier"); - files.map(|dir| { - let entry = dir?; - let file_type = entry.file_type()?; - - // skip files - if file_type.is_file() { - return Err(io::Error::new(io::ErrorKind::NotFound, "Not a file")); - } - - // take directory name and path - entry.file_name().into_string() - .map(|name| (name, entry.path())) - .map_err(|e| { - info!(target: "dapps", "Unable to load dapp: {:?}. Reason: {:?}", entry.path(), e); - io::Error::new(io::ErrorKind::NotFound, "Invalid name") - }) - }) - .filter_map(|m| { - if let Err(ref e) = m { - debug!(target: "dapps", "Ignoring local dapp: {:?}", e); - } - m.ok() - }) - .map(|(name, path)| local_dapp(name, path)) - .collect() -} - +/// Tries to find and read manifest file in given `path` to extract `EndpointInfo` +/// If manifest is not found sensible default `EndpointInfo` is returned based on given `name`. fn read_manifest(name: &str, mut path: PathBuf) -> EndpointInfo { path.push(MANIFEST_FILENAME); @@ -99,6 +56,9 @@ fn read_manifest(name: &str, mut path: PathBuf) -> EndpointInfo { }) } +/// Returns Dapp Id and Local Dapp Endpoint for given filesystem path. +/// Parses the path to extract last component (for name). +/// `None` is returned when path is invalid or non-existent. pub fn local_endpoint>(path: P, signer_address: Option<(String, u16)>) -> Option<(String, Box)> { let path = path.as_ref().to_owned(); path.canonicalize().ok().and_then(|path| { @@ -112,6 +72,19 @@ pub fn local_endpoint>(path: P, signer_address: Option<(String, u }) } + +fn local_dapp(name: String, path: PathBuf) -> LocalDapp { + // try to get manifest file + let info = read_manifest(&name, path.clone()); + LocalDapp { + id: name, + path: path, + info: info, + } +} + +/// Returns endpoints for Local Dapps found for given filesystem path. +/// Scans the directory and collects `LocalPageEndpoints`. pub fn local_endpoints>(dapps_path: P, signer_address: Option<(String, u16)>) -> Endpoints { let mut pages = Endpoints::new(); for dapp in local_dapps(dapps_path.as_ref()) { @@ -122,3 +95,39 @@ pub fn local_endpoints>(dapps_path: P, signer_address: Option<(St } pages } + + +fn local_dapps(dapps_path: &Path) -> Vec { + let files = fs::read_dir(dapps_path); + if let Err(e) = files { + warn!(target: "dapps", "Unable to load local dapps from: {}. Reason: {:?}", dapps_path.display(), e); + return vec![]; + } + + let files = files.expect("Check is done earlier"); + files.map(|dir| { + let entry = dir?; + let file_type = entry.file_type()?; + + // skip files + if file_type.is_file() { + return Err(io::Error::new(io::ErrorKind::NotFound, "Not a file")); + } + + // take directory name and path + entry.file_name().into_string() + .map(|name| (name, entry.path())) + .map_err(|e| { + info!(target: "dapps", "Unable to load dapp: {:?}. Reason: {:?}", entry.path(), e); + io::Error::new(io::ErrorKind::NotFound, "Invalid name") + }) + }) + .filter_map(|m| { + if let Err(ref e) = m { + debug!(target: "dapps", "Ignoring local dapp: {:?}", e); + } + m.ok() + }) + .map(|(name, path)| local_dapp(name, path)) + .collect() +} diff --git a/dapps/src/apps/mod.rs b/dapps/src/apps/mod.rs index 59f9aef94f2..f32cf904223 100644 --- a/dapps/src/apps/mod.rs +++ b/dapps/src/apps/mod.rs @@ -57,7 +57,7 @@ pub fn all_endpoints( if let Some((id, endpoint)) = fs::local_endpoint(path.clone(), signer_address.clone()) { pages.insert(id, endpoint); } else { - warn!(target: "dapps", "Ingoring invalid dapp at {}", path.display()); + warn!(target: "dapps", "Ignoring invalid dapp at {}", path.display()); } }