dont try to redirect if post body cannot be reset
This commit is contained in:
@@ -115,3 +115,10 @@ pub fn as_hyper_body<'a>(body: &'a mut Body) -> ::hyper::client::Body<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn can_reset(body: &Body) -> bool {
|
||||
match body.reader {
|
||||
Kind::Bytes(_) => true,
|
||||
Kind::Reader(..) => false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,7 +213,13 @@ impl<'a> RequestBuilder<'a> {
|
||||
true
|
||||
},
|
||||
StatusCode::TemporaryRedirect |
|
||||
StatusCode::PermanentRedirect => true,
|
||||
StatusCode::PermanentRedirect => {
|
||||
if let Some(ref body) = body {
|
||||
body::can_reset(body)
|
||||
} else {
|
||||
true
|
||||
}
|
||||
},
|
||||
_ => false,
|
||||
};
|
||||
|
||||
|
||||
111
tests/client.rs
111
tests/client.rs
@@ -33,32 +33,35 @@ fn test_get() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_redirect_302_changes_post_to_get() {
|
||||
fn test_redirect_301_and_302_and_303_changes_post_to_get() {
|
||||
let client = reqwest::Client::new().unwrap();
|
||||
let codes = [301, 302, 303];
|
||||
|
||||
for code in codes.iter() {
|
||||
let redirect = server! {
|
||||
request: b"\
|
||||
POST /302 HTTP/1.1\r\n\
|
||||
request: format!("\
|
||||
POST /{} HTTP/1.1\r\n\
|
||||
Host: $HOST\r\n\
|
||||
User-Agent: $USERAGENT\r\n\
|
||||
Content-Length: 0\r\n\
|
||||
\r\n\
|
||||
",
|
||||
response: b"\
|
||||
HTTP/1.1 302 Found\r\n\
|
||||
", code),
|
||||
response: format!("\
|
||||
HTTP/1.1 {} reason\r\n\
|
||||
Server: test-redirect\r\n\
|
||||
Content-Length: 0\r\n\
|
||||
Location: /dst\r\n\
|
||||
Connection: close\r\n\
|
||||
\r\n\
|
||||
",
|
||||
", code),
|
||||
|
||||
request: b"\
|
||||
request: format!("\
|
||||
GET /dst HTTP/1.1\r\n\
|
||||
Host: $HOST\r\n\
|
||||
User-Agent: $USERAGENT\r\n\
|
||||
Referer: http://$HOST/302\r\n\
|
||||
Referer: http://$HOST/{}\r\n\
|
||||
\r\n\
|
||||
",
|
||||
", code),
|
||||
response: b"\
|
||||
HTTP/1.1 200 OK\r\n\
|
||||
Server: test-dst\r\n\
|
||||
@@ -67,11 +70,93 @@ fn test_redirect_302_changes_post_to_get() {
|
||||
"
|
||||
};
|
||||
|
||||
let client = reqwest::Client::new().unwrap();
|
||||
let res = client.post(&format!("http://{}/302", redirect.addr()))
|
||||
let res = client.post(&format!("http://{}/{}", redirect.addr(), code))
|
||||
.send()
|
||||
.unwrap();
|
||||
assert_eq!(res.status(), &reqwest::StatusCode::Ok);
|
||||
assert_eq!(res.headers().get(), Some(&reqwest::header::Server("test-dst".to_string())));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_redirect_307_and_308_tries_to_post_again() {
|
||||
let client = reqwest::Client::new().unwrap();
|
||||
let codes = [307, 308];
|
||||
for code in codes.iter() {
|
||||
let redirect = server! {
|
||||
request: format!("\
|
||||
POST /{} HTTP/1.1\r\n\
|
||||
Host: $HOST\r\n\
|
||||
User-Agent: $USERAGENT\r\n\
|
||||
Content-Length: 5\r\n\
|
||||
\r\n\
|
||||
Hello\
|
||||
", code),
|
||||
response: format!("\
|
||||
HTTP/1.1 {} reason\r\n\
|
||||
Server: test-redirect\r\n\
|
||||
Content-Length: 0\r\n\
|
||||
Location: /dst\r\n\
|
||||
Connection: close\r\n\
|
||||
\r\n\
|
||||
", code),
|
||||
|
||||
request: format!("\
|
||||
POST /dst HTTP/1.1\r\n\
|
||||
Host: $HOST\r\n\
|
||||
User-Agent: $USERAGENT\r\n\
|
||||
Referer: http://$HOST/{}\r\n\
|
||||
Content-Length: 5\r\n\
|
||||
\r\n\
|
||||
Hello\
|
||||
", code),
|
||||
response: b"\
|
||||
HTTP/1.1 200 OK\r\n\
|
||||
Server: test-dst\r\n\
|
||||
Content-Length: 0\r\n\
|
||||
\r\n\
|
||||
"
|
||||
};
|
||||
|
||||
let res = client.post(&format!("http://{}/{}", redirect.addr(), code))
|
||||
.body("Hello")
|
||||
.send()
|
||||
.unwrap();
|
||||
assert_eq!(res.status(), &reqwest::StatusCode::Ok);
|
||||
assert_eq!(res.headers().get(), Some(&reqwest::header::Server("test-dst".to_string())));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_redirect_307_does_not_try_if_reader_cannot_reset() {
|
||||
let client = reqwest::Client::new().unwrap();
|
||||
let codes = [307, 308];
|
||||
for &code in codes.iter() {
|
||||
let redirect = server! {
|
||||
request: format!("\
|
||||
POST /{} HTTP/1.1\r\n\
|
||||
Host: $HOST\r\n\
|
||||
User-Agent: $USERAGENT\r\n\
|
||||
Transfer-Encoding: chunked\r\n\
|
||||
\r\n\
|
||||
5\r\n\
|
||||
Hello\r\n\
|
||||
0\r\n\r\n\
|
||||
", code),
|
||||
response: format!("\
|
||||
HTTP/1.1 {} reason\r\n\
|
||||
Server: test-redirect\r\n\
|
||||
Content-Length: 0\r\n\
|
||||
Location: /dst\r\n\
|
||||
Connection: close\r\n\
|
||||
\r\n\
|
||||
", code)
|
||||
};
|
||||
|
||||
let res = client.post(&format!("http://{}/{}", redirect.addr(), code))
|
||||
.body(reqwest::Body::new(&b"Hello"[..]))
|
||||
.send()
|
||||
.unwrap();
|
||||
assert_eq!(res.status(), &reqwest::StatusCode::from_u16(code));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user