aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/net/http_loader.rs215
1 files changed, 111 insertions, 104 deletions
diff --git a/components/net/http_loader.rs b/components/net/http_loader.rs
index ca972034471..7e19825dff7 100644
--- a/components/net/http_loader.rs
+++ b/components/net/http_loader.rs
@@ -808,15 +808,17 @@ fn http_network_or_cache_fetch(request: Rc<Request>,
// TODO: Implement Window enum for Request
let request_has_no_window = true;
- // Step 1
+ // Step 2
let http_request = if request_has_no_window &&
request.redirect_mode.get() == RedirectMode::Error {
request
} else {
+ // Step 3
+ // TODO Implement body source
Rc::new((*request).clone())
};
- // Step 2
+ // Step 4
let credentials_flag = match http_request.credentials_mode {
CredentialsMode::Include => true,
CredentialsMode::CredentialsSameOrigin if http_request.response_tainting.get() == ResponseTainting::Basic
@@ -827,24 +829,24 @@ fn http_network_or_cache_fetch(request: Rc<Request>,
let content_length_value = match *http_request.body.borrow() {
None =>
match *http_request.method.borrow() {
- // Step 4
+ // Step 6
Method::Post | Method::Put =>
Some(0),
- // Step 3
+ // Step 5
_ => None
},
- // Step 5
+ // Step 7
Some(ref http_request_body) => Some(http_request_body.len() as u64)
};
- // Step 6
+ // Step 8
if let Some(content_length_value) = content_length_value {
http_request.headers.borrow_mut().set(ContentLength(content_length_value));
}
- // Step 7 TODO
+ // Step 9 TODO: needs request's client object
- // Step 8
+ // Step 10
match *http_request.referrer.borrow() {
Referrer::NoReferrer => (),
Referrer::ReferrerUrl(ref http_request_referrer) =>
@@ -855,7 +857,7 @@ fn http_network_or_cache_fetch(request: Rc<Request>,
unreachable!()
};
- // Step 9
+ // Step 11
if !http_request.omit_origin_header.get() {
let method = http_request.method.borrow();
if cors_flag || (*method != Method::Get && *method != Method::Head) {
@@ -868,24 +870,24 @@ fn http_network_or_cache_fetch(request: Rc<Request>,
}
}
- // Step 10
+ // Step 12
if !http_request.headers.borrow().has::<UserAgent>() {
let user_agent = context.user_agent.clone().into_owned();
http_request.headers.borrow_mut().set(UserAgent(user_agent));
}
match http_request.cache_mode.get() {
- // Step 11
+ // Step 13
CacheMode::Default if is_no_store_cache(&http_request.headers.borrow()) => {
http_request.cache_mode.set(CacheMode::NoStore);
},
- // Step 12
+ // Step 14
CacheMode::NoCache if !http_request.headers.borrow().has::<CacheControl>() => {
http_request.headers.borrow_mut().set(CacheControl(vec![CacheDirective::MaxAge(0)]));
},
- // Step 13
+ // Step 15
CacheMode::Reload | CacheMode::NoStore => {
// Substep 1
if !http_request.headers.borrow().has::<Pragma>() {
@@ -901,7 +903,7 @@ fn http_network_or_cache_fetch(request: Rc<Request>,
_ => {}
}
- // Step 14
+ // Step 16
let current_url = http_request.current_url();
{
let headers = &mut *http_request.headers.borrow_mut();
@@ -915,7 +917,7 @@ fn http_network_or_cache_fetch(request: Rc<Request>,
set_default_accept_encoding(headers);
}
- // Step 15
+ // Step 17
// TODO some of this step can't be implemented yet
if credentials_flag {
// Substep 1
@@ -953,136 +955,141 @@ fn http_network_or_cache_fetch(request: Rc<Request>,
}
}
- // Step 16
+ // Step 18
// TODO If there’s a proxy-authentication entry, use it as appropriate.
- // Step 17
+ // Step 19
let mut response: Option<Response> = None;
- // Step 18
+ // Step 20
+ let mut revalidation_needed = false;
+
+ // Step 21
// TODO have a HTTP cache to check for a completed response
let complete_http_response_from_cache: Option<Response> = None;
if http_request.cache_mode.get() != CacheMode::NoStore &&
- http_request.cache_mode.get() != CacheMode::Reload &&
- complete_http_response_from_cache.is_some() {
- // Substep 1
+ http_request.cache_mode.get() != CacheMode::Reload &&
+ complete_http_response_from_cache.is_some() {
+ // TODO Substep 1 and 2. Select a response from HTTP cache.
+
+ // Substep 3
+ if let Some(ref response) = response {
+ revalidation_needed = response_needs_revalidation(&response);
+ };
+
+ // Substep 4
if http_request.cache_mode.get() == CacheMode::ForceCache ||
http_request.cache_mode.get() == CacheMode::OnlyIfCached {
// TODO pull response from HTTP cache
// response = http_request
}
- let revalidation_needed = match response {
- Some(ref response) => response_needs_revalidation(&response),
- _ => false
- };
-
- // Substep 2
- if !revalidation_needed && http_request.cache_mode.get() == CacheMode::Default {
+ if revalidation_needed {
+ // Substep 5
+ // TODO set If-None-Match and If-Modified-Since according to cached
+ // response headers.
+ } else {
+ // Substep 6
// TODO pull response from HTTP cache
// response = http_request
// response.cache_state = CacheState::Local;
}
-
- // Substep 3
- if revalidation_needed && http_request.cache_mode.get() == CacheMode::Default ||
- http_request.cache_mode.get() == CacheMode::NoCache {
- // TODO this substep
- }
-
- // Step 19
- // TODO have a HTTP cache to check for a partial response
- } else if http_request.cache_mode.get() == CacheMode::Default ||
- http_request.cache_mode.get() == CacheMode::ForceCache {
- // TODO this substep
}
- // Step 20
+ // Step 22
if response.is_none() {
+ // Substep 1
if http_request.cache_mode.get() == CacheMode::OnlyIfCached {
- return Response::network_error(NetworkError::Internal("Couldn't find response in cache".into()))
+ return Response::network_error(
+ NetworkError::Internal("Couldn't find response in cache".into()))
}
- response = Some(http_network_fetch(http_request.clone(), credentials_flag,
- done_chan, context));
- }
- let response = response.unwrap();
-
- if let Some(status) = response.status {
- match status {
- StatusCode::NotModified => {
- // Step 21
- if http_request.cache_mode.get() == CacheMode::Default ||
- http_request.cache_mode.get() == CacheMode::NoCache {
- // Substep 1
- // TODO this substep
- // let cached_response: Option<Response> = None;
-
- // Substep 2
- // if cached_response.is_none() {
- // return Response::network_error();
- // }
-
- // Substep 3
-
- // Substep 4
- // response = cached_response;
-
- // Substep 5
- // TODO cache_state is immutable?
- // response.cache_state = CacheState::Validated;
+ // Substep 2
+ let forward_response = http_network_fetch(http_request.clone(), credentials_flag,
+ done_chan, context);
+ match forward_response.raw_status {
+ // Substep 3
+ Some((200...303, _)) |
+ Some((305...399, _)) => {
+ if !http_request.method.borrow().safe() {
+ // TODO Invalidate HTTP cache response
}
},
- StatusCode::Unauthorized => {
- // Step 22
- // FIXME: Figure out what to do with request window objects
- if cors_flag && !credentials_flag {
- return response;
+ // Substep 4
+ Some((304, _)) => {
+ if revalidation_needed {
+ // TODO update forward_response headers with cached response
+ // headers
}
+ },
+ _ => {}
+ }
- // Step 1
- // TODO: Spec says requires testing on multiple WWW-Authenticate headers
+ // Substep 5
+ if response.is_none() {
+ response = Some(forward_response);
+ }
+ }
- // Step 2
- if !http_request.use_url_credentials || authentication_fetch_flag {
- // TODO: Prompt the user for username and password from the window
- // Wrong, but will have to do until we are able to prompt the user
- // otherwise this creates an infinite loop
- // We basically pretend that the user declined to enter credentials
- return response;
- }
+ let response = response.unwrap();
- // Step 3
- return http_network_or_cache_fetch(http_request, true, cors_flag, done_chan, context);
- },
- StatusCode::ProxyAuthenticationRequired => {
- // Step 23
- // Step 1
- // TODO: Figure out what to do with request window objects
+ match response.status {
+ Some(StatusCode::Unauthorized) => {
+ // Step 23
+ // FIXME: Figure out what to do with request window objects
+ if cors_flag && !credentials_flag {
+ return response;
+ }
+
+ // Substep 1
+ // TODO: Spec says requires testing on multiple WWW-Authenticate headers
- // Step 2
- // TODO: Spec says requires testing on Proxy-Authenticate headers
+ // Substep 2
+ if http_request.body.borrow().is_some() {
+ // TODO Implement body source
+ }
- // Step 3
- // TODO: Prompt the user for proxy authentication credentials
+ // Substep 3
+ if !http_request.use_url_credentials || authentication_fetch_flag {
+ // TODO: Prompt the user for username and password from the window
// Wrong, but will have to do until we are able to prompt the user
// otherwise this creates an infinite loop
// We basically pretend that the user declined to enter credentials
return response;
+ }
- // Step 4
- // return http_network_or_cache_fetch(request, authentication_fetch_flag,
- // cors_flag, done_chan, context);
- },
- _ => {}
- }
+ // Substep 4
+ return http_network_or_cache_fetch(http_request,
+ true /* authentication flag */,
+ cors_flag, done_chan, context);
+ },
+ Some(StatusCode::ProxyAuthenticationRequired) => {
+ // Step 24
+ // Step 1
+ // TODO: Figure out what to do with request window objects
+
+ // Step 2
+ // TODO: Spec says requires testing on Proxy-Authenticate headers
+
+ // Step 3
+ // TODO: Prompt the user for proxy authentication credentials
+ // Wrong, but will have to do until we are able to prompt the user
+ // otherwise this creates an infinite loop
+ // We basically pretend that the user declined to enter credentials
+ return response;
+
+ // Step 4
+ // return http_network_or_cache_fetch(request, authentication_fetch_flag,
+ // cors_flag, done_chan, context);
+ },
+ _ => {}
}
- // Step 24
+ // Step 25
if authentication_fetch_flag {
// TODO Create the authentication entry for request and the given realm
}
- // Step 25
+ // Step 26
response
}