summaryrefslogtreecommitdiffstats
path: root/net/http
diff options
context:
space:
mode:
authorericroman@google.com <ericroman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-10-16 02:02:47 +0000
committerericroman@google.com <ericroman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-10-16 02:02:47 +0000
commitaecfbf25fe132328429d2ec8570d2327c060e042 (patch)
treeff3758b7473240809833d5f686911eb442d7a7fe /net/http
parentd5bd66aa1267692edbd6f911e20b42e12f69ed40 (diff)
downloadchromium_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.cc43
-rw-r--r--net/http/http_network_transaction.h4
-rw-r--r--net/http/http_network_transaction_unittest.cc19
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.