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

Fixes #14787 building on #14811: Set Origin header in http_network_or_cache_fetch #15547

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

Fixes #14787: Set Origin header in http_network_or_cache_fetch

Sets Origin header on request with CORS flag set or on requests other
than those with GET/HEAD methods

Updates WPTs
  • Loading branch information
rabisg authored and samgiles committed Feb 21, 2017
commit 8d14c7111588bf8281e13a92c83e609192c2db5c
@@ -23,6 +23,7 @@ use hyper::header::{Authorization, Basic, CacheControl, CacheDirective, ContentE
use hyper::header::{ContentLength, Encoding, Header, Headers, Host, IfMatch, IfRange};
use hyper::header::{IfUnmodifiedSince, IfModifiedSince, IfNoneMatch, Location, Pragma, Quality};
use hyper::header::{QualityItem, Referer, SetCookie, UserAgent, qitem};
use hyper::header::Origin as HyperOrigin;
use hyper::method::Method;
use hyper::net::Fresh;
use hyper::status::StatusCode;
@@ -789,6 +790,15 @@ fn http_redirect_fetch(request: Rc<Request>,
main_fetch(request, cache, cors_flag, true, target, done_chan, context)
}

fn try_url_origin_to_hyper_origin(url_origin: &UrlOrigin) -> Option<HyperOrigin> {
match *url_origin {
// TODO (servo/servo#15569) Set "Origin: null" when hyper supports it
UrlOrigin::Opaque(_) => None,
UrlOrigin::Tuple(ref scheme, ref host, ref port) =>
Some(HyperOrigin::new(scheme.clone(), host.to_string(), Some(port.clone())))
}
}

/// [HTTP network or cache fetch](https://fetch.spec.whatwg.org#http-network-or-cache-fetch)
fn http_network_or_cache_fetch(request: Rc<Request>,
authentication_fetch_flag: bool,
@@ -847,10 +857,16 @@ fn http_network_or_cache_fetch(request: Rc<Request>,
};

// Step 9
if cors_flag ||
(*http_request.method.borrow() != Method::Get && *http_request.method.borrow() != Method::Head) {
// TODO update this when https://github.com/hyperium/hyper/pull/691 is finished
// http_request.headers.borrow_mut().set_raw("origin", origin);
if !http_request.omit_origin_header.get() {
let method = http_request.method.borrow();
if cors_flag || (*method != Method::Get && *method != Method::Head) {
debug_assert!(*http_request.origin.borrow() != Origin::Client);
if let Origin::Origin(ref url_origin) = *http_request.origin.borrow() {
if let Some(hyper_origin) = try_url_origin_to_hyper_origin(url_origin) {
http_request.headers.borrow_mut().set(hyper_origin)
}
}
}
}

// Step 10
@@ -13,8 +13,8 @@ use flate2::Compression;
use flate2::write::{DeflateEncoder, GzEncoder};
use hyper::LanguageTag;
use hyper::header::{Accept, AcceptEncoding, ContentEncoding, ContentLength, Cookie as CookieHeader};
use hyper::header::{AcceptLanguage, Authorization, Basic, Date};
use hyper::header::{Encoding, Headers, Host, Location, Quality, QualityItem, SetCookie, qitem};
use hyper::header::{AcceptLanguage, AccessControlAllowOrigin, Authorization, Basic, Date};
use hyper::header::{Encoding, Headers, Host, Location, Origin, Quality, QualityItem, SetCookie, qitem};
use hyper::header::{StrictTransportSecurity, UserAgent};
use hyper::method::Method;
use hyper::mime::{Mime, SubLevel, TopLevel};
@@ -28,12 +28,13 @@ use net::cookie_storage::CookieStorage;
use net::resource_thread::AuthCacheEntry;
use net_traits::{CookieSource, NetworkError};
use net_traits::hosts::replace_host_table;
use net_traits::request::{Request, RequestInit, CredentialsMode, Destination};
use net_traits::request::{Request, RequestInit, RequestMode, CredentialsMode, Destination};
use net_traits::response::ResponseBody;
use new_fetch_context;
use servo_url::ServoUrl;
use std::collections::HashMap;
use std::io::{Read, Write};
use std::str::FromStr;
use std::sync::{Arc, Mutex, RwLock, mpsc};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::Receiver;
@@ -146,8 +147,13 @@ fn test_check_default_headers_loaded_in_every_request() {
assert!(response.status.unwrap().is_success());

// Testing for method.POST
headers.set(ContentLength(0 as u64));
*expected_headers.lock().unwrap() = Some(headers.clone());
let mut post_headers = headers.clone();
post_headers.set(ContentLength(0 as u64));
let url_str = url.as_str();
// request gets header "Origin: http://example.com" but expected_headers has
// "Origin: http://example.com/" which do not match for equality so strip trailing '/'
post_headers.set(Origin::from_str(&url_str[..url_str.len()-1]).unwrap());
*expected_headers.lock().unwrap() = Some(post_headers);
let request = Request::from_init(RequestInit {
url: url.clone(),
method: Method::Post,
@@ -1193,3 +1199,61 @@ fn test_cookies_blocked() {

assert!(response.status.unwrap().is_success());
}

#[test]
fn test_origin_set() {
let origin_header = Arc::new(Mutex::new(None));
let origin_header_clone = origin_header.clone();
let handler = move |request: HyperRequest, mut resp: HyperResponse| {
let origin_header_clone = origin_header.clone();
resp.headers_mut().set(AccessControlAllowOrigin::Any);
match request.headers.get::<Origin>() {
None => assert_eq!(origin_header_clone.lock().unwrap().take(), None),
Some(h) => assert_eq!(*h, origin_header_clone.lock().unwrap().take().unwrap()),
}
};
let (mut server, url) = make_server(handler);

let mut origin = Origin::new(url.scheme(), url.host_str().unwrap(), url.port());
*origin_header_clone.lock().unwrap() = Some(origin.clone());
let request = Request::from_init(RequestInit {
url: url.clone(),
method: Method::Post,
body: None,
origin: url.clone(),
.. RequestInit::default()
});
let response = fetch(request, None);
assert!(response.status.unwrap().is_success());

let origin_url = ServoUrl::parse("http://example.com").unwrap();
origin = Origin::new(origin_url.scheme(), origin_url.host_str().unwrap(), origin_url.port());
// Test Origin header is set on Get request with CORS mode
let request = Request::from_init(RequestInit {
url: url.clone(),
method: Method::Get,
mode: RequestMode::CorsMode,
body: None,
origin: origin_url.clone(),
.. RequestInit::default()
});

*origin_header_clone.lock().unwrap() = Some(origin.clone());
let response = fetch(request, None);
assert!(response.status.unwrap().is_success());

// Test Origin header is not set on method Head
let request = Request::from_init(RequestInit {
url: url.clone(),
method: Method::Head,
body: None,
origin: url.clone(),
.. RequestInit::default()
});

*origin_header_clone.lock().unwrap() = None;
let response = fetch(request, None);
assert!(response.status.unwrap().is_success());

let _ = server.close();
}
@@ -3,6 +3,3 @@
[Referer header]
expected: FAIL

[Origin header]
expected: FAIL

@@ -1,14 +1,5 @@
[allow-headers.htm]
type: testharness
[Allow origin: *]
expected: FAIL

[Allow origin: _*__]
expected: FAIL

[Allow origin: [tab\]*]
expected: FAIL

[Allow origin: undefined//undefined]
expected: FAIL

@@ -21,15 +12,6 @@
[Allow origin: [tab\]undefined//undefined]
expected: FAIL

[Allow origin: http://web-platform.test:8000]
expected: FAIL

[Allow origin: _http://web-platform.test:8000]
expected: FAIL

[Allow origin: _http://web-platform.test:8000___[tab\]_]
expected: FAIL

[Allow origin: [tab\]http://web-platform.test:8000]
expected: FAIL

@@ -1,14 +1,5 @@
[basic.htm]
type: testharness
[Cross domain basic usage]
expected: FAIL

[Same domain different port]
expected: FAIL

[Cross domain different port]
expected: FAIL

[Cross domain different protocol]
expected: FAIL

@@ -1,12 +1,8 @@
[credentials-flag.htm]
type: testharness
expected: TIMEOUT
[Don't send cookie by default]
expected: TIMEOUT
[Access-Control-Allow-Credentials: True should be disallowed (async)]
expected: FAIL

[Don't send cookie part 2]
expected: TIMEOUT

[Don't obey Set-Cookie when withCredentials=false]
expected: TIMEOUT
[Access-Control-Allow-Credentials: TRUE should be disallowed (async)]
expected: FAIL

@@ -1,14 +1,5 @@
[origin.htm]
type: testharness
[Allow origin: *]
expected: FAIL

[Allow origin: _*__]
expected: FAIL

[Allow origin: [tab\]*]
expected: FAIL

[Allow origin: undefined//undefined]
expected: FAIL

@@ -21,15 +12,6 @@
[Allow origin: [tab\]undefined//undefined]
expected: FAIL

[Allow origin: http://web-platform.test:8000]
expected: FAIL

[Allow origin: _http://web-platform.test:8000]
expected: FAIL

[Allow origin: _http://web-platform.test:8000___[tab\]_]
expected: FAIL

[Allow origin: [tab\]http://web-platform.test:8000]
expected: FAIL

@@ -56,24 +56,6 @@
[remote (undefined//undefined) to remote2 (null), expect origin=null]
expected: FAIL

[local (*) to remote (*), expect origin=http://web-platform.test:8000]
expected: FAIL

[local (*) to remote (http://web-platform.test:8000), expect origin=http://web-platform.test:8000]
expected: FAIL

[local (http://web-platform.test:8000) to remote (*), expect origin=http://web-platform.test:8000]
expected: FAIL

[local (http://web-platform.test:8000) to remote (http://web-platform.test:8000), expect origin=http://web-platform.test:8000]
expected: FAIL

[local (null) to remote (*), expect origin=http://web-platform.test:8000]
expected: FAIL

[local (none) to remote (*), expect origin=http://web-platform.test:8000]
expected: FAIL

[remote (http://web-platform.test:8000) to local (*), expect origin=null]
expected: FAIL

This file was deleted.

This file was deleted.

This file was deleted.

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.