Skip to content

Commit 77adab4

Browse files
committed
fix(client): prevent empty bodies sending transfer-encoding for GET, HEAD
1 parent dd79a4a commit 77adab4

File tree

2 files changed

+31
-5
lines changed

2 files changed

+31
-5
lines changed

src/proto/h1/role.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use proto::{MessageHead, RawStatus, Http1Transaction, ParseResult,
1010
use proto::h1::{Encoder, Decoder, date};
1111
use method::Method;
1212
use status::StatusCode;
13-
use version::HttpVersion::{self, Http10, Http11};
13+
use version::HttpVersion::{Http10, Http11};
1414

1515
const MAX_HEADERS: usize = 100;
1616
const AVERAGE_HEADER_SIZE: usize = 30; // totally scientific
@@ -203,7 +203,7 @@ impl ServerTransaction {
203203
};
204204

205205
if has_body && can_have_body {
206-
set_length(head.version, &mut head.headers)
206+
set_length(&mut head.headers, head.version == Http11)
207207
} else {
208208
head.headers.remove::<TransferEncoding>();
209209
if can_have_body {
@@ -354,7 +354,11 @@ impl Http1Transaction for ClientTransaction {
354354
impl ClientTransaction {
355355
fn set_length(head: &mut RequestHead, has_body: bool) -> Encoder {
356356
if has_body {
357-
set_length(head.version, &mut head.headers)
357+
let can_chunked = head.version == Http11
358+
&& (head.subject.0 != Method::Head)
359+
&& (head.subject.0 != Method::Get)
360+
&& (head.subject.0 != Method::Connect);
361+
set_length(&mut head.headers, can_chunked)
358362
} else {
359363
head.headers.remove::<ContentLength>();
360364
head.headers.remove::<TransferEncoding>();
@@ -363,12 +367,12 @@ impl ClientTransaction {
363367
}
364368
}
365369

366-
fn set_length(version: HttpVersion, headers: &mut Headers) -> Encoder {
370+
fn set_length(headers: &mut Headers, can_chunked: bool) -> Encoder {
367371
let len = headers.get::<header::ContentLength>().map(|n| **n);
368372

369373
if let Some(len) = len {
370374
Encoder::length(len)
371-
} else if version == Http11 {
375+
} else if can_chunked {
372376
let encodings = match headers.get_mut::<header::TransferEncoding>() {
373377
Some(&mut header::TransferEncoding(ref mut encodings)) => {
374378
if encodings.last() != Some(&header::Encoding::Chunked) {

tests/client.rs

+22
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,28 @@ test! {
234234
body: None,
235235
}
236236

237+
test! {
238+
name: client_get_implicitly_empty,
239+
240+
server:
241+
expected: "GET / HTTP/1.1\r\nHost: {addr}\r\n\r\n",
242+
reply: REPLY_OK,
243+
244+
client:
245+
request:
246+
method: Get,
247+
url: "http://{addr}/",
248+
headers: [],
249+
body: Some(""),
250+
proxy: false,
251+
response:
252+
status: Ok,
253+
headers: [
254+
ContentLength(0),
255+
],
256+
body: None,
257+
}
258+
237259
test! {
238260
name: client_post_sized,
239261

0 commit comments

Comments
 (0)