mirror of
https://github.com/servo/servo.git
synced 2025-07-24 15:50:21 +01:00
Make XMLHttpRequest user-set headers be preserved across redirects.
This commit is contained in:
parent
542e8d52d5
commit
fb217ab24b
4 changed files with 49 additions and 41 deletions
|
@ -108,22 +108,29 @@ reason: \"certificate verify failed\" }]";
|
|||
}
|
||||
};
|
||||
|
||||
// Avoid automatically preserving request headers when redirects occur.
|
||||
// See https://bugzilla.mozilla.org/show_bug.cgi?id=401564 and
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=216828
|
||||
if iters == 1 {
|
||||
// Preserve the `host` header set automatically by Request.
|
||||
let host = req.headers().get::<Host>().unwrap().clone();
|
||||
*req.headers_mut() = load_data.headers.clone();
|
||||
req.headers_mut().set(host);
|
||||
|
||||
// Avoid automatically preserving request headers when redirects occur.
|
||||
// See https://bugzilla.mozilla.org/show_bug.cgi?id=401564 and
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=216828 .
|
||||
// Only preserve ones which have been explicitly marked as such.
|
||||
if iters == 1 {
|
||||
let mut combined_headers = load_data.headers.clone();
|
||||
combined_headers.extend(load_data.preserved_headers.iter());
|
||||
*req.headers_mut() = combined_headers;
|
||||
} else {
|
||||
*req.headers_mut() = load_data.preserved_headers.clone();
|
||||
}
|
||||
|
||||
req.headers_mut().set(host);
|
||||
|
||||
let (tx, rx) = channel();
|
||||
cookies_chan.send(ControlMsg::GetCookiesForUrl(url.clone(), tx, CookieSource::HTTP));
|
||||
if let Some(cookie_list) = rx.recv().unwrap() {
|
||||
let mut v = Vec::new();
|
||||
v.push(cookie_list.into_bytes());
|
||||
load_data.headers.set_raw("Cookie".to_owned(), v);
|
||||
req.headers_mut().set_raw("Cookie".to_owned(), v);
|
||||
}
|
||||
|
||||
// FIXME(seanmonstar): use AcceptEncoding from Hyper once available
|
||||
|
|
|
@ -40,7 +40,10 @@ pub enum ControlMsg {
|
|||
pub struct LoadData {
|
||||
pub url: Url,
|
||||
pub method: Method,
|
||||
/// Headers that will apply to the initial request only
|
||||
pub headers: Headers,
|
||||
/// Headers that will apply to the initial request and any redirects
|
||||
pub preserved_headers: Headers,
|
||||
pub data: Option<Vec<u8>>,
|
||||
pub cors: Option<ResourceCORSData>,
|
||||
pub consumer: Sender<LoadResponse>,
|
||||
|
@ -52,6 +55,7 @@ impl LoadData {
|
|||
url: url,
|
||||
method: Method::Get,
|
||||
headers: Headers::new(),
|
||||
preserved_headers: Headers::new(),
|
||||
data: None,
|
||||
cors: None,
|
||||
consumer: consumer,
|
||||
|
|
|
@ -561,8 +561,6 @@ impl<'a> XMLHttpRequestMethods for JSRef<'a, XMLHttpRequest> {
|
|||
let mut load_data = LoadData::new(self.request_url.borrow().clone().unwrap(), start_chan);
|
||||
load_data.data = extracted;
|
||||
|
||||
// Default headers
|
||||
{
|
||||
#[inline]
|
||||
fn join_raw(a: &str, b: &str) -> Vec<u8> {
|
||||
let len = a.len() + b.len();
|
||||
|
@ -571,31 +569,27 @@ impl<'a> XMLHttpRequestMethods for JSRef<'a, XMLHttpRequest> {
|
|||
vec.push_all(b.as_bytes());
|
||||
vec
|
||||
}
|
||||
let ref mut request_headers = self.request_headers.borrow_mut();
|
||||
if !request_headers.has::<ContentType>() {
|
||||
|
||||
// XHR spec differs from http, and says UTF-8 should be in capitals,
|
||||
// instead of "utf-8", which is what Hyper defaults to.
|
||||
let params = ";charset=UTF-8";
|
||||
let n = "content-type";
|
||||
match data {
|
||||
Some(eString(_)) =>
|
||||
request_headers.set_raw(n.to_owned(), vec![join_raw("text/plain", params)]),
|
||||
load_data.headers.set_raw(n.to_owned(), vec![join_raw("text/plain", params)]),
|
||||
Some(eURLSearchParams(_)) =>
|
||||
request_headers.set_raw(
|
||||
load_data.headers.set_raw(
|
||||
n.to_owned(), vec![join_raw("application/x-www-form-urlencoded", params)]),
|
||||
None => ()
|
||||
}
|
||||
}
|
||||
|
||||
load_data.preserved_headers = (*self.request_headers.borrow()).clone();
|
||||
|
||||
if !request_headers.has::<Accept>() {
|
||||
if !load_data.preserved_headers.has::<Accept>() {
|
||||
let mime = Mime(mime::TopLevel::Star, mime::SubLevel::Star, vec![]);
|
||||
request_headers.set(
|
||||
Accept(vec![QualityItem::new(mime, 1.0)]));
|
||||
load_data.preserved_headers.set(Accept(vec![QualityItem::new(mime, 1.0)]));
|
||||
}
|
||||
} // drops the borrow_mut
|
||||
|
||||
load_data.headers = (*self.request_headers.borrow()).clone();
|
||||
load_data.method = (*self.request_method.borrow()).clone();
|
||||
let (terminate_sender, terminate_receiver) = channel();
|
||||
*self.terminate_sender.borrow_mut() = Some(terminate_sender);
|
||||
|
@ -607,8 +601,10 @@ impl<'a> XMLHttpRequestMethods for JSRef<'a, XMLHttpRequest> {
|
|||
} else {
|
||||
RequestMode::CORS
|
||||
};
|
||||
let mut combined_headers = load_data.headers.clone();
|
||||
combined_headers.extend(load_data.preserved_headers.iter());
|
||||
let cors_request = CORSRequest::maybe_new(referer_url.clone(), load_data.url.clone(), mode,
|
||||
load_data.method.clone(), load_data.headers.clone());
|
||||
load_data.method.clone(), combined_headers);
|
||||
match cors_request {
|
||||
Ok(None) => {
|
||||
let mut buf = String::new();
|
||||
|
|
|
@ -67,7 +67,7 @@ use util::task::spawn_named_with_send_on_failure;
|
|||
use util::task_state;
|
||||
|
||||
use geom::point::Point2D;
|
||||
use hyper::header::{Header, HeaderFormat};
|
||||
use hyper::header::{Header, Headers, HeaderFormat};
|
||||
use hyper::header::shared::util as header_util;
|
||||
use js::jsapi::{JS_SetWrapObjectCallbacks, JS_SetGCZeal, JS_DEFAULT_ZEAL_FREQ, JS_GC};
|
||||
use js::jsapi::{JSContext, JSRuntime, JSObject};
|
||||
|
@ -795,7 +795,8 @@ impl ScriptTask {
|
|||
self.resource_task.send(ControlMsg::Load(NetLoadData {
|
||||
url: url,
|
||||
method: load_data.method,
|
||||
headers: load_data.headers,
|
||||
headers: Headers::new(),
|
||||
preserved_headers: load_data.headers,
|
||||
data: load_data.data,
|
||||
cors: None,
|
||||
consumer: input_chan,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue