Fix sending Authorization header from --user when following redirect

This commit is contained in:
Jean-Christophe Amiel 2024-05-21 13:33:55 +02:00 committed by hurl-bot
parent 24da88526d
commit 9dee51c22d
No known key found for this signature in database
GPG Key ID: 1283A2B4A0DCAF8D
8 changed files with 61 additions and 12 deletions

View File

@ -2,4 +2,6 @@ curl --header 'Accept: text/plain' --location 'http://localhost:8000/follow-redi
curl --data '' --header 'Accept: text/plain' --location 'http://localhost:8000/follow-redirect'
curl --header 'Accept: text/plain' --location 'http://localhost:8000/follow-redirect/relative/foo'
curl --header 'Authorization: Basic Ym9iQGVtYWlsLmNvbTpzZWNyZXQ=' --location 'http://localhost:8000/follow-redirect-basic-auth'
curl --data '' --header 'Accept: text/plain' --location 'http://localhost:8000/follow-redirect-308'
curl --location --user 'bob@email.com:secret' 'http://localhost:8000/follow-redirect-basic-auth'
curl --header 'Authorization: Basic Ym9iQGVtYWlsLmNvbTpzZWNyZXQ=' --location 'http://localhost:8000/follow-redirect-basic-auth'
curl --data '' --header 'Accept: text/plain' --location 'http://localhost:8000/follow-redirect-308'

View File

@ -37,15 +37,33 @@ url == "http://localhost:8000/follow-redirect/bar"
# Do not forward authorization header by default to a different host
GET http://localhost:8000/follow-redirect-basic-auth
Authorization: Basic Ym9iQGVtYWlsLmNvbTpzZWNyZXQ=
# FIXME: Authorization header can also be set via --user
#[Options]
#user: bob@email.com:secret
HTTP 200
[Asserts]
header "Location" not exists
`Followed redirect Basic Auth!`
# Another kinds of user authentication:
GET http://localhost:8000/follow-redirect-basic-auth
[Options]
user: bob@email.com:secret
HTTP 200
[Asserts]
header "Location" not exists
`Followed redirect Basic Auth!`
GET http://localhost:8000/follow-redirect-basic-auth
[BasicAuth]
bob@email.com: secret
HTTP 200
[Asserts]
header "Location" not exists
`Followed redirect Basic Auth!`
POST http://localhost:8000/follow-redirect-308
Accept: text/plain
HTTP 200

View File

@ -1,3 +1,3 @@
Set-StrictMode -Version latest
$ErrorActionPreference = 'Stop'
hurl --location --verbose tests_ok/follow_redirect.hurl
hurl --location tests_ok/follow_redirect.hurl

View File

@ -1,3 +1,3 @@
#!/bin/bash
set -Eeuo pipefail
hurl --location --verbose tests_ok/follow_redirect.hurl
hurl --location tests_ok/follow_redirect.hurl

View File

@ -68,6 +68,28 @@ header "Location" not exists
`Followed redirect Basic Auth!`
# Another kinds of user authentication:
GET http://localhost:8000/follow-redirect-basic-auth
[Options]
location: true
user: bob@email.com:secret
HTTP 200
[Asserts]
header "Location" not exists
`Followed redirect Basic Auth!`
GET http://localhost:8000/follow-redirect-basic-auth
[Options]
location: true
[BasicAuth]
bob@email.com: secret
HTTP 200
[Asserts]
header "Location" not exists
`Followed redirect Basic Auth!`
# Forward authorization header to a different host explicitly
GET http://localhost:8000/follow-redirect-basic-auth-trusted
Authorization: Basic Ym9iQGVtYWlsLmNvbTpzZWNyZXQ=

View File

@ -1,3 +1,3 @@
Set-StrictMode -Version latest
$ErrorActionPreference = 'Stop'
hurl --verbose tests_ok/follow_redirect_option.hurl
hurl tests_ok/follow_redirect_option.hurl

View File

@ -1,3 +1,3 @@
#!/bin/bash
set -Eeuo pipefail
hurl --verbose tests_ok/follow_redirect_option.hurl
hurl tests_ok/follow_redirect_option.hurl

View File

@ -107,13 +107,14 @@ impl Client {
let mut calls = vec![];
let mut request_spec = request_spec.clone();
let mut options = options.clone();
// Unfortunately, follow-location feature from libcurl can not be used
// libcurl returns a single list of headers for the 2 responses
// Hurl needs to keep everything.
// Unfortunately, follow-location feature from libcurl can not be used as libcurl returns a
// single list of headers for the 2 responses and Hurl needs to keep every header of every
// response.
let mut redirect_count = 0;
loop {
let call = self.execute(&request_spec, options, logger)?;
let call = self.execute(&request_spec, &options, logger)?;
let redirect_url = self.get_follow_location(&call.request, &call.response)?;
let status = call.response.status;
calls.push(call);
@ -131,12 +132,18 @@ impl Client {
}
}
let redirect_method = get_redirect_method(status, request_spec.method);
// 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 {
options.user = None;
}
request_spec = RequestSpec {
method: redirect_method,
url: redirect_url.to_string(),