diff options
author | eustas@chromium.org <eustas@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-24 15:18:19 +0000 |
---|---|---|
committer | eustas@chromium.org <eustas@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-24 15:18:19 +0000 |
commit | b8015c43fdc2ec814384955288c3771e10b54f17 (patch) | |
tree | f1a417a2940d40de9d5fff505b116006541b0741 /net | |
parent | 88a907c0bcc93efb850785941986eab829edc654 (diff) | |
download | chromium_src-b8015c43fdc2ec814384955288c3771e10b54f17.zip chromium_src-b8015c43fdc2ec814384955288c3771e10b54f17.tar.gz chromium_src-b8015c43fdc2ec814384955288c3771e10b54f17.tar.bz2 |
Implement GetTotalReceivedBytes for http transaction.
BUG=111052
Review URL: https://codereview.chromium.org/99723004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@242433 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/http/http_basic_stream.cc | 4 | ||||
-rw-r--r-- | net/http/http_cache_transaction.cc | 9 | ||||
-rw-r--r-- | net/http/http_cache_transaction.h | 3 | ||||
-rw-r--r-- | net/http/http_cache_unittest.cc | 112 | ||||
-rw-r--r-- | net/http/http_network_transaction.cc | 20 | ||||
-rw-r--r-- | net/http/http_network_transaction.h | 6 | ||||
-rw-r--r-- | net/http/http_network_transaction_unittest.cc | 52 | ||||
-rw-r--r-- | net/http/http_pipelined_connection_impl.cc | 5 | ||||
-rw-r--r-- | net/http/http_transaction.h | 3 | ||||
-rw-r--r-- | net/http/http_transaction_unittest.cc | 6 | ||||
-rw-r--r-- | net/http/http_transaction_unittest.h | 3 |
11 files changed, 212 insertions, 11 deletions
diff --git a/net/http/http_basic_stream.cc b/net/http/http_basic_stream.cc index 87f6469..ee1f46f 100644 --- a/net/http/http_basic_stream.cc +++ b/net/http/http_basic_stream.cc @@ -86,7 +86,9 @@ bool HttpBasicStream::IsConnectionReusable() const { } int64 HttpBasicStream::GetTotalReceivedBytes() const { - return parser()->received_bytes(); + if (parser()) + return parser()->received_bytes(); + return 0; } bool HttpBasicStream::GetLoadTimingInfo( diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc index 88fb53a..95fd4f1 100644 --- a/net/http/http_cache_transaction.cc +++ b/net/http/http_cache_transaction.cc @@ -214,6 +214,7 @@ HttpCache::Transaction::Transaction( weak_factory_.GetWeakPtr())), transaction_pattern_(PATTERN_UNDEFINED), transaction_delegate_(transaction_delegate), + total_received_bytes_(0), websocket_handshake_stream_base_create_helper_(NULL) { COMPILE_ASSERT(HttpCache::Transaction::kNumValidationHeaders == arraysize(kValidationHeaders), @@ -465,6 +466,13 @@ bool HttpCache::Transaction::GetFullRequestHeaders( return false; } +int64 HttpCache::Transaction::GetTotalReceivedBytes() const { + int64 total_received_bytes = total_received_bytes_; + if (network_trans_) + total_received_bytes += network_trans_->GetTotalReceivedBytes(); + return total_received_bytes; +} + void HttpCache::Transaction::DoneReading() { if (cache_.get() && entry_) { DCHECK_NE(mode_, UPDATE); @@ -2387,6 +2395,7 @@ void HttpCache::Transaction::ResetNetworkTransaction() { LoadTimingInfo load_timing; if (network_trans_->GetLoadTimingInfo(&load_timing)) old_network_trans_load_timing_.reset(new LoadTimingInfo(load_timing)); + total_received_bytes_ += network_trans_->GetTotalReceivedBytes(); network_trans_.reset(); } diff --git a/net/http/http_cache_transaction.h b/net/http/http_cache_transaction.h index 90c4db5..14c6ad6 100644 --- a/net/http/http_cache_transaction.h +++ b/net/http/http_cache_transaction.h @@ -123,6 +123,7 @@ class HttpCache::Transaction : public HttpTransaction { virtual void StopCaching() OVERRIDE; virtual bool GetFullRequestHeaders( HttpRequestHeaders* headers) const OVERRIDE; + virtual int64 GetTotalReceivedBytes() const OVERRIDE; virtual void DoneReading() OVERRIDE; virtual const HttpResponseInfo* GetResponseInfo() const OVERRIDE; virtual LoadState GetLoadState() const OVERRIDE; @@ -431,6 +432,8 @@ class HttpCache::Transaction : public HttpTransaction { HttpTransactionDelegate* transaction_delegate_; + int64 total_received_bytes_; + // Load timing information for the last network request, if any. Set in the // 304 and 206 response cases, as the network transaction may be destroyed // before the caller requests load timing information. diff --git a/net/http/http_cache_unittest.cc b/net/http/http_cache_unittest.cc index aa6056a..1c42ba2 100644 --- a/net/http/http_cache_unittest.cc +++ b/net/http/http_cache_unittest.cc @@ -182,7 +182,8 @@ void RunTransactionTestWithRequestAndDelegateAndGetTiming( int num_cache_delegate_actions, int num_network_delegate_actions, const net::BoundNetLog& net_log, - net::LoadTimingInfo* load_timing_info) { + net::LoadTimingInfo* load_timing_info, + int64* received_bytes) { net::TestCompletionCallback callback; // write to the cache @@ -223,6 +224,9 @@ void RunTransactionTestWithRequestAndDelegateAndGetTiming( } ReadAndVerifyTransaction(trans.get(), trans_info); + + if (received_bytes) + *received_bytes = trans->GetTotalReceivedBytes(); } void RunTransactionTestWithRequestAndDelegate( @@ -234,7 +238,7 @@ void RunTransactionTestWithRequestAndDelegate( int num_network_delegate_actions) { RunTransactionTestWithRequestAndDelegateAndGetTiming( cache, trans_info, request, response_info, num_cache_delegate_actions, - num_network_delegate_actions, net::BoundNetLog(), NULL); + num_network_delegate_actions, net::BoundNetLog(), NULL, NULL); } void RunTransactionTestWithRequest(net::HttpCache* cache, @@ -254,7 +258,7 @@ void RunTransactionTestAndGetTiming( RunTransactionTestWithRequestAndDelegateAndGetTiming( cache, trans_info, MockHttpRequest(trans_info), NULL, kNoDelegateTransactionCheck, kNoDelegateTransactionCheck, log, - load_timing_info); + load_timing_info, NULL); } void RunTransactionTestWithDelegate(net::HttpCache* cache, @@ -268,7 +272,8 @@ void RunTransactionTestWithDelegate(net::HttpCache* cache, void RunTransactionTest(net::HttpCache* cache, const MockTransaction& trans_info) { - RunTransactionTestAndGetTiming(cache, trans_info, net::BoundNetLog(), NULL); + RunTransactionTestAndGetTiming( + cache, trans_info, net::BoundNetLog(), NULL); } void RunTransactionTestWithResponseInfo(net::HttpCache* cache, @@ -287,7 +292,7 @@ void RunTransactionTestWithResponseInfoAndGetTiming( RunTransactionTestWithRequestAndDelegateAndGetTiming( cache, trans_info, MockHttpRequest(trans_info), response, kNoDelegateTransactionCheck, kNoDelegateTransactionCheck, log, - load_timing_info); + load_timing_info, NULL); } void RunTransactionTestWithResponse(net::HttpCache* cache, @@ -308,7 +313,7 @@ void RunTransactionTestWithResponseAndGetTiming( RunTransactionTestWithRequestAndDelegateAndGetTiming( cache, trans_info, MockHttpRequest(trans_info), &response, kNoDelegateTransactionCheck, kNoDelegateTransactionCheck, - log, load_timing_info); + log, load_timing_info, NULL); response.headers->GetNormalizedHeaders(response_headers); } @@ -6390,3 +6395,98 @@ TEST(HttpCache, SetPriorityNewTransaction) { RemoveMockTransaction(&kRangeGET_TransactionOK); } + +int64 RunTransactionAndGetReceivedBytes( + MockHttpCache& cache, + const MockTransaction& trans_info) { + int64 received_bytes = -1; + RunTransactionTestWithRequestAndDelegateAndGetTiming( + cache.http_cache(), trans_info, MockHttpRequest(trans_info), NULL, + kNoDelegateTransactionCheck, kNoDelegateTransactionCheck, + net::BoundNetLog(), NULL, &received_bytes); + return received_bytes; +} + +int64 TransactionSize(MockTransaction& transaction) { + return strlen(transaction.status) + strlen(transaction.response_headers) + + strlen(transaction.data); +} + +TEST(HttpCache, ReceivedBytesCacheMissAndThenHit) { + MockHttpCache cache; + + MockTransaction transaction(kSimpleGET_Transaction); + int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction); + EXPECT_EQ(TransactionSize(transaction), received_bytes); + + received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction); + EXPECT_EQ(0, received_bytes); +} + +TEST(HttpCache, ReceivedBytesConditionalRequest304) { + MockHttpCache cache; + + ScopedMockTransaction transaction(kETagGET_Transaction); + int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction); + EXPECT_EQ(TransactionSize(transaction), received_bytes); + + transaction.load_flags = net::LOAD_VALIDATE_CACHE; + transaction.handler = ETagGet_ConditionalRequest_Handler; + received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction); + EXPECT_EQ(TransactionSize(transaction), received_bytes); +} + +TEST(HttpCache, ReceivedBytesConditionalRequest200) { + MockHttpCache cache; + + MockTransaction transaction(kTypicalGET_Transaction); + transaction.request_headers = "Foo: bar\r\n"; + transaction.response_headers = + "Date: Wed, 28 Nov 2007 09:40:09 GMT\n" + "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n" + "Etag: \"foopy\"\n" + "Cache-Control: max-age=0\n" + "Vary: Foo\n"; + AddMockTransaction(&transaction); + int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction); + EXPECT_EQ(TransactionSize(transaction), received_bytes); + + RevalidationServer server; + transaction.handler = server.Handler; + transaction.request_headers = "Foo: none\r\n"; + received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction); + EXPECT_EQ(TransactionSize(transaction), received_bytes); + + RemoveMockTransaction(&transaction); +} + +TEST(HttpCache, ReceivedBytesRange) { + MockHttpCache cache; + AddMockTransaction(&kRangeGET_TransactionOK); + MockTransaction transaction(kRangeGET_TransactionOK); + + // Read bytes 40-49 from the network. + int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction); + int64 range_response_size = TransactionSize(transaction); + EXPECT_EQ(range_response_size, received_bytes); + + // Read bytes 40-49 from the cache. + received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction); + EXPECT_EQ(0, received_bytes); + base::MessageLoop::current()->RunUntilIdle(); + + // Read bytes 30-39 from the network. + transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER; + transaction.data = "rg: 30-39 "; + received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction); + EXPECT_EQ(range_response_size, received_bytes); + base::MessageLoop::current()->RunUntilIdle(); + + // Read bytes 20-29 and 50-59 from the network, bytes 30-49 from the cache. + transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER; + transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 "; + received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction); + EXPECT_EQ(range_response_size * 2, received_bytes); + + RemoveMockTransaction(&kRangeGET_TransactionOK); +} diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index d956fb3..322e2e1 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc @@ -135,6 +135,7 @@ HttpNetworkTransaction::HttpNetworkTransaction(RequestPriority priority, fallback_error_code_(ERR_SSL_INAPPROPRIATE_FALLBACK), request_headers_(), read_buf_len_(0), + total_received_bytes_(0), next_state_(STATE_NONE), establishing_tunnel_(false), websocket_handshake_stream_base_create_helper_(NULL) { @@ -306,6 +307,7 @@ void HttpNetworkTransaction::DidDrainBodyForAuthRestart(bool keep_alive) { DCHECK(!stream_request_.get()); if (stream_.get()) { + total_received_bytes_ += stream_->GetTotalReceivedBytes(); HttpStream* new_stream = NULL; if (keep_alive && stream_->IsConnectionReusable()) { // We should call connection_->set_idle_time(), but this doesn't occur @@ -322,6 +324,8 @@ void HttpNetworkTransaction::DidDrainBodyForAuthRestart(bool keep_alive) { stream_->Close(true); next_state_ = STATE_CREATE_STREAM; } else { + // Renewed streams shouldn't carry over received bytes. + DCHECK_EQ(0, new_stream->GetTotalReceivedBytes()); next_state_ = STATE_INIT_STREAM; } stream_.reset(new_stream); @@ -382,6 +386,13 @@ bool HttpNetworkTransaction::GetFullRequestHeaders( return true; } +int64 HttpNetworkTransaction::GetTotalReceivedBytes() const { + int64 total_received_bytes = total_received_bytes_; + if (stream_) + total_received_bytes += stream_->GetTotalReceivedBytes(); + return total_received_bytes; +} + const HttpResponseInfo* HttpNetworkTransaction::GetResponseInfo() const { return ((headers_valid_ && response_.headers.get()) || response_.ssl_info.cert.get() || response_.cert_request_info.get()) @@ -448,6 +459,8 @@ void HttpNetworkTransaction::OnStreamReady(const SSLConfig& used_ssl_config, DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); DCHECK(stream_request_.get()); + if (stream_) + total_received_bytes_ += stream_->GetTotalReceivedBytes(); stream_.reset(stream); server_ssl_config_ = used_ssl_config; proxy_info_ = used_proxy_info; @@ -541,6 +554,8 @@ void HttpNetworkTransaction::OnHttpsProxyTunnelResponse( response_ = response_info; server_ssl_config_ = used_ssl_config; proxy_info_ = used_proxy_info; + if (stream_) + total_received_bytes_ += stream_->GetTotalReceivedBytes(); stream_.reset(stream); stream_request_.reset(); // we're done with the stream request OnIOComplete(ERR_HTTPS_PROXY_TUNNEL_RESPONSE); @@ -730,6 +745,8 @@ int HttpNetworkTransaction::DoInitStreamComplete(int result) { result = HandleIOError(result); // The stream initialization failed, so this stream will never be useful. + if (stream_) + total_received_bytes_ += stream_->GetTotalReceivedBytes(); stream_.reset(); } @@ -1248,6 +1265,7 @@ int HttpNetworkTransaction::HandleCertificateRequest(int error) { // Since we already have a stream, we're being called as part of SSL // renegotiation. DCHECK(!stream_request_.get()); + total_received_bytes_ += stream_->GetTotalReceivedBytes(); stream_->Close(true); stream_.reset(); } @@ -1425,6 +1443,8 @@ int HttpNetworkTransaction::HandleIOError(int error) { void HttpNetworkTransaction::ResetStateForRestart() { ResetStateForAuthRestart(); + if (stream_) + total_received_bytes_ += stream_->GetTotalReceivedBytes(); stream_.reset(); } diff --git a/net/http/http_network_transaction.h b/net/http/http_network_transaction.h index 3ae1725..10436b6 100644 --- a/net/http/http_network_transaction.h +++ b/net/http/http_network_transaction.h @@ -62,6 +62,7 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction virtual void StopCaching() OVERRIDE {} virtual bool GetFullRequestHeaders( HttpRequestHeaders* headers) const OVERRIDE; + virtual int64 GetTotalReceivedBytes() const OVERRIDE; virtual void DoneReading() OVERRIDE {} virtual const HttpResponseInfo* GetResponseInfo() const OVERRIDE; virtual LoadState GetLoadState() const OVERRIDE; @@ -254,6 +255,8 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction // Debug helper. static std::string DescribeState(State state); + void SetStream(HttpStreamBase* stream); + scoped_refptr<HttpAuthController> auth_controllers_[HttpAuth::AUTH_NUM_TARGETS]; @@ -306,6 +309,9 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction scoped_refptr<IOBuffer> read_buf_; int read_buf_len_; + // Total number of bytes received on streams for this transaction. + int64 total_received_bytes_; + // The time the Start method was called. base::Time start_time_; diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index 6df20ac..a0d622a 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc @@ -244,6 +244,7 @@ class HttpNetworkTransactionTest int rv; std::string status_line; std::string response_data; + int64 totalReceivedBytes; LoadTimingInfo load_timing_info; }; @@ -356,6 +357,7 @@ class HttpNetworkTransactionTest EXPECT_EQ("['Host: www.google.com','Connection: keep-alive']", response_headers); + out.totalReceivedBytes = trans->GetTotalReceivedBytes(); return out; } @@ -366,6 +368,13 @@ class HttpNetworkTransactionTest return SimpleGetHelperForData(data, 1); } + int64 ReadsSize(MockRead data_reads[], size_t reads_count) { + int64 size = 0; + for (size_t i = 0; i < reads_count; ++i) + size += data_reads[i].data_len; + return size; + } + void ConnectStatusHelperWithExpectedStatus(const MockRead& status, int expected_status); @@ -584,6 +593,8 @@ TEST_P(HttpNetworkTransactionTest, SimpleGET) { EXPECT_EQ(OK, out.rv); EXPECT_EQ("HTTP/1.0 200 OK", out.status_line); EXPECT_EQ("hello world", out.response_data); + int64 reads_size = ReadsSize(data_reads, arraysize(data_reads)); + EXPECT_EQ(reads_size, out.totalReceivedBytes); } // Response with no status line. @@ -597,6 +608,8 @@ TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) { EXPECT_EQ(OK, out.rv); EXPECT_EQ("HTTP/0.9 200 OK", out.status_line); EXPECT_EQ("hello world", out.response_data); + int64 reads_size = ReadsSize(data_reads, arraysize(data_reads)); + EXPECT_EQ(reads_size, out.totalReceivedBytes); } // Allow up to 4 bytes of junk to precede status line. @@ -610,6 +623,8 @@ TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) { EXPECT_EQ(OK, out.rv); EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line); EXPECT_EQ("DATA", out.response_data); + int64 reads_size = ReadsSize(data_reads, arraysize(data_reads)); + EXPECT_EQ(reads_size, out.totalReceivedBytes); } // Allow up to 4 bytes of junk to precede status line. @@ -623,6 +638,8 @@ TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) { EXPECT_EQ(OK, out.rv); EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line); EXPECT_EQ("DATA", out.response_data); + int64 reads_size = ReadsSize(data_reads, arraysize(data_reads)); + EXPECT_EQ(reads_size, out.totalReceivedBytes); } // Beyond 4 bytes of slop and it should fail to find a status line. @@ -636,6 +653,8 @@ TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) { EXPECT_EQ(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); + int64 reads_size = ReadsSize(data_reads, arraysize(data_reads)); + EXPECT_EQ(reads_size, out.totalReceivedBytes); } // Same as StatusLineJunk4Bytes, except the read chunks are smaller. @@ -653,6 +672,8 @@ TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) { EXPECT_EQ(OK, out.rv); EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line); EXPECT_EQ("DATA", out.response_data); + int64 reads_size = ReadsSize(data_reads, arraysize(data_reads)); + EXPECT_EQ(reads_size, out.totalReceivedBytes); } // Close the connection before enough bytes to have a status line. @@ -666,15 +687,18 @@ TEST_P(HttpNetworkTransactionTest, StatusLinePartial) { EXPECT_EQ(OK, out.rv); EXPECT_EQ("HTTP/0.9 200 OK", out.status_line); EXPECT_EQ("HTT", out.response_data); + int64 reads_size = ReadsSize(data_reads, arraysize(data_reads)); + EXPECT_EQ(reads_size, out.totalReceivedBytes); } // 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_P(HttpNetworkTransactionTest, StopsReading204) { + char junk[] = "junk"; MockRead data_reads[] = { MockRead("HTTP/1.1 204 No Content\r\n\r\n"), - MockRead("junk"), // Should not be read!! + MockRead(junk), // Should not be read!! MockRead(SYNCHRONOUS, OK), }; SimpleGetHelperResult out = SimpleGetHelper(data_reads, @@ -682,18 +706,24 @@ TEST_P(HttpNetworkTransactionTest, StopsReading204) { EXPECT_EQ(OK, out.rv); EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line); EXPECT_EQ("", out.response_data); + int64 reads_size = ReadsSize(data_reads, arraysize(data_reads)); + int64 response_size = reads_size - strlen(junk); + EXPECT_EQ(response_size, out.totalReceivedBytes); } // A simple request using chunked encoding with some extra data after. // (Like might be seen in a pipelined response.) TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) { + std::string final_chunk = "0\r\n\r\n"; + std::string extra_data = "HTTP/1.1 200 OK\r\n"; + std::string last_read = final_chunk + extra_data; MockRead data_reads[] = { MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"), MockRead("5\r\nHello\r\n"), MockRead("1\r\n"), MockRead(" \r\n"), MockRead("5\r\nworld\r\n"), - MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"), + MockRead(last_read.data()), MockRead(SYNCHRONOUS, OK), }; SimpleGetHelperResult out = SimpleGetHelper(data_reads, @@ -701,6 +731,9 @@ TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) { EXPECT_EQ(OK, out.rv); EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); EXPECT_EQ("Hello world", out.response_data); + int64 reads_size = ReadsSize(data_reads, arraysize(data_reads)); + int64 response_size = reads_size - extra_data.size(); + EXPECT_EQ(response_size, out.totalReceivedBytes); } // Next tests deal with http://crbug.com/56344. @@ -1569,6 +1602,9 @@ TEST_P(HttpNetworkTransactionTest, BasicAuth) { EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1)); TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES); + int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1)); + EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes()); + const HttpResponseInfo* response = trans->GetResponseInfo(); ASSERT_TRUE(response != NULL); EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); @@ -1591,6 +1627,9 @@ TEST_P(HttpNetworkTransactionTest, BasicAuth) { load_timing_info2.connect_timing.connect_start); EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id); + int64 reads_size2 = ReadsSize(data_reads2, arraysize(data_reads2)); + EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes()); + response = trans->GetResponseInfo(); ASSERT_TRUE(response != NULL); EXPECT_TRUE(response->auth_challenge.get() == NULL); @@ -1633,6 +1672,9 @@ TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) { rv = callback.WaitForResult(); EXPECT_EQ(0, rv); + int64 reads_size = ReadsSize(data_reads, arraysize(data_reads)); + EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes()); + const HttpResponseInfo* response = trans->GetResponseInfo(); ASSERT_TRUE(response != NULL); EXPECT_TRUE(response->auth_challenge.get() == NULL); @@ -1730,6 +1772,12 @@ TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) { ASSERT_TRUE(response != NULL); EXPECT_TRUE(response->auth_challenge.get() == NULL); EXPECT_EQ(5, response->headers->GetContentLength()); + + std::string response_data; + rv = ReadTransaction(trans.get(), &response_data); + EXPECT_EQ(OK, rv); + int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1)); + EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes()); } // Test the request-challenge-retry sequence for basic auth, over a keep-alive diff --git a/net/http/http_pipelined_connection_impl.cc b/net/http/http_pipelined_connection_impl.cc index 284b254..2ee9c29 100644 --- a/net/http/http_pipelined_connection_impl.cc +++ b/net/http/http_pipelined_connection_impl.cc @@ -656,8 +656,9 @@ void HttpPipelinedConnectionImpl::SetConnectionReused(int pipeline_id) { int64 HttpPipelinedConnectionImpl::GetTotalReceivedBytes( int pipeline_id) const { CHECK(ContainsKey(stream_info_map_, pipeline_id)); - CHECK(stream_info_map_.find(pipeline_id)->second.parser.get()); - return stream_info_map_.find(pipeline_id)->second.parser->received_bytes(); + if (stream_info_map_.find(pipeline_id)->second.parser.get()) + return stream_info_map_.find(pipeline_id)->second.parser->received_bytes(); + return 0; } bool HttpPipelinedConnectionImpl::GetLoadTimingInfo( diff --git a/net/http/http_transaction.h b/net/http/http_transaction.h index 849d03a..3776998 100644 --- a/net/http/http_transaction.h +++ b/net/http/http_transaction.h @@ -106,6 +106,9 @@ class NET_EXPORT_PRIVATE HttpTransaction { // otherwise, returns false and does not modify headers. virtual bool GetFullRequestHeaders(HttpRequestHeaders* headers) const = 0; + // Get the number of bytes received from network. + virtual int64 GetTotalReceivedBytes() const = 0; + // Called to tell the transaction that we have successfully reached the end // of the stream. This is equivalent to performing an extra Read() at the end // that should return 0 bytes. This method should not be called if the diff --git a/net/http/http_transaction_unittest.cc b/net/http/http_transaction_unittest.cc index e161eca..ef2923f 100644 --- a/net/http/http_transaction_unittest.cc +++ b/net/http/http_transaction_unittest.cc @@ -230,6 +230,7 @@ MockNetworkTransaction::MockNetworkTransaction( priority_(priority), websocket_handshake_stream_create_helper_(NULL), transaction_factory_(factory->AsWeakPtr()), + received_bytes_(0), socket_log_id_(net::NetLog::Source::kInvalidId) { } @@ -255,6 +256,7 @@ int MockNetworkTransaction::Start(const net::HttpRequestInfo* request, std::string resp_status = t->status; std::string resp_headers = t->response_headers; std::string resp_data = t->data; + received_bytes_ = resp_status.size() + resp_headers.size() + resp_data.size(); if (t->handler) (t->handler)(request, &resp_status, &resp_headers, &resp_data); @@ -331,6 +333,10 @@ bool MockNetworkTransaction::GetFullRequestHeaders( return false; } +int64 MockNetworkTransaction::GetTotalReceivedBytes() const { + return received_bytes_; +} + void MockNetworkTransaction::DoneReading() { if (transaction_factory_.get()) transaction_factory_->TransactionDoneReading(); diff --git a/net/http/http_transaction_unittest.h b/net/http/http_transaction_unittest.h index 3d6bb02..a91ebbd 100644 --- a/net/http/http_transaction_unittest.h +++ b/net/http/http_transaction_unittest.h @@ -193,6 +193,8 @@ class MockNetworkTransaction virtual bool GetFullRequestHeaders( net::HttpRequestHeaders* headers) const OVERRIDE; + virtual int64 GetTotalReceivedBytes() const OVERRIDE; + virtual void DoneReading() OVERRIDE; virtual const net::HttpResponseInfo* GetResponseInfo() const OVERRIDE; @@ -226,6 +228,7 @@ class MockNetworkTransaction net::RequestPriority priority_; CreateHelper* websocket_handshake_stream_create_helper_; base::WeakPtr<MockNetworkLayer> transaction_factory_; + int64 received_bytes_; // NetLog ID of the fake / non-existent underlying socket used by the // connection. Requires Start() be passed a BoundNetLog with a real NetLog to |