diff options
author | darin@google.com <darin@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-09-23 23:57:17 +0000 |
---|---|---|
committer | darin@google.com <darin@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-09-23 23:57:17 +0000 |
commit | f9d44aa6e5fdefae83b3e02effdd7376b31dd3ef (patch) | |
tree | 02e58aecf9901d5e8060cdb9f54456b6b697831c | |
parent | b1670ee840ae84cbb5f837d73ed35591a0c82a25 (diff) | |
download | chromium_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.h | 3 | ||||
-rw-r--r-- | net/http/http_network_transaction.cc | 27 | ||||
-rw-r--r-- | net/http/http_network_transaction_unittest.cc | 16 |
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(); |