Skip to content

Commit 8bbd0ce

Browse files
committed
Fix partial redirect bug
1 parent 5a3ee94 commit 8bbd0ce

File tree

3 files changed

+30
-7
lines changed

3 files changed

+30
-7
lines changed

Cargo.lock

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ features = ["rustls", "platform-verifier", "native-tls", "socks-proxy", "cookies
5656

5757
[dependencies]
5858
base64 = "0.22.1"
59-
ureq-proto = "0.2.5"
59+
ureq-proto = "0.2.6"
6060
# ureq-proto = { path = "../ureq-proto" }
6161
log = "0.4.22"
6262
once_cell = "1.19.0"

src/run.rs

+27-4
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,15 @@ fn flow_run(
153153
SendRequestResult::RecvResponse(flow) => flow,
154154
};
155155

156-
let (mut response, response_result) = recv_response(flow, &mut connection, config, timings)?;
156+
let is_following_redirects = redirect_count < config.max_redirects();
157+
158+
let (mut response, response_result) = recv_response(
159+
flow,
160+
&mut connection,
161+
config,
162+
timings,
163+
is_following_redirects,
164+
)?;
157165

158166
info!("{:?}", DebugResponse(&response));
159167

@@ -190,7 +198,7 @@ fn flow_run(
190198
};
191199

192200
if response.status().is_redirection() {
193-
if redirect_count < config.max_redirects() {
201+
if is_following_redirects {
194202
let flow = handler.consume_redirect_body()?;
195203

196204
FlowResult::Redirect(flow, handler.timings)
@@ -206,7 +214,7 @@ fn flow_run(
206214
RecvResponseResult::Redirect(flow) => {
207215
cleanup(connection, flow.must_close_connection(), timings.now());
208216

209-
if redirect_count < config.max_redirects() {
217+
if is_following_redirects {
210218
FlowResult::Redirect(flow, mem::take(timings))
211219
} else if config.max_redirects_do_error() {
212220
return Err(Error::TooManyRedirects);
@@ -488,14 +496,29 @@ fn recv_response(
488496
connection: &mut Connection,
489497
config: &Config,
490498
timings: &mut CallTimings,
499+
is_following_redirects: bool,
491500
) -> Result<(Response<()>, RecvResponseResult<()>), Error> {
492501
let response = loop {
493502
let timeout = timings.next_timeout(Timeout::RecvResponse);
494503
let made_progress = connection.await_input(timeout)?;
495504

496505
let input = connection.buffers().input();
497506

498-
let (amount, maybe_response) = flow.try_response(input)?;
507+
// If cookies are disabled, we can allow ourselves to follow
508+
// the redirect as soon as we discover the `Location` header.
509+
// There are plenty of broken servers out there that don't send
510+
// the finishing \r\n on redirects. With cookies off, we can
511+
// handle that situation.
512+
//
513+
// If cookies are enabled, we risk mising a `Set-Cookie` header
514+
// with such a strategy.
515+
let cookies_enabled = cfg!(feature = "cookies");
516+
517+
// If we are not following redirects, do not allow partial returned
518+
// 302 responses.
519+
let allow_partial_redirect = !cookies_enabled && is_following_redirects;
520+
521+
let (amount, maybe_response) = flow.try_response(input, allow_partial_redirect)?;
499522

500523
if input.len() > config.max_response_header_size() {
501524
return Err(Error::LargeResponseHeader(

0 commit comments

Comments
 (0)