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

Commit

Permalink
Merge branch 'master' into ipc
Browse files Browse the repository at this point in the history
  • Loading branch information
NikVolf committed Jul 20, 2016
2 parents 2f3fffa + b007770 commit bf76d50
Show file tree
Hide file tree
Showing 33 changed files with 334 additions and 196 deletions.
8 changes: 4 additions & 4 deletions Cargo.lock

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

9 changes: 9 additions & 0 deletions dapps/src/handlers/content.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ impl ContentHandler {
}
}

pub fn forbidden(content: String, mimetype: String) -> Self {
ContentHandler {
code: StatusCode::Forbidden,
content: content,
mimetype: mimetype,
write_pos: 0
}
}

pub fn not_found(content: String, mimetype: String) -> Self {
ContentHandler {
code: StatusCode::NotFound,
Expand Down
2 changes: 2 additions & 0 deletions dapps/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,13 +129,15 @@ impl Server {
special.insert(router::SpecialEndpoint::Utils, apps::utils());
special
});
let bind_address = format!("{}", addr);

try!(hyper::Server::http(addr))
.handle(move |_| router::Router::new(
apps::main_page(),
endpoints.clone(),
special.clone(),
authorization.clone(),
bind_address.clone(),
))
.map(|(l, srv)| {

Expand Down
45 changes: 45 additions & 0 deletions dapps/src/router/host_validation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright 2015, 2016 Ethcore (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 <http://www.gnu.org/licenses/>.


use DAPPS_DOMAIN;
use hyper::server;
use hyper::net::HttpStream;

use jsonrpc_http_server::{is_host_header_valid};
use handlers::ContentHandler;


pub fn is_valid(request: &server::Request<HttpStream>, bind_address: &str, endpoints: Vec<String>) -> bool {
let mut endpoints = endpoints.into_iter()
.map(|endpoint| format!("{}{}", endpoint, DAPPS_DOMAIN))
.collect::<Vec<String>>();
// Add localhost domain as valid too if listening on loopback interface.
endpoints.push(bind_address.replace("127.0.0.1", "localhost").into());
endpoints.push(bind_address.into());

is_host_header_valid(request, &endpoints)
}

pub fn host_invalid_response() -> Box<server::Handler<HttpStream> + Send> {
Box::new(ContentHandler::forbidden(
r#"
<h1>Request with disallowed <code>Host</code> header has been blocked.</h1>
<p>Check the URL in your browser address bar.</p>
"#.into(),
"text/html".into()
))
}
60 changes: 35 additions & 25 deletions dapps/src/router/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
//! Processes request handling authorization and dispatching it to proper application.

pub mod auth;
mod host_validation;

use DAPPS_DOMAIN;
use std::sync::Arc;
Expand All @@ -44,40 +45,46 @@ pub struct Router<A: Authorization + 'static> {
endpoints: Arc<Endpoints>,
special: Arc<HashMap<SpecialEndpoint, Box<Endpoint>>>,
authorization: Arc<A>,
bind_address: String,
handler: Box<server::Handler<HttpStream> + Send>,
}

impl<A: Authorization + 'static> server::Handler<HttpStream> for Router<A> {

fn on_request(&mut self, req: server::Request<HttpStream>) -> Next {
// Validate Host header
if !host_validation::is_valid(&req, &self.bind_address, self.endpoints.keys().cloned().collect()) {
self.handler = host_validation::host_invalid_response();
return self.handler.on_request(req);
}

// Check authorization
let auth = self.authorization.is_authorized(&req);
if let Authorized::No(handler) = auth {
self.handler = handler;
return self.handler.on_request(req);
}

// Choose proper handler depending on path / domain
self.handler = match auth {
Authorized::No(handler) => handler,
Authorized::Yes => {
let url = extract_url(&req);
let endpoint = extract_endpoint(&url);

match endpoint {
// 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) => {
self.endpoints.get(&path.app_id).unwrap().to_handler(path.clone())
},
// Redirection to main page
_ if *req.method() == hyper::method::Method::Get => {
Redirection::new(self.main_page)
},
// RPC by default
_ => {
self.special.get(&SpecialEndpoint::Rpc).unwrap().to_handler(EndpointPath::default())
}
}
let url = extract_url(&req);
let endpoint = extract_endpoint(&url);

self.handler = match endpoint {
// 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) => {
self.endpoints.get(&path.app_id).unwrap().to_handler(path.clone())
},
// Redirection to main page
_ if *req.method() == hyper::method::Method::Get => {
Redirection::new(self.main_page)
},
// RPC by default
_ => {
self.special.get(&SpecialEndpoint::Rpc).unwrap().to_handler(EndpointPath::default())
}
};

Expand Down Expand Up @@ -106,14 +113,17 @@ impl<A: Authorization> Router<A> {
main_page: &'static str,
endpoints: Arc<Endpoints>,
special: Arc<HashMap<SpecialEndpoint, Box<Endpoint>>>,
authorization: Arc<A>) -> Self {
authorization: Arc<A>,
bind_address: String,
) -> Self {

let handler = special.get(&SpecialEndpoint::Rpc).unwrap().to_handler(EndpointPath::default());
Router {
main_page: main_page,
endpoints: endpoints,
special: special,
authorization: authorization,
bind_address: bind_address,
handler: handler,
}
}
Expand Down
9 changes: 6 additions & 3 deletions dapps/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,22 @@ pub fn rpc(handler: Arc<IoHandler>, panic_handler: Arc<Mutex<Option<Box<Fn() ->
Box::new(RpcEndpoint {
handler: handler,
panic_handler: panic_handler,
cors_domain: vec![AccessControlAllowOrigin::Null],
cors_domain: Some(vec![AccessControlAllowOrigin::Null]),
// NOTE [ToDr] We don't need to do any hosts validation here. It's already done in router.
allowed_hosts: None,
})
}

struct RpcEndpoint {
handler: Arc<IoHandler>,
panic_handler: Arc<Mutex<Option<Box<Fn() -> () + Send>>>>,
cors_domain: Vec<AccessControlAllowOrigin>,
cors_domain: Option<Vec<AccessControlAllowOrigin>>,
allowed_hosts: Option<Vec<String>>,
}

impl Endpoint for RpcEndpoint {
fn to_handler(&self, _path: EndpointPath) -> Box<Handler> {
let panic_handler = PanicHandler { handler: self.panic_handler.clone() };
Box::new(ServerHandler::new(self.handler.clone(), self.cors_domain.clone(), panic_handler))
Box::new(ServerHandler::new(self.handler.clone(), self.cors_domain.clone(), self.allowed_hosts.clone(), panic_handler))
}
}
2 changes: 1 addition & 1 deletion ethcore/src/blockchain/block_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub enum BlockLocation {
/// It's not a part of the canon chain.
Branch,
/// It's part of the fork which should become canon chain,
/// because it's total difficulty is higher than current
/// because its total difficulty is higher than current
/// canon chain difficulty.
BranchBecomingCanonChain(BranchBecomingCanonChainData),
}
Expand Down
3 changes: 2 additions & 1 deletion ethcore/src/client/chain_notify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ pub trait ChainNotify : Send + Sync {
_invalid: Vec<H256>,
_enacted: Vec<H256>,
_retracted: Vec<H256>,
_sealed: Vec<H256>) {
_sealed: Vec<H256>,
_duration: u64) {
// does nothing by default
}

Expand Down
Loading

0 comments on commit bf76d50

Please sign in to comment.