summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordarin@google.com <darin@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-09-23 23:57:17 +0000
committerdarin@google.com <darin@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-09-23 23:57:17 +0000
commitf9d44aa6e5fdefae83b3e02effdd7376b31dd3ef (patch)
tree02e58aecf9901d5e8060cdb9f54456b6b697831c
parentb1670ee840ae84cbb5f837d73ed35591a0c82a25 (diff)
downloadchromium_src-f9d44aa6e5fdefae83b3e02effdd7376b31dd3ef.zip
chromium_src-f9d44aa6e5fdefae83b3e02effdd7376b31dd3ef.tar.gz
chromium_src-f9d44aa6e5fdefae83b3e02effdd7376b31dd3ef.tar.bz2
Fix support for 204 responses that lack an explicit EOF.
BUG=2347 R=wtc Review URL: http://codereview.chromium.org/3085 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@2533 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--net/base/net_error_list.h3
-rw-r--r--net/http/http_network_transaction.cc27
-rw-r--r--net/http/http_network_transaction_unittest.cc16
3 files changed, 32 insertions, 14 deletions
diff --git a/net/base/net_error_list.h b/net/base/net_error_list.h
index c3b7a60..9fbb942 100644
--- a/net/base/net_error_list.h
+++ b/net/base/net_error_list.h
@@ -192,6 +192,9 @@ NET_ERROR(INVALID_RESPONSE, -320)
// Error in chunked transfer encoding.
NET_ERROR(INVALID_CHUNKED_ENCODING, -321)
+// The server did not support the request method.
+NET_ERROR(METHOD_NOT_SUPPORTED, -322)
+
// The cache does not have the requested entry.
NET_ERROR(CACHE_MISS, -400)
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index 08748af..8c12261 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -632,6 +632,10 @@ int HttpNetworkTransaction::DoReadBody() {
next_state_ = STATE_READ_BODY_COMPLETE;
+ // We may have already consumed the indicated content length.
+ if (content_length_ != -1 && content_read_ >= content_length_)
+ return 0;
+
// We may have some data remaining in the header buffer.
if (header_buf_.get() && header_buf_body_offset_ < header_buf_len_) {
int n = std::min(read_buf_len_, header_buf_len_ - header_buf_body_offset_);
@@ -711,18 +715,17 @@ int HttpNetworkTransaction::DidReadResponseHeaders() {
headers = new HttpResponseHeaders(std::string("HTTP/0.9 200 OK"));
}
- if (establishing_tunnel_ &&
- headers->GetParsedHttpVersion() < HttpVersion(1, 0)) {
- // Require the "HTTP/1.x" status line.
- return ERR_TUNNEL_CONNECTION_FAILED;
- }
+ if (headers->GetParsedHttpVersion() < HttpVersion(1, 0)) {
+ // Require the "HTTP/1.x" status line for SSL CONNECT.
+ if (establishing_tunnel_)
+ return ERR_TUNNEL_CONNECTION_FAILED;
- // HTTP/0.9 doesn't support the PUT method, so lack of response headers
- // indicates a buggy server.
- // See: https://bugzilla.mozilla.org/show_bug.cgi?id=193921
- if (headers->GetHttpVersion() == HttpVersion(0, 9) &&
- request_->method == "PUT")
- return ERR_ABORTED;
+ // HTTP/0.9 doesn't support the PUT method, so lack of response headers
+ // indicates a buggy server. See:
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=193921
+ if (request_->method == "PUT")
+ return ERR_METHOD_NOT_SUPPORTED;
+ }
// Check for an intermediate 100 Continue response. An origin server is
// allowed to send this response even if we didn't ask for it, so we just
@@ -773,7 +776,7 @@ int HttpNetworkTransaction::DidReadResponseHeaders() {
if (content_length_ == -1) {
// Ignore spurious chunked responses from HTTP/1.0 servers and proxies.
// Otherwise "Transfer-Encoding: chunked" trumps "Content-Length: N"
- if (response_.headers->GetHttpVersion() != HttpVersion(1, 0) &&
+ if (response_.headers->GetHttpVersion() >= HttpVersion(1, 1) &&
response_.headers->HasHeaderValue("Transfer-Encoding", "chunked")) {
chunked_decoder_.reset(new HttpChunkedDecoder());
} else {
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index bba719b..2b54e09 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -234,7 +234,6 @@ TEST_F(HttpNetworkTransactionTest, SimpleGET) {
{ true, 0, "hello world", -1 },
{ false, net::OK, NULL, 0 },
};
-
SimpleGetHelperResult out = SimpleGetHelper(data_reads);
EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
EXPECT_EQ("hello world", out.response_data);
@@ -246,7 +245,6 @@ TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
{ true, 0, "hello world", -1 },
{ false, net::OK, NULL, 0 },
};
-
SimpleGetHelperResult out = SimpleGetHelper(data_reads);
EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
EXPECT_EQ("hello world", out.response_data);
@@ -311,6 +309,20 @@ TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
EXPECT_EQ("HTT", out.response_data);
}
+// Simulate a 204 response, lacking a Content-Length header, sent over a
+// persistent connection. The response should still terminate since a 204
+// cannot have a response body.
+TEST_F(HttpNetworkTransactionTest, StopsReading204) {
+ MockRead data_reads[] = {
+ { true, 0, "HTTP/1.1 204 No Content\r\n\r\n", -1 },
+ { true, 0, "junk", -1 }, // Should not be read!!
+ { false, net::OK, NULL, 0 },
+ };
+ SimpleGetHelperResult out = SimpleGetHelper(data_reads);
+ EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
+ EXPECT_EQ("", out.response_data);
+}
+
TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
scoped_refptr<net::HttpNetworkSession> session = CreateSession();