fix(client): prevent empty bodies sending transfer-encoding for GET, HEAD
This commit is contained in:
@@ -10,7 +10,7 @@ use proto::{MessageHead, RawStatus, Http1Transaction, ParseResult,
|
|||||||
use proto::h1::{Encoder, Decoder, date};
|
use proto::h1::{Encoder, Decoder, date};
|
||||||
use method::Method;
|
use method::Method;
|
||||||
use status::StatusCode;
|
use status::StatusCode;
|
||||||
use version::HttpVersion::{self, Http10, Http11};
|
use version::HttpVersion::{Http10, Http11};
|
||||||
|
|
||||||
const MAX_HEADERS: usize = 100;
|
const MAX_HEADERS: usize = 100;
|
||||||
const AVERAGE_HEADER_SIZE: usize = 30; // totally scientific
|
const AVERAGE_HEADER_SIZE: usize = 30; // totally scientific
|
||||||
@@ -203,7 +203,7 @@ impl ServerTransaction {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if has_body && can_have_body {
|
if has_body && can_have_body {
|
||||||
set_length(head.version, &mut head.headers)
|
set_length(&mut head.headers, head.version == Http11)
|
||||||
} else {
|
} else {
|
||||||
head.headers.remove::<TransferEncoding>();
|
head.headers.remove::<TransferEncoding>();
|
||||||
if can_have_body {
|
if can_have_body {
|
||||||
@@ -354,7 +354,11 @@ impl Http1Transaction for ClientTransaction {
|
|||||||
impl ClientTransaction {
|
impl ClientTransaction {
|
||||||
fn set_length(head: &mut RequestHead, has_body: bool) -> Encoder {
|
fn set_length(head: &mut RequestHead, has_body: bool) -> Encoder {
|
||||||
if has_body {
|
if has_body {
|
||||||
set_length(head.version, &mut head.headers)
|
let can_chunked = head.version == Http11
|
||||||
|
&& (head.subject.0 != Method::Head)
|
||||||
|
&& (head.subject.0 != Method::Get)
|
||||||
|
&& (head.subject.0 != Method::Connect);
|
||||||
|
set_length(&mut head.headers, can_chunked)
|
||||||
} else {
|
} else {
|
||||||
head.headers.remove::<ContentLength>();
|
head.headers.remove::<ContentLength>();
|
||||||
head.headers.remove::<TransferEncoding>();
|
head.headers.remove::<TransferEncoding>();
|
||||||
@@ -363,12 +367,12 @@ impl ClientTransaction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_length(version: HttpVersion, headers: &mut Headers) -> Encoder {
|
fn set_length(headers: &mut Headers, can_chunked: bool) -> Encoder {
|
||||||
let len = headers.get::<header::ContentLength>().map(|n| **n);
|
let len = headers.get::<header::ContentLength>().map(|n| **n);
|
||||||
|
|
||||||
if let Some(len) = len {
|
if let Some(len) = len {
|
||||||
Encoder::length(len)
|
Encoder::length(len)
|
||||||
} else if version == Http11 {
|
} else if can_chunked {
|
||||||
let encodings = match headers.get_mut::<header::TransferEncoding>() {
|
let encodings = match headers.get_mut::<header::TransferEncoding>() {
|
||||||
Some(&mut header::TransferEncoding(ref mut encodings)) => {
|
Some(&mut header::TransferEncoding(ref mut encodings)) => {
|
||||||
if encodings.last() != Some(&header::Encoding::Chunked) {
|
if encodings.last() != Some(&header::Encoding::Chunked) {
|
||||||
|
|||||||
@@ -234,6 +234,28 @@ test! {
|
|||||||
body: None,
|
body: None,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test! {
|
||||||
|
name: client_get_implicitly_empty,
|
||||||
|
|
||||||
|
server:
|
||||||
|
expected: "GET / HTTP/1.1\r\nHost: {addr}\r\n\r\n",
|
||||||
|
reply: REPLY_OK,
|
||||||
|
|
||||||
|
client:
|
||||||
|
request:
|
||||||
|
method: Get,
|
||||||
|
url: "http://{addr}/",
|
||||||
|
headers: [],
|
||||||
|
body: Some(""),
|
||||||
|
proxy: false,
|
||||||
|
response:
|
||||||
|
status: Ok,
|
||||||
|
headers: [
|
||||||
|
ContentLength(0),
|
||||||
|
],
|
||||||
|
body: None,
|
||||||
|
}
|
||||||
|
|
||||||
test! {
|
test! {
|
||||||
name: client_post_sized,
|
name: client_post_sized,
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user