// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see .
use std::io;
use std::sync::Arc;
use std::path::PathBuf;
use std::collections::HashSet;
use dapps;
use dir::default_data_path;
use dir::helpers::replace_home;
use helpers::parity_ipc_path;
use jsonrpc_core::MetaIoHandler;
use parity_reactor::TokioRemote;
use parity_rpc::informant::{RpcStats, Middleware};
use parity_rpc::{self as rpc, Metadata, DomainsValidation};
use rpc_apis::{self, ApiSet};
pub use parity_rpc::{IpcServer, HttpServer, RequestMiddleware};
pub use parity_rpc::ws::Server as WsServer;
pub use parity_rpc::informant::CpuPool;
pub const DAPPS_DOMAIN: &'static str = "web3.site";
#[derive(Debug, Clone, PartialEq)]
pub struct HttpConfiguration {
pub enabled: bool,
pub interface: String,
pub port: u16,
pub apis: ApiSet,
pub cors: Option>,
pub hosts: Option>,
pub server_threads: usize,
pub processing_threads: usize,
}
impl HttpConfiguration {
pub fn address(&self) -> Option {
address(self.enabled, &self.interface, self.port, &self.hosts)
}
}
impl Default for HttpConfiguration {
fn default() -> Self {
HttpConfiguration {
enabled: true,
interface: "127.0.0.1".into(),
port: 8545,
apis: ApiSet::UnsafeContext,
cors: Some(vec![]),
hosts: Some(vec![]),
server_threads: 1,
processing_threads: 4,
}
}
}
#[derive(Debug, PartialEq, Clone)]
pub struct UiConfiguration {
pub enabled: bool,
pub interface: String,
pub port: u16,
pub hosts: Option>,
pub info_page_only: bool,
}
impl UiConfiguration {
pub fn address(&self) -> Option {
address(self.enabled, &self.interface, self.port, &self.hosts)
}
pub fn redirection_address(&self) -> Option<(String, u16)> {
self.address().map(|host| {
let mut it = host.split(':');
let hostname: Option = it.next().map(|s| s.to_owned());
let port: Option = it.next().and_then(|s| s.parse().ok());
(hostname.unwrap_or_else(|| "localhost".into()), port.unwrap_or(8180))
})
}
}
impl From for HttpConfiguration {
fn from(conf: UiConfiguration) -> Self {
HttpConfiguration {
enabled: conf.enabled,
interface: conf.interface,
port: conf.port,
apis: rpc_apis::ApiSet::UnsafeContext,
cors: Some(vec![]),
hosts: conf.hosts,
server_threads: 1,
processing_threads: 0,
}
}
}
impl Default for UiConfiguration {
fn default() -> Self {
UiConfiguration {
enabled: cfg!(feature = "ui-enabled"),
port: 8180,
interface: "127.0.0.1".into(),
hosts: Some(vec![]),
info_page_only: true,
}
}
}
#[derive(Debug, PartialEq)]
pub struct IpcConfiguration {
pub enabled: bool,
pub socket_addr: String,
pub apis: ApiSet,
}
impl Default for IpcConfiguration {
fn default() -> Self {
IpcConfiguration {
enabled: true,
socket_addr: if cfg!(windows) {
r"\\.\pipe\jsonrpc.ipc".into()
} else {
let data_dir = ::dir::default_data_path();
parity_ipc_path(&data_dir, "$BASE/jsonrpc.ipc", 0)
},
apis: ApiSet::IpcContext,
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct WsConfiguration {
pub enabled: bool,
pub interface: String,
pub port: u16,
pub apis: ApiSet,
pub max_connections: usize,
pub origins: Option>,
pub hosts: Option>,
pub signer_path: PathBuf,
pub support_token_api: bool,
pub ui_address: Option,
pub dapps_address: Option,
}
impl Default for WsConfiguration {
fn default() -> Self {
let data_dir = default_data_path();
WsConfiguration {
enabled: true,
interface: "127.0.0.1".into(),
port: 8546,
apis: ApiSet::UnsafeContext,
max_connections: 100,
origins: Some(vec!["parity://*".into(),"chrome-extension://*".into(), "moz-extension://*".into()]),
hosts: Some(Vec::new()),
signer_path: replace_home(&data_dir, "$BASE/signer").into(),
support_token_api: true,
ui_address: Some("127.0.0.1:8180".into()),
dapps_address: Some("127.0.0.1:8545".into()),
}
}
}
impl WsConfiguration {
pub fn address(&self) -> Option {
address(self.enabled, &self.interface, self.port, &self.hosts)
}
}
fn address(enabled: bool, bind_iface: &str, bind_port: u16, hosts: &Option>) -> Option {
if !enabled {
return None;
}
match *hosts {
Some(ref hosts) if !hosts.is_empty() => Some(hosts[0].clone().into()),
_ => Some(format!("{}:{}", bind_iface, bind_port).into()),
}
}
pub struct Dependencies {
pub apis: Arc,
pub remote: TokioRemote,
pub stats: Arc,
pub pool: Option,
}
pub fn new_ws(
conf: WsConfiguration,
deps: &Dependencies,
) -> Result