Host validation (again) (#1666)

* Revert "Revert "Validating Host headers in RPC requests" (#1663)"

This reverts commit 3cc3dbef66.

* Fixing binding on MacOS
This commit is contained in:
Tomasz Drwięga
2016-07-20 12:34:17 +02:00
committed by Gav Wood
parent 9c8b80f998
commit 0cba70fba3
11 changed files with 172 additions and 56 deletions

View File

@@ -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;
@@ -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);
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())
}
}
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())
}
};
@@ -106,7 +113,9 @@ 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 {
@@ -114,6 +123,7 @@ impl<A: Authorization> Router<A> {
endpoints: endpoints,
special: special,
authorization: authorization,
bind_address: bind_address,
handler: handler,
}
}