diff options
Diffstat (limited to 'components/net_traits/lib.rs')
-rw-r--r-- | components/net_traits/lib.rs | 103 |
1 files changed, 96 insertions, 7 deletions
diff --git a/components/net_traits/lib.rs b/components/net_traits/lib.rs index 4af820b0ebd..bb8638d7c3c 100644 --- a/components/net_traits/lib.rs +++ b/components/net_traits/lib.rs @@ -36,6 +36,8 @@ use hyper::method::Method; use hyper::mime::{Attr, Mime}; use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; use msg::constellation_msg::{PipelineId, ReferrerPolicy}; +use request::{Request, RequestInit}; +use response::{HttpsState, Response}; use std::io::Error as IOError; use std::sync::mpsc::Sender; use std::thread; @@ -112,6 +114,7 @@ pub struct LoadData { pub headers: Headers, #[ignore_heap_size_of = "Defined in hyper"] /// Headers that will apply to the initial request and any redirects + /// Unused in fetch pub preserved_headers: Headers, pub data: Option<Vec<u8>>, pub cors: Option<ResourceCORSData>, @@ -154,9 +157,81 @@ pub trait LoadOrigin { fn pipeline_id(&self) -> Option<PipelineId>; } -/// Interface for observing the final response for an asynchronous fetch operation. -pub trait AsyncFetchListener { - fn response_available(&self, response: response::Response); +#[derive(Deserialize, Serialize)] +pub enum FetchResponseMsg { + // todo: should have fields for transmitted/total bytes + ProcessRequestBody, + ProcessRequestEOF, + // todo: send more info about the response (or perhaps the entire Response) + ProcessResponse(Result<Metadata, NetworkError>), + ProcessResponseChunk(Vec<u8>), + ProcessResponseEOF(Result<(), NetworkError>), +} + +pub trait FetchTaskTarget { + /// https://fetch.spec.whatwg.org/#process-request-body + /// + /// Fired when a chunk of the request body is transmitted + fn process_request_body(&mut self, request: &Request); + + /// https://fetch.spec.whatwg.org/#process-request-end-of-file + /// + /// Fired when the entire request finishes being transmitted + fn process_request_eof(&mut self, request: &Request); + + /// https://fetch.spec.whatwg.org/#process-response + /// + /// Fired when headers are received + fn process_response(&mut self, response: &Response); + + /// Fired when a chunk of response content is received + fn process_response_chunk(&mut self, chunk: Vec<u8>); + + /// https://fetch.spec.whatwg.org/#process-response-end-of-file + /// + /// Fired when the response is fully fetched + fn process_response_eof(&mut self, response: &Response); +} + +pub trait FetchResponseListener { + fn process_request_body(&mut self); + fn process_request_eof(&mut self); + fn process_response(&mut self, metadata: Result<Metadata, NetworkError>); + fn process_response_chunk(&mut self, chunk: Vec<u8>); + fn process_response_eof(&mut self, response: Result<(), NetworkError>); +} + +impl FetchTaskTarget for IpcSender<FetchResponseMsg> { + fn process_request_body(&mut self, _: &Request) { + let _ = self.send(FetchResponseMsg::ProcessRequestBody); + } + + fn process_request_eof(&mut self, _: &Request) { + let _ = self.send(FetchResponseMsg::ProcessRequestEOF); + } + + fn process_response(&mut self, response: &Response) { + let _ = self.send(FetchResponseMsg::ProcessResponse(response.metadata())); + } + + fn process_response_chunk(&mut self, chunk: Vec<u8>) { + let _ = self.send(FetchResponseMsg::ProcessResponseChunk(chunk)); + } + + fn process_response_eof(&mut self, response: &Response) { + if response.is_network_error() { + // todo: finer grained errors + let _ = self.send(FetchResponseMsg::ProcessResponseEOF( + Err(NetworkError::Internal("Network error".into())))); + } else { + let _ = self.send(FetchResponseMsg::ProcessResponseEOF(Ok(()))); + } + } +} + + +pub trait Action<Listener> { + fn process(self, listener: &mut Listener); } /// A listener for asynchronous network events. Cancelling the underlying request is unsupported. @@ -183,9 +258,9 @@ pub enum ResponseAction { ResponseComplete(Result<(), NetworkError>) } -impl ResponseAction { +impl<T: AsyncResponseListener> Action<T> for ResponseAction { /// Execute the default action on a provided listener. - pub fn process(self, listener: &mut AsyncResponseListener) { + fn process(self, listener: &mut T) { match self { ResponseAction::HeadersAvailable(m) => listener.headers_available(m), ResponseAction::DataAvailable(d) => listener.data_available(d), @@ -194,6 +269,19 @@ impl ResponseAction { } } +impl<T: FetchResponseListener> Action<T> for FetchResponseMsg { + /// Execute the default action on a provided listener. + fn process(self, listener: &mut T) { + match self { + FetchResponseMsg::ProcessRequestBody => listener.process_request_body(), + FetchResponseMsg::ProcessRequestEOF => listener.process_request_eof(), + FetchResponseMsg::ProcessResponse(meta) => listener.process_response(meta), + FetchResponseMsg::ProcessResponseChunk(data) => listener.process_response_chunk(data), + FetchResponseMsg::ProcessResponseEOF(data) => listener.process_response_eof(data), + } + } +} + /// A target for async networking events. Commonly used to dispatch a runnable event to another /// thread storing the wrapped closure for later execution. #[derive(Deserialize, Serialize)] @@ -331,6 +419,7 @@ pub struct WebSocketConnectData { pub enum CoreResourceMsg { /// Request the data associated with a particular URL Load(LoadData, LoadConsumer, Option<IpcSender<ResourceId>>), + Fetch(RequestInit, IpcSender<FetchResponseMsg>), /// Try to make a websocket connection to a URL. WebsocketConnect(WebSocketCommunicate, WebSocketConnectData), /// Store a set of cookies for a given originating URL @@ -469,7 +558,7 @@ pub struct Metadata { pub status: Option<RawStatus>, /// Is successful HTTPS connection - pub https_state: response::HttpsState, + pub https_state: HttpsState, } impl Metadata { @@ -482,7 +571,7 @@ impl Metadata { headers: None, // https://fetch.spec.whatwg.org/#concept-response-status-message status: Some(RawStatus(200, "OK".into())), - https_state: response::HttpsState::None, + https_state: HttpsState::None, } } |