Auto merge of #23090 - miller-time:nav-fetch-referrer, r=gterzian

Add referrer to navigation fetch request

<!-- Please describe your changes on the following line: -->
Implement step 13 of [following hyperlinks](https://html.spec.whatwg.org/#following-hyperlinks-2) and step 14.3 of [window open](https://html.spec.whatwg.org/#window-open-steps), as well as other referrer- and fetch-related updates.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix #22890 (GitHub issue number if applicable)

<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because ___

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- 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/23090)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2019-04-25 20:21:23 -04:00 committed by GitHub
commit b73956cc37
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 136 additions and 88 deletions

View file

@ -781,21 +781,27 @@ fn http_network_or_cache_fetch(
done_chan: &mut DoneChannel,
context: &FetchContext,
) -> Response {
// Step 2
let mut response: Option<Response> = None;
// Step 4
let mut revalidating_flag = false;
// TODO: Implement Window enum for Request
let request_has_no_window = true;
// Step 2
// Step 5.1
let mut http_request;
let http_request = if request_has_no_window && request.redirect_mode == RedirectMode::Error {
request
} else {
// Step 3
// Step 5.2
// TODO Implement body source
http_request = request.clone();
&mut http_request
};
// Step 4
// Step 5.3
let credentials_flag = match http_request.credentials_mode {
CredentialsMode::Include => true,
CredentialsMode::CredentialsSameOrigin
@ -808,26 +814,26 @@ fn http_network_or_cache_fetch(
let content_length_value = match http_request.body {
None => match http_request.method {
// Step 6
// Step 5.5
Method::POST | Method::PUT => Some(0),
// Step 5
// Step 5.4
_ => None,
},
// Step 7
// Step 5.6
Some(ref http_request_body) => Some(http_request_body.len() as u64),
};
// Step 8
// Step 5.7
if let Some(content_length_value) = content_length_value {
http_request
.headers
.typed_insert(ContentLength(content_length_value));
if http_request.keep_alive {
// Step 9 TODO: needs request's client object
// Step 5.8 TODO: needs request's client object
}
}
// Step 10
// Step 5.9
match http_request.referrer {
Referrer::NoReferrer => (),
Referrer::ReferrerUrl(ref http_request_referrer) => http_request
@ -841,7 +847,7 @@ fn http_network_or_cache_fetch(
},
};
// Step 11
// Step 5.10
if cors_flag || (http_request.method != Method::GET && http_request.method != Method::HEAD) {
debug_assert_ne!(http_request.origin, Origin::Client);
if let Origin::Origin(ref url_origin) = http_request.origin {
@ -851,7 +857,7 @@ fn http_network_or_cache_fetch(
}
}
// Step 12
// Step 5.11
if !http_request.headers.contains_key(header::USER_AGENT) {
let user_agent = context.user_agent.clone().into_owned();
http_request
@ -860,19 +866,19 @@ fn http_network_or_cache_fetch(
}
match http_request.cache_mode {
// Step 13
// Step 5.12
CacheMode::Default if is_no_store_cache(&http_request.headers) => {
http_request.cache_mode = CacheMode::NoStore;
},
// Step 14
// Step 5.13
CacheMode::NoCache if !http_request.headers.contains_key(header::CACHE_CONTROL) => {
http_request
.headers
.typed_insert(CacheControl::new().with_max_age(Duration::from_secs(0)));
},
// Step 15
// Step 5.14
CacheMode::Reload | CacheMode::NoStore => {
// Substep 1
if !http_request.headers.contains_key(header::PRAGMA) {
@ -890,7 +896,10 @@ fn http_network_or_cache_fetch(
_ => {},
}
// Step 16
// Step 5.15
// TODO: if necessary append `Accept-Encoding`/`identity` to headers
// Step 5.16
let current_url = http_request.current_url();
let host = Host::from(
format!(
@ -910,7 +919,7 @@ fn http_network_or_cache_fetch(
// here, according to the fetch spec
set_default_accept_encoding(&mut http_request.headers);
// Step 17
// Step 5.17
// TODO some of this step can't be implemented yet
if credentials_flag {
// Substep 1
@ -950,16 +959,10 @@ fn http_network_or_cache_fetch(
}
}
// Step 18
// Step 5.18
// TODO If theres a proxy-authentication entry, use it as appropriate.
// Step 19
let mut response: Option<Response> = None;
// Step 20
let mut revalidating_flag = false;
// Step 21
// Step 5.19
if let Ok(http_cache) = context.state.http_cache.read() {
if let Some(response_from_cache) = http_cache.construct_response(&http_request, done_chan) {
let response_headers = response_from_cache.response.headers.clone();
@ -1027,7 +1030,10 @@ fn http_network_or_cache_fetch(
wait_for_cached_response(done_chan, &mut response);
// Step 22
// Step 6
// TODO: https://infra.spec.whatwg.org/#if-aborted
// Step 7
if response.is_none() {
// Substep 1
if http_request.cache_mode == CacheMode::OnlyIfCached {
@ -1036,7 +1042,7 @@ fn http_network_or_cache_fetch(
));
}
}
// More Step 22
// More Step 7
if response.is_none() {
// Substep 2
let forward_response =
@ -1077,7 +1083,13 @@ fn http_network_or_cache_fetch(
let mut response = response.unwrap();
// Step 23
// Step 8
// TODO: if necessary set response's range-requested flag
// Step 9
// TODO: handle CORS not set and cross-origin blocked
// Step 10
// FIXME: Figure out what to do with request window objects
if let (Some((StatusCode::UNAUTHORIZED, _)), false, true) =
(response.status.as_ref(), cors_flag, credentials_flag)
@ -1110,7 +1122,7 @@ fn http_network_or_cache_fetch(
);
}
// Step 24
// Step 11
if let Some((StatusCode::PROXY_AUTHENTICATION_REQUIRED, _)) = response.status.as_ref() {
// Step 1
if request_has_no_window {
@ -1135,12 +1147,12 @@ fn http_network_or_cache_fetch(
// cors_flag, done_chan, context);
}
// Step 25
// Step 12
if authentication_fetch_flag {
// TODO Create the authentication entry for request and the given realm
}
// Step 26
// Step 13
response
}