diff options
author | cbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-22 21:21:44 +0000 |
---|---|---|
committer | cbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-22 21:21:44 +0000 |
commit | f0e2bf4f0e53ddada17ac8cd01f684f6934a65d3 (patch) | |
tree | 6c940de52ce6578ac04a7e02ba9f9804a49c3ff7 /net | |
parent | 47507874d8952be20eaaed5afe4b0792ed63844d (diff) | |
download | chromium_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.cc | 6 | ||||
-rw-r--r-- | net/http/http_stream_parser.cc | 7 | ||||
-rw-r--r-- | net/url_request/url_request_http_job.cc | 28 | ||||
-rw-r--r-- | net/url_request/url_request_http_job.h | 7 | ||||
-rw-r--r-- | net/url_request/url_request_unittest.cc | 5 |
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; |