mirror of
https://github.com/Orange-OpenSource/hurl.git
synced 2024-11-23 00:44:55 +03:00
Do not filter 'Authorization' header if host doesn't change while following redirection
This commit is contained in:
parent
9dee51c22d
commit
af0417d25d
@ -25,7 +25,7 @@ HTTP 200
|
||||
url == "http://localhost:8000/followed-redirect"
|
||||
`Followed redirect!`
|
||||
|
||||
|
||||
# Check relative redirection
|
||||
GET http://localhost:8000/follow-redirect/relative/foo
|
||||
Accept: text/plain
|
||||
HTTP 200
|
||||
@ -34,34 +34,61 @@ url == "http://localhost:8000/follow-redirect/bar"
|
||||
`Followed relative redirect!`
|
||||
|
||||
|
||||
# Do not forward authorization header by default to a different host
|
||||
GET http://localhost:8000/follow-redirect-basic-auth
|
||||
# Do not forward `Authorization` header to a different host
|
||||
GET http://localhost:8000/follow-redirect-basic-auth?change_host=true
|
||||
Authorization: Basic Ym9iQGVtYWlsLmNvbTpzZWNyZXQ=
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
header "Location" not exists
|
||||
`Followed redirect Basic Auth!`
|
||||
`Followed redirect without Authorization header!`
|
||||
|
||||
|
||||
# Another kinds of user authentication:
|
||||
GET http://localhost:8000/follow-redirect-basic-auth
|
||||
# Same has previous but the host doesn't change during redirection.
|
||||
# Back checks will insure that `Authorization` is forwarded.
|
||||
GET http://localhost:8000/follow-redirect-basic-auth?change_host=false
|
||||
Authorization: Basic Ym9iQGVtYWlsLmNvbTpzZWNyZXQ=
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
header "Location" not exists
|
||||
`Followed redirect with Authorization header!`
|
||||
|
||||
|
||||
# Another kinds of user authentication with `--user` in `[Options]` section:
|
||||
GET http://localhost:8000/follow-redirect-basic-auth?change_host=true
|
||||
[Options]
|
||||
user: bob@email.com:secret
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
header "Location" not exists
|
||||
`Followed redirect Basic Auth!`
|
||||
`Followed redirect without Authorization header!`
|
||||
|
||||
|
||||
GET http://localhost:8000/follow-redirect-basic-auth
|
||||
GET http://localhost:8000/follow-redirect-basic-auth?change_host=false
|
||||
[Options]
|
||||
user: bob@email.com:secret
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
header "Location" not exists
|
||||
`Followed redirect with Authorization header!`
|
||||
|
||||
|
||||
# Another kinds of user authentication with `[BasicAuth]` section:
|
||||
GET http://localhost:8000/follow-redirect-basic-auth?change_host=true
|
||||
[BasicAuth]
|
||||
bob@email.com: secret
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
header "Location" not exists
|
||||
`Followed redirect Basic Auth!`
|
||||
`Followed redirect without Authorization header!`
|
||||
|
||||
|
||||
GET http://localhost:8000/follow-redirect-basic-auth?change_host=false
|
||||
[BasicAuth]
|
||||
bob@email.com: secret
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
header "Location" not exists
|
||||
`Followed redirect with Authorization header!`
|
||||
|
||||
|
||||
POST http://localhost:8000/follow-redirect-308
|
||||
|
@ -43,13 +43,22 @@ def follow_redirect_308():
|
||||
@app.route("/follow-redirect-basic-auth")
|
||||
def follow_redirect_basic_auth():
|
||||
assert "Authorization" in request.headers
|
||||
return redirect("http://127.0.0.1:8000/followed-redirect-basic-auth")
|
||||
change_host = request.args.get("change_host") == "true"
|
||||
if change_host:
|
||||
return redirect("http://127.0.0.1:8000/followed-redirect-basic-auth")
|
||||
else:
|
||||
return redirect("http://localhost:8000/followed-redirect-basic-auth")
|
||||
|
||||
|
||||
@app.route("/followed-redirect-basic-auth")
|
||||
def followed_redirect_basic_auth():
|
||||
assert "Authorization" not in request.headers
|
||||
return "Followed redirect Basic Auth!"
|
||||
# When host changes, authorization should be filtered
|
||||
if request.headers["Host"] == "localhost:8000":
|
||||
assert "Authorization" in request.headers
|
||||
return "Followed redirect with Authorization header!"
|
||||
else:
|
||||
assert "Authorization" not in request.headers
|
||||
return "Followed redirect without Authorization header!"
|
||||
|
||||
|
||||
@app.route("/follow-redirect-basic-auth-trusted")
|
||||
|
@ -57,29 +57,52 @@ url == "http://localhost:8000/follow-redirect/bar"
|
||||
`Followed relative redirect!`
|
||||
|
||||
|
||||
# Do not forward authorization header by default to a different host
|
||||
GET http://localhost:8000/follow-redirect-basic-auth
|
||||
# Do not forward `Authorization` header to a different host
|
||||
GET http://localhost:8000/follow-redirect-basic-auth?change_host=true
|
||||
Authorization: Basic Ym9iQGVtYWlsLmNvbTpzZWNyZXQ=
|
||||
[Options]
|
||||
location: true
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
header "Location" not exists
|
||||
`Followed redirect Basic Auth!`
|
||||
`Followed redirect without Authorization header!`
|
||||
|
||||
|
||||
# Another kinds of user authentication:
|
||||
GET http://localhost:8000/follow-redirect-basic-auth
|
||||
# Same has previous but the host doesn't change during redirection.
|
||||
# Back checks will insure that `Authorization` is forwarded.
|
||||
GET http://localhost:8000/follow-redirect-basic-auth?change_host=false
|
||||
Authorization: Basic Ym9iQGVtYWlsLmNvbTpzZWNyZXQ=
|
||||
[Options]
|
||||
location: true
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
header "Location" not exists
|
||||
`Followed redirect with Authorization header!`
|
||||
|
||||
|
||||
# Another kinds of user authentication with `--user` in `[Options]` section:
|
||||
GET http://localhost:8000/follow-redirect-basic-auth?change_host=true
|
||||
[Options]
|
||||
location: true
|
||||
user: bob@email.com:secret
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
header "Location" not exists
|
||||
`Followed redirect Basic Auth!`
|
||||
`Followed redirect without Authorization header!`
|
||||
|
||||
|
||||
GET http://localhost:8000/follow-redirect-basic-auth
|
||||
GET http://localhost:8000/follow-redirect-basic-auth?change_host=false
|
||||
[Options]
|
||||
location: true
|
||||
user: bob@email.com:secret
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
header "Location" not exists
|
||||
`Followed redirect with Authorization header!`
|
||||
|
||||
|
||||
# Another kinds of user authentication with `[BasicAuth]` section:
|
||||
GET http://localhost:8000/follow-redirect-basic-auth?change_host=true
|
||||
[Options]
|
||||
location: true
|
||||
[BasicAuth]
|
||||
@ -87,7 +110,18 @@ bob@email.com: secret
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
header "Location" not exists
|
||||
`Followed redirect Basic Auth!`
|
||||
`Followed redirect without Authorization header!`
|
||||
|
||||
|
||||
GET http://localhost:8000/follow-redirect-basic-auth?change_host=false
|
||||
[Options]
|
||||
location: true
|
||||
[BasicAuth]
|
||||
bob@email.com: secret
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
header "Location" not exists
|
||||
`Followed redirect with Authorization header!`
|
||||
|
||||
|
||||
# Forward authorization header to a different host explicitly
|
||||
|
@ -115,7 +115,8 @@ impl Client {
|
||||
let mut redirect_count = 0;
|
||||
loop {
|
||||
let call = self.execute(&request_spec, &options, logger)?;
|
||||
let redirect_url = self.get_follow_location(&call.request, &call.response)?;
|
||||
let request_url = call.request.url.clone();
|
||||
let redirect_url = self.get_follow_location(&request_url, &call.response)?;
|
||||
let status = call.response.status;
|
||||
calls.push(call);
|
||||
if !options.follow_location || redirect_url.is_none() {
|
||||
@ -132,16 +133,13 @@ impl Client {
|
||||
}
|
||||
}
|
||||
let redirect_method = get_redirect_method(status, request_spec.method);
|
||||
let mut headers = request_spec.headers;
|
||||
|
||||
// When following redirection, we filter `AUTHORIZATION` header unless explicitly told
|
||||
// to trust the redirected host.
|
||||
// FIXME: we should filter only if we're changing host
|
||||
let headers = if options.follow_location_trusted {
|
||||
request_spec.headers
|
||||
} else {
|
||||
request_spec.headers.retain(|h| !h.name_eq(AUTHORIZATION));
|
||||
request_spec.headers
|
||||
};
|
||||
if options.user.is_some() && !options.follow_location_trusted {
|
||||
// to trust the redirected host with `--location-trusted`.
|
||||
let host_changed = request_url.host() != redirect_url.host();
|
||||
if host_changed && !options.follow_location_trusted {
|
||||
headers.retain(|h| !h.name_eq(AUTHORIZATION));
|
||||
options.user = None;
|
||||
}
|
||||
request_spec = RequestSpec {
|
||||
@ -692,7 +690,7 @@ impl Client {
|
||||
/// 3. a header Location
|
||||
fn get_follow_location(
|
||||
&mut self,
|
||||
request: &Request,
|
||||
request_url: &Url,
|
||||
response: &Response,
|
||||
) -> Result<Option<Url>, HttpError> {
|
||||
let response_code = response.status;
|
||||
@ -702,7 +700,7 @@ impl Client {
|
||||
let Some(location) = response.headers.get(LOCATION) else {
|
||||
return Ok(None);
|
||||
};
|
||||
let url = request.url.join(&location.value)?;
|
||||
let url = request_url.join(&location.value)?;
|
||||
Ok(Some(url))
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,13 @@ impl Url {
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn host(&self) -> String {
|
||||
self.inner
|
||||
.host()
|
||||
.expect("HTTP and HTTPS URL must have a domain")
|
||||
.to_string()
|
||||
}
|
||||
|
||||
/// Parse a string `input` as an URL, with this URL as the base URL.
|
||||
pub fn join(&self, input: &str) -> Result<Url, HttpError> {
|
||||
let new_inner = self.inner.join(input);
|
||||
|
Loading…
Reference in New Issue
Block a user