diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/base/net_error_list.h | 3 | ||||
-rw-r--r-- | net/http/http_network_transaction.cc | 55 | ||||
-rw-r--r-- | net/http/http_network_transaction_unittest.cc | 209 | ||||
-rw-r--r-- | net/http/http_response_body_drainer.cc | 119 | ||||
-rw-r--r-- | net/http/http_response_body_drainer.h | 66 | ||||
-rw-r--r-- | net/http/http_response_body_drainer_unittest.cc | 208 | ||||
-rw-r--r-- | net/http/http_util.cc | 10 | ||||
-rw-r--r-- | net/http/http_util.h | 7 | ||||
-rw-r--r-- | net/net.gyp | 3 | ||||
-rw-r--r-- | net/spdy/spdy_network_transaction_unittest.cc | 5 |
10 files changed, 103 insertions, 582 deletions
diff --git a/net/base/net_error_list.h b/net/base/net_error_list.h index abf18d1..7f2a6c2 100644 --- a/net/base/net_error_list.h +++ b/net/base/net_error_list.h @@ -379,9 +379,6 @@ NET_ERROR(MISCONFIGURED_AUTH_ENVIRONMENT, -343) // An undocumented SSPI or GSSAPI status code was returned. NET_ERROR(UNDOCUMENTED_SECURITY_LIBRARY_STATUS, -344) -// The HTTP response was too big to drain. -NET_ERROR(RESPONSE_BODY_TOO_BIG_TO_DRAIN, -345) - // The cache does not have the requested entry. NET_ERROR(CACHE_MISS, -400) diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index e6084bc..e04ed1d 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc @@ -166,40 +166,6 @@ HttpNetworkTransaction::HttpNetworkTransaction(HttpNetworkSession* session) } -HttpNetworkTransaction::~HttpNetworkTransaction() { - if (stream_.get()) { - HttpResponseHeaders* headers = GetResponseHeaders(); - // TODO(mbelshe): The stream_ should be able to compute whether or not the - // stream should be kept alive. No reason to compute here - // and pass it in. - bool try_to_keep_alive = - next_state_ == STATE_NONE && - stream_->CanFindEndOfResponse() && - (!headers || headers->IsKeepAlive()); - if (!try_to_keep_alive) { - stream_->Close(true /* not reusable */); - } else { - if (stream_->IsResponseBodyComplete()) { - // If the response body is complete, we can just reuse the socket. - stream_->Close(false /* reusable */); - } else { - // Otherwise, we try to drain the response body. - // TODO(willchan): Consider moving this response body draining to the - // stream implementation. For SPDY, there's clearly no point. For - // HTTP, it can vary depending on whether or not we're pipelining. It's - // stream dependent, so the different subtypes should be implementing - // their solutions. - HttpUtil::DrainStreamBodyAndClose(stream_.release()); - } - } - } - - if (stream_request_.get()) { - stream_request_->Cancel(); - stream_request_ = NULL; - } -} - int HttpNetworkTransaction::Start(const HttpRequestInfo* request_info, CompletionCallback* callback, const BoundNetLog& net_log) { @@ -474,12 +440,31 @@ void HttpNetworkTransaction::OnNeedsClientAuth( OnIOComplete(ERR_SSL_CLIENT_AUTH_CERT_NEEDED); } +HttpNetworkTransaction::~HttpNetworkTransaction() { + if (stream_.get()) { + HttpResponseHeaders* headers = GetResponseHeaders(); + // TODO(mbelshe): The stream_ should be able to compute whether or not the + // stream should be kept alive. No reason to compute here + // and pass it in. + bool keep_alive = next_state_ == STATE_NONE && + stream_->IsResponseBodyComplete() && + stream_->CanFindEndOfResponse() && + (!headers || headers->IsKeepAlive()); + stream_->Close(!keep_alive); + } + + if (stream_request_.get()) { + stream_request_->Cancel(); + stream_request_ = NULL; + } +} + bool HttpNetworkTransaction::is_https_request() const { return request_->url.SchemeIs("https"); } void HttpNetworkTransaction::DoCallback(int rv) { - DCHECK_NE(rv, ERR_IO_PENDING); + DCHECK(rv != ERR_IO_PENDING); DCHECK(user_callback_); // Since Run may result in Read being called, clear user_callback_ up front. diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index a8d9ea5..d2a35bc 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc @@ -154,20 +154,14 @@ HttpNetworkSession* CreateSession(SessionDependencies* session_deps) { class HttpNetworkTransactionTest : public PlatformTest { public: virtual void SetUp() { - NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); - MessageLoop::current()->RunAllPending(); spdy::SpdyFramer::set_enable_compression_default(false); } virtual void TearDown() { - NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); - MessageLoop::current()->RunAllPending(); spdy::SpdyFramer::set_enable_compression_default(true); // Empty the current queue. MessageLoop::current()->RunAllPending(); PlatformTest::TearDown(); - NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); - MessageLoop::current()->RunAllPending(); } protected: @@ -566,7 +560,7 @@ TEST_F(HttpNetworkTransactionTest, ReuseConnection) { StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); session_deps.socket_factory.AddSocketDataProvider(&data); - const char* const kExpectedResponseData[] = { + const char* kExpectedResponseData[] = { "hello", "world" }; @@ -856,9 +850,8 @@ TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) { EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv); } -// Test that we correctly reuse a keep-alive connection after not explicitly -// reading the body. -TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) { +// Test that we correctly reuse a keep-alive connection after receiving a 304. +TEST_F(HttpNetworkTransactionTest, KeepAliveAfter304) { SessionDependencies session_deps; scoped_refptr<HttpNetworkSession> session = CreateSession(&session_deps); @@ -867,23 +860,8 @@ TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) { request.url = GURL("http://www.foo.com/"); request.load_flags = 0; - // Note that because all these reads happen in the same - // StaticSocketDataProvider, it shows that the same socket is being reused for - // all transactions. MockRead data1_reads[] = { - MockRead("HTTP/1.1 204 No Content\r\n\r\n"), - MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"), MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"), - MockRead("HTTP/1.1 302 Found\r\n" - "Content-Length: 0\r\n\r\n"), - MockRead("HTTP/1.1 302 Found\r\n" - "Content-Length: 5\r\n\r\n" - "hello"), - MockRead("HTTP/1.1 301 Moved Permanently\r\n" - "Content-Length: 0\r\n\r\n"), - MockRead("HTTP/1.1 301 Moved Permanently\r\n" - "Content-Length: 5\r\n\r\n" - "hello"), MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), MockRead("hello"), }; @@ -896,10 +874,7 @@ TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) { StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0); session_deps.socket_factory.AddSocketDataProvider(&data2); - const int kNumUnreadBodies = arraysize(data1_reads) - 2; - std::string response_lines[kNumUnreadBodies]; - - for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) { + for (int i = 0; i < 2; ++i) { TestCompletionCallback callback; scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); @@ -911,44 +886,22 @@ TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) { EXPECT_EQ(OK, rv); const HttpResponseInfo* response = trans->GetResponseInfo(); - ASSERT_TRUE(response != NULL); - - ASSERT_TRUE(response->headers != NULL); - response_lines[i] = response->headers->GetStatusLine(); + EXPECT_TRUE(response != NULL); - // We intentionally don't read the response bodies. + EXPECT_TRUE(response->headers != NULL); + if (i == 0) { + EXPECT_EQ("HTTP/1.1 304 Not Modified", + response->headers->GetStatusLine()); + // We intentionally don't read the response in this case, to reflect how + // HttpCache::Transaction uses HttpNetworkTransaction. + } else { + EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); + std::string response_data; + rv = ReadTransaction(trans.get(), &response_data); + EXPECT_EQ(OK, rv); + EXPECT_EQ("hello", response_data); + } } - - const char* const kStatusLines[] = { - "HTTP/1.1 204 No Content", - "HTTP/1.1 205 Reset Content", - "HTTP/1.1 304 Not Modified", - "HTTP/1.1 302 Found", - "HTTP/1.1 302 Found", - "HTTP/1.1 301 Moved Permanently", - "HTTP/1.1 301 Moved Permanently", - }; - - COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines), - forgot_to_update_kStatusLines); - - for (int i = 0; i < kNumUnreadBodies; ++i) - EXPECT_EQ(kStatusLines[i], response_lines[i]); - - TestCompletionCallback callback; - scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); - int rv = trans->Start(&request, &callback, BoundNetLog()); - EXPECT_EQ(ERR_IO_PENDING, rv); - rv = callback.WaitForResult(); - EXPECT_EQ(OK, rv); - const HttpResponseInfo* response = trans->GetResponseInfo(); - ASSERT_TRUE(response != NULL); - ASSERT_TRUE(response->headers != NULL); - EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); - std::string response_data; - rv = ReadTransaction(trans.get(), &response_data); - EXPECT_EQ(OK, rv); - EXPECT_EQ("hello", response_data); } // Test the request-challenge-retry sequence for basic auth. @@ -1083,7 +1036,8 @@ TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) { // connection. TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) { SessionDependencies session_deps; - scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); + scoped_ptr<HttpTransaction> trans( + new HttpNetworkTransaction(CreateSession(&session_deps))); HttpRequestInfo request; request.method = "GET"; @@ -1113,8 +1067,8 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) { // Lastly, the server responds with the actual content. MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), - MockRead("Content-Length: 5\r\n\r\n"), - MockRead("Hello"), + MockRead("Content-Length: 100\r\n\r\n"), + MockRead(false, OK), }; StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), @@ -1123,7 +1077,6 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) { TestCompletionCallback callback1; - scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); int rv = trans->Start(&request, &callback1, BoundNetLog()); EXPECT_EQ(ERR_IO_PENDING, rv); @@ -1151,14 +1104,15 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) { response = trans->GetResponseInfo(); EXPECT_FALSE(response == NULL); EXPECT_TRUE(response->auth_challenge.get() == NULL); - EXPECT_EQ(5, response->headers->GetContentLength()); + EXPECT_EQ(100, response->headers->GetContentLength()); } // Test the request-challenge-retry sequence for basic auth, over a keep-alive // connection and with no response body to drain. TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) { SessionDependencies session_deps; - scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); + scoped_ptr<HttpTransaction> trans( + new HttpNetworkTransaction(CreateSession(&session_deps))); HttpRequestInfo request; request.method = "GET"; @@ -1186,8 +1140,8 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) { // Lastly, the server responds with the actual content. MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), - MockRead("Content-Length: 5\r\n\r\n"), - MockRead("hello"), + MockRead("Content-Length: 100\r\n\r\n"), + MockRead(false, OK), }; StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), @@ -1196,7 +1150,6 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) { TestCompletionCallback callback1; - scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); int rv = trans->Start(&request, &callback1, BoundNetLog()); EXPECT_EQ(ERR_IO_PENDING, rv); @@ -1224,14 +1177,15 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) { response = trans->GetResponseInfo(); EXPECT_FALSE(response == NULL); EXPECT_TRUE(response->auth_challenge.get() == NULL); - EXPECT_EQ(5, response->headers->GetContentLength()); + EXPECT_EQ(100, response->headers->GetContentLength()); } // Test the request-challenge-retry sequence for basic auth, over a keep-alive // connection and with a large response body to drain. TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) { SessionDependencies session_deps; - scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); + scoped_ptr<HttpTransaction> trans( + new HttpNetworkTransaction(CreateSession(&session_deps))); HttpRequestInfo request; request.method = "GET"; @@ -1267,8 +1221,8 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) { // Lastly, the server responds with the actual content. MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), - MockRead("Content-Length: 5\r\n\r\n"), - MockRead("hello"), + MockRead("Content-Length: 100\r\n\r\n"), + MockRead(false, OK), }; StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), @@ -1277,7 +1231,6 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) { TestCompletionCallback callback1; - scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); int rv = trans->Start(&request, &callback1, BoundNetLog()); EXPECT_EQ(ERR_IO_PENDING, rv); @@ -1305,14 +1258,15 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) { response = trans->GetResponseInfo(); EXPECT_FALSE(response == NULL); EXPECT_TRUE(response->auth_challenge.get() == NULL); - EXPECT_EQ(5, response->headers->GetContentLength()); + EXPECT_EQ(100, response->headers->GetContentLength()); } // Test the request-challenge-retry sequence for basic auth, over a keep-alive // connection, but the server gets impatient and closes the connection. TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) { SessionDependencies session_deps; - scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); + scoped_ptr<HttpTransaction> trans( + new HttpNetworkTransaction(CreateSession(&session_deps))); HttpRequestInfo request; request.method = "GET"; @@ -1355,8 +1309,8 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) { MockRead data_reads2[] = { MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), - MockRead("Content-Length: 5\r\n\r\n"), - MockRead("hello"), + MockRead("Content-Length: 100\r\n\r\n"), + MockRead(false, OK), }; StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), @@ -1368,7 +1322,6 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) { TestCompletionCallback callback1; - scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); int rv = trans->Start(&request, &callback1, BoundNetLog()); EXPECT_EQ(ERR_IO_PENDING, rv); @@ -1396,7 +1349,7 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) { response = trans->GetResponseInfo(); ASSERT_FALSE(response == NULL); EXPECT_TRUE(response->auth_challenge.get() == NULL); - EXPECT_EQ(5, response->headers->GetContentLength()); + EXPECT_EQ(100, response->headers->GetContentLength()); } // Test the request-challenge-retry sequence for basic auth, over a connection @@ -1408,6 +1361,8 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) { session_deps.net_log = log.bound().net_log(); scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); + scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); + HttpRequestInfo request; request.method = "GET"; request.url = GURL("https://www.google.com/"); @@ -1444,8 +1399,8 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) { MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), - MockRead("Content-Length: 5\r\n\r\n"), - MockRead(false, "hello"), + MockRead("Content-Length: 100\r\n\r\n"), + MockRead(false, OK), }; StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), @@ -1456,8 +1411,6 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) { TestCompletionCallback callback1; - scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); - int rv = trans->Start(&request, &callback1, log.bound()); EXPECT_EQ(ERR_IO_PENDING, rv); @@ -1497,14 +1450,11 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) { EXPECT_TRUE(response->headers->IsKeepAlive()); EXPECT_EQ(200, response->headers->response_code()); - EXPECT_EQ(5, response->headers->GetContentLength()); + EXPECT_EQ(100, response->headers->GetContentLength()); EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); // The password prompt info should not be set. EXPECT_TRUE(response->auth_challenge.get() == NULL); - - trans.reset(); - session->FlushSocketPools(); } // Test the request-challenge-retry sequence for basic auth, over a keep-alive @@ -1726,6 +1676,8 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) { session_deps.net_log = log.bound().net_log(); scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); + scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); + HttpRequestInfo request; request.method = "GET"; request.url = GURL("http://www.google.com/"); @@ -1752,8 +1704,6 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) { TestCompletionCallback callback1; - scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); - int rv = trans->Start(&request, &callback1, log.bound()); EXPECT_EQ(ERR_IO_PENDING, rv); @@ -1780,6 +1730,8 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) { session_deps.net_log = log.bound().net_log(); scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); + scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); + HttpRequestInfo request; request.method = "GET"; request.url = GURL("http://www.google.com/"); @@ -1813,8 +1765,6 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) { TestCompletionCallback callback1; - scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); - int rv = trans->Start(&request, &callback1, log.bound()); EXPECT_EQ(ERR_IO_PENDING, rv); @@ -1839,6 +1789,8 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) { session_deps.net_log = log.bound().net_log(); scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); + scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); + HttpRequestInfo request; request.method = "GET"; request.url = GURL("http://www.google.com/"); @@ -1882,8 +1834,6 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) { TestCompletionCallback callback1; - scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); - int rv = trans->Start(&request, &callback1, log.bound()); EXPECT_EQ(ERR_IO_PENDING, rv); @@ -1930,6 +1880,8 @@ void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus( scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); + scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); + HttpRequestInfo request; request.method = "GET"; request.url = GURL("https://www.google.com/"); @@ -1955,8 +1907,6 @@ void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus( TestCompletionCallback callback; - scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); - int rv = trans->Start(&request, &callback, BoundNetLog()); EXPECT_EQ(ERR_IO_PENDING, rv); @@ -2277,7 +2227,8 @@ TEST_F(HttpNetworkTransactionTest, NTLMAuth1) { HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1, MockGetHostName); SessionDependencies session_deps; - scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); + scoped_ptr<HttpTransaction> trans( + new HttpNetworkTransaction(CreateSession(&session_deps))); HttpRequestInfo request; request.method = "GET"; @@ -2358,8 +2309,6 @@ TEST_F(HttpNetworkTransactionTest, NTLMAuth1) { TestCompletionCallback callback1; - scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); - int rv = trans->Start(&request, &callback1, BoundNetLog()); EXPECT_EQ(ERR_IO_PENDING, rv); @@ -2405,7 +2354,8 @@ TEST_F(HttpNetworkTransactionTest, NTLMAuth2) { HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2, MockGetHostName); SessionDependencies session_deps; - scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); + scoped_ptr<HttpTransaction> trans( + new HttpNetworkTransaction(CreateSession(&session_deps))); HttpRequestInfo request; request.method = "GET"; @@ -2537,8 +2487,6 @@ TEST_F(HttpNetworkTransactionTest, NTLMAuth2) { TestCompletionCallback callback1; - scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); - int rv = trans->Start(&request, &callback1, BoundNetLog()); EXPECT_EQ(ERR_IO_PENDING, rv); @@ -5186,7 +5134,8 @@ TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) { // restart does the right thing. TEST_F(HttpNetworkTransactionTest, DrainResetOK) { SessionDependencies session_deps; - scoped_refptr<HttpNetworkSession> session = CreateSession(&session_deps); + scoped_ptr<HttpTransaction> trans( + new HttpNetworkTransaction(CreateSession(&session_deps))); HttpRequestInfo request; request.method = "GET"; @@ -5235,8 +5184,6 @@ TEST_F(HttpNetworkTransactionTest, DrainResetOK) { TestCompletionCallback callback1; - scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); - int rv = trans->Start(&request, &callback1, BoundNetLog()); EXPECT_EQ(ERR_IO_PENDING, rv); @@ -5541,6 +5488,8 @@ TEST_F(HttpNetworkTransactionTest, UnreadableUploadFileAfterAuthRestart) { // Tests that changes to Auth realms are treated like auth rejections. TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) { SessionDependencies session_deps; + scoped_ptr<HttpTransaction> trans( + new HttpNetworkTransaction(CreateSession(&session_deps))); HttpRequestInfo request; request.method = "GET"; @@ -5603,9 +5552,8 @@ TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) { MockRead data_reads4[] = { MockRead("HTTP/1.1 200 OK\r\n" "Content-Type: text/html; charset=iso-8859-1\r\n" - "Content-Length: 5\r\n" - "\r\n" - "hello"), + "Content-Length: 100\r\n" + "\r\n"), }; StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), @@ -5623,9 +5571,6 @@ TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) { TestCompletionCallback callback1; - scoped_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(CreateSession(&session_deps))); - // Issue the first request with Authorize headers. There should be a // password prompt for first_realm waiting to be filled in after the // transaction completes. @@ -6250,9 +6195,9 @@ TEST_F(HttpNetworkTransactionTest, // specifies both the configuration for the test as well as the expectations // for the results. TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) { - static const char kServer[] = "http://www.example.com"; - static const char kSecureServer[] = "https://www.example.com"; - static const char kProxy[] = "myproxy:70"; + const char* kServer = "http://www.example.com"; + const char* kSecureServer = "https://www.example.com"; + const char* kProxy = "myproxy:70"; const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS; enum AuthTiming { @@ -6537,6 +6482,7 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) { }; SessionDependencies session_deps; + scoped_refptr<HttpNetworkSession> session = CreateSession(&session_deps); HttpAuthHandlerMock::Factory* auth_factory( new HttpAuthHandlerMock::Factory()); session_deps.http_auth_handler_factory.reset(auth_factory); @@ -6583,8 +6529,8 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) { request.url = GURL(test_config.server_url); request.load_flags = 0; - scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); - HttpNetworkTransaction trans(CreateSession(&session_deps)); + scoped_ptr<HttpTransaction> trans( + new HttpNetworkTransaction(CreateSession(&session_deps))); for (int round = 0; round < test_config.num_auth_rounds; ++round) { const TestRound& read_write_round = test_config.rounds[round]; @@ -6619,16 +6565,16 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) { TestCompletionCallback callback; int rv; if (round == 0) { - rv = trans.Start(&request, &callback, BoundNetLog()); + rv = trans->Start(&request, &callback, BoundNetLog()); } else { - rv = trans.RestartWithAuth(kFoo, kBar, &callback); + rv = trans->RestartWithAuth(kFoo, kBar, &callback); } if (rv == ERR_IO_PENDING) rv = callback.WaitForResult(); // Compare results with expected data. EXPECT_EQ(read_write_round.expected_rv, rv); - const HttpResponseInfo* response = trans.GetResponseInfo(); + const HttpResponseInfo* response = trans->GetResponseInfo(); if (read_write_round.expected_rv == OK) { EXPECT_FALSE(response == NULL); } else { @@ -6643,6 +6589,9 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) { } } } + + // Flush the idle socket before the HttpNetworkTransaction goes out of scope. + session->FlushSocketPools(); } TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) { @@ -7171,6 +7120,8 @@ TEST_F(HttpNetworkTransactionTest, ProxyGet) { session_deps.net_log = log.bound().net_log(); scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); + scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); + HttpRequestInfo request; request.method = "GET"; request.url = GURL("http://www.google.com/"); @@ -7194,8 +7145,6 @@ TEST_F(HttpNetworkTransactionTest, ProxyGet) { TestCompletionCallback callback1; - scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); - int rv = trans->Start(&request, &callback1, log.bound()); EXPECT_EQ(ERR_IO_PENDING, rv); @@ -7219,6 +7168,8 @@ TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) { session_deps.net_log = log.bound().net_log(); scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); + scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); + HttpRequestInfo request; request.method = "GET"; request.url = GURL("https://www.google.com/"); @@ -7251,8 +7202,6 @@ TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) { TestCompletionCallback callback1; - scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); - int rv = trans->Start(&request, &callback1, log.bound()); EXPECT_EQ(ERR_IO_PENDING, rv); @@ -7284,6 +7233,8 @@ TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) { session_deps.net_log = log.bound().net_log(); scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); + scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); + HttpRequestInfo request; request.method = "GET"; request.url = GURL("https://www.google.com/"); @@ -7313,8 +7264,6 @@ TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) { TestCompletionCallback callback1; - scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); - int rv = trans->Start(&request, &callback1, log.bound()); EXPECT_EQ(ERR_IO_PENDING, rv); diff --git a/net/http/http_response_body_drainer.cc b/net/http/http_response_body_drainer.cc deleted file mode 100644 index c857106..0000000 --- a/net/http/http_response_body_drainer.cc +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/http/http_response_body_drainer.h" - -#include "base/compiler_specific.h" -#include "base/logging.h" -#include "net/base/io_buffer.h" -#include "net/base/net_errors.h" -#include "net/http/http_stream.h" - -namespace net { - -HttpResponseBodyDrainer::HttpResponseBodyDrainer(HttpStream* stream) - : stream_(stream), - next_state_(STATE_NONE), - total_read_(0), - ALLOW_THIS_IN_INITIALIZER_LIST( - io_callback_(this, &HttpResponseBodyDrainer::OnIOComplete)), - user_callback_(NULL) {} - -HttpResponseBodyDrainer::~HttpResponseBodyDrainer() {} - -void HttpResponseBodyDrainer::Start() { - read_buf_ = new IOBuffer(kDrainBodyBufferSize); - next_state_ = STATE_DRAIN_RESPONSE_BODY; - int rv = DoLoop(OK); - - if (rv == ERR_IO_PENDING) { - timer_.Start(base::TimeDelta::FromSeconds(kTimeoutInSeconds), - this, - &HttpResponseBodyDrainer::OnTimerFired); - return; - } - - Finish(rv); -} - -int HttpResponseBodyDrainer::DoLoop(int result) { - DCHECK_NE(next_state_, STATE_NONE); - - int rv = result; - do { - State state = next_state_; - next_state_ = STATE_NONE; - switch (state) { - case STATE_DRAIN_RESPONSE_BODY: - DCHECK_EQ(OK, rv); - rv = DoDrainResponseBody(); - break; - case STATE_DRAIN_RESPONSE_BODY_COMPLETE: - rv = DoDrainResponseBodyComplete(rv); - break; - default: - NOTREACHED() << "bad state"; - rv = ERR_UNEXPECTED; - break; - } - } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); - - return rv; -} - -int HttpResponseBodyDrainer::DoDrainResponseBody() { - next_state_ = STATE_DRAIN_RESPONSE_BODY_COMPLETE; - - return stream_->ReadResponseBody( - read_buf_ + total_read_, kDrainBodyBufferSize - total_read_, - &io_callback_); -} - -int HttpResponseBodyDrainer::DoDrainResponseBodyComplete(int result) { - DCHECK_NE(ERR_IO_PENDING, result); - - if (result < 0) - return result; - - if (result == 0) - return ERR_CONNECTION_CLOSED; - - total_read_ += result; - if (stream_->IsResponseBodyComplete()) - return OK; - - DCHECK_LE(total_read_, kDrainBodyBufferSize); - if (total_read_ >= kDrainBodyBufferSize) - return ERR_RESPONSE_BODY_TOO_BIG_TO_DRAIN; - - next_state_ = STATE_DRAIN_RESPONSE_BODY; - return OK; -} - -void HttpResponseBodyDrainer::OnIOComplete(int result) { - int rv = DoLoop(result); - if (rv != ERR_IO_PENDING) { - timer_.Stop(); - Finish(rv); - } -} - -void HttpResponseBodyDrainer::OnTimerFired() { - Finish(ERR_TIMED_OUT); -} - -void HttpResponseBodyDrainer::Finish(int result) { - DCHECK_NE(ERR_IO_PENDING, result); - - if (result < 0) { - stream_->Close(true /* no keep-alive */); - } else { - DCHECK_EQ(OK, result); - stream_->Close(false /* keep-alive */); - } - - delete this; -} - -} // namespace net diff --git a/net/http/http_response_body_drainer.h b/net/http/http_response_body_drainer.h deleted file mode 100644 index dbcdd99..0000000 --- a/net/http/http_response_body_drainer.h +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_HTTP_HTTP_RESPONSE_BODY_DRAINER_H_ -#define NET_HTTP_HTTP_RESPONSE_BODY_DRAINER_H_ -#pragma once - -#include "base/basictypes.h" -#include "base/ref_counted.h" -#include "base/scoped_ptr.h" -#include "base/timer.h" -#include "net/base/completion_callback.h" - -namespace net { - -class HttpStream; -class IOBuffer; - -class HttpResponseBodyDrainer { - public: - // The size in bytes of the buffer we use to drain the response body that - // we want to throw away. The response body is typically a small page just a - // few hundred bytes long. We set a limit to prevent it from taking too long, - // since we may as well just create a new socket then. - enum { kDrainBodyBufferSize = 16384 }; - enum { kTimeoutInSeconds = 5 }; - - explicit HttpResponseBodyDrainer(HttpStream* stream); - - // Starts reading the body until completion, or we hit the buffer limit, or we - // timeout. After Start(), |this| will eventually delete itself. - void Start(); - - private: - enum State { - STATE_DRAIN_RESPONSE_BODY, - STATE_DRAIN_RESPONSE_BODY_COMPLETE, - STATE_NONE, - }; - - ~HttpResponseBodyDrainer(); - - int DoLoop(int result); - - int DoDrainResponseBody(); - int DoDrainResponseBodyComplete(int result); - - void OnIOComplete(int result); - void OnTimerFired(); - void Finish(int result); - - const scoped_ptr<HttpStream> stream_; - State next_state_; - scoped_refptr<IOBuffer> read_buf_; - int total_read_; - CompletionCallbackImpl<HttpResponseBodyDrainer> io_callback_; - CompletionCallback* user_callback_; - base::OneShotTimer<HttpResponseBodyDrainer> timer_; - - DISALLOW_COPY_AND_ASSIGN(HttpResponseBodyDrainer); -}; - -} // namespace net - -#endif // NET_HTTP_HTTP_RESPONSE_BODY_DRAINER_H_ diff --git a/net/http/http_response_body_drainer_unittest.cc b/net/http/http_response_body_drainer_unittest.cc deleted file mode 100644 index 41b4225..0000000 --- a/net/http/http_response_body_drainer_unittest.cc +++ /dev/null @@ -1,208 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/http/http_response_body_drainer.h" - -#include "base/compiler_specific.h" -#include "base/message_loop.h" -#include "base/task.h" -#include "net/base/net_errors.h" -#include "net/base/test_completion_callback.h" -#include "net/http/http_stream.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace net { - -namespace { - -const int kMagicChunkSize = 1024; -COMPILE_ASSERT( - (HttpResponseBodyDrainer::kDrainBodyBufferSize % kMagicChunkSize) == 0, - chunk_size_needs_to_divide_evenly_into_buffer_size); - -class CloseResultWaiter { - public: - CloseResultWaiter() - : result_(false), - have_result_(false), - waiting_for_result_(false) {} - - int WaitForResult() { - DCHECK(!waiting_for_result_); - while (!have_result_) { - waiting_for_result_ = true; - MessageLoop::current()->Run(); - waiting_for_result_ = false; - } - return result_; - } - - void set_result(bool result) { - result_ = result; - have_result_ = true; - if (waiting_for_result_) - MessageLoop::current()->Quit(); - } - - private: - int result_; - bool have_result_; - bool waiting_for_result_; - - DISALLOW_COPY_AND_ASSIGN(CloseResultWaiter); -}; - -class MockHttpStream : public HttpStream { - public: - MockHttpStream(CloseResultWaiter* result_waiter) - : result_waiter_(result_waiter), - user_callback_(NULL), - closed_(false), - stall_reads_forever_(false), - num_chunks_(0), - is_complete_(false), - ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {} - virtual ~MockHttpStream() {} - - // HttpStream implementation: - virtual int InitializeStream(const HttpRequestInfo* request_info, - const BoundNetLog& net_log, - CompletionCallback* callback) { - return ERR_UNEXPECTED; - } - virtual int SendRequest(const std::string& request_headers, - UploadDataStream* request_body, - HttpResponseInfo* response, - CompletionCallback* callback) { - return ERR_UNEXPECTED; - } - virtual uint64 GetUploadProgress() const { return 0; } - virtual int ReadResponseHeaders(CompletionCallback* callback) { - return ERR_UNEXPECTED; - } - virtual const HttpResponseInfo* GetResponseInfo() const { return NULL; } - - virtual bool CanFindEndOfResponse() const { return true; } - virtual bool IsMoreDataBuffered() const { return false; } - virtual bool IsConnectionReused() const { return false; } - virtual void SetConnectionReused() {} - virtual void GetSSLInfo(SSLInfo* ssl_info) {} - virtual void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) {} - - // Mocked API - virtual int ReadResponseBody(IOBuffer* buf, int buf_len, - CompletionCallback* callback); - virtual void Close(bool not_reusable) { - DCHECK(!closed_); - closed_ = true; - result_waiter_->set_result(not_reusable); - } - virtual bool IsResponseBodyComplete() const { return is_complete_; } - - // Methods to tweak/observer mock behavior: - void StallReadsForever() { stall_reads_forever_ = true; } - - void set_num_chunks(int num_chunks) { num_chunks_ = num_chunks; } - - private: - void CompleteRead(); - - bool closed() const { return closed_; } - - CloseResultWaiter* const result_waiter_; - CompletionCallback* user_callback_; - bool closed_; - bool stall_reads_forever_; - int num_chunks_; - bool is_complete_; - ScopedRunnableMethodFactory<MockHttpStream> method_factory_; -}; - -int MockHttpStream::ReadResponseBody( - IOBuffer* buf, int buf_len, CompletionCallback* callback) { - DCHECK(callback); - DCHECK(!user_callback_); - - if (stall_reads_forever_) - return ERR_IO_PENDING; - - if (num_chunks_ == 0) - return ERR_UNEXPECTED; - - if (buf_len > kMagicChunkSize && num_chunks_ > 1) { - user_callback_ = callback; - MessageLoop::current()->PostTask( - FROM_HERE, - method_factory_.NewRunnableMethod(&MockHttpStream::CompleteRead)); - return ERR_IO_PENDING; - } - - num_chunks_--; - if (!num_chunks_) - is_complete_ = true; - - return buf_len; -} - -void MockHttpStream::CompleteRead() { - CompletionCallback* callback = user_callback_; - user_callback_ = NULL; - num_chunks_--; - if (!num_chunks_) - is_complete_ = true; - callback->Run(kMagicChunkSize); -} - -class HttpResponseBodyDrainerTest : public testing::Test { - protected: - HttpResponseBodyDrainerTest() - : mock_stream_(new MockHttpStream(&result_waiter_)), - drainer_(new HttpResponseBodyDrainer(mock_stream_)) {} - ~HttpResponseBodyDrainerTest() {} - - CloseResultWaiter result_waiter_; - MockHttpStream* const mock_stream_; // Owned by |drainer_|. - HttpResponseBodyDrainer* const drainer_; // Deletes itself. -}; - -TEST_F(HttpResponseBodyDrainerTest, DrainBodySyncOK) { - mock_stream_->set_num_chunks(1); - drainer_->Start(); - EXPECT_FALSE(result_waiter_.WaitForResult()); -} - -TEST_F(HttpResponseBodyDrainerTest, DrainBodyAsyncOK) { - mock_stream_->set_num_chunks(3); - drainer_->Start(); - EXPECT_FALSE(result_waiter_.WaitForResult()); -} - -TEST_F(HttpResponseBodyDrainerTest, DrainBodySizeEqualsDrainBuffer) { - mock_stream_->set_num_chunks( - HttpResponseBodyDrainer::kDrainBodyBufferSize / kMagicChunkSize); - drainer_->Start(); - EXPECT_FALSE(result_waiter_.WaitForResult()); -} - -TEST_F(HttpResponseBodyDrainerTest, DrainBodyTimeOut) { - mock_stream_->set_num_chunks(2); - mock_stream_->StallReadsForever(); - drainer_->Start(); - EXPECT_TRUE(result_waiter_.WaitForResult()); -} - -TEST_F(HttpResponseBodyDrainerTest, DrainBodyTooLarge) { - TestCompletionCallback callback; - int too_many_chunks = - HttpResponseBodyDrainer::kDrainBodyBufferSize / kMagicChunkSize; - too_many_chunks += 1; // Now it's too large. - - mock_stream_->set_num_chunks(too_many_chunks); - drainer_->Start(); - EXPECT_TRUE(result_waiter_.WaitForResult()); -} - -} // namespace - -} // namespace net diff --git a/net/http/http_util.cc b/net/http/http_util.cc index 4b52cc3..83c17ab 100644 --- a/net/http/http_util.cc +++ b/net/http/http_util.cc @@ -9,15 +9,11 @@ #include <algorithm> -#include "base/basictypes.h" #include "base/logging.h" #include "base/string_number_conversions.h" #include "base/string_piece.h" #include "base/string_util.h" -#include "net/base/net_errors.h" #include "net/base/net_util.h" -#include "net/http/http_response_body_drainer.h" -#include "net/http/http_stream.h" using std::string; @@ -699,10 +695,4 @@ bool HttpUtil::ValuesIterator::GetNext() { return false; } -void HttpUtil::DrainStreamBodyAndClose(HttpStream* stream) { - HttpResponseBodyDrainer* drainer = new HttpResponseBodyDrainer(stream); - drainer->Start(); - // |drainer| will delete itself. -} - } // namespace net diff --git a/net/http/http_util.h b/net/http/http_util.h index 3179782..33da33d 100644 --- a/net/http/http_util.h +++ b/net/http/http_util.h @@ -10,7 +10,6 @@ #include "base/string_tokenizer.h" #include "googleurl/src/gurl.h" -#include "net/base/completion_callback.h" #include "net/http/http_byte_range.h" // This is a macro to support extending this string literal at compile time. @@ -19,8 +18,6 @@ namespace net { -class HttpStream; - class HttpUtil { public: // Returns the absolute path of the URL, to be used for the http request. @@ -250,10 +247,6 @@ class HttpUtil { std::string::const_iterator value_begin_; std::string::const_iterator value_end_; }; - - // Attempts to read all of the response body of |stream|. Closes |stream| and - // deletes it when complete. - static void DrainStreamBodyAndClose(HttpStream* stream); }; } // namespace net diff --git a/net/net.gyp b/net/net.gyp index 080b5b0..10a4d8d 100644 --- a/net/net.gyp +++ b/net/net.gyp @@ -429,8 +429,6 @@ 'http/http_request_headers.cc', 'http/http_request_headers.h', 'http/http_request_info.h', - 'http/http_response_body_drainer.cc', - 'http/http_response_body_drainer.h', 'http/http_response_headers.cc', 'http/http_response_headers.h', 'http/http_response_info.cc', @@ -808,7 +806,6 @@ 'http/http_network_transaction_unittest.cc', 'http/http_proxy_client_socket_pool_unittest.cc', 'http/http_request_headers_unittest.cc', - 'http/http_response_body_drainer_unittest.cc', 'http/http_response_headers_unittest.cc', 'http/http_transaction_unittest.cc', 'http/http_transaction_unittest.h', diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc index 927d2aa..6d5d644 100644 --- a/net/spdy/spdy_network_transaction_unittest.cc +++ b/net/spdy/spdy_network_transaction_unittest.cc @@ -2296,15 +2296,18 @@ TEST_P(SpdyNetworkTransactionTest, RedirectServerPush) { "301 Moved Permanently", "http://www.foo.com/index.php", "http://www.foo.com/index.php")); scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); + scoped_ptr<spdy::SpdyFrame> res( + ConstructSpdyRstStream(2, spdy::CANCEL)); MockWrite writes[] = { CreateMockWrite(*req, 1), + CreateMockWrite(*res, 6), }; MockRead reads[] = { CreateMockRead(*resp, 2), CreateMockRead(*rep, 3), CreateMockRead(*body, 4), MockRead(true, ERR_IO_PENDING, 5), // Force a pause - MockRead(true, 0, 0, 6) // EOF + MockRead(true, 0, 0, 7) // EOF }; // Setup writes/reads to www.foo.com |