Opening local dapp (#4041)
* Opening local dapp * Using Path/PathBuf instead of Strings * Fixing typo and adding some docs to apps::fs functions
This commit is contained in:
parent
332a45846d
commit
e983339edd
@ -17,7 +17,7 @@
|
|||||||
use std::io;
|
use std::io;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::PathBuf;
|
use std::path::{Path, PathBuf};
|
||||||
use page::{LocalPageEndpoint, PageCache};
|
use page::{LocalPageEndpoint, PageCache};
|
||||||
use endpoint::{Endpoints, EndpointInfo};
|
use endpoint::{Endpoints, EndpointInfo};
|
||||||
use apps::manifest::{MANIFEST_FILENAME, deserialize_manifest};
|
use apps::manifest::{MANIFEST_FILENAME, deserialize_manifest};
|
||||||
@ -28,10 +28,79 @@ struct LocalDapp {
|
|||||||
info: EndpointInfo,
|
info: EndpointInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn local_dapps(dapps_path: String) -> Vec<LocalDapp> {
|
/// Tries to find and read manifest file in given `path` to extract `EndpointInfo`
|
||||||
let files = fs::read_dir(dapps_path.as_str());
|
/// 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);
|
||||||
|
|
||||||
|
fs::File::open(path.clone())
|
||||||
|
.map_err(|e| format!("{:?}", e))
|
||||||
|
.and_then(|mut f| {
|
||||||
|
// Reat file
|
||||||
|
let mut s = String::new();
|
||||||
|
f.read_to_string(&mut s).map_err(|e| format!("{:?}", e))?;
|
||||||
|
// Try to deserialize manifest
|
||||||
|
deserialize_manifest(s)
|
||||||
|
})
|
||||||
|
.map(Into::into)
|
||||||
|
.unwrap_or_else(|e| {
|
||||||
|
warn!(target: "dapps", "Cannot read manifest file at: {:?}. Error: {:?}", path, e);
|
||||||
|
|
||||||
|
EndpointInfo {
|
||||||
|
name: name.into(),
|
||||||
|
description: name.into(),
|
||||||
|
version: "0.0.0".into(),
|
||||||
|
author: "?".into(),
|
||||||
|
icon_url: "icon.png".into(),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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<P: AsRef<Path>>(path: P, signer_address: Option<(String, u16)>) -> Option<(String, Box<LocalPageEndpoint>)> {
|
||||||
|
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| {
|
||||||
|
let dapp = local_dapp(name.into(), path.clone());
|
||||||
|
(dapp.id, Box::new(LocalPageEndpoint::new(
|
||||||
|
dapp.path, dapp.info, PageCache::Disabled, signer_address.clone())
|
||||||
|
))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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<P: AsRef<Path>>(dapps_path: P, signer_address: Option<(String, u16)>) -> Endpoints {
|
||||||
|
let mut pages = Endpoints::new();
|
||||||
|
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()))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
pages
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn local_dapps(dapps_path: &Path) -> Vec<LocalDapp> {
|
||||||
|
let files = fs::read_dir(dapps_path);
|
||||||
if let Err(e) = files {
|
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![];
|
return vec![];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,51 +128,6 @@ fn local_dapps(dapps_path: String) -> Vec<LocalDapp> {
|
|||||||
}
|
}
|
||||||
m.ok()
|
m.ok()
|
||||||
})
|
})
|
||||||
.map(|(name, path)| {
|
.map(|(name, path)| local_dapp(name, path))
|
||||||
// try to get manifest file
|
|
||||||
let info = read_manifest(&name, path.clone());
|
|
||||||
LocalDapp {
|
|
||||||
id: name,
|
|
||||||
path: path,
|
|
||||||
info: info,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_manifest(name: &str, mut path: PathBuf) -> EndpointInfo {
|
|
||||||
path.push(MANIFEST_FILENAME);
|
|
||||||
|
|
||||||
fs::File::open(path.clone())
|
|
||||||
.map_err(|e| format!("{:?}", e))
|
|
||||||
.and_then(|mut f| {
|
|
||||||
// Reat file
|
|
||||||
let mut s = String::new();
|
|
||||||
f.read_to_string(&mut s).map_err(|e| format!("{:?}", e))?;
|
|
||||||
// Try to deserialize manifest
|
|
||||||
deserialize_manifest(s)
|
|
||||||
})
|
|
||||||
.map(Into::into)
|
|
||||||
.unwrap_or_else(|e| {
|
|
||||||
warn!(target: "dapps", "Cannot read manifest file at: {:?}. Error: {:?}", path, e);
|
|
||||||
|
|
||||||
EndpointInfo {
|
|
||||||
name: name.into(),
|
|
||||||
description: name.into(),
|
|
||||||
version: "0.0.0".into(),
|
|
||||||
author: "?".into(),
|
|
||||||
icon_url: "icon.png".into(),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
|
||||||
pages.insert(
|
|
||||||
dapp.id,
|
|
||||||
Box::new(LocalPageEndpoint::new(dapp.path, dapp.info, PageCache::Disabled, signer_address.clone()))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
pages
|
|
||||||
}
|
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use endpoint::{Endpoints, Endpoint};
|
use endpoint::{Endpoints, Endpoint};
|
||||||
use page::PageEndpoint;
|
use page::PageEndpoint;
|
||||||
@ -43,7 +44,8 @@ pub fn utils() -> Box<Endpoint> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn all_endpoints<F: Fetch>(
|
pub fn all_endpoints<F: Fetch>(
|
||||||
dapps_path: String,
|
dapps_path: PathBuf,
|
||||||
|
extra_dapps: Vec<PathBuf>,
|
||||||
signer_address: Option<(String, u16)>,
|
signer_address: Option<(String, u16)>,
|
||||||
web_proxy_tokens: Arc<WebProxyTokens>,
|
web_proxy_tokens: Arc<WebProxyTokens>,
|
||||||
remote: Remote,
|
remote: Remote,
|
||||||
@ -51,6 +53,13 @@ pub fn all_endpoints<F: Fetch>(
|
|||||||
) -> Endpoints {
|
) -> Endpoints {
|
||||||
// fetch fs dapps at first to avoid overwriting builtins
|
// fetch fs dapps at first to avoid overwriting builtins
|
||||||
let mut pages = fs::local_endpoints(dapps_path, signer_address.clone());
|
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", "Ignoring invalid dapp at {}", path.display());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE [ToDr] Dapps will be currently embeded on 8180
|
// NOTE [ToDr] Dapps will be currently embeded on 8180
|
||||||
insert::<parity_ui::App>(&mut pages, "ui", Embeddable::Yes(signer_address.clone()));
|
insert::<parity_ui::App>(&mut pages, "ui", Embeddable::Yes(signer_address.clone()));
|
||||||
|
@ -88,6 +88,7 @@ mod web;
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
@ -123,7 +124,8 @@ impl<F> WebProxyTokens for F where F: Fn(String) -> bool + Send + Sync {
|
|||||||
|
|
||||||
/// Webapps HTTP+RPC server build.
|
/// Webapps HTTP+RPC server build.
|
||||||
pub struct ServerBuilder<T: Fetch = FetchClient> {
|
pub struct ServerBuilder<T: Fetch = FetchClient> {
|
||||||
dapps_path: String,
|
dapps_path: PathBuf,
|
||||||
|
extra_dapps: Vec<PathBuf>,
|
||||||
handler: Arc<IoHandler>,
|
handler: Arc<IoHandler>,
|
||||||
registrar: Arc<ContractClient>,
|
registrar: Arc<ContractClient>,
|
||||||
sync_status: Arc<SyncStatus>,
|
sync_status: Arc<SyncStatus>,
|
||||||
@ -141,9 +143,10 @@ impl<T: Fetch> Extendable for ServerBuilder<T> {
|
|||||||
|
|
||||||
impl ServerBuilder {
|
impl ServerBuilder {
|
||||||
/// Construct new dapps server
|
/// Construct new dapps server
|
||||||
pub fn new(dapps_path: String, registrar: Arc<ContractClient>, remote: Remote) -> Self {
|
pub fn new<P: AsRef<Path>>(dapps_path: P, registrar: Arc<ContractClient>, remote: Remote) -> Self {
|
||||||
ServerBuilder {
|
ServerBuilder {
|
||||||
dapps_path: dapps_path,
|
dapps_path: dapps_path.as_ref().to_owned(),
|
||||||
|
extra_dapps: vec![],
|
||||||
handler: Arc::new(IoHandler::new()),
|
handler: Arc::new(IoHandler::new()),
|
||||||
registrar: registrar,
|
registrar: registrar,
|
||||||
sync_status: Arc::new(|| false),
|
sync_status: Arc::new(|| false),
|
||||||
@ -160,6 +163,7 @@ impl<T: Fetch> ServerBuilder<T> {
|
|||||||
pub fn fetch<X: Fetch>(self, fetch: X) -> ServerBuilder<X> {
|
pub fn fetch<X: Fetch>(self, fetch: X) -> ServerBuilder<X> {
|
||||||
ServerBuilder {
|
ServerBuilder {
|
||||||
dapps_path: self.dapps_path,
|
dapps_path: self.dapps_path,
|
||||||
|
extra_dapps: vec![],
|
||||||
handler: self.handler,
|
handler: self.handler,
|
||||||
registrar: self.registrar,
|
registrar: self.registrar,
|
||||||
sync_status: self.sync_status,
|
sync_status: self.sync_status,
|
||||||
@ -188,6 +192,12 @@ impl<T: Fetch> ServerBuilder<T> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Change extra dapps paths (apart from `dapps_path`)
|
||||||
|
pub fn extra_dapps<P: AsRef<Path>>(mut self, extra_dapps: &[P]) -> Self {
|
||||||
|
self.extra_dapps = extra_dapps.iter().map(|p| p.as_ref().to_owned()).collect();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Asynchronously start server with no authentication,
|
/// Asynchronously start server with no authentication,
|
||||||
/// returns result with `Server` handle on success or an error.
|
/// returns result with `Server` handle on success or an error.
|
||||||
pub fn start_unsecured_http(self, addr: &SocketAddr, hosts: Option<Vec<String>>) -> Result<Server, ServerError> {
|
pub fn start_unsecured_http(self, addr: &SocketAddr, hosts: Option<Vec<String>>) -> Result<Server, ServerError> {
|
||||||
@ -197,6 +207,7 @@ impl<T: Fetch> ServerBuilder<T> {
|
|||||||
NoAuth,
|
NoAuth,
|
||||||
self.handler.clone(),
|
self.handler.clone(),
|
||||||
self.dapps_path.clone(),
|
self.dapps_path.clone(),
|
||||||
|
self.extra_dapps.clone(),
|
||||||
self.signer_address.clone(),
|
self.signer_address.clone(),
|
||||||
self.registrar.clone(),
|
self.registrar.clone(),
|
||||||
self.sync_status.clone(),
|
self.sync_status.clone(),
|
||||||
@ -215,6 +226,7 @@ impl<T: Fetch> ServerBuilder<T> {
|
|||||||
HttpBasicAuth::single_user(username, password),
|
HttpBasicAuth::single_user(username, password),
|
||||||
self.handler.clone(),
|
self.handler.clone(),
|
||||||
self.dapps_path.clone(),
|
self.dapps_path.clone(),
|
||||||
|
self.extra_dapps.clone(),
|
||||||
self.signer_address.clone(),
|
self.signer_address.clone(),
|
||||||
self.registrar.clone(),
|
self.registrar.clone(),
|
||||||
self.sync_status.clone(),
|
self.sync_status.clone(),
|
||||||
@ -270,7 +282,8 @@ impl Server {
|
|||||||
hosts: Option<Vec<String>>,
|
hosts: Option<Vec<String>>,
|
||||||
authorization: A,
|
authorization: A,
|
||||||
handler: Arc<IoHandler>,
|
handler: Arc<IoHandler>,
|
||||||
dapps_path: String,
|
dapps_path: PathBuf,
|
||||||
|
extra_dapps: Vec<PathBuf>,
|
||||||
signer_address: Option<(String, u16)>,
|
signer_address: Option<(String, u16)>,
|
||||||
registrar: Arc<ContractClient>,
|
registrar: Arc<ContractClient>,
|
||||||
sync_status: Arc<SyncStatus>,
|
sync_status: Arc<SyncStatus>,
|
||||||
@ -287,7 +300,14 @@ impl Server {
|
|||||||
remote.clone(),
|
remote.clone(),
|
||||||
fetch.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 cors_domains = Self::cors_domains(signer_address.clone());
|
||||||
|
|
||||||
let special = Arc::new({
|
let special = Arc::new({
|
||||||
|
@ -51,7 +51,7 @@ pub fn init_server<F, B>(hosts: Option<Vec<String>>, process: F, remote: Remote)
|
|||||||
let mut dapps_path = env::temp_dir();
|
let mut dapps_path = env::temp_dir();
|
||||||
dapps_path.push("non-existent-dir-to-prevent-fs-files-from-loading");
|
dapps_path.push("non-existent-dir-to-prevent-fs-files-from-loading");
|
||||||
let server = process(ServerBuilder::new(
|
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)))
|
.signer_address(Some(("127.0.0.1".into(), SIGNER_PORT)))
|
||||||
.start_unsecured_http(&"127.0.0.1:0".parse().unwrap(), hosts).unwrap();
|
.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 registrar = Arc::new(FakeRegistrar::new());
|
||||||
let mut dapps_path = env::temp_dir();
|
let mut dapps_path = env::temp_dir();
|
||||||
dapps_path.push("non-existent-dir-to-prevent-fs-files-from-loading");
|
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)))
|
.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()
|
.start_basic_auth_http(&"127.0.0.1:0".parse().unwrap(), None, user, pass).unwrap()
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@ usage! {
|
|||||||
cmd_snapshot: bool,
|
cmd_snapshot: bool,
|
||||||
cmd_restore: bool,
|
cmd_restore: bool,
|
||||||
cmd_ui: bool,
|
cmd_ui: bool,
|
||||||
|
cmd_dapp: bool,
|
||||||
cmd_tools: bool,
|
cmd_tools: bool,
|
||||||
cmd_hash: bool,
|
cmd_hash: bool,
|
||||||
cmd_kill: bool,
|
cmd_kill: bool,
|
||||||
@ -525,6 +526,7 @@ mod tests {
|
|||||||
cmd_snapshot: false,
|
cmd_snapshot: false,
|
||||||
cmd_restore: false,
|
cmd_restore: false,
|
||||||
cmd_ui: false,
|
cmd_ui: false,
|
||||||
|
cmd_dapp: false,
|
||||||
cmd_tools: false,
|
cmd_tools: false,
|
||||||
cmd_hash: false,
|
cmd_hash: false,
|
||||||
cmd_db: false,
|
cmd_db: false,
|
||||||
|
@ -5,6 +5,7 @@ Parity. Ethereum Client.
|
|||||||
Usage:
|
Usage:
|
||||||
parity [options]
|
parity [options]
|
||||||
parity ui [options]
|
parity ui [options]
|
||||||
|
parity dapp <path> [options]
|
||||||
parity daemon <pid-file> [options]
|
parity daemon <pid-file> [options]
|
||||||
parity account (new | list ) [options]
|
parity account (new | list ) [options]
|
||||||
parity account import <path>... [options]
|
parity account import <path>... [options]
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::path::PathBuf;
|
use std::path::{Path, PathBuf};
|
||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
use cli::{Args, ArgsError};
|
use cli::{Args, ArgsError};
|
||||||
use util::{Hashable, U256, Uint, Bytes, version_data, Secret, Address};
|
use util::{Hashable, U256, Uint, Bytes, version_data, Secret, Address};
|
||||||
@ -335,6 +335,7 @@ impl Configuration {
|
|||||||
net_settings: self.network_settings(),
|
net_settings: self.network_settings(),
|
||||||
dapps_conf: dapps_conf,
|
dapps_conf: dapps_conf,
|
||||||
signer_conf: signer_conf,
|
signer_conf: signer_conf,
|
||||||
|
dapp: self.dapp_to_open()?,
|
||||||
ui: self.args.cmd_ui,
|
ui: self.args.cmd_ui,
|
||||||
name: self.args.flag_identity,
|
name: self.args.flag_identity,
|
||||||
custom_bootnodes: self.args.flag_bootnodes.is_some(),
|
custom_bootnodes: self.args.flag_bootnodes.is_some(),
|
||||||
@ -507,10 +508,28 @@ impl Configuration {
|
|||||||
hosts: self.dapps_hosts(),
|
hosts: self.dapps_hosts(),
|
||||||
user: self.args.flag_dapps_user.clone(),
|
user: self.args.flag_dapps_user.clone(),
|
||||||
pass: self.args.flag_dapps_pass.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.iter().map(|path| PathBuf::from(path)).collect()
|
||||||
|
} else {
|
||||||
|
vec![]
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn dapp_to_open(&self) -> Result<Option<String>, 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<GasPricerConfig, String> {
|
fn gas_pricer_config(&self) -> Result<GasPricerConfig, String> {
|
||||||
if let Some(d) = self.args.flag_gasprice.as_ref() {
|
if let Some(d) = self.args.flag_gasprice.as_ref() {
|
||||||
return Ok(GasPricerConfig::Fixed(to_u256(d)?));
|
return Ok(GasPricerConfig::Fixed(to_u256(d)?));
|
||||||
@ -1030,6 +1049,7 @@ mod tests {
|
|||||||
dapps_conf: Default::default(),
|
dapps_conf: Default::default(),
|
||||||
signer_conf: Default::default(),
|
signer_conf: Default::default(),
|
||||||
ui: false,
|
ui: false,
|
||||||
|
dapp: None,
|
||||||
name: "".into(),
|
name: "".into(),
|
||||||
custom_bootnodes: false,
|
custom_bootnodes: false,
|
||||||
fat_db: Default::default(),
|
fat_db: Default::default(),
|
||||||
@ -1224,6 +1244,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_owned()]);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_not_bail_on_empty_line_in_reserved_peers() {
|
fn should_not_bail_on_empty_line_in_reserved_peers() {
|
||||||
let temp = RandomTempPath::new();
|
let temp = RandomTempPath::new();
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use io::PanicHandler;
|
use io::PanicHandler;
|
||||||
use rpc_apis;
|
use rpc_apis;
|
||||||
@ -33,7 +34,8 @@ pub struct Configuration {
|
|||||||
pub hosts: Option<Vec<String>>,
|
pub hosts: Option<Vec<String>>,
|
||||||
pub user: Option<String>,
|
pub user: Option<String>,
|
||||||
pub pass: Option<String>,
|
pub pass: Option<String>,
|
||||||
pub dapps_path: String,
|
pub dapps_path: PathBuf,
|
||||||
|
pub extra_dapps: Vec<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Configuration {
|
impl Default for Configuration {
|
||||||
@ -46,7 +48,8 @@ impl Default for Configuration {
|
|||||||
hosts: Some(Vec::new()),
|
hosts: Some(Vec::new()),
|
||||||
user: None,
|
user: None,
|
||||||
pass: None,
|
pass: None,
|
||||||
dapps_path: replace_home(&data_dir, "$BASE/dapps"),
|
dapps_path: replace_home(&data_dir, "$BASE/dapps").into(),
|
||||||
|
extra_dapps: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,7 +83,14 @@ pub fn new(configuration: Configuration, deps: Dependencies) -> Result<Option<We
|
|||||||
(username.to_owned(), password)
|
(username.to_owned(), password)
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(Some(setup_dapps_server(deps, configuration.dapps_path, &addr, configuration.hosts, auth)?))
|
Ok(Some(setup_dapps_server(
|
||||||
|
deps,
|
||||||
|
configuration.dapps_path,
|
||||||
|
configuration.extra_dapps,
|
||||||
|
&addr,
|
||||||
|
configuration.hosts,
|
||||||
|
auth
|
||||||
|
)?))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub use self::server::WebappServer;
|
pub use self::server::WebappServer;
|
||||||
@ -94,7 +104,8 @@ mod server {
|
|||||||
pub struct WebappServer;
|
pub struct WebappServer;
|
||||||
pub fn setup_dapps_server(
|
pub fn setup_dapps_server(
|
||||||
_deps: Dependencies,
|
_deps: Dependencies,
|
||||||
_dapps_path: String,
|
_dapps_path: PathBuf,
|
||||||
|
_extra_dapps: Vec<PathBuf>,
|
||||||
_url: &SocketAddr,
|
_url: &SocketAddr,
|
||||||
_allowed_hosts: Option<Vec<String>>,
|
_allowed_hosts: Option<Vec<String>>,
|
||||||
_auth: Option<(String, String)>,
|
_auth: Option<(String, String)>,
|
||||||
@ -106,6 +117,7 @@ mod server {
|
|||||||
#[cfg(feature = "dapps")]
|
#[cfg(feature = "dapps")]
|
||||||
mod server {
|
mod server {
|
||||||
use super::Dependencies;
|
use super::Dependencies;
|
||||||
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::io;
|
use std::io;
|
||||||
@ -122,7 +134,8 @@ mod server {
|
|||||||
|
|
||||||
pub fn setup_dapps_server(
|
pub fn setup_dapps_server(
|
||||||
deps: Dependencies,
|
deps: Dependencies,
|
||||||
dapps_path: String,
|
dapps_path: PathBuf,
|
||||||
|
extra_dapps: Vec<PathBuf>,
|
||||||
url: &SocketAddr,
|
url: &SocketAddr,
|
||||||
allowed_hosts: Option<Vec<String>>,
|
allowed_hosts: Option<Vec<String>>,
|
||||||
auth: Option<(String, String)>,
|
auth: Option<(String, String)>,
|
||||||
@ -130,7 +143,7 @@ mod server {
|
|||||||
use ethcore_dapps as dapps;
|
use ethcore_dapps as dapps;
|
||||||
|
|
||||||
let server = dapps::ServerBuilder::new(
|
let server = dapps::ServerBuilder::new(
|
||||||
dapps_path,
|
&dapps_path,
|
||||||
Arc::new(Registrar { client: deps.client.clone() }),
|
Arc::new(Registrar { client: deps.client.clone() }),
|
||||||
deps.remote.clone(),
|
deps.remote.clone(),
|
||||||
);
|
);
|
||||||
@ -141,6 +154,7 @@ mod server {
|
|||||||
.fetch(deps.fetch.clone())
|
.fetch(deps.fetch.clone())
|
||||||
.sync_status(Arc::new(move || is_major_importing(Some(sync.status().state), client.queue_info())))
|
.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)))
|
.web_proxy_tokens(Arc::new(move |token| signer.is_valid_web_proxy_access_token(&token)))
|
||||||
|
.extra_dapps(&extra_dapps)
|
||||||
.signer_address(deps.signer.address());
|
.signer_address(deps.signer.address());
|
||||||
|
|
||||||
let server = rpc_apis::setup_rpc(server, deps.apis.clone(), rpc_apis::ApiSet::UnsafeContext);
|
let server = rpc_apis::setup_rpc(server, deps.apis.clone(), rpc_apis::ApiSet::UnsafeContext);
|
||||||
|
@ -92,6 +92,7 @@ pub struct RunCmd {
|
|||||||
pub net_settings: NetworkSettings,
|
pub net_settings: NetworkSettings,
|
||||||
pub dapps_conf: dapps::Configuration,
|
pub dapps_conf: dapps::Configuration,
|
||||||
pub signer_conf: signer::Configuration,
|
pub signer_conf: signer::Configuration,
|
||||||
|
pub dapp: Option<String>,
|
||||||
pub ui: bool,
|
pub ui: bool,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub custom_bootnodes: bool,
|
pub custom_bootnodes: bool,
|
||||||
@ -118,6 +119,17 @@ pub fn open_ui(dapps_conf: &dapps::Configuration, signer_conf: &signer::Configur
|
|||||||
Ok(())
|
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<RotatingLogger>) -> Result<bool, String> {
|
pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> Result<bool, String> {
|
||||||
if cmd.ui && cmd.dapps_conf.enabled {
|
if cmd.ui && cmd.dapps_conf.enabled {
|
||||||
// Check if Parity is already running
|
// Check if Parity is already running
|
||||||
@ -441,6 +453,10 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> R
|
|||||||
open_ui(&cmd.dapps_conf, &cmd.signer_conf)?;
|
open_ui(&cmd.dapps_conf, &cmd.signer_conf)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(dapp) = cmd.dapp {
|
||||||
|
open_dapp(&cmd.dapps_conf, &dapp)?;
|
||||||
|
}
|
||||||
|
|
||||||
// Handle exit
|
// Handle exit
|
||||||
let restart = wait_for_exit(panic_handler, Some(updater), can_restart);
|
let restart = wait_for_exit(panic_handler, Some(updater), can_restart);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user