mirror of
https://github.com/servo/servo.git
synced 2025-08-07 14:35:33 +01:00
Update HTTP-redirect fetch
This commit is contained in:
parent
0ff47c4475
commit
d6c197b40c
2 changed files with 35 additions and 33 deletions
|
@ -650,29 +650,20 @@ pub fn http_redirect_fetch(request: &mut Request,
|
||||||
// Step 1
|
// Step 1
|
||||||
assert!(response.return_internal);
|
assert!(response.return_internal);
|
||||||
|
|
||||||
// Step 2
|
let location_url = response.actual_response().location_url.clone();
|
||||||
if !response.actual_response().headers.has::<Location>() {
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 3
|
|
||||||
let location = match response.actual_response().headers.get::<Location>() {
|
|
||||||
Some(&Location(ref location)) => location.clone(),
|
|
||||||
_ => return Response::network_error(NetworkError::Internal("Location header parsing failure".into()))
|
|
||||||
};
|
|
||||||
let response_url = response.actual_response().url().unwrap();
|
|
||||||
let location_url = response_url.join(&*location);
|
|
||||||
let location_url = match location_url {
|
let location_url = match location_url {
|
||||||
Ok(url) => url,
|
// Step 2
|
||||||
_ => return Response::network_error(NetworkError::Internal("Location URL parsing failure".into()))
|
None => return response,
|
||||||
|
// Step 3
|
||||||
|
Some(Err(err)) =>
|
||||||
|
return Response::network_error(
|
||||||
|
NetworkError::Internal("Location URL parse failure: ".to_owned() + &err)),
|
||||||
|
// Step 4
|
||||||
|
Some(Ok(ref url)) if !matches!(url.scheme(), "http" | "https") =>
|
||||||
|
return Response::network_error(NetworkError::Internal("Location URL not an HTTP(S) scheme".into())),
|
||||||
|
Some(Ok(url)) => url,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Step 4
|
|
||||||
match location_url.scheme() {
|
|
||||||
"http" | "https" => { },
|
|
||||||
_ => return Response::network_error(NetworkError::Internal("Not an HTTP(S) Scheme".into()))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 5
|
// Step 5
|
||||||
if request.redirect_count >= 20 {
|
if request.redirect_count >= 20 {
|
||||||
return Response::network_error(NetworkError::Internal("Too many redirects".into()));
|
return Response::network_error(NetworkError::Internal("Too many redirects".into()));
|
||||||
|
@ -682,7 +673,8 @@ pub fn http_redirect_fetch(request: &mut Request,
|
||||||
request.redirect_count += 1;
|
request.redirect_count += 1;
|
||||||
|
|
||||||
// Step 7
|
// Step 7
|
||||||
let same_origin = location_url.origin()== request.current_url().origin();
|
// FIXME: Correctly use request's origin
|
||||||
|
let same_origin = location_url.origin() == request.current_url().origin();
|
||||||
let has_credentials = has_credentials(&location_url);
|
let has_credentials = has_credentials(&location_url);
|
||||||
|
|
||||||
if request.mode == RequestMode::CorsMode && !same_origin && has_credentials {
|
if request.mode == RequestMode::CorsMode && !same_origin && has_credentials {
|
||||||
|
@ -695,28 +687,38 @@ pub fn http_redirect_fetch(request: &mut Request,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 9
|
// Step 9
|
||||||
|
if response.actual_response().status.map_or(true, |s| s != StatusCode::SeeOther) &&
|
||||||
|
request.body.as_ref().map_or(false, |b| b.is_empty()) {
|
||||||
|
return Response::network_error(NetworkError::Internal("Request body is not done".into()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 10
|
||||||
if cors_flag && !same_origin {
|
if cors_flag && !same_origin {
|
||||||
request.origin = Origin::Origin(ImmutableOrigin::new_opaque());
|
request.origin = Origin::Origin(ImmutableOrigin::new_opaque());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 10
|
// Step 11
|
||||||
let status_code = response.actual_response().status.unwrap();
|
if response.actual_response().status.map_or(false, |code|
|
||||||
if ((status_code == StatusCode::MovedPermanently || status_code == StatusCode::Found) &&
|
((code == StatusCode::MovedPermanently || code == StatusCode::Found) && request.method == Method::Post) ||
|
||||||
request.method == Method::Post) ||
|
code == StatusCode::SeeOther) {
|
||||||
status_code == StatusCode::SeeOther {
|
|
||||||
request.method = Method::Get;
|
request.method = Method::Get;
|
||||||
request.body = None;
|
request.body = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 11
|
|
||||||
request.url_list.push(location_url);
|
|
||||||
|
|
||||||
// Step 12
|
// Step 12
|
||||||
// TODO implement referrer policy
|
if let Some(_) = request.body {
|
||||||
|
// TODO: extract request's body's source
|
||||||
let recursive_flag = request.redirect_mode != RedirectMode::Manual;
|
}
|
||||||
|
|
||||||
// Step 13
|
// Step 13
|
||||||
|
request.url_list.push(location_url);
|
||||||
|
|
||||||
|
// Step 14
|
||||||
|
// TODO implement referrer policy
|
||||||
|
|
||||||
|
// Step 15
|
||||||
|
let recursive_flag = request.redirect_mode != RedirectMode::Manual;
|
||||||
|
|
||||||
main_fetch(request, cache, cors_flag, recursive_flag, target, done_chan, context)
|
main_fetch(request, cache, cors_flag, recursive_flag, target, done_chan, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -220,7 +220,7 @@ pub struct Request {
|
||||||
// TODO: target browsing context
|
// TODO: target browsing context
|
||||||
/// https://fetch.spec.whatwg.org/#request-keepalive-flag
|
/// https://fetch.spec.whatwg.org/#request-keepalive-flag
|
||||||
pub keep_alive: bool,
|
pub keep_alive: bool,
|
||||||
// https://fetch.spec.whatwg.org/#request-service-workers-mode
|
/// https://fetch.spec.whatwg.org/#request-service-workers-mode
|
||||||
pub service_workers_mode: ServiceWorkersMode,
|
pub service_workers_mode: ServiceWorkersMode,
|
||||||
/// https://fetch.spec.whatwg.org/#concept-request-initiator
|
/// https://fetch.spec.whatwg.org/#concept-request-initiator
|
||||||
pub initiator: Initiator,
|
pub initiator: Initiator,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue