Dapps errors embeddable on signer (#3115)

This commit is contained in:
Tomasz Drwięga 2016-11-03 12:22:28 +01:00 committed by Gav Wood
parent d99f1b517c
commit e251fd49a1
9 changed files with 37 additions and 24 deletions

View File

@ -71,12 +71,13 @@ impl<R: URLHint> ContentFetcher<R> {
} }
} }
fn still_syncing() -> Box<Handler> { fn still_syncing(port: Option<u16>) -> Box<Handler> {
Box::new(ContentHandler::error( Box::new(ContentHandler::error(
StatusCode::ServiceUnavailable, StatusCode::ServiceUnavailable,
"Sync In Progress", "Sync In Progress",
"Your node is still syncing. We cannot resolve any content before it's fully synced.", "Your node is still syncing. We cannot resolve any content before it's fully synced.",
Some("<a href=\"javascript:window.location.reload()\">Refresh</a>") Some("<a href=\"javascript:window.location.reload()\">Refresh</a>"),
port,
)) ))
} }
@ -143,7 +144,7 @@ impl<R: URLHint> ContentFetcher<R> {
match content { match content {
// Don't serve dapps if we are still syncing (but serve content) // Don't serve dapps if we are still syncing (but serve content)
Some(URLHintResult::Dapp(_)) if self.sync.is_major_importing() => { Some(URLHintResult::Dapp(_)) if self.sync.is_major_importing() => {
(None, Self::still_syncing()) (None, Self::still_syncing(self.embeddable_at))
}, },
Some(URLHintResult::Dapp(dapp)) => { Some(URLHintResult::Dapp(dapp)) => {
let (handler, fetch_control) = ContentFetcherHandler::new( let (handler, fetch_control) = ContentFetcherHandler::new(
@ -155,7 +156,8 @@ impl<R: URLHint> ContentFetcher<R> {
dapps_path: self.dapps_path.clone(), dapps_path: self.dapps_path.clone(),
on_done: Box::new(on_done), on_done: Box::new(on_done),
embeddable_at: self.embeddable_at, embeddable_at: self.embeddable_at,
} },
self.embeddable_at,
); );
(Some(ContentStatus::Fetching(fetch_control)), Box::new(handler) as Box<Handler>) (Some(ContentStatus::Fetching(fetch_control)), Box::new(handler) as Box<Handler>)
@ -170,13 +172,14 @@ impl<R: URLHint> ContentFetcher<R> {
mime: content.mime, mime: content.mime,
content_path: self.dapps_path.clone(), content_path: self.dapps_path.clone(),
on_done: Box::new(on_done), on_done: Box::new(on_done),
} },
self.embeddable_at,
); );
(Some(ContentStatus::Fetching(fetch_control)), Box::new(handler) as Box<Handler>) (Some(ContentStatus::Fetching(fetch_control)), Box::new(handler) as Box<Handler>)
}, },
None if self.sync.is_major_importing() => { None if self.sync.is_major_importing() => {
(None, Self::still_syncing()) (None, Self::still_syncing(self.embeddable_at))
}, },
None => { None => {
// This may happen when sync status changes in between // This may happen when sync status changes in between
@ -185,7 +188,8 @@ impl<R: URLHint> ContentFetcher<R> {
StatusCode::NotFound, StatusCode::NotFound,
"Resource Not Found", "Resource Not Found",
"Requested resource was not found.", "Requested resource was not found.",
None None,
self.embeddable_at,
)) as Box<Handler>) )) as Box<Handler>)
}, },
} }

View File

@ -48,11 +48,7 @@ impl ContentHandler {
Self::new_embeddable(code, content, mime!(Text/Html), embeddable_at) Self::new_embeddable(code, content, mime!(Text/Html), embeddable_at)
} }
pub fn error(code: StatusCode, title: &str, message: &str, details: Option<&str>) -> Self { pub fn error(code: StatusCode, title: &str, message: &str, details: Option<&str>, embeddable_at: Option<u16>) -> Self {
Self::error_embeddable(code, title, message, details, None)
}
pub fn error_embeddable(code: StatusCode, title: &str, message: &str, details: Option<&str>, embeddable_at: Option<u16>) -> Self {
Self::html(code, format!( Self::html(code, format!(
include_str!("../error_tpl.html"), include_str!("../error_tpl.html"),
title=title, title=title,

View File

@ -138,6 +138,7 @@ pub struct ContentFetcherHandler<H: ContentValidator> {
client: Option<Client>, client: Option<Client>,
using_dapps_domains: bool, using_dapps_domains: bool,
installer: H, installer: H,
embeddable_at: Option<u16>,
} }
impl<H: ContentValidator> Drop for ContentFetcherHandler<H> { impl<H: ContentValidator> Drop for ContentFetcherHandler<H> {
@ -156,7 +157,9 @@ impl<H: ContentValidator> ContentFetcherHandler<H> {
url: String, url: String,
control: Control, control: Control,
using_dapps_domains: bool, using_dapps_domains: bool,
handler: H) -> (Self, Arc<FetchControl>) { handler: H,
embeddable_at: Option<u16>,
) -> (Self, Arc<FetchControl>) {
let fetch_control = Arc::new(FetchControl::default()); let fetch_control = Arc::new(FetchControl::default());
let client = Client::default(); let client = Client::default();
@ -167,6 +170,7 @@ impl<H: ContentValidator> ContentFetcherHandler<H> {
status: FetchState::NotStarted(url), status: FetchState::NotStarted(url),
using_dapps_domains: using_dapps_domains, using_dapps_domains: using_dapps_domains,
installer: handler, installer: handler,
embeddable_at: embeddable_at,
}; };
(handler, fetch_control) (handler, fetch_control)
@ -204,6 +208,7 @@ impl<H: ContentValidator> server::Handler<HttpStream> for ContentFetcherHandler<
"Unable To Start Dapp Download", "Unable To Start Dapp Download",
"Could not initialize download of the dapp. It might be a problem with the remote server.", "Could not initialize download of the dapp. It might be a problem with the remote server.",
Some(&format!("{}", e)), Some(&format!("{}", e)),
self.embeddable_at,
)), )),
} }
}, },
@ -213,6 +218,7 @@ impl<H: ContentValidator> server::Handler<HttpStream> for ContentFetcherHandler<
"Method Not Allowed", "Method Not Allowed",
"Only <code>GET</code> requests are allowed.", "Only <code>GET</code> requests are allowed.",
None, None,
self.embeddable_at,
)), )),
}) })
} else { None }; } else { None };
@ -234,7 +240,8 @@ impl<H: ContentValidator> server::Handler<HttpStream> for ContentFetcherHandler<
StatusCode::GatewayTimeout, StatusCode::GatewayTimeout,
"Download Timeout", "Download Timeout",
&format!("Could not fetch content within {} seconds.", FETCH_TIMEOUT), &format!("Could not fetch content within {} seconds.", FETCH_TIMEOUT),
None None,
self.embeddable_at,
); );
Self::close_client(&mut self.client); Self::close_client(&mut self.client);
(Some(FetchState::Error(timeout)), Next::write()) (Some(FetchState::Error(timeout)), Next::write())
@ -255,7 +262,8 @@ impl<H: ContentValidator> server::Handler<HttpStream> for ContentFetcherHandler<
StatusCode::BadGateway, StatusCode::BadGateway,
"Invalid Dapp", "Invalid Dapp",
"Downloaded bundle does not contain a valid content.", "Downloaded bundle does not contain a valid content.",
Some(&format!("{:?}", e)) Some(&format!("{:?}", e)),
self.embeddable_at,
)) ))
}, },
Ok((id, result)) => { Ok((id, result)) => {
@ -274,6 +282,7 @@ impl<H: ContentValidator> server::Handler<HttpStream> for ContentFetcherHandler<
"Download Error", "Download Error",
"There was an error when fetching the content.", "There was an error when fetching the content.",
Some(&format!("{:?}", e)), Some(&format!("{:?}", e)),
self.embeddable_at,
); );
(Some(FetchState::Error(error)), Next::write()) (Some(FetchState::Error(error)), Next::write())
}, },

View File

@ -59,7 +59,7 @@ pub enum ServedFile<T: Dapp> {
impl<T: Dapp> ServedFile<T> { impl<T: Dapp> ServedFile<T> {
pub fn new(embeddable_at: Option<u16>) -> Self { pub fn new(embeddable_at: Option<u16>) -> Self {
ServedFile::Error(ContentHandler::error_embeddable( ServedFile::Error(ContentHandler::error(
StatusCode::NotFound, StatusCode::NotFound,
"404 Not Found", "404 Not Found",
"Requested dapp resource was not found.", "Requested dapp resource was not found.",

View File

@ -59,7 +59,8 @@ impl Authorization for HttpBasicAuth {
status::StatusCode::Unauthorized, status::StatusCode::Unauthorized,
"Unauthorized", "Unauthorized",
"You need to provide valid credentials to access this page.", "You need to provide valid credentials to access this page.",
None None,
None,
))) )))
}, },
Access::AuthRequired => { Access::AuthRequired => {

View File

@ -41,6 +41,7 @@ pub fn host_invalid_response() -> Box<server::Handler<HttpStream> + Send> {
Box::new(ContentHandler::error(StatusCode::Forbidden, Box::new(ContentHandler::error(StatusCode::Forbidden,
"Current Host Is Disallowed", "Current Host Is Disallowed",
"You are trying to access your node using incorrect address.", "You are trying to access your node using incorrect address.",
Some("Use allowed URL or specify different <code>hosts</code> CLI options.") Some("Use allowed URL or specify different <code>hosts</code> CLI options."),
None,
)) ))
} }

View File

@ -117,6 +117,7 @@ impl<A: Authorization + 'static> server::Handler<HttpStream> for Router<A> {
"404 Not Found", "404 Not Found",
"Requested content was not found.", "Requested content was not found.",
None, None,
self.signer_port,
)) ))
}, },
// Redirect any other GET request to signer. // Redirect any other GET request to signer.
@ -131,6 +132,7 @@ impl<A: Authorization + 'static> server::Handler<HttpStream> for Router<A> {
"404 Not Found", "404 Not Found",
"Your homepage is not available when Trusted Signer is disabled.", "Your homepage is not available when Trusted Signer is disabled.",
Some("You can still access dapps by writing a correct address, though. Re-enabled Signer to get your homepage back."), Some("You can still access dapps by writing a correct address, though. Re-enabled Signer to get your homepage back."),
self.signer_port,
)) ))
} }
}, },

View File

@ -14,7 +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 tests::helpers::{serve_with_registrar, serve_with_registrar_and_sync, request, assert_security_headers}; use tests::helpers::{serve_with_registrar, serve_with_registrar_and_sync, request, assert_security_headers_for_embed};
#[test] #[test]
fn should_resolve_dapp() { fn should_resolve_dapp() {
@ -34,7 +34,7 @@ fn should_resolve_dapp() {
// then // then
assert_eq!(response.status, "HTTP/1.1 404 Not Found".to_owned()); assert_eq!(response.status, "HTTP/1.1 404 Not Found".to_owned());
assert_eq!(registrar.calls.lock().len(), 2); assert_eq!(registrar.calls.lock().len(), 2);
assert_security_headers(&response.headers); assert_security_headers_for_embed(&response.headers);
} }
#[test] #[test]
@ -63,5 +63,5 @@ fn should_return_503_when_syncing_but_should_make_the_calls() {
// then // then
assert_eq!(response.status, "HTTP/1.1 503 Service Unavailable".to_owned()); assert_eq!(response.status, "HTTP/1.1 503 Service Unavailable".to_owned());
assert_eq!(registrar.calls.lock().len(), 4); assert_eq!(registrar.calls.lock().len(), 4);
assert_security_headers(&response.headers); assert_security_headers_for_embed(&response.headers);
} }

View File

@ -14,7 +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 tests::helpers::{serve, request, assert_security_headers}; use tests::helpers::{serve, request, assert_security_headers, assert_security_headers_for_embed};
#[test] #[test]
fn should_redirect_to_home() { fn should_redirect_to_home() {
@ -93,7 +93,7 @@ fn should_display_404_on_invalid_dapp() {
// then // then
assert_eq!(response.status, "HTTP/1.1 404 Not Found".to_owned()); assert_eq!(response.status, "HTTP/1.1 404 Not Found".to_owned());
assert_security_headers(&response.headers); assert_security_headers_for_embed(&response.headers);
} }
#[test] #[test]
@ -113,7 +113,7 @@ fn should_display_404_on_invalid_dapp_with_domain() {
// then // then
assert_eq!(response.status, "HTTP/1.1 404 Not Found".to_owned()); assert_eq!(response.status, "HTTP/1.1 404 Not Found".to_owned());
assert_security_headers(&response.headers); assert_security_headers_for_embed(&response.headers);
} }
#[test] #[test]