summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorcbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-22 21:21:44 +0000
committercbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-22 21:21:44 +0000
commitf0e2bf4f0e53ddada17ac8cd01f684f6934a65d3 (patch)
tree6c940de52ce6578ac04a7e02ba9f9804a49c3ff7 /net
parent47507874d8952be20eaaed5afe4b0792ed63844d (diff)
downloadchromium_src-f0e2bf4f0e53ddada17ac8cd01f684f6934a65d3.zip
chromium_src-f0e2bf4f0e53ddada17ac8cd01f684f6934a65d3.tar.gz
chromium_src-f0e2bf4f0e53ddada17ac8cd01f684f6934a65d3.tar.bz2
Revert 93704 - Remove Content-Length mismatch checks.
Although the transferred bytes are supposed to match the advertised Content-Length, in practice a small but non-trivial number of sites do not obey this behavior. BUG=52847 TEST=None Review URL: http://codereview.chromium.org/7482005 TBR=cbentzel@chromium.org Review URL: http://codereview.chromium.org/7461040 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@93710 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r--net/http/http_network_transaction_unittest.cc6
-rw-r--r--net/http/http_stream_parser.cc7
-rw-r--r--net/url_request/url_request_http_job.cc28
-rw-r--r--net/url_request/url_request_http_job.h7
-rw-r--r--net/url_request/url_request_unittest.cc5
5 files changed, 45 insertions, 8 deletions
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index 86c3c01..2e76b4b 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -6074,10 +6074,6 @@ TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
}
-// If a server advertises a large Content-Length, and then fails to send that
-// many bytes in the message body prior to closing the connection, still treat
-// the response as if it was OK. Although this is erroneous behavior, it is
-// common in the wild and matches behavior of the other major browsers.
TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
HttpRequestInfo request;
request.method = "GET";
@@ -6111,7 +6107,7 @@ TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
std::string response_data;
rv = ReadTransaction(trans.get(), &response_data);
- EXPECT_EQ(OK, rv);
+ EXPECT_EQ(ERR_CONNECTION_CLOSED, rv);
}
TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
diff --git a/net/http/http_stream_parser.cc b/net/http/http_stream_parser.cc
index 9560f7d..31ce76b 100644
--- a/net/http/http_stream_parser.cc
+++ b/net/http/http_stream_parser.cc
@@ -509,6 +509,13 @@ int HttpStreamParser::DoReadBody() {
}
int HttpStreamParser::DoReadBodyComplete(int result) {
+ // If we didn't get a content-length and aren't using a chunked encoding,
+ // the only way to signal the end of a stream is to close the connection,
+ // so we don't treat that as an error, though in some cases we may not
+ // have completely received the resource.
+ if (result == 0 && !IsResponseBodyComplete() && CanFindEndOfResponse())
+ result = ERR_CONNECTION_CLOSED;
+
// Filter incoming data if appropriate. FilterBuf may return an error.
if (result > 0 && chunked_decoder_.get()) {
result = chunked_decoder_->FilterBuf(user_read_buf_->data(), result);
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc
index fbb4a34..4007282 100644
--- a/net/url_request/url_request_http_job.cc
+++ b/net/url_request/url_request_http_job.cc
@@ -751,6 +751,9 @@ void URLRequestHttpJob::OnStartCompleted(int result) {
void URLRequestHttpJob::OnReadCompleted(int result) {
read_in_progress_ = false;
+ if (ShouldFixMismatchedContentLength(result))
+ result = 0;
+
if (result == 0) {
NotifyDone(URLRequestStatus());
} else if (result < 0) {
@@ -1110,6 +1113,28 @@ void URLRequestHttpJob::ContinueDespiteLastError() {
&URLRequestHttpJob::OnStartCompleted, rv));
}
+bool URLRequestHttpJob::ShouldFixMismatchedContentLength(int rv) const {
+ // Some servers send the body compressed, but specify the content length as
+ // the uncompressed size. Although this violates the HTTP spec we want to
+ // support it (as IE and FireFox do), but *only* for an exact match.
+ // See http://crbug.com/79694.
+ if (rv == net::ERR_CONNECTION_CLOSED) {
+ if (request_ && request_->response_headers()) {
+ int64 expected_length = request_->response_headers()->GetContentLength();
+ VLOG(1) << __FUNCTION__ << "() "
+ << "\"" << request_->url().spec() << "\""
+ << " content-length = " << expected_length
+ << " pre total = " << prefilter_bytes_read()
+ << " post total = " << postfilter_bytes_read();
+ if (postfilter_bytes_read() == expected_length) {
+ // Clear the error.
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
bool URLRequestHttpJob::ReadRawData(IOBuffer* buf, int buf_size,
int *bytes_read) {
DCHECK_NE(buf_size, 0);
@@ -1118,6 +1143,9 @@ bool URLRequestHttpJob::ReadRawData(IOBuffer* buf, int buf_size,
int rv = transaction_->Read(buf, buf_size, &read_callback_);
+ if (ShouldFixMismatchedContentLength(rv))
+ rv = 0;
+
if (rv >= 0) {
*bytes_read = rv;
if (!rv)
diff --git a/net/url_request/url_request_http_job.h b/net/url_request/url_request_http_job.h
index 5a6fd6b..c5b045d 100644
--- a/net/url_request/url_request_http_job.h
+++ b/net/url_request/url_request_http_job.h
@@ -161,6 +161,13 @@ class URLRequestHttpJob : public URLRequestJob {
void RecordPerfHistograms(CompletionCause reason);
void DoneWithRequest(CompletionCause reason);
+ // Some servers send the body compressed, but specify the content length as
+ // the uncompressed size. If this is the case, we return true in order
+ // to request to work around this non-adherence to the HTTP standard.
+ // |rv| is the standard return value of a read function indicating the number
+ // of bytes read or, if negative, an error code.
+ bool ShouldFixMismatchedContentLength(int rv) const;
+
base::Time request_creation_time_;
// Data used for statistics gathering. This data is only used for histograms
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc
index 0378b62..7fe23bf 100644
--- a/net/url_request/url_request_unittest.cc
+++ b/net/url_request/url_request_unittest.cc
@@ -463,11 +463,10 @@ TEST_F(URLRequestTestHTTP, GetZippedTest) {
const char test_parameters[] = "CULMS";
const int num_tests = arraysize(test_parameters)- 1; // Skip NULL.
// C & U should be OK.
- // L & M are larger than the data sent, but we still accept it since a number
- // of servers in the wild have invalid Content-Lengths.
+ // L & M are larger than the data sent, and show an error.
// S has too little data, but we seem to accept it.
const bool test_expect_success[num_tests] =
- { true, true, true, true, true };
+ { true, true, false, false, true };
for (int i = 0; i < num_tests ; i++) {
TestDelegate d;