Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrap hyper::header::Headers in Rc #12884

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -29,6 +29,7 @@ use net_traits::request::{Type, Origin, Window};
use net_traits::response::{HttpsState, TerminationReason};
use net_traits::response::{Response, ResponseBody, ResponseType};
use resource_thread::CancellationListener;
use std::cell::RefCell;
use std::collections::HashSet;
use std::fs::File;
use std::io::Read;
@@ -393,7 +394,7 @@ fn basic_fetch(request: Rc<Request>, cache: &mut CORSCache,
let mut response = Response::new();
// https://github.com/whatwg/fetch/issues/312
response.url = Some(url);
response.headers.set(ContentType(mime!(Text / Html; Charset = Utf8)));
response.headers.borrow_mut().set(ContentType(mime!(Text / Html; Charset = Utf8)));
*response.body.lock().unwrap() = ResponseBody::Done(vec![]);
response
},
@@ -410,7 +411,7 @@ fn basic_fetch(request: Rc<Request>, cache: &mut CORSCache,
// https://github.com/whatwg/fetch/issues/312
response.url = Some(url.clone());
*response.body.lock().unwrap() = ResponseBody::Done(bytes);
response.headers.set(ContentType(mime));
response.headers.borrow_mut().set(ContentType(mime));
response
},
Err(_) => Response::network_error()
@@ -433,7 +434,7 @@ fn basic_fetch(request: Rc<Request>, cache: &mut CORSCache,
// https://github.com/whatwg/fetch/issues/312
response.url = Some(url.clone());
*response.body.lock().unwrap() = ResponseBody::Done(bytes);
response.headers.set(ContentType(mime));
response.headers.borrow_mut().set(ContentType(mime));
response
})
},
@@ -638,12 +639,12 @@ fn http_redirect_fetch(request: Rc<Request>,
// Step 3
// this step is done early, because querying if Location exists says
// if it is None or Some, making it easy to seperate from the retrieval failure case
if !response.actual_response().headers.has::<Location>() {
if !response.actual_response().headers.borrow().has::<Location>() {
return Rc::try_unwrap(response).ok().unwrap();
}

// Step 2
let location = match response.actual_response().headers.get::<Location>() {
let location = match response.actual_response().headers.borrow_mut().get::<Location>() {
Some(&Location(ref location)) => location.clone(),
// Step 4
_ => return Response::network_error()
@@ -971,7 +972,7 @@ fn http_network_fetch(request: Rc<Request>,
response.url = Some(url.clone());
response.status = Some(res.response.status);
response.raw_status = Some(res.response.status_raw().clone());
response.headers = res.response.headers.clone();
response.headers = Rc::new(RefCell::new(res.response.headers.clone()));

let res_body = response.body.clone();

@@ -1065,7 +1066,7 @@ fn http_network_fetch(request: Rc<Request>,
// TODO when https://bugzilla.mozilla.org/show_bug.cgi?id=1030660
// is resolved, this step will become uneccesary
// TODO this step
if let Some(encoding) = response.headers.get::<ContentEncoding>() {
if let Some(encoding) = response.headers.borrow().get::<ContentEncoding>() {
if encoding.contains(&Encoding::Gzip) {
}

@@ -1136,8 +1137,8 @@ fn cors_preflight_fetch(request: Rc<Request>, cache: &mut CORSCache,
if cors_check(request.clone(), &response).is_ok() &&
response.status.map_or(false, |status| status.is_success()) {
// Substep 1
let mut methods = if response.headers.has::<AccessControlAllowMethods>() {
match response.headers.get::<AccessControlAllowMethods>() {
let mut methods = if response.headers.borrow().has::<AccessControlAllowMethods>() {
match response.headers.borrow().get::<AccessControlAllowMethods>() {
Some(&AccessControlAllowMethods(ref m)) => m.clone(),
// Substep 3
None => return Response::network_error()
@@ -1147,8 +1148,8 @@ fn cors_preflight_fetch(request: Rc<Request>, cache: &mut CORSCache,
};

// Substep 2
let header_names = if response.headers.has::<AccessControlAllowHeaders>() {
match response.headers.get::<AccessControlAllowHeaders>() {
let header_names = if response.headers.borrow().has::<AccessControlAllowHeaders>() {
match response.headers.borrow().get::<AccessControlAllowHeaders>() {
Some(&AccessControlAllowHeaders(ref hn)) => hn.clone(),
// Substep 3
None => return Response::network_error()
@@ -1180,7 +1181,7 @@ fn cors_preflight_fetch(request: Rc<Request>, cache: &mut CORSCache,
}

// Substep 7, 8
let max_age = response.headers.get::<AccessControlMaxAge>().map(|acma| acma.0).unwrap_or(0);
let max_age = response.headers.borrow().get::<AccessControlMaxAge>().map(|acma| acma.0).unwrap_or(0);

// TODO: Substep 9 - Need to define what an imposed limit on max-age is

@@ -1205,7 +1206,7 @@ fn cors_preflight_fetch(request: Rc<Request>, cache: &mut CORSCache,
/// [CORS check](https://fetch.spec.whatwg.org#concept-cors-check)
fn cors_check(request: Rc<Request>, response: &Response) -> Result<(), ()> {
// Step 1
let origin = response.headers.get::<AccessControlAllowOrigin>().cloned();
let origin = response.headers.borrow().get::<AccessControlAllowOrigin>().cloned();

// Step 2
let origin = try!(origin.ok_or(()));
@@ -7,6 +7,7 @@ use hyper::method::Method;
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
use std::cell::{Cell, RefCell};
use std::mem::swap;
use std::rc::Rc;
use url::{Origin as UrlOrigin, Url};

/// An [initiator](https://fetch.spec.whatwg.org/#concept-request-initiator)
@@ -138,14 +139,14 @@ pub struct RequestInit {
}

/// A [Request](https://fetch.spec.whatwg.org/#requests) as defined by the Fetch spec
#[derive(Clone, HeapSizeOf)]
#[derive(HeapSizeOf)]
pub struct Request {
#[ignore_heap_size_of = "Defined in hyper"]
pub method: RefCell<Method>,
pub local_urls_only: bool,
pub sandboxed_storage_area_urls: bool,
#[ignore_heap_size_of = "Defined in hyper"]
pub headers: RefCell<Headers>,
pub headers: Rc<RefCell<Headers>>,
pub unsafe_request: bool,
pub body: RefCell<Option<Vec<u8>>>,
// TODO: client object
@@ -192,7 +193,7 @@ impl Request {
method: RefCell::new(Method::Get),
local_urls_only: false,
sandboxed_storage_area_urls: false,
headers: RefCell::new(Headers::new()),
headers: Rc::new(RefCell::new(Headers::new())),
unsafe_request: false,
body: RefCell::new(None),
is_service_worker_global_scope: is_service_worker_global_scope,
@@ -258,7 +259,7 @@ impl Request {
method: RefCell::new(Method::Get),
local_urls_only: false,
sandboxed_storage_area_urls: false,
headers: RefCell::new(Headers::new()),
headers: Rc::new(RefCell::new(Headers::new())),
unsafe_request: false,
body: RefCell::new(None),
is_service_worker_global_scope: is_service_worker_global_scope,
@@ -348,3 +349,42 @@ impl Referer {
}
}
}

impl Clone for Request {
fn clone(&self) -> Request {
let headers = (*self.headers).clone();
Request {
method: self.method.clone(),
local_urls_only: self.local_urls_only.clone(),
sandboxed_storage_area_urls: self.sandboxed_storage_area_urls.clone(),
headers: Rc::new(headers),
unsafe_request: self.unsafe_request.clone(),
body: self.body.clone(),
is_service_worker_global_scope: self.is_service_worker_global_scope.clone(),
window: self.window.clone(),
keep_alive: self.keep_alive.clone(),
skip_service_worker: self.skip_service_worker.clone(),
initiator: self.initiator.clone(),
type_: self.type_.clone(),
destination: self.destination.clone(),
origin: self.origin.clone(),
omit_origin_header: self.omit_origin_header.clone(),
same_origin_data: self.same_origin_data.clone(),
referer: self.referer.clone(),
referrer_policy: self.referrer_policy.clone(),
pipeline_id: self.pipeline_id.clone(),
synchronous: self.synchronous.clone(),
mode: self.mode.clone(),
use_cors_preflight: self.use_cors_preflight.clone(),
credentials_mode: self.credentials_mode.clone(),
use_url_credentials: self.use_url_credentials.clone(),
cache_mode: self.cache_mode.clone(),
redirect_mode: self.redirect_mode.clone(),
integrity_metadata: self.integrity_metadata.clone(),
url_list: self.url_list.clone(),
redirect_count: self.redirect_count.clone(),
response_tainting: self.response_tainting.clone(),
done: self.done.clone()
}
}
}
@@ -10,6 +10,7 @@ use hyper::status::StatusCode;
use hyper_serde::Serde;
use std::ascii::AsciiExt;
use std::cell::{Cell, RefCell};
use std::rc::Rc;
use std::sync::{Arc, Mutex};
use url::Url;
use {Metadata, NetworkError};
@@ -76,7 +77,6 @@ pub enum 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>,
@@ -85,7 +85,7 @@ pub struct Response {
/// `None` can be considered a StatusCode of `0`.
pub status: Option<StatusCode>,
pub raw_status: Option<RawStatus>,
pub headers: Headers,
pub headers: Rc<RefCell<Headers>>,
pub body: Arc<Mutex<ResponseBody>>,
pub cache_state: CacheState,
pub https_state: HttpsState,
@@ -105,7 +105,7 @@ impl Response {
url_list: RefCell::new(Vec::new()),
status: Some(StatusCode::Ok),
raw_status: Some(RawStatus(200, "OK".into())),
headers: Headers::new(),
headers: Rc::new(RefCell::new(Headers::new())),
body: Arc::new(Mutex::new(ResponseBody::Empty)),
cache_state: CacheState::None,
https_state: HttpsState::None,
@@ -122,7 +122,7 @@ impl Response {
url_list: RefCell::new(vec![]),
status: None,
raw_status: None,
headers: Headers::new(),
headers: Rc::new(RefCell::new(Headers::new())),
body: Arc::new(Mutex::new(ResponseBody::Empty)),
cache_state: CacheState::None,
https_state: HttpsState::None,
@@ -166,7 +166,7 @@ impl Response {
return Response::network_error();
}

let old_headers = old_response.headers.clone();
let old_headers = (*old_response.headers).clone().into_inner();
let mut response = old_response.clone();
response.internal_response = Some(Box::new(old_response));
response.response_type = filter_type;
@@ -181,7 +181,7 @@ impl Response {
_ => true
}
}).collect();
response.headers = headers;
response.headers = Rc::new(RefCell::new(headers));
},

ResponseType::CORS => {
@@ -200,20 +200,20 @@ impl Response {
}
}
}).collect();
response.headers = headers;
response.headers = Rc::new(RefCell::new(headers));
},

ResponseType::Opaque => {
response.url_list = RefCell::new(vec![]);
response.url = None;
response.headers = Headers::new();
response.headers = Rc::new(RefCell::new(Headers::new()));
response.status = None;
response.body = Arc::new(Mutex::new(ResponseBody::Empty));
response.cache_state = CacheState::None;
},

ResponseType::OpaqueRedirect => {
response.headers = Headers::new();
response.headers = Rc::new(RefCell::new(Headers::new()));
response.status = None;
response.body = Arc::new(Mutex::new(ResponseBody::Empty));
response.cache_state = CacheState::None;
@@ -234,13 +234,35 @@ impl Response {
return Err(NetworkError::Internal("Cannot extract metadata from network error".to_string()));
}

metadata.set_content_type(match self.headers.get() {
let headers = (*self.headers).clone().into_inner();

metadata.set_content_type(match headers.get() {
Some(&ContentType(ref mime)) => Some(mime),
None => None
});
metadata.headers = Some(Serde(self.headers.clone()));
metadata.headers = Some(Serde(headers));
metadata.status = self.raw_status.clone().map(Serde);
metadata.https_state = self.https_state;
return Ok(metadata);
}
}

impl Clone for Response {
fn clone(&self) -> Response {
let headers = (*self.headers).clone();
Response {
response_type: self.response_type.clone(),
termination_reason: self.termination_reason.clone(),
url: self.url.clone(),
url_list: self.url_list.clone(),
status: self.status.clone(),
raw_status: self.raw_status.clone(),
headers: Rc::new(headers),
body: self.body.clone(),
cache_state: self.cache_state.clone(),
https_state: self.https_state.clone(),
internal_response: self.internal_response.clone(),
return_internal: self.return_internal.clone()
}
}
}
@@ -2,7 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::HeadersBinding;
use dom::bindings::codegen::Bindings::HeadersBinding::HeadersMethods;
use dom::bindings::codegen::UnionTypes::HeadersOrByteStringSequenceSequence;
@@ -11,16 +10,21 @@ use dom::bindings::global::GlobalRef;
use dom::bindings::js::Root;
use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::bindings::str::{ByteString, is_token};
use dom::bindings::trace::JSTraceable;
use hyper::header::Headers as HyperHeaders;
use std::cell::Cell;
use js::jsapi::JSTracer;
use std::cell::{Cell, RefCell};
use std::rc::Rc;
use std::result::Result;

// TODO Implement clone manually when needed.
// #[derive(Clone)] will undesirably increment Rc count.
#[dom_struct]
pub struct Headers {
reflector_: Reflector,
guard: Cell<Guard>,
#[ignore_heap_size_of = "Defined in hyper"]
header_list: DOMRefCell<HyperHeaders>
header_list: Rc<RefCell<HyperHeaders>>
}

// https://fetch.spec.whatwg.org/#concept-headers-guard
@@ -38,7 +42,7 @@ impl Headers {
Headers {
reflector_: Reflector::new(),
guard: Cell::new(Guard::None),
header_list: DOMRefCell::new(HyperHeaders::new()),
header_list: Rc::new(RefCell::new(HyperHeaders::new())),
}
}

@@ -399,3 +403,9 @@ fn is_obs_text(x: u8) -> bool {
_ => false,
}
}

impl<T: JSTraceable> JSTraceable for RefCell<T> {

This comment has been minimized.

@Manishearth

Manishearth Aug 16, 2016

Member

this goes in dom/bindings/trace.rs

This comment has been minimized.

@Manishearth

Manishearth Aug 16, 2016

Member

Actually, use DOMRefCell here, that's what it's for 😄

fn trace(&self, trc: *mut JSTracer) {
(*self).borrow().trace(trc)
}
}
@@ -33,6 +33,7 @@ use net_traits::request::RequestMode as NetTraitsRequestMode;
use net_traits::request::Type as NetTraitsRequestType;
use net_traits::request::{Origin, Window};
use std::cell::Cell;
use std::rc::Rc;
use url::Url;

#[dom_struct]
@@ -147,7 +148,7 @@ impl Request {
temporary_request.current_url(),
false);
request.method = temporary_request.method;
request.headers = temporary_request.headers.clone();
request.headers = Rc::new((*temporary_request.headers).clone());
request.unsafe_request = true;
request.window.set(window);
// TODO: `entry settings object` is not implemented in Servo yet.
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.