aboutsummaryrefslogtreecommitdiffstats
path: root/components/net_traits/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/net_traits/lib.rs')
-rw-r--r--components/net_traits/lib.rs103
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,
}
}