mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
Rustfmt some of script.
This commit is contained in:
parent
ceb72e54e4
commit
0c61be7a57
50 changed files with 1499 additions and 885 deletions
|
@ -46,7 +46,7 @@ pub struct CORSRequest {
|
|||
pub headers: Headers,
|
||||
/// CORS preflight flag (https://fetch.spec.whatwg.org/#concept-http-fetch)
|
||||
/// Indicates that a CORS preflight request and/or cache check is to be performed
|
||||
pub preflight_flag: bool
|
||||
pub preflight_flag: bool,
|
||||
}
|
||||
|
||||
/// https://fetch.spec.whatwg.org/#concept-request-mode
|
||||
|
@ -55,15 +55,18 @@ pub struct CORSRequest {
|
|||
#[derive(PartialEq, Copy, Clone, HeapSizeOf)]
|
||||
pub enum RequestMode {
|
||||
CORS, // CORS
|
||||
ForcedPreflight // CORS-with-forced-preflight
|
||||
ForcedPreflight, // CORS-with-forced-preflight
|
||||
}
|
||||
|
||||
impl CORSRequest {
|
||||
/// Creates a CORS request if necessary. Will return an error when fetching is forbidden
|
||||
pub fn maybe_new(referer: Url, destination: Url, mode: RequestMode,
|
||||
method: Method, headers: Headers) -> Result<Option<CORSRequest>, ()> {
|
||||
if referer.scheme == destination.scheme &&
|
||||
referer.host() == destination.host() &&
|
||||
pub fn maybe_new(referer: Url,
|
||||
destination: Url,
|
||||
mode: RequestMode,
|
||||
method: Method,
|
||||
headers: Headers)
|
||||
-> Result<Option<CORSRequest>, ()> {
|
||||
if referer.scheme == destination.scheme && referer.host() == destination.host() &&
|
||||
referer.port() == destination.port() {
|
||||
return Ok(None); // Not cross-origin, proceed with a normal fetch
|
||||
}
|
||||
|
@ -72,7 +75,8 @@ impl CORSRequest {
|
|||
// we can fetch a data URL normally. about:blank can also be fetched by XHR
|
||||
"http" | "https" => {
|
||||
let mut req = CORSRequest::new(referer, destination, mode, method, headers);
|
||||
req.preflight_flag = !is_simple_method(&req.method) || mode == RequestMode::ForcedPreflight;
|
||||
req.preflight_flag = !is_simple_method(&req.method) ||
|
||||
mode == RequestMode::ForcedPreflight;
|
||||
if req.headers.iter().all(|h| is_simple_header(&h)) {
|
||||
req.preflight_flag = true;
|
||||
}
|
||||
|
@ -82,10 +86,14 @@ impl CORSRequest {
|
|||
}
|
||||
}
|
||||
|
||||
fn new(mut referer: Url, destination: Url, mode: RequestMode, method: Method,
|
||||
headers: Headers) -> CORSRequest {
|
||||
fn new(mut referer: Url,
|
||||
destination: Url,
|
||||
mode: RequestMode,
|
||||
method: Method,
|
||||
headers: Headers)
|
||||
-> CORSRequest {
|
||||
match referer.scheme_data {
|
||||
SchemeData::Relative(ref mut data) => data.path = vec!(),
|
||||
SchemeData::Relative(ref mut data) => data.path = vec![],
|
||||
_ => {}
|
||||
};
|
||||
referer.fragment = None;
|
||||
|
@ -96,7 +104,7 @@ impl CORSRequest {
|
|||
mode: mode,
|
||||
method: method,
|
||||
headers: headers,
|
||||
preflight_flag: false
|
||||
preflight_flag: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -181,12 +189,13 @@ impl CORSRequest {
|
|||
preflight.headers.set(AccessControlRequestMethod(self.method.clone()));
|
||||
|
||||
// Step 5 - 7
|
||||
let mut header_names = vec!();
|
||||
let mut header_names = vec![];
|
||||
for header in self.headers.iter() {
|
||||
header_names.push(header.name().to_owned());
|
||||
}
|
||||
header_names.sort();
|
||||
preflight.headers.set(AccessControlRequestHeaders(header_names.into_iter().map(UniCase).collect()));
|
||||
preflight.headers
|
||||
.set(AccessControlRequestHeaders(header_names.into_iter().map(UniCase).collect()));
|
||||
|
||||
// Step 8 unnecessary, we don't use the request body
|
||||
// Step 9, 10 unnecessary, we're writing our own fetch code
|
||||
|
@ -195,7 +204,7 @@ impl CORSRequest {
|
|||
let preflight_request = Request::new(preflight.method, preflight.destination);
|
||||
let mut req = match preflight_request {
|
||||
Ok(req) => req,
|
||||
Err(_) => return error
|
||||
Err(_) => return error,
|
||||
};
|
||||
|
||||
let host = req.headers().get::<Host>().unwrap().clone();
|
||||
|
@ -203,37 +212,36 @@ impl CORSRequest {
|
|||
req.headers_mut().set(host);
|
||||
let stream = match req.start() {
|
||||
Ok(s) => s,
|
||||
Err(_) => return error
|
||||
Err(_) => return error,
|
||||
};
|
||||
let response = match stream.send() {
|
||||
Ok(r) => r,
|
||||
Err(_) => return error
|
||||
Err(_) => return error,
|
||||
};
|
||||
|
||||
// Step 12
|
||||
match response.status.class() {
|
||||
Success => {}
|
||||
_ => return error
|
||||
_ => return error,
|
||||
}
|
||||
cors_response.headers = response.headers.clone();
|
||||
// Substeps 1-3 (parsing rules: https://fetch.spec.whatwg.org/#http-new-header-syntax)
|
||||
let methods_substep4 = [self.method.clone()];
|
||||
let mut methods = match response.headers.get() {
|
||||
Some(&AccessControlAllowMethods(ref v)) => &**v,
|
||||
_ => return error
|
||||
_ => return error,
|
||||
};
|
||||
let headers = match response.headers.get() {
|
||||
Some(&AccessControlAllowHeaders(ref h)) => h,
|
||||
_ => return error
|
||||
_ => return error,
|
||||
};
|
||||
// Substep 4
|
||||
if methods.is_empty() || preflight.mode == RequestMode::ForcedPreflight {
|
||||
methods = &methods_substep4;
|
||||
}
|
||||
// Substep 5
|
||||
if !is_simple_method(&self.method) &&
|
||||
!methods.iter().any(|m| m == &self.method) {
|
||||
return error;
|
||||
if !is_simple_method(&self.method) && !methods.iter().any(|m| m == &self.method) {
|
||||
return error;
|
||||
}
|
||||
// Substep 6
|
||||
for h in self.headers.iter() {
|
||||
|
@ -247,25 +255,31 @@ impl CORSRequest {
|
|||
// Substep 7, 8
|
||||
let max_age = match response.headers.get() {
|
||||
Some(&AccessControlMaxAge(num)) => num,
|
||||
None => 0
|
||||
None => 0,
|
||||
};
|
||||
// Substep 9: Impose restrictions on max-age, if any (unimplemented)
|
||||
// Substeps 10-12: Add a cache (partially implemented, XXXManishearth)
|
||||
// This cache should come from the user agent, creating a new one here to check
|
||||
// for compile time errors
|
||||
let cache = &mut CORSCache(vec!());
|
||||
let cache = &mut CORSCache(vec![]);
|
||||
for m in methods {
|
||||
let cache_match = cache.match_method_and_update(self, m, max_age);
|
||||
if !cache_match {
|
||||
cache.insert(CORSCacheEntry::new(self.origin.clone(), self.destination.clone(),
|
||||
max_age, false, HeaderOrMethod::MethodData(m.clone())));
|
||||
cache.insert(CORSCacheEntry::new(self.origin.clone(),
|
||||
self.destination.clone(),
|
||||
max_age,
|
||||
false,
|
||||
HeaderOrMethod::MethodData(m.clone())));
|
||||
}
|
||||
}
|
||||
for h in response.headers.iter() {
|
||||
let cache_match = cache.match_header_and_update(self, h.name(), max_age);
|
||||
if !cache_match {
|
||||
cache.insert(CORSCacheEntry::new(self.origin.clone(), self.destination.clone(),
|
||||
max_age, false, HeaderOrMethod::HeaderData(h.to_string())));
|
||||
cache.insert(CORSCacheEntry::new(self.origin.clone(),
|
||||
self.destination.clone(),
|
||||
max_age,
|
||||
false,
|
||||
HeaderOrMethod::HeaderData(h.to_string())));
|
||||
}
|
||||
}
|
||||
cors_response
|
||||
|
@ -275,21 +289,21 @@ impl CORSRequest {
|
|||
|
||||
pub struct CORSResponse {
|
||||
pub network_error: bool,
|
||||
pub headers: Headers
|
||||
pub headers: Headers,
|
||||
}
|
||||
|
||||
impl CORSResponse {
|
||||
fn new() -> CORSResponse {
|
||||
CORSResponse {
|
||||
network_error: false,
|
||||
headers: Headers::new()
|
||||
headers: Headers::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn new_error() -> CORSResponse {
|
||||
CORSResponse {
|
||||
CORSResponse {
|
||||
network_error: true,
|
||||
headers: Headers::new()
|
||||
headers: Headers::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -305,21 +319,21 @@ pub struct CORSCache(Vec<CORSCacheEntry>);
|
|||
#[derive(Clone)]
|
||||
pub enum HeaderOrMethod {
|
||||
HeaderData(String),
|
||||
MethodData(Method)
|
||||
MethodData(Method),
|
||||
}
|
||||
|
||||
impl HeaderOrMethod {
|
||||
fn match_header(&self, header_name: &str) -> bool {
|
||||
match *self {
|
||||
HeaderOrMethod::HeaderData(ref s) => s.eq_ignore_ascii_case(header_name),
|
||||
_ => false
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn match_method(&self, method: &Method) -> bool {
|
||||
match *self {
|
||||
HeaderOrMethod::MethodData(ref m) => m == method,
|
||||
_ => false
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -332,7 +346,7 @@ pub struct CORSCacheEntry {
|
|||
pub max_age: u32,
|
||||
pub credentials: bool,
|
||||
pub header_or_method: HeaderOrMethod,
|
||||
created: Timespec
|
||||
created: Timespec,
|
||||
}
|
||||
|
||||
impl CORSCacheEntry {
|
||||
|
@ -340,14 +354,15 @@ impl CORSCacheEntry {
|
|||
url: Url,
|
||||
max_age: u32,
|
||||
credentials: bool,
|
||||
header_or_method: HeaderOrMethod) -> CORSCacheEntry {
|
||||
header_or_method: HeaderOrMethod)
|
||||
-> CORSCacheEntry {
|
||||
CORSCacheEntry {
|
||||
origin: origin,
|
||||
url: url,
|
||||
max_age: max_age,
|
||||
credentials: credentials,
|
||||
header_or_method: header_or_method,
|
||||
created: time::now().to_timespec()
|
||||
created: time::now().to_timespec(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -377,15 +392,16 @@ impl CORSCache {
|
|||
/// https://fetch.spec.whatwg.org/#concept-cache-match-header
|
||||
fn find_entry_by_header<'a>(&'a mut self,
|
||||
request: &CORSRequest,
|
||||
header_name: &str) -> Option<&'a mut CORSCacheEntry> {
|
||||
header_name: &str)
|
||||
-> Option<&'a mut CORSCacheEntry> {
|
||||
self.cleanup();
|
||||
let CORSCache(ref mut buf) = *self;
|
||||
// Credentials are not yet implemented here
|
||||
let entry = buf.iter_mut().find(|e| e.origin.scheme == request.origin.scheme &&
|
||||
e.origin.host() == request.origin.host() &&
|
||||
e.origin.port() == request.origin.port() &&
|
||||
e.url == request.destination &&
|
||||
e.header_or_method.match_header(header_name));
|
||||
let entry = buf.iter_mut().find(|e| {
|
||||
e.origin.scheme == request.origin.scheme && e.origin.host() == request.origin.host() &&
|
||||
e.origin.port() == request.origin.port() && e.url == request.destination &&
|
||||
e.header_or_method.match_header(header_name)
|
||||
});
|
||||
entry
|
||||
}
|
||||
|
||||
|
@ -393,22 +409,27 @@ impl CORSCache {
|
|||
self.find_entry_by_header(request, header_name).is_some()
|
||||
}
|
||||
|
||||
fn match_header_and_update(&mut self, request: &CORSRequest, header_name: &str, new_max_age: u32) -> bool {
|
||||
fn match_header_and_update(&mut self,
|
||||
request: &CORSRequest,
|
||||
header_name: &str,
|
||||
new_max_age: u32)
|
||||
-> bool {
|
||||
self.find_entry_by_header(request, header_name).map(|e| e.max_age = new_max_age).is_some()
|
||||
}
|
||||
|
||||
fn find_entry_by_method<'a>(&'a mut self,
|
||||
request: &CORSRequest,
|
||||
method: &Method) -> Option<&'a mut CORSCacheEntry> {
|
||||
method: &Method)
|
||||
-> Option<&'a mut CORSCacheEntry> {
|
||||
// we can take the method from CORSRequest itself
|
||||
self.cleanup();
|
||||
let CORSCache(ref mut buf) = *self;
|
||||
// Credentials are not yet implemented here
|
||||
let entry = buf.iter_mut().find(|e| e.origin.scheme == request.origin.scheme &&
|
||||
e.origin.host() == request.origin.host() &&
|
||||
e.origin.port() == request.origin.port() &&
|
||||
e.url == request.destination &&
|
||||
e.header_or_method.match_method(method));
|
||||
let entry = buf.iter_mut().find(|e| {
|
||||
e.origin.scheme == request.origin.scheme && e.origin.host() == request.origin.host() &&
|
||||
e.origin.port() == request.origin.port() && e.url == request.destination &&
|
||||
e.header_or_method.match_method(method)
|
||||
});
|
||||
entry
|
||||
}
|
||||
|
||||
|
@ -417,7 +438,11 @@ impl CORSCache {
|
|||
self.find_entry_by_method(request, method).is_some()
|
||||
}
|
||||
|
||||
fn match_method_and_update(&mut self, request: &CORSRequest, method: &Method, new_max_age: u32) -> bool {
|
||||
fn match_method_and_update(&mut self,
|
||||
request: &CORSRequest,
|
||||
method: &Method,
|
||||
new_max_age: u32)
|
||||
-> bool {
|
||||
self.find_entry_by_method(request, method).map(|e| e.max_age = new_max_age).is_some()
|
||||
}
|
||||
|
||||
|
@ -429,8 +454,8 @@ impl CORSCache {
|
|||
}
|
||||
|
||||
fn is_simple_header(h: &HeaderView) -> bool {
|
||||
//FIXME: use h.is::<HeaderType>() when AcceptLanguage and
|
||||
//ContentLanguage headers exist
|
||||
// FIXME: use h.is::<HeaderType>() when AcceptLanguage and
|
||||
// ContentLanguage headers exist
|
||||
match &*h.name().to_ascii_lowercase() {
|
||||
"accept" | "accept-language" | "content-language" => true,
|
||||
"content-type" => match h.value() {
|
||||
|
@ -438,17 +463,17 @@ fn is_simple_header(h: &HeaderView) -> bool {
|
|||
Some(&ContentType(Mime(TopLevel::Application, SubLevel::WwwFormUrlEncoded, _))) |
|
||||
Some(&ContentType(Mime(TopLevel::Multipart, SubLevel::FormData, _))) => true,
|
||||
|
||||
_ => false
|
||||
_ => false,
|
||||
|
||||
},
|
||||
_ => false
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_simple_method(m: &Method) -> bool {
|
||||
match *m {
|
||||
Method::Get | Method::Head | Method::Post => true,
|
||||
_ => false
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -459,6 +484,6 @@ pub fn allow_cross_origin_request(req: &CORSRequest, headers: &Headers) -> bool
|
|||
Some(&AccessControlAllowOrigin::Any) => true, // Not always true, depends on credentials mode
|
||||
Some(&AccessControlAllowOrigin::Value(ref url)) => req.origin.serialize() == *url,
|
||||
Some(&AccessControlAllowOrigin::Null) |
|
||||
None => false
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue