Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Commit

Permalink
Merge pull request #1092 from ethcore/idmanager
Browse files Browse the repository at this point in the history
Injectable topbar support.
  • Loading branch information
NikVolf committed May 16, 2016
2 parents d249918 + 2ef6f75 commit 00ae3cf
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 38 deletions.
21 changes: 15 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions webapp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ ethcore-rpc = { path = "../rpc" }
ethcore-util = { path = "../util" }
parity-webapp = { git = "https://github.com/ethcore/parity-webapp.git" }
# List of apps
parity-status = { git = "https://github.com/ethcore/parity-status.git", version = "0.3.7" }
parity-wallet = { git = "https://github.com/ethcore/parity-wallet.git", version = "0.2.0", optional = true }
parity-status = { git = "https://github.com/ethcore/parity-status.git", version = "0.4.1" }
parity-idmanager = { git = "https://github.com/ethcore/parity-idmanager-rs.git", version = "0.1.3" }
parity-wallet = { git = "https://github.com/ethcore/parity-wallet.git", version = "0.3.0", optional = true }
clippy = { version = "0.0.64", optional = true}

[features]
Expand Down
12 changes: 11 additions & 1 deletion webapp/src/apps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,29 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

use endpoint::Endpoints;
use endpoint::{Endpoints, Endpoint};
use page::PageEndpoint;
use proxypac::ProxyPac;
use parity_webapp::WebApp;

extern crate parity_status;
extern crate parity_idmanager;
#[cfg(feature = "parity-wallet")]
extern crate parity_wallet;

pub const DAPPS_DOMAIN : &'static str = ".parity";
pub const RPC_PATH : &'static str = "rpc";
pub const API_PATH : &'static str = "api";
pub const UTILS_PATH : &'static str = "parity-utils";

pub fn main_page() -> &'static str {
"/status/"
}

pub fn utils() -> Box<Endpoint> {
Box::new(PageEndpoint::with_prefix(parity_idmanager::App::default(), UTILS_PATH.to_owned()))
}

pub fn all_endpoints() -> Endpoints {
let mut pages = Endpoints::new();
pages.insert("proxy".to_owned(), ProxyPac::boxed());
Expand Down
15 changes: 10 additions & 5 deletions webapp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ mod proxypac;

use std::sync::{Arc, Mutex};
use std::net::SocketAddr;
use std::collections::HashMap;
use jsonrpc_core::{IoHandler, IoDelegate};
use router::auth::{Authorization, NoAuth, HttpBasicAuth};

Expand Down Expand Up @@ -106,17 +107,21 @@ pub struct Server {
impl Server {
fn start_http<A: Authorization + 'static>(addr: &SocketAddr, authorization: A, handler: Arc<IoHandler>) -> Result<Server, ServerError> {
let panic_handler = Arc::new(Mutex::new(None));
let endpoints = Arc::new(apps::all_endpoints());
let authorization = Arc::new(authorization);
let rpc_endpoint = Arc::new(rpc::rpc(handler, panic_handler.clone()));
let api = Arc::new(api::RestApi::new(endpoints.clone()));
let endpoints = Arc::new(apps::all_endpoints());
let special = Arc::new({
let mut special = HashMap::new();
special.insert(router::SpecialEndpoint::Rpc, rpc::rpc(handler, panic_handler.clone()));
special.insert(router::SpecialEndpoint::Api, api::RestApi::new(endpoints.clone()));
special.insert(router::SpecialEndpoint::Utils, apps::utils());
special
});

try!(hyper::Server::http(addr))
.handle(move |_| router::Router::new(
apps::main_page(),
endpoints.clone(),
rpc_endpoint.clone(),
api.clone(),
special.clone(),
authorization.clone(),
))
.map(|l| Server {
Expand Down
17 changes: 15 additions & 2 deletions webapp/src/page/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,23 @@ use endpoint::{Endpoint, EndpointPath};
use parity_webapp::WebApp;

pub struct PageEndpoint<T : WebApp + 'static> {
/// Content of the files
pub app: Arc<T>,
/// Prefix to strip from the path (when `None` deducted from `app_id`)
pub prefix: Option<String>,
}

impl<T: WebApp + 'static> PageEndpoint<T> {
pub fn new(app: T) -> Self {
PageEndpoint {
app: Arc::new(app)
app: Arc::new(app),
prefix: None,
}
}
pub fn with_prefix(app: T, prefix: String) -> Self {
PageEndpoint {
app: Arc::new(app),
prefix: Some(prefix),
}
}
}
Expand All @@ -41,6 +51,7 @@ impl<T: WebApp> Endpoint for PageEndpoint<T> {
fn to_handler(&self, path: EndpointPath) -> Box<server::Handler<HttpStream>> {
Box::new(PageHandler {
app: self.app.clone(),
prefix: self.prefix.clone(),
path: path,
file: None,
write_pos: 0,
Expand All @@ -50,14 +61,16 @@ impl<T: WebApp> Endpoint for PageEndpoint<T> {

struct PageHandler<T: WebApp + 'static> {
app: Arc<T>,
prefix: Option<String>,
path: EndpointPath,
file: Option<String>,
write_pos: usize,
}

impl<T: WebApp + 'static> PageHandler<T> {
fn extract_path(&self, path: &str) -> String {
let prefix = "/".to_owned() + &self.path.app_id;
let app_id = &self.path.app_id;
let prefix = "/".to_owned() + self.prefix.as_ref().unwrap_or(app_id);
let prefix_with_slash = prefix.clone() + "/";

// Index file support
Expand Down
2 changes: 1 addition & 1 deletion webapp/src/proxypac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
//! Serving ProxyPac file
use endpoint::{Endpoint, Handler, ContentHandler, EndpointPath};
use DAPPS_DOMAIN;
use apps::DAPPS_DOMAIN;

pub struct ProxyPac;

Expand Down
50 changes: 29 additions & 21 deletions webapp/src/router/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,28 +23,31 @@ pub mod auth;

use DAPPS_DOMAIN;
use std::sync::Arc;
use std::collections::HashMap;
use url::Host;
use hyper;
use hyper::{server, uri, header};
use hyper::{Next, Encoder, Decoder};
use hyper::net::HttpStream;
use apps;
use endpoint::{Endpoint, Endpoints, EndpointPath};
use self::url::Url;
use self::auth::{Authorization, Authorized};
use self::redirect::Redirection;

#[derive(Debug, PartialEq)]
enum SpecialEndpoint {
/// Special endpoints are accessible on every domain (every dapp)
#[derive(Debug, PartialEq, Hash, Eq)]
pub enum SpecialEndpoint {
Rpc,
Api,
None
Utils,
None,
}

pub struct Router<A: Authorization + 'static> {
main_page: &'static str,
endpoints: Arc<Endpoints>,
rpc: Arc<Box<Endpoint>>,
api: Arc<Box<Endpoint>>,
special: Arc<HashMap<SpecialEndpoint, Box<Endpoint>>>,
authorization: Arc<A>,
handler: Box<server::Handler<HttpStream>>,
}
Expand All @@ -63,13 +66,9 @@ impl<A: Authorization + 'static> server::Handler<HttpStream> for Router<A> {
let endpoint = extract_endpoint(&url);

match endpoint {
// First check RPC requests
(ref path, SpecialEndpoint::Rpc) if *req.method() != hyper::method::Method::Get => {
self.rpc.to_handler(path.clone().unwrap_or_default())
},
// Check API requests
(ref path, SpecialEndpoint::Api) => {
self.api.to_handler(path.clone().unwrap_or_default())
// First check special endpoints
(ref path, ref endpoint) if self.special.contains_key(endpoint) => {
self.special.get(endpoint).unwrap().to_handler(path.clone().unwrap_or_default())
},
// Then delegate to dapp
(Some(ref path), _) if self.endpoints.contains_key(&path.app_id) => {
Expand All @@ -81,7 +80,7 @@ impl<A: Authorization + 'static> server::Handler<HttpStream> for Router<A> {
},
// RPC by default
_ => {
self.rpc.to_handler(EndpointPath::default())
self.special.get(&SpecialEndpoint::Rpc).unwrap().to_handler(EndpointPath::default())
}
}
}
Expand Down Expand Up @@ -111,16 +110,14 @@ impl<A: Authorization> Router<A> {
pub fn new(
main_page: &'static str,
endpoints: Arc<Endpoints>,
rpc: Arc<Box<Endpoint>>,
api: Arc<Box<Endpoint>>,
special: Arc<HashMap<SpecialEndpoint, Box<Endpoint>>>,
authorization: Arc<A>) -> Self {

let handler = rpc.to_handler(EndpointPath::default());
let handler = special.get(&SpecialEndpoint::Rpc).unwrap().to_handler(EndpointPath::default());
Router {
main_page: main_page,
endpoints: endpoints,
rpc: rpc,
api: api,
special: special,
authorization: authorization,
handler: handler,
}
Expand Down Expand Up @@ -158,9 +155,11 @@ fn extract_endpoint(url: &Option<Url>) -> (Option<EndpointPath>, SpecialEndpoint
if url.path.len() <= 1 {
return SpecialEndpoint::None;
}

match url.path[0].as_ref() {
"rpc" => SpecialEndpoint::Rpc,
"api" => SpecialEndpoint::Api,
apps::RPC_PATH => SpecialEndpoint::Rpc,
apps::API_PATH => SpecialEndpoint::Api,
apps::UTILS_PATH => SpecialEndpoint::Utils,
_ => SpecialEndpoint::None,
}
}
Expand Down Expand Up @@ -215,6 +214,15 @@ fn should_extract_endpoint() {
}), SpecialEndpoint::Rpc)
);

assert_eq!(
extract_endpoint(&Url::parse("http://my.status.dapp/parity-utils/inject.js").ok()),
(Some(EndpointPath {
app_id: "my.status".to_owned(),
host: "my.status.dapp".to_owned(),
port: 80,
}), SpecialEndpoint::Utils)
);

// By Subdomain
assert_eq!(
extract_endpoint(&Url::parse("http://my.status.dapp/test.html").ok()),
Expand All @@ -237,7 +245,7 @@ fn should_extract_endpoint() {

// API by subdomain
assert_eq!(
extract_endpoint(&Url::parse("http://my.status.dapp/rpc/").ok()),
extract_endpoint(&Url::parse("http://my.status.dapp/api/").ok()),
(Some(EndpointPath {
app_id: "my.status".to_owned(),
host: "my.status.dapp".to_owned(),
Expand Down

0 comments on commit 00ae3cf

Please sign in to comment.