Fix regression in following redirection with query sections.
This commit is contained in:
parent
9c3096eb6a
commit
607ca0dac1
|
|
@ -10,6 +10,9 @@
|
|||
|
||||
GET http://localhost:8000/follow-redirect
|
||||
Accept: text/plain
|
||||
[Query]
|
||||
# We add a query param to test that query params strings are not forwarded
|
||||
foo: bar
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
redirects count == 2
|
||||
|
|
|
|||
|
|
@ -19,9 +19,16 @@ GET http://localhost:8000/follow-redirect
|
|||
Accept: text/plain
|
||||
[Options]
|
||||
location: true
|
||||
[Query]
|
||||
# We add a query param to test that query params strings are not forwarded
|
||||
foo: bar
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
header "Location" not exists
|
||||
redirects count == 2
|
||||
redirects nth 0 location == "http://localhost:8000/following-redirect"
|
||||
redirects nth 1 location == "http://localhost:8000/followed-redirect"
|
||||
url == "http://localhost:8000/followed-redirect"
|
||||
`Followed redirect!`
|
||||
|
||||
|
||||
|
|
@ -35,6 +42,9 @@ location: true
|
|||
HTTP 200
|
||||
[Asserts]
|
||||
header "Location" not exists
|
||||
redirects count == 1
|
||||
redirects nth 0 location == "http://localhost:8000/followed-redirect-from-post"
|
||||
url == "http://localhost:8000/followed-redirect-from-post"
|
||||
`Followed redirect!`
|
||||
|
||||
|
||||
|
|
@ -46,6 +56,9 @@ location: true
|
|||
HTTP 200
|
||||
[Asserts]
|
||||
header "Location" not exists
|
||||
redirects count == 1
|
||||
redirects nth 0 location == "http://localhost:8000/followed-redirect-post"
|
||||
url == "http://localhost:8000/followed-redirect-post"
|
||||
`Followed redirect POST!`
|
||||
|
||||
|
||||
|
|
@ -55,6 +68,8 @@ Accept: text/plain
|
|||
location: true
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
redirects nth 0 location == "http://localhost:8000/follow-redirect/bar"
|
||||
redirects count == 1
|
||||
url == "http://localhost:8000/follow-redirect/bar"
|
||||
`Followed relative redirect!`
|
||||
|
||||
|
|
@ -68,6 +83,9 @@ location: true
|
|||
fruit: lemon
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
redirects count == 1
|
||||
redirects nth 0 location == "http://127.0.0.1:8000/followed-redirect-basic-auth"
|
||||
url == "http://127.0.0.1:8000/followed-redirect-basic-auth"
|
||||
header "Location" not exists
|
||||
`Followed redirect without Authorization header!`
|
||||
|
||||
|
|
@ -83,6 +101,9 @@ location: true
|
|||
fruit: lemon
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
redirects count == 1
|
||||
redirects nth 0 location == "http://127.0.0.1:8000/followed-redirect-basic-auth"
|
||||
url == "http://127.0.0.1:8000/followed-redirect-basic-auth"
|
||||
header "Location" not exists
|
||||
`Followed redirect without Authorization header!`
|
||||
|
||||
|
|
@ -97,6 +118,9 @@ location: true
|
|||
fruit: lemon
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
redirects count == 1
|
||||
redirects nth 0 location == "http://localhost:8000/followed-redirect-basic-auth"
|
||||
url == "http://localhost:8000/followed-redirect-basic-auth"
|
||||
header "Location" not exists
|
||||
`Followed redirect with Authorization header!`
|
||||
|
||||
|
|
@ -110,6 +134,9 @@ user: bob@email.com:secret
|
|||
fruit: lemon
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
redirects count == 1
|
||||
redirects nth 0 location == "http://127.0.0.1:8000/followed-redirect-basic-auth"
|
||||
url == "http://127.0.0.1:8000/followed-redirect-basic-auth"
|
||||
header "Location" not exists
|
||||
`Followed redirect without Authorization header!`
|
||||
|
||||
|
|
@ -123,6 +150,9 @@ fruit: lemon
|
|||
HTTP 200
|
||||
[Asserts]
|
||||
header "Location" not exists
|
||||
redirects count == 1
|
||||
redirects nth 0 location == "http://localhost:8000/followed-redirect-basic-auth"
|
||||
url == "http://localhost:8000/followed-redirect-basic-auth"
|
||||
`Followed redirect with Authorization header!`
|
||||
|
||||
|
||||
|
|
@ -136,6 +166,9 @@ bob@email.com: secret
|
|||
fruit: lemon
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
redirects count == 1
|
||||
redirects nth 0 location == "http://127.0.0.1:8000/followed-redirect-basic-auth"
|
||||
url == "http://127.0.0.1:8000/followed-redirect-basic-auth"
|
||||
header "Location" not exists
|
||||
`Followed redirect without Authorization header!`
|
||||
|
||||
|
|
@ -149,6 +182,9 @@ bob@email.com: secret
|
|||
fruit: lemon
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
redirects count == 1
|
||||
redirects nth 0 location == "http://localhost:8000/followed-redirect-basic-auth"
|
||||
url == "http://localhost:8000/followed-redirect-basic-auth"
|
||||
header "Location" not exists
|
||||
`Followed redirect with Authorization header!`
|
||||
|
||||
|
|
@ -162,5 +198,8 @@ location-trusted: true
|
|||
fruit: lemon
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
redirects count == 1
|
||||
redirects nth 0 location == "http://127.0.0.1:8000/followed-redirect-basic-auth-trusted"
|
||||
url == "http://127.0.0.1:8000/followed-redirect-basic-auth-trusted"
|
||||
header "Location" not exists
|
||||
`Followed redirect Basic Auth!`
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ GET http://localhost:8000/redirected
|
|||
HTTP 200
|
||||
[Asserts]
|
||||
url == "http://localhost:8000/redirected"
|
||||
redirects count == 0
|
||||
`Redirected`
|
||||
|
||||
|
||||
|
|
@ -12,6 +13,9 @@ HTTP 302
|
|||
Location: http://localhost:8000/redirected
|
||||
[Asserts]
|
||||
url == "http://localhost:8000/redirect-absolute"
|
||||
# `redirects` query extracts data only if Hurl has run redirection (using --location or --location-trusted)
|
||||
# If this case we have a 302, but we've nots asked Hurl to follow redirection so `redirects` query is empty.
|
||||
redirects count == 0
|
||||
|
||||
|
||||
GET http://localhost:8000/redirect-absolute
|
||||
|
|
@ -20,6 +24,23 @@ location: true
|
|||
HTTP 200
|
||||
[Asserts]
|
||||
url == "http://localhost:8000/redirected"
|
||||
redirects count == 1
|
||||
redirects nth 0 location == "http://localhost:8000/redirected"
|
||||
`Redirected`
|
||||
|
||||
|
||||
# Redirection can redirect body from requests to requests (provided the method doesn't
|
||||
# change) but query strings params are NEVER forwarded
|
||||
GET http://localhost:8000/redirect-absolute
|
||||
[Options]
|
||||
location: true
|
||||
[Query]
|
||||
foo: bar
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
url == "http://localhost:8000/redirected"
|
||||
redirects count == 1
|
||||
redirects nth 0 location == "http://localhost:8000/redirected"
|
||||
`Redirected`
|
||||
|
||||
|
||||
|
|
@ -30,6 +51,7 @@ HTTP 302
|
|||
Location: /redirected
|
||||
[Asserts]
|
||||
url == "http://localhost:8000/redirect-relative"
|
||||
redirects count == 0
|
||||
|
||||
|
||||
GET http://localhost:8000/redirect-relative
|
||||
|
|
@ -38,4 +60,6 @@ location: true
|
|||
HTTP 200
|
||||
[Asserts]
|
||||
url == "http://localhost:8000/redirected"
|
||||
redirects count == 1
|
||||
redirects nth 0 location == "http://localhost:8000/redirected"
|
||||
`Redirected`
|
||||
|
|
|
|||
|
|
@ -33,14 +33,15 @@ use crate::http::certificate::Certificate;
|
|||
use crate::http::curl_cmd::CurlCmd;
|
||||
use crate::http::debug::log_body;
|
||||
use crate::http::header::{
|
||||
HeaderVec, ACCEPT_ENCODING, AUTHORIZATION, CONTENT_TYPE, EXPECT, LOCATION, USER_AGENT,
|
||||
HeaderVec, ACCEPT_ENCODING, AUTHORIZATION, CONTENT_TYPE, EXPECT, LOCATION, SET_COOKIE,
|
||||
USER_AGENT,
|
||||
};
|
||||
use crate::http::ip::IpAddr;
|
||||
use crate::http::options::ClientOptions;
|
||||
use crate::http::timings::Timings;
|
||||
use crate::http::url::Url;
|
||||
use crate::http::{
|
||||
easy_ext, Call, Cookie, FileParam, Header, HttpError, HttpVersion, IpResolve, Method,
|
||||
easy_ext, Body, Call, Cookie, FileParam, Header, HttpError, HttpVersion, IpResolve, Method,
|
||||
MultipartParam, Param, Request, RequestCookie, RequestSpec, RequestedHttpVersion, Response,
|
||||
Verbosity,
|
||||
};
|
||||
|
|
@ -120,11 +121,17 @@ impl Client {
|
|||
let redirect_method = 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 with `--location-trusted`.
|
||||
// When following redirection, we filter `Authorization` and `Set-Cookie` headers if the
|
||||
// hostname changes unless the user explicitly trusts the redirected host with `--location-trusted`.
|
||||
// <https://curl.se/libcurl/c/CURLOPT_FOLLOWLOCATION.html>:
|
||||
//
|
||||
// > By default, libcurl only sends Authentication: or explicitly set Cookie: headers
|
||||
// > to the initial host given in the original URL, to avoid leaking username + password
|
||||
// > to other sites.
|
||||
let host_changed = request_url.host() != redirect_url.host();
|
||||
if host_changed && !options.follow_location_trusted {
|
||||
headers.retain(|h| !h.name_eq(AUTHORIZATION));
|
||||
headers.retain(|h| !h.name_eq(SET_COOKIE));
|
||||
options.user = None;
|
||||
}
|
||||
|
||||
|
|
@ -134,21 +141,21 @@ impl Client {
|
|||
// > When libcurl switches method to GET, it then uses that method without sending any
|
||||
// > request body. If it does not change the method, it sends the subsequent request the
|
||||
// > same way as the previous one; including the request body if one was provided.
|
||||
if redirect_method != request_spec.method {
|
||||
request_spec = RequestSpec {
|
||||
method: redirect_method,
|
||||
url: redirect_url,
|
||||
headers,
|
||||
..Default::default()
|
||||
};
|
||||
let (form, multipart, body) = if redirect_method != request_spec.method {
|
||||
(vec![], vec![], Body::Binary(vec![]))
|
||||
} else {
|
||||
request_spec = RequestSpec {
|
||||
method: redirect_method,
|
||||
url: redirect_url,
|
||||
headers,
|
||||
..request_spec
|
||||
};
|
||||
}
|
||||
(request_spec.form, request_spec.multipart, request_spec.body)
|
||||
};
|
||||
request_spec = RequestSpec {
|
||||
method: redirect_method,
|
||||
url: redirect_url,
|
||||
headers,
|
||||
form,
|
||||
multipart,
|
||||
body,
|
||||
cookies: request_spec.cookies,
|
||||
..Default::default()
|
||||
};
|
||||
}
|
||||
Ok(calls)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue