diff options
-rw-r--r-- | components/net/fetch/request.rs | 15 | ||||
-rw-r--r-- | components/net/fetch/response.rs | 80 | ||||
-rw-r--r-- | components/net_traits/lib.rs | 86 |
3 files changed, 104 insertions, 77 deletions
diff --git a/components/net/fetch/request.rs b/components/net/fetch/request.rs index 1751fed49ba..d5b2439553a 100644 --- a/components/net/fetch/request.rs +++ b/components/net/fetch/request.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use fetch::cors_cache::{CORSCache, CacheRequestDetails}; -use fetch::response::{Response, ResponseType}; +use fetch::response::ResponseMethods; use hyper::header::{Accept, IfMatch, IfRange, IfUnmodifiedSince, Location}; use hyper::header::{AcceptLanguage, ContentLanguage, HeaderView}; use hyper::header::{ContentType, Header, Headers, IfModifiedSince, IfNoneMatch}; @@ -11,9 +11,11 @@ use hyper::header::{QualityItem, q, qitem}; use hyper::method::Method; use hyper::mime::{Attr, Mime, SubLevel, TopLevel, Value}; use hyper::status::StatusCode; +use net_traits::{AsyncFetchListener, Response, ResponseType, Metadata}; use std::ascii::AsciiExt; use std::str::FromStr; use url::Url; +use util::task::spawn_named; /// A [request context](https://fetch.spec.whatwg.org/#concept-request-context) #[derive(Copy, Clone, PartialEq)] @@ -112,7 +114,7 @@ pub struct Request { pub redirect_mode: RedirectMode, pub redirect_count: usize, pub response_tainting: ResponseTainting, - pub cache: Option<Box<CORSCache + 'static>> + pub cache: Option<Box<CORSCache + Send>> } impl Request { @@ -145,6 +147,15 @@ impl Request { } } + pub fn fetch_async(mut self, + cors_flag: bool, + listener: Box<AsyncFetchListener + Send>) { + spawn_named(format!("fetch for {:?}", self.url.serialize()), move || { + let res = self.fetch(cors_flag); + listener.response_available(res); + }); + } + /// [Fetch](https://fetch.spec.whatwg.org#concept-fetch) pub fn fetch(&mut self, cors_flag: bool) -> Response { // Step 1 diff --git a/components/net/fetch/response.rs b/components/net/fetch/response.rs index 8d41a1c81a4..fe39e1495c0 100644 --- a/components/net/fetch/response.rs +++ b/components/net/fetch/response.rs @@ -4,65 +4,18 @@ use hyper::header::Headers; use hyper::status::StatusCode; +use net_traits::{Response, ResponseBody, ResponseType}; use std::ascii::AsciiExt; use std::sync::mpsc::Receiver; use url::Url; -/// [Response type](https://fetch.spec.whatwg.org/#concept-response-type) -#[derive(Clone, PartialEq, Copy)] -pub enum ResponseType { - Basic, - CORS, - Default, - Error, - Opaque +pub trait ResponseMethods { + fn new() -> Response; + fn to_filtered(self, ResponseType) -> Response; } -/// [Response termination reason](https://fetch.spec.whatwg.org/#concept-response-termination-reason) -#[derive(Clone, Copy)] -pub enum TerminationReason { - EndUserAbort, - Fatal, - Timeout -} - -/// The response body can still be pushed to after fetch -/// This provides a way to store unfinished response bodies -#[derive(Clone)] -pub enum ResponseBody { - Empty, // XXXManishearth is this necessary, or is Done(vec![]) enough? - Receiving(Vec<u8>), - Done(Vec<u8>), -} - -pub enum ResponseMsg { - Chunk(Vec<u8>), - Finished, - Errored -} - -pub struct ResponseLoader { - response: Response, - chan: Receiver<ResponseMsg> -} - -/// A [Response](https://fetch.spec.whatwg.org/#concept-response) as defined by the Fetch spec -#[derive(Clone)] -pub struct Response { - pub response_type: ResponseType, - pub termination_reason: Option<TerminationReason>, - pub url: Option<Url>, - /// `None` can be considered a StatusCode of `0`. - pub status: Option<StatusCode>, - pub headers: Headers, - pub body: ResponseBody, - /// [Internal response](https://fetch.spec.whatwg.org/#concept-internal-response), only used if the Response - /// is a filtered response - pub internal_response: Option<Box<Response>>, -} - -impl Response { - pub fn new() -> Response { +impl ResponseMethods for Response { + fn new() -> Response { Response { response_type: ResponseType::Default, termination_reason: None, @@ -74,28 +27,9 @@ impl Response { } } - pub fn network_error() -> Response { - Response { - response_type: ResponseType::Error, - termination_reason: None, - url: None, - status: None, - headers: Headers::new(), - body: ResponseBody::Empty, - internal_response: None - } - } - - pub fn is_network_error(&self) -> bool { - match self.response_type { - ResponseType::Error => true, - _ => false - } - } - /// Convert to a filtered response, of type `filter_type`. /// Do not use with type Error or Default - pub fn to_filtered(self, filter_type: ResponseType) -> Response { + fn to_filtered(self, filter_type: ResponseType) -> Response { assert!(filter_type != ResponseType::Error); assert!(filter_type != ResponseType::Default); if self.is_network_error() { diff --git a/components/net_traits/lib.rs b/components/net_traits/lib.rs index 68911832989..86c7c85b204 100644 --- a/components/net_traits/lib.rs +++ b/components/net_traits/lib.rs @@ -5,12 +5,13 @@ #![feature(box_syntax)] #![feature(custom_attribute)] #![feature(custom_derive)] +#![feature(box_raw)] #![feature(plugin)] #![feature(slice_patterns)] #![feature(step_by)] #![feature(vec_push_all)] - -#![plugin(plugins, serde_macros)] +#![feature(custom_attribute)] +#![plugin(serde_macros, plugins)] #![plugin(regex_macros)] #[macro_use] @@ -30,10 +31,12 @@ use hyper::header::{ContentType, Headers}; use hyper::http::RawStatus; use hyper::method::Method; use hyper::mime::{Attr, Mime}; +use hyper::status::StatusCode; use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; use msg::constellation_msg::{PipelineId}; use regex::Regex; use serde::{Deserializer, Serializer}; +use std::sync::mpsc::Receiver; use std::thread; use url::Url; use util::mem::HeapSizeOf; @@ -47,6 +50,80 @@ pub static IPV4_REGEX: Regex = regex!( r"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"); pub static IPV6_REGEX: Regex = regex!(r"^([a-fA-F0-9]{0,4}[:]?){1,8}(/\d{1,3})?$"); +/// [Response type](https://fetch.spec.whatwg.org/#concept-response-type) +#[derive(Clone, PartialEq, Copy)] +pub enum ResponseType { + Basic, + CORS, + Default, + Error, + Opaque +} + +/// [Response termination reason](https://fetch.spec.whatwg.org/#concept-response-termination-reason) +#[derive(Clone, Copy)] +pub enum TerminationReason { + EndUserAbort, + Fatal, + Timeout +} + +/// The response body can still be pushed to after fetch +/// This provides a way to store unfinished response bodies +#[derive(Clone)] +pub enum ResponseBody { + Empty, // XXXManishearth is this necessary, or is Done(vec![]) enough? + Receiving(Vec<u8>), + Done(Vec<u8>), +} + +pub enum ResponseMsg { + Chunk(Vec<u8>), + Finished, + Errored +} + +pub struct ResponseLoader { + response: Response, + chan: Receiver<ResponseMsg> +} + +/// A [Response](https://fetch.spec.whatwg.org/#concept-response) as defined by the Fetch spec +#[derive(Clone)] +pub struct Response { + pub response_type: ResponseType, + pub termination_reason: Option<TerminationReason>, + pub url: Option<Url>, + /// `None` can be considered a StatusCode of `0`. + pub status: Option<StatusCode>, + pub headers: Headers, + pub body: ResponseBody, + /// [Internal response](https://fetch.spec.whatwg.org/#concept-internal-response), only used if the Response + /// is a filtered response + pub internal_response: Option<Box<Response>>, +} + +impl Response { + pub fn network_error() -> Response { + Response { + response_type: ResponseType::Error, + termination_reason: None, + url: None, + status: None, + headers: Headers::new(), + body: ResponseBody::Empty, + internal_response: None + } + } + + pub fn is_network_error(&self) -> bool { + match self.response_type { + ResponseType::Error => true, + _ => false + } + } +} + /// Image handling. /// /// It may be surprising that this goes in the network crate as opposed to the graphics crate. @@ -85,6 +162,11 @@ impl LoadData { } } +/// Interface for observing the final response for an asynchronous fetch operation. +pub trait AsyncFetchListener { + fn response_available(&self, response: Response); +} + /// A listener for asynchronous network events. Cancelling the underlying request is unsupported. pub trait AsyncResponseListener { /// The response headers for a request have been received. |