From c6912c8e0a48a01bce08c96658921f20be9cb7dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Thu, 15 Dec 2016 11:38:05 +0100 Subject: [PATCH 1/3] Removing on_done --- dapps/src/apps/fetcher.rs | 169 ++++++++++++++++++------------------ dapps/src/handlers/fetch.rs | 18 +--- 2 files changed, 90 insertions(+), 97 deletions(-) diff --git a/dapps/src/apps/fetcher.rs b/dapps/src/apps/fetcher.rs index 2430af035..e1fa4c066 100644 --- a/dapps/src/apps/fetcher.rs +++ b/dapps/src/apps/fetcher.rs @@ -120,7 +120,7 @@ impl ContentFetcher { // Content is already being fetched Some(&mut ContentStatus::Fetching(ref fetch_control)) => { trace!(target: "dapps", "Content fetching in progress. Waiting..."); - (None, fetch_control.to_handler(control)) + (None, fetch_control.to_async_handler(path, control)) }, // We need to start fetching the content None => { @@ -129,11 +129,12 @@ impl ContentFetcher { let content = self.resolver.resolve(content_hex); let cache = self.cache.clone(); - let on_done = move |id: String, result: Option| { + let id = content_id.clone(); + let on_done = move |result: Option| { let mut cache = cache.lock(); match result { Some(endpoint) => { - cache.insert(id, ContentStatus::Ready(endpoint)); + cache.insert(id.clone(), ContentStatus::Ready(endpoint)); }, // In case of error None => { @@ -248,43 +249,45 @@ struct ContentInstaller { id: String, mime: String, content_path: PathBuf, - on_done: Box) + Send>, + on_done: Box) + Send>, } impl ContentValidator for ContentInstaller { type Error = ValidationError; fn validate_and_install(&self, path: PathBuf) -> Result<(String, LocalPageEndpoint), ValidationError> { - // Create dir - try!(fs::create_dir_all(&self.content_path)); + let validate = || { + // Create dir + try!(fs::create_dir_all(&self.content_path)); - // Validate hash - let mut file_reader = io::BufReader::new(try!(fs::File::open(&path))); - let hash = try!(sha3(&mut file_reader)); - let id = try!(self.id.as_str().parse().map_err(|_| ValidationError::InvalidContentId)); - if id != hash { - return Err(ValidationError::HashMismatch { - expected: id, - got: hash, - }); - } + // Validate hash + let mut file_reader = io::BufReader::new(try!(fs::File::open(&path))); + let hash = try!(sha3(&mut file_reader)); + let id = try!(self.id.as_str().parse().map_err(|_| ValidationError::InvalidContentId)); + if id != hash { + return Err(ValidationError::HashMismatch { + expected: id, + got: hash, + }); + } - // And prepare path for a file - let filename = path.file_name().expect("We always fetch a file."); - let mut content_path = self.content_path.clone(); - content_path.push(&filename); + // And prepare path for a file + let filename = path.file_name().expect("We always fetch a file."); + let mut content_path = self.content_path.clone(); + content_path.push(&filename); - if content_path.exists() { - try!(fs::remove_dir_all(&content_path)) - } + if content_path.exists() { + try!(fs::remove_dir_all(&content_path)) + } - try!(fs::copy(&path, &content_path)); + try!(fs::copy(&path, &content_path)); + Ok(LocalPageEndpoint::single_file(content_path, self.mime.clone(), PageCache::Enabled)) + }; - Ok((self.id.clone(), LocalPageEndpoint::single_file(content_path, self.mime.clone(), PageCache::Enabled))) - } - - fn done(&self, endpoint: Option) { - (self.on_done)(self.id.clone(), endpoint) + // Make sure to always call on_done (even in case of errors)! + let result = validate(); + (self.on_done)(result.as_ref().ok().cloned()); + result.map(|endpoint| (self.id.clone(), endpoint)) } } @@ -292,7 +295,7 @@ impl ContentValidator for ContentInstaller { struct DappInstaller { id: String, dapps_path: PathBuf, - on_done: Box) + Send>, + on_done: Box) + Send>, embeddable_on: Option<(String, u16)>, } @@ -333,67 +336,67 @@ impl ContentValidator for DappInstaller { fn validate_and_install(&self, app_path: PathBuf) -> Result<(String, LocalPageEndpoint), ValidationError> { trace!(target: "dapps", "Opening dapp bundle at {:?}", app_path); - let mut file_reader = io::BufReader::new(try!(fs::File::open(app_path))); - let hash = try!(sha3(&mut file_reader)); - let id = try!(self.id.as_str().parse().map_err(|_| ValidationError::InvalidContentId)); - if id != hash { - return Err(ValidationError::HashMismatch { - expected: id, - got: hash, - }); - } - let file = file_reader.into_inner(); - // Unpack archive - let mut zip = try!(zip::ZipArchive::new(file)); - // First find manifest file - let (mut manifest, manifest_dir) = try!(Self::find_manifest(&mut zip)); - // Overwrite id to match hash - manifest.id = self.id.clone(); + let validate = || { + let mut file_reader = io::BufReader::new(try!(fs::File::open(app_path))); + let hash = try!(sha3(&mut file_reader)); + let id = try!(self.id.as_str().parse().map_err(|_| ValidationError::InvalidContentId)); + if id != hash { + return Err(ValidationError::HashMismatch { + expected: id, + got: hash, + }); + } + let file = file_reader.into_inner(); + // Unpack archive + let mut zip = try!(zip::ZipArchive::new(file)); + // First find manifest file + let (mut manifest, manifest_dir) = try!(Self::find_manifest(&mut zip)); + // Overwrite id to match hash + manifest.id = self.id.clone(); - let target = self.dapp_target_path(&manifest); + let target = self.dapp_target_path(&manifest); - // Remove old directory - if target.exists() { - warn!(target: "dapps", "Overwriting existing dapp: {}", manifest.id); - try!(fs::remove_dir_all(target.clone())); - } + // Remove old directory + if target.exists() { + warn!(target: "dapps", "Overwriting existing dapp: {}", manifest.id); + try!(fs::remove_dir_all(target.clone())); + } - // Unpack zip - for i in 0..zip.len() { - let mut file = try!(zip.by_index(i)); - // TODO [todr] Check if it's consistent on windows. - let is_dir = file.name().chars().rev().next() == Some('/'); + // Unpack zip + for i in 0..zip.len() { + let mut file = try!(zip.by_index(i)); + // TODO [todr] Check if it's consistent on windows. + let is_dir = file.name().chars().rev().next() == Some('/'); - let file_path = PathBuf::from(file.name()); - let location_in_manifest_base = file_path.strip_prefix(&manifest_dir); - // Create files that are inside manifest directory - if let Ok(location_in_manifest_base) = location_in_manifest_base { - let p = target.join(location_in_manifest_base); - // Check if it's a directory - if is_dir { - try!(fs::create_dir_all(p)); - } else { - let mut target = try!(fs::File::create(p)); - try!(io::copy(&mut file, &mut target)); + let file_path = PathBuf::from(file.name()); + let location_in_manifest_base = file_path.strip_prefix(&manifest_dir); + // Create files that are inside manifest directory + if let Ok(location_in_manifest_base) = location_in_manifest_base { + let p = target.join(location_in_manifest_base); + // Check if it's a directory + if is_dir { + try!(fs::create_dir_all(p)); + } else { + let mut target = try!(fs::File::create(p)); + try!(io::copy(&mut file, &mut target)); + } } } - } - // Write manifest - let manifest_str = try!(serialize_manifest(&manifest).map_err(ValidationError::ManifestSerialization)); - let manifest_path = target.join(MANIFEST_FILENAME); - let mut manifest_file = try!(fs::File::create(manifest_path)); - try!(manifest_file.write_all(manifest_str.as_bytes())); + // Write manifest + let manifest_str = try!(serialize_manifest(&manifest).map_err(ValidationError::ManifestSerialization)); + let manifest_path = target.join(MANIFEST_FILENAME); + let mut manifest_file = try!(fs::File::create(manifest_path)); + try!(manifest_file.write_all(manifest_str.as_bytes())); + // Create endpoint + let endpoint = LocalPageEndpoint::new(target, manifest.clone().into(), PageCache::Enabled, self.embeddable_on.clone()); + // Return modified app manifest + Ok(endpoint) + }; - // Create endpoint - let app = LocalPageEndpoint::new(target, manifest.clone().into(), PageCache::Enabled, self.embeddable_on.clone()); - - // Return modified app manifest - Ok((manifest.id.clone(), app)) - } - - fn done(&self, endpoint: Option) { - (self.on_done)(self.id.clone(), endpoint) + let result = validate(); + (self.on_done)(result.as_ref().ok().cloned()); + result.map(|endpoint| (self.id.clone(), endpoint)) } } diff --git a/dapps/src/handlers/fetch.rs b/dapps/src/handlers/fetch.rs index 6fb524293..8e5f250ce 100644 --- a/dapps/src/handlers/fetch.rs +++ b/dapps/src/handlers/fetch.rs @@ -29,6 +29,7 @@ use hyper::{server, Decoder, Encoder, Next, Method, Control}; use hyper::net::HttpStream; use hyper::status::StatusCode; +use endpoint::EndpointPath; use handlers::{ContentHandler, Redirection, extract_url}; use page::LocalPageEndpoint; @@ -45,7 +46,6 @@ pub trait ContentValidator { type Error: fmt::Debug + fmt::Display; fn validate_and_install(&self, app: PathBuf) -> Result<(String, LocalPageEndpoint), Self::Error>; - fn done(&self, Option); } pub struct FetchControl { @@ -88,7 +88,9 @@ impl FetchControl { self.abort.store(true, Ordering::SeqCst); } - pub fn to_handler(&self, control: Control) -> Box + Send> { + pub fn to_async_handler(&self, path: EndpointPath, control: Control) -> Box + Send> { + // TODO [ToDr] We should be able to pass EndpointPath to handler as well + // (request may be coming from different domain, etc) let (tx, rx) = mpsc::channel(); self.listeners.lock().push((control, tx)); @@ -141,25 +143,13 @@ pub struct ContentFetcherHandler { embeddable_on: Option<(String, u16)>, } -impl Drop for ContentFetcherHandler { - fn drop(&mut self) { - let result = match self.status { - FetchState::Done(_, ref result, _) => Some(result.clone()), - _ => None, - }; - self.installer.done(result); - } -} - impl ContentFetcherHandler { - pub fn new( url: String, control: Control, handler: H, embeddable_on: Option<(String, u16)>, ) -> (Self, Arc) { - let fetch_control = Arc::new(FetchControl::default()); let client = Client::default(); let handler = ContentFetcherHandler { From dedf9d6dcee2acd694723073c6ddd6f8355e4eca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Thu, 15 Dec 2016 14:46:10 +0100 Subject: [PATCH 2/3] Getting rid of redirection --- dapps/src/apps/fetcher.rs | 15 +++--- dapps/src/handlers/fetch.rs | 99 ++++++++++++++++++++++++------------- dapps/src/page/handler.rs | 33 +++++++++---- dapps/src/page/local.rs | 50 ++++++++++++------- dapps/src/page/mod.rs | 2 +- 5 files changed, 129 insertions(+), 70 deletions(-) diff --git a/dapps/src/apps/fetcher.rs b/dapps/src/apps/fetcher.rs index e1fa4c066..006858e73 100644 --- a/dapps/src/apps/fetcher.rs +++ b/dapps/src/apps/fetcher.rs @@ -151,6 +151,7 @@ impl ContentFetcher { Some(URLHintResult::Dapp(dapp)) => { let (handler, fetch_control) = ContentFetcherHandler::new( dapp.url(), + path, control, DappInstaller { id: content_id.clone(), @@ -166,6 +167,7 @@ impl ContentFetcher { Some(URLHintResult::Content(content)) => { let (handler, fetch_control) = ContentFetcherHandler::new( content.url, + path, control, ContentInstaller { id: content_id.clone(), @@ -255,7 +257,7 @@ struct ContentInstaller { impl ContentValidator for ContentInstaller { type Error = ValidationError; - fn validate_and_install(&self, path: PathBuf) -> Result<(String, LocalPageEndpoint), ValidationError> { + fn validate_and_install(&self, path: PathBuf) -> Result { let validate = || { // Create dir try!(fs::create_dir_all(&self.content_path)); @@ -287,7 +289,7 @@ impl ContentValidator for ContentInstaller { // Make sure to always call on_done (even in case of errors)! let result = validate(); (self.on_done)(result.as_ref().ok().cloned()); - result.map(|endpoint| (self.id.clone(), endpoint)) + result } } @@ -334,10 +336,10 @@ impl DappInstaller { impl ContentValidator for DappInstaller { type Error = ValidationError; - fn validate_and_install(&self, app_path: PathBuf) -> Result<(String, LocalPageEndpoint), ValidationError> { - trace!(target: "dapps", "Opening dapp bundle at {:?}", app_path); + fn validate_and_install(&self, path: PathBuf) -> Result { + trace!(target: "dapps", "Opening dapp bundle at {:?}", path); let validate = || { - let mut file_reader = io::BufReader::new(try!(fs::File::open(app_path))); + let mut file_reader = io::BufReader::new(try!(fs::File::open(path))); let hash = try!(sha3(&mut file_reader)); let id = try!(self.id.as_str().parse().map_err(|_| ValidationError::InvalidContentId)); if id != hash { @@ -390,13 +392,12 @@ impl ContentValidator for DappInstaller { try!(manifest_file.write_all(manifest_str.as_bytes())); // Create endpoint let endpoint = LocalPageEndpoint::new(target, manifest.clone().into(), PageCache::Enabled, self.embeddable_on.clone()); - // Return modified app manifest Ok(endpoint) }; let result = validate(); (self.on_done)(result.as_ref().ok().cloned()); - result.map(|endpoint| (self.id.clone(), endpoint)) + result } } diff --git a/dapps/src/handlers/fetch.rs b/dapps/src/handlers/fetch.rs index 8e5f250ce..d62b425d9 100644 --- a/dapps/src/handlers/fetch.rs +++ b/dapps/src/handlers/fetch.rs @@ -22,35 +22,41 @@ use std::sync::{mpsc, Arc}; use std::sync::atomic::{AtomicBool, Ordering}; use std::time::{Instant, Duration}; use util::Mutex; -use url::Url; use fetch::{Client, Fetch, FetchResult}; use hyper::{server, Decoder, Encoder, Next, Method, Control}; use hyper::net::HttpStream; +use hyper::uri::RequestUri; use hyper::status::StatusCode; use endpoint::EndpointPath; -use handlers::{ContentHandler, Redirection, extract_url}; -use page::LocalPageEndpoint; +use handlers::ContentHandler; +use page::{LocalPageEndpoint, PageHandlerWaiting}; const FETCH_TIMEOUT: u64 = 30; enum FetchState { + Waiting, NotStarted(String), Error(ContentHandler), InProgress(mpsc::Receiver), - Done(String, LocalPageEndpoint, Redirection), + Done(LocalPageEndpoint, Box), +} + +enum WaitResult { + Error(ContentHandler), + Done(LocalPageEndpoint), } pub trait ContentValidator { type Error: fmt::Debug + fmt::Display; - fn validate_and_install(&self, app: PathBuf) -> Result<(String, LocalPageEndpoint), Self::Error>; + fn validate_and_install(&self, path: PathBuf) -> Result; } pub struct FetchControl { abort: Arc, - listeners: Mutex)>>, + listeners: Mutex)>>, deadline: Instant, } @@ -65,9 +71,10 @@ impl Default for FetchControl { } impl FetchControl { - fn notify FetchState>(&self, status: F) { + fn notify WaitResult>(&self, status: F) { let mut listeners = self.listeners.lock(); for (control, sender) in listeners.drain(..) { + trace!(target: "dapps", "Resuming request waiting for content..."); if let Err(e) = sender.send(status()) { trace!(target: "dapps", "Waiting listener notification failed: {:?}", e); } else { @@ -78,9 +85,9 @@ impl FetchControl { fn set_status(&self, status: &FetchState) { match *status { - FetchState::Error(ref handler) => self.notify(|| FetchState::Error(handler.clone())), - FetchState::Done(ref id, ref endpoint, ref handler) => self.notify(|| FetchState::Done(id.clone(), endpoint.clone(), handler.clone())), - FetchState::NotStarted(_) | FetchState::InProgress(_) => {}, + FetchState::Error(ref handler) => self.notify(|| WaitResult::Error(handler.clone())), + FetchState::Done(ref endpoint, _) => self.notify(|| WaitResult::Done(endpoint.clone())), + FetchState::NotStarted(_) | FetchState::InProgress(_) | FetchState::Waiting => {}, } } @@ -89,45 +96,65 @@ impl FetchControl { } pub fn to_async_handler(&self, path: EndpointPath, control: Control) -> Box + Send> { - // TODO [ToDr] We should be able to pass EndpointPath to handler as well - // (request may be coming from different domain, etc) let (tx, rx) = mpsc::channel(); self.listeners.lock().push((control, tx)); Box::new(WaitingHandler { receiver: rx, - state: None, + state: FetchState::Waiting, + uri: RequestUri::default(), + path: path, }) } } pub struct WaitingHandler { - receiver: mpsc::Receiver, - state: Option, + receiver: mpsc::Receiver, + state: FetchState, + uri: RequestUri, + path: EndpointPath, } impl server::Handler for WaitingHandler { - fn on_request(&mut self, _request: server::Request) -> Next { + fn on_request(&mut self, request: server::Request) -> Next { + self.uri = request.uri().clone(); Next::wait() } - fn on_request_readable(&mut self, _decoder: &mut Decoder) -> Next { - self.state = self.receiver.try_recv().ok(); - Next::write() + fn on_request_readable(&mut self, decoder: &mut Decoder) -> Next { + let result = self.receiver.try_recv().ok(); + self.state = match result { + Some(WaitResult::Error(handler)) => FetchState::Error(handler), + Some(WaitResult::Done(endpoint)) => { + let mut page_handler = endpoint.to_page_handler(self.path.clone()); + page_handler.set_uri(&self.uri); + FetchState::Done(endpoint, page_handler) + }, + None => { + warn!("A result for waiting request was not received."); + FetchState::Waiting + }, + }; + + match self.state { + FetchState::Done(_, ref mut handler) => handler.on_request_readable(decoder), + FetchState::Error(ref mut handler) => handler.on_request_readable(decoder), + _ => Next::write(), + } } fn on_response(&mut self, res: &mut server::Response) -> Next { match self.state { - Some(FetchState::Done(_, _, ref mut handler)) => handler.on_response(res), - Some(FetchState::Error(ref mut handler)) => handler.on_response(res), + FetchState::Done(_, ref mut handler) => handler.on_response(res), + FetchState::Error(ref mut handler) => handler.on_response(res), _ => Next::end(), } } fn on_response_writable(&mut self, encoder: &mut Encoder) -> Next { match self.state { - Some(FetchState::Done(_, _, ref mut handler)) => handler.on_response_writable(encoder), - Some(FetchState::Error(ref mut handler)) => handler.on_response_writable(encoder), + FetchState::Done(_, ref mut handler) => handler.on_response_writable(encoder), + FetchState::Error(ref mut handler) => handler.on_response_writable(encoder), _ => Next::end(), } } @@ -139,13 +166,15 @@ pub struct ContentFetcherHandler { status: FetchState, client: Option, installer: H, - request_url: Option, + path: EndpointPath, + uri: RequestUri, embeddable_on: Option<(String, u16)>, } impl ContentFetcherHandler { pub fn new( url: String, + path: EndpointPath, control: Control, handler: H, embeddable_on: Option<(String, u16)>, @@ -158,7 +187,8 @@ impl ContentFetcherHandler { client: Some(client), status: FetchState::NotStarted(url), installer: handler, - request_url: None, + path: path, + uri: RequestUri::default(), embeddable_on: embeddable_on, }; @@ -182,7 +212,6 @@ impl ContentFetcherHandler { impl server::Handler for ContentFetcherHandler { fn on_request(&mut self, request: server::Request) -> Next { - self.request_url = extract_url(&request); let status = if let FetchState::NotStarted(ref url) = self.status { Some(match *request.method() { // Start fetching content @@ -195,8 +224,8 @@ impl server::Handler for ContentFetcherHandler< Ok(receiver) => FetchState::InProgress(receiver), Err(e) => FetchState::Error(ContentHandler::error( StatusCode::BadGateway, - "Unable To Start Dapp Download", - "Could not initialize download of the dapp. It might be a problem with the remote server.", + "Unable To Start Content Download", + "Could not initialize download of the content. It might be a problem with the remote server.", Some(&format!("{}", e)), self.embeddable_on.clone(), )), @@ -217,6 +246,7 @@ impl server::Handler for ContentFetcherHandler< self.fetch_control.set_status(&status); self.status = status; } + self.uri = request.uri().clone(); Next::read() } @@ -256,11 +286,10 @@ impl server::Handler for ContentFetcherHandler< self.embeddable_on.clone(), )) }, - Ok((id, result)) => { - let url: String = self.request_url.take() - .map(|url| url.raw.into_string()) - .expect("Request URL always read in on_request; qed"); - FetchState::Done(id, result, Redirection::new(&url)) + Ok(endpoint) => { + let mut handler = endpoint.to_page_handler(self.path.clone()); + handler.set_uri(&self.uri); + FetchState::Done(endpoint, handler) }, }; // Remove temporary zip file @@ -296,7 +325,7 @@ impl server::Handler for ContentFetcherHandler< fn on_response(&mut self, res: &mut server::Response) -> Next { match self.status { - FetchState::Done(_, _, ref mut handler) => handler.on_response(res), + FetchState::Done(_, ref mut handler) => handler.on_response(res), FetchState::Error(ref mut handler) => handler.on_response(res), _ => Next::end(), } @@ -304,7 +333,7 @@ impl server::Handler for ContentFetcherHandler< fn on_response_writable(&mut self, encoder: &mut Encoder) -> Next { match self.status { - FetchState::Done(_, _, ref mut handler) => handler.on_response_writable(encoder), + FetchState::Done(_, ref mut handler) => handler.on_response_writable(encoder), FetchState::Error(ref mut handler) => handler.on_response_writable(encoder), _ => Next::end(), } diff --git a/dapps/src/page/handler.rs b/dapps/src/page/handler.rs index 382dfa5d1..ba7a7ee04 100644 --- a/dapps/src/page/handler.rs +++ b/dapps/src/page/handler.rs @@ -83,13 +83,19 @@ impl Default for PageCache { } } +/// A generic type for `PageHandler` allowing to set the URL. +/// Used by dapps fetching to set the URL after the content was downloaded. +pub trait PageHandlerWaiting: server::Handler + Send { + fn set_uri(&mut self, uri: &RequestUri); +} + /// A handler for a single webapp. /// Resolves correct paths and serves as a plumbing code between /// hyper server and dapp. pub struct PageHandler { /// A Dapp. pub app: T, - /// File currently being served (or `None` if file does not exist). + /// File currently being served pub file: ServedFile, /// Optional prefix to strip from path. pub prefix: Option, @@ -101,6 +107,21 @@ pub struct PageHandler { pub cache: PageCache, } +impl PageHandlerWaiting for PageHandler { + fn set_uri(&mut self, uri: &RequestUri) { + trace!(target: "dapps", "Setting URI: {:?}", uri); + self.file = match *uri { + RequestUri::AbsolutePath { ref path, .. } => { + self.app.file(&self.extract_path(path)) + }, + RequestUri::AbsoluteUri(ref url) => { + self.app.file(&self.extract_path(url.path())) + }, + _ => None, + }.map_or_else(|| ServedFile::new(self.safe_to_embed_on.clone()), |f| ServedFile::File(f)); + } +} + impl PageHandler { fn extract_path(&self, path: &str) -> String { let app_id = &self.path.app_id; @@ -124,15 +145,7 @@ impl PageHandler { impl server::Handler for PageHandler { fn on_request(&mut self, req: server::Request) -> Next { - self.file = match *req.uri() { - RequestUri::AbsolutePath { ref path, .. } => { - self.app.file(&self.extract_path(path)) - }, - RequestUri::AbsoluteUri(ref url) => { - self.app.file(&self.extract_path(url.path())) - }, - _ => None, - }.map_or_else(|| ServedFile::new(self.safe_to_embed_on.clone()), |f| ServedFile::File(f)); + self.set_uri(req.uri()); Next::write() } diff --git a/dapps/src/page/local.rs b/dapps/src/page/local.rs index 77c91019d..e8ab9ce14 100644 --- a/dapps/src/page/local.rs +++ b/dapps/src/page/local.rs @@ -18,7 +18,7 @@ use mime_guess; use std::io::{Seek, Read, SeekFrom}; use std::fs; use std::path::{Path, PathBuf}; -use page::handler::{self, PageCache}; +use page::handler::{self, PageCache, PageHandlerWaiting}; use endpoint::{Endpoint, EndpointInfo, EndpointPath, Handler}; #[derive(Debug, Clone)] @@ -54,6 +54,36 @@ impl LocalPageEndpoint { pub fn path(&self) -> PathBuf { self.path.clone() } + + fn page_handler_with_mime(&self, path: EndpointPath, mime: &str) -> handler::PageHandler { + handler::PageHandler { + app: LocalSingleFile { path: self.path.clone(), mime: mime.into() }, + prefix: None, + path: path, + file: handler::ServedFile::new(None), + safe_to_embed_on: self.embeddable_on.clone(), + cache: self.cache, + } + } + + fn page_handler(&self, path: EndpointPath) -> handler::PageHandler { + handler::PageHandler { + app: LocalDapp { path: self.path.clone() }, + prefix: None, + path: path, + file: handler::ServedFile::new(None), + safe_to_embed_on: self.embeddable_on.clone(), + cache: self.cache, + } + } + + pub fn to_page_handler(&self, path: EndpointPath) -> Box { + if let Some(ref mime) = self.mime { + Box::new(self.page_handler_with_mime(path, mime)) + } else { + Box::new(self.page_handler(path)) + } + } } impl Endpoint for LocalPageEndpoint { @@ -63,23 +93,9 @@ impl Endpoint for LocalPageEndpoint { fn to_handler(&self, path: EndpointPath) -> Box { if let Some(ref mime) = self.mime { - Box::new(handler::PageHandler { - app: LocalSingleFile { path: self.path.clone(), mime: mime.clone() }, - prefix: None, - path: path, - file: handler::ServedFile::new(None), - safe_to_embed_on: self.embeddable_on.clone(), - cache: self.cache, - }) + Box::new(self.page_handler_with_mime(path, mime)) } else { - Box::new(handler::PageHandler { - app: LocalDapp { path: self.path.clone() }, - prefix: None, - path: path, - file: handler::ServedFile::new(None), - safe_to_embed_on: self.embeddable_on.clone(), - cache: self.cache, - }) + Box::new(self.page_handler(path)) } } } diff --git a/dapps/src/page/mod.rs b/dapps/src/page/mod.rs index 9619f1b10..5c2b008f8 100644 --- a/dapps/src/page/mod.rs +++ b/dapps/src/page/mod.rs @@ -21,5 +21,5 @@ mod handler; pub use self::local::LocalPageEndpoint; pub use self::builtin::PageEndpoint; -pub use self::handler::PageCache; +pub use self::handler::{PageCache, PageHandlerWaiting}; From 2be6223eb32ab941e09ba82105cbcafd01718c70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Thu, 15 Dec 2016 15:57:21 +0100 Subject: [PATCH 3/3] Updating submodules to latest --- ethcore/res/ethereum/tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethcore/res/ethereum/tests b/ethcore/res/ethereum/tests index 9028c4801..e8f4624b7 160000 --- a/ethcore/res/ethereum/tests +++ b/ethcore/res/ethereum/tests @@ -1 +1 @@ -Subproject commit 9028c4801fd39fbb71a9796979182549a24e81c8 +Subproject commit e8f4624b7f1a15c63674eecf577c7ab76c3b16be