mirror of
https://github.com/servo/servo.git
synced 2025-08-02 12:10:29 +01:00
Auto merge of #15903 - servo:set-origin-header, r=Wafflespeanut
Set Origin header in http_network_or_cache_fetch <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/15903) <!-- Reviewable:end -->
This commit is contained in:
commit
a11a3fe68b
16 changed files with 93 additions and 250 deletions
|
@ -22,6 +22,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;
|
||||
|
@ -785,6 +786,15 @@ fn http_redirect_fetch(request: Rc<Request>,
|
|||
main_fetch(request, cache, cors_flag, true, target, done_chan, context)
|
||||
}
|
||||
|
||||
fn try_immutable_origin_to_hyper_origin(url_origin: &ImmutableOrigin) -> Option<HyperOrigin> {
|
||||
match *url_origin {
|
||||
// TODO (servo/servo#15569) Set "Origin: null" when hyper supports it
|
||||
ImmutableOrigin::Opaque(_) => None,
|
||||
ImmutableOrigin::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,
|
||||
|
@ -843,10 +853,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_immutable_origin_to_hyper_origin(url_origin) {
|
||||
http_request.headers.borrow_mut().set(hyper_origin)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 10
|
||||
|
|
|
@ -12,8 +12,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};
|
||||
|
@ -27,12 +27,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;
|
||||
|
@ -145,8 +146,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,
|
||||
|
@ -1117,3 +1123,61 @@ fn test_auth_ui_needs_www_auth() {
|
|||
|
||||
assert_eq!(response.status.unwrap(), StatusCode::Unauthorized);
|
||||
}
|
||||
|
||||
#[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
|
||||
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
[request-headers.htm]
|
||||
type: testharness
|
||||
[basic request header]
|
||||
expected: FAIL
|
||||
|
||||
[Simple request headers need not be in allow-headers]
|
||||
expected: FAIL
|
||||
|
||||
[Strange allowheaders (case insensitive)]
|
||||
expected: FAIL
|
||||
|
||||
[INVALID_STATE_ERR on setRequestHeader after send()]
|
||||
expected: FAIL
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
[status-async.htm]
|
||||
type: testharness
|
||||
[Status on GET 200]
|
||||
expected: FAIL
|
||||
|
||||
[Status on GET 201]
|
||||
expected: FAIL
|
||||
|
||||
[Status on GET 202]
|
||||
expected: FAIL
|
||||
|
||||
[Status on GET 203]
|
||||
expected: FAIL
|
||||
|
||||
[Status on GET 204]
|
||||
expected: FAIL
|
||||
|
||||
[Status on GET 205]
|
||||
expected: FAIL
|
||||
|
||||
[Status on GET 206]
|
||||
expected: FAIL
|
||||
|
||||
[Status on GET 209]
|
||||
expected: FAIL
|
||||
|
||||
[Status on GET 299]
|
||||
expected: FAIL
|
||||
|
||||
[Status on POST 200]
|
||||
expected: FAIL
|
||||
|
||||
[Status on HEAD 200]
|
||||
expected: FAIL
|
||||
|
||||
[Status on PUT 200]
|
||||
expected: FAIL
|
||||
|
||||
[Status on CHICKEN 200]
|
||||
expected: FAIL
|
||||
|
||||
[Status on GET 400]
|
||||
expected: FAIL
|
||||
|
||||
[Status on HEAD 401]
|
||||
expected: FAIL
|
||||
|
||||
[Status on POST 404]
|
||||
expected: FAIL
|
||||
|
||||
[Status on POST 500]
|
||||
expected: FAIL
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
[status-preflight.htm]
|
||||
type: testharness
|
||||
[CORS - status after preflight on GET 200]
|
||||
expected: FAIL
|
||||
|
||||
[CORS - status after preflight on GET 204]
|
||||
expected: FAIL
|
||||
|
||||
[CORS - status after preflight on GET 400]
|
||||
expected: FAIL
|
||||
|
||||
[CORS - status after preflight on GET 401]
|
||||
expected: FAIL
|
||||
|
||||
[CORS - status after preflight on HEAD 200]
|
||||
expected: FAIL
|
||||
|
||||
[CORS - status after preflight on HEAD 204]
|
||||
expected: FAIL
|
||||
|
||||
[CORS - status after preflight on HEAD 400]
|
||||
expected: FAIL
|
||||
|
||||
[CORS - status after preflight on HEAD 401]
|
||||
expected: FAIL
|
||||
|
||||
[CORS - status after preflight on HEAD 501]
|
||||
expected: FAIL
|
||||
|
||||
[CORS - status after preflight on HEAD 699]
|
||||
expected: FAIL
|
||||
|
||||
[CORS - status after preflight on POST 204]
|
||||
expected: FAIL
|
||||
|
||||
[CORS - status after preflight on POST 400]
|
||||
expected: FAIL
|
||||
|
||||
[CORS - status after preflight on POST 401]
|
||||
expected: FAIL
|
||||
|
||||
[CORS - status after preflight on POST 404]
|
||||
expected: FAIL
|
||||
|
||||
[CORS - status after preflight on PUT 699]
|
||||
expected: FAIL
|
||||
|
||||
[CORS - status after preflight on CHICKEN 501]
|
||||
expected: FAIL
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
[status.htm]
|
||||
type: testharness
|
||||
[3. CORS allowed, response status 400.]
|
||||
expected: FAIL
|
||||
|
||||
[4. CORS allowed, preflight status 200, response status 400.]
|
||||
expected: FAIL
|
||||
|
|
@ -1,15 +1,9 @@
|
|||
[eventsource-cross-origin.htm]
|
||||
type: testharness
|
||||
expected: TIMEOUT
|
||||
[EventSource: cross-origin basic use]
|
||||
expected: TIMEOUT
|
||||
|
||||
[EventSource: cross-origin redirect use]
|
||||
expected: TIMEOUT
|
||||
|
||||
[EventSource: cross-origin redirect use recon]
|
||||
expected: TIMEOUT
|
||||
|
||||
[EventSource: cross-origin allow-origin: http://example.org should fail]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
[request-cache-control.htm]
|
||||
type: testharness
|
||||
expected: TIMEOUT
|
||||
[EventSource: Cache-Control 1]
|
||||
expected: TIMEOUT
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
[request-credentials.htm]
|
||||
type: testharness
|
||||
expected: TIMEOUT
|
||||
[EventSource: credentials: credentials enabled]
|
||||
expected: TIMEOUT
|
||||
|
||||
[EventSource: credentials: credentials disabled]
|
||||
expected: TIMEOUT
|
||||
|
||||
[EventSource: credentials: credentials default]
|
||||
expected: TIMEOUT
|
||||
|
|
@ -1,23 +1,14 @@
|
|||
[request-headers.html]
|
||||
type: testharness
|
||||
[Fetch with PUT without body]
|
||||
expected: FAIL
|
||||
|
||||
[Fetch with PUT with body]
|
||||
expected: FAIL
|
||||
|
||||
[Fetch with POST without body]
|
||||
expected: FAIL
|
||||
|
||||
[Fetch with POST with text body]
|
||||
expected: FAIL
|
||||
|
||||
[Fetch with POST with FormData body]
|
||||
expected: FAIL
|
||||
|
||||
[Fetch with POST with Blob body]
|
||||
expected: FAIL
|
||||
|
||||
[Fetch with POST with ArrayBuffer body]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -48,15 +39,6 @@
|
|||
[Fetch with POST with URLSearchParams body]
|
||||
expected: FAIL
|
||||
|
||||
[Fetch with POST and mode "same-origin" needs an Origin header]
|
||||
expected: FAIL
|
||||
|
||||
[Fetch with POST and mode "no-cors" needs an Origin header]
|
||||
expected: FAIL
|
||||
|
||||
[Fetch with PUT and mode "same-origin" needs an Origin header]
|
||||
expected: FAIL
|
||||
|
||||
[Fetch with TacO and mode "same-origin" needs an Origin header]
|
||||
expected: FAIL
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue