diff options
author | ericroman@google.com <ericroman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-16 02:02:47 +0000 |
---|---|---|
committer | ericroman@google.com <ericroman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-16 02:02:47 +0000 |
commit | aecfbf25fe132328429d2ec8570d2327c060e042 (patch) | |
tree | ff3758b7473240809833d5f686911eb442d7a7fe /net/http | |
parent | d5bd66aa1267692edbd6f911e20b42e12f69ed40 (diff) | |
download | chromium_src-aecfbf25fe132328429d2ec8570d2327c060e042.zip chromium_src-aecfbf25fe132328429d2ec8570d2327c060e042.tar.gz chromium_src-aecfbf25fe132328429d2ec8570d2327c060e042.tar.bz2 |
Make zero-byte responses an error, rather than an empty HTTP/0.9 case.
Review URL: http://codereview.chromium.org/7381
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@3446 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/http')
-rw-r--r-- | net/http/http_network_transaction.cc | 43 | ||||
-rw-r--r-- | net/http/http_network_transaction.h | 4 | ||||
-rw-r--r-- | net/http/http_network_transaction_unittest.cc | 19 |
3 files changed, 49 insertions, 17 deletions
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index 168b99d..7fc99e8 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc @@ -603,6 +603,34 @@ int HttpNetworkTransaction::DoReadHeaders() { return connection_.socket()->Read(buf, buf_len, &io_callback_); } +int HttpNetworkTransaction::HandleSocketClosedBeforeReadingEndOfHeaders() { + if (establishing_tunnel_) { + // The socket was closed before the tunnel could be established. + return ERR_TUNNEL_CONNECTION_FAILED; + } + + if (has_found_status_line_start()) { + // Assume EOF is end-of-headers. + header_buf_body_offset_ = header_buf_len_; + return OK; + } + + // No status line was matched yet. Could have been a HTTP/0.9 response, or + // a partial HTTP/1.x response. + + if (header_buf_len_ == 0) { + // The connection was closed before any data was sent. This could have + // been intended as a HTTP/0.9 response with no data, but more likely + // than not it represents an error. + return ERR_EMPTY_RESPONSE; + } + + // Assume everything else is a HTTP/0.9 response (including responses + // of 'h', 'ht', 'htt'). + header_buf_body_offset_ = 0; + return OK; +} + int HttpNetworkTransaction::DoReadHeadersComplete(int result) { if (result < 0) return HandleIOError(result); @@ -617,18 +645,9 @@ int HttpNetworkTransaction::DoReadHeadersComplete(int result) { // The socket was closed before we found end-of-headers. if (result == 0) { - if (establishing_tunnel_) { - // The socket was closed before the tunnel could be established. - return ERR_TUNNEL_CONNECTION_FAILED; - } - if (has_found_status_line_start()) { - // Assume EOF is end-of-headers. - header_buf_body_offset_ = header_buf_len_; - } else { - // No status line was matched yet, assume HTTP/0.9 - // (this will also match a HTTP/1.x that got closed early). - header_buf_body_offset_ = 0; - } + int rv = HandleSocketClosedBeforeReadingEndOfHeaders(); + if (rv != OK) + return rv; } else { header_buf_len_ += result; DCHECK(header_buf_len_ <= header_buf_capacity_); diff --git a/net/http/http_network_transaction.h b/net/http/http_network_transaction.h index 475056e..c686cd6 100644 --- a/net/http/http_network_transaction.h +++ b/net/http/http_network_transaction.h @@ -108,6 +108,10 @@ class HttpNetworkTransaction : public HttpTransaction { // code is simply returned. int ReconsiderProxyAfterError(int error); + // Decides the policy when the connection is closed before the end of headers + // has been reached. + int HandleSocketClosedBeforeReadingEndOfHeaders(); + // Return true if based on the bytes read so far, the start of the // status line is known. This is used to distingish between HTTP/0.9 // responses (which have no status line) and HTTP/1.x responses. diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index 9c2d6a7..b421d3c 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc @@ -228,6 +228,7 @@ class HttpNetworkTransactionTest : public PlatformTest { }; struct SimpleGetHelperResult { + int rv; std::string status_line; std::string response_data; }; @@ -253,8 +254,9 @@ SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[]) { int rv = trans->Start(&request, &callback); EXPECT_EQ(net::ERR_IO_PENDING, rv); - rv = callback.WaitForResult(); - EXPECT_EQ(net::OK, rv); + out.rv = callback.WaitForResult(); + if (out.rv != net::OK) + return out; const net::HttpResponseInfo* response = trans->GetResponseInfo(); EXPECT_TRUE(response != NULL); @@ -288,6 +290,7 @@ TEST_F(HttpNetworkTransactionTest, SimpleGET) { MockRead(false, net::OK), }; SimpleGetHelperResult out = SimpleGetHelper(data_reads); + EXPECT_EQ(net::OK, out.rv); EXPECT_EQ("HTTP/1.0 200 OK", out.status_line); EXPECT_EQ("hello world", out.response_data); } @@ -299,6 +302,7 @@ TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) { MockRead(false, net::OK), }; SimpleGetHelperResult out = SimpleGetHelper(data_reads); + EXPECT_EQ(net::OK, out.rv); EXPECT_EQ("HTTP/0.9 200 OK", out.status_line); EXPECT_EQ("hello world", out.response_data); } @@ -310,6 +314,7 @@ TEST_F(HttpNetworkTransactionTest, StatusLineJunk2Bytes) { MockRead(false, net::OK), }; SimpleGetHelperResult out = SimpleGetHelper(data_reads); + EXPECT_EQ(net::OK, out.rv); EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line); EXPECT_EQ("DATA", out.response_data); } @@ -321,6 +326,7 @@ TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) { MockRead(false, net::OK), }; SimpleGetHelperResult out = SimpleGetHelper(data_reads); + EXPECT_EQ(net::OK, out.rv); EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line); EXPECT_EQ("DATA", out.response_data); } @@ -332,6 +338,7 @@ TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) { MockRead(false, net::OK), }; SimpleGetHelperResult out = SimpleGetHelper(data_reads); + EXPECT_EQ(net::OK, out.rv); EXPECT_EQ("HTTP/0.9 200 OK", out.status_line); EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data); } @@ -347,6 +354,7 @@ TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) { MockRead(false, net::OK), }; SimpleGetHelperResult out = SimpleGetHelper(data_reads); + EXPECT_EQ(net::OK, out.rv); EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line); EXPECT_EQ("DATA", out.response_data); } @@ -358,6 +366,7 @@ TEST_F(HttpNetworkTransactionTest, StatusLinePartial) { MockRead(false, net::OK), }; SimpleGetHelperResult out = SimpleGetHelper(data_reads); + EXPECT_EQ(net::OK, out.rv); EXPECT_EQ("HTTP/0.9 200 OK", out.status_line); EXPECT_EQ("HTT", out.response_data); } @@ -372,6 +381,7 @@ TEST_F(HttpNetworkTransactionTest, StopsReading204) { MockRead(false, net::OK), }; SimpleGetHelperResult out = SimpleGetHelper(data_reads); + EXPECT_EQ(net::OK, out.rv); EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line); EXPECT_EQ("", out.response_data); } @@ -595,7 +605,7 @@ TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) { // Firefox 3.0.1: blank page // Opera 9.52: after five attempts, blank page // Us with WinHTTP: error page (net::ERR_INVALID_RESPONSE) -// Us: blank page +// Us: error page (net::EMPTY_RESPONSE) TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) { MockRead data_reads[] = { MockRead(false, net::OK), // EOF @@ -604,8 +614,7 @@ TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) { MockRead(false, net::OK), }; SimpleGetHelperResult out = SimpleGetHelper(data_reads); - EXPECT_EQ("HTTP/0.9 200 OK", out.status_line); - EXPECT_EQ("", out.response_data); + EXPECT_EQ(out.rv, net::ERR_EMPTY_RESPONSE); } // Test the request-challenge-retry sequence for basic auth. |