Index: net/http/http_network_transaction_unittest.cc |
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc |
index 0f37ed291a2e39bd66f3e0bcdd6ba8eb8974840a..524a5643bfb2e4bb89c063da0cb5104231e2deed 100644 |
--- a/net/http/http_network_transaction_unittest.cc |
+++ b/net/http/http_network_transaction_unittest.cc |
@@ -404,6 +404,26 @@ INSTANTIATE_TEST_CASE_P( |
namespace { |
+class BeforeNetworkStartHandler { |
+ public: |
+ BeforeNetworkStartHandler(bool defer) |
mmenke
2014/01/07 15:26:23
explicit
jkarlin
2014/01/07 16:19:32
Done.
|
+ : defer_on_before_network_start_(defer), |
+ observed_before_network_start_(false) {} |
+ |
+ void OnBeforeNetworkStart(bool* defer) { |
+ *defer = defer_on_before_network_start_; |
+ observed_before_network_start_ = true; |
+ } |
+ |
+ bool observed_before_network_start() const { |
+ return observed_before_network_start_; |
+ } |
+ |
+ private: |
+ bool defer_on_before_network_start_; |
mmenke
2014/01/07 15:26:23
const?
jkarlin
2014/01/07 16:19:32
Done.
|
+ bool observed_before_network_start_; |
mmenke
2014/01/07 15:26:23
DISALLOW_COPY_AND_ASSIGN?
jkarlin
2014/01/07 16:19:32
Done.
|
+}; |
+ |
// Fill |str| with a long header list that consumes >= |size| bytes. |
void FillLargeHeadersString(std::string* str, int size) { |
const char* row = |
@@ -1343,6 +1363,100 @@ TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) { |
EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv); |
} |
+// Test that network access can be deferred and resumed. |
+TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) { |
+ HttpRequestInfo request; |
+ request.method = "GET"; |
+ request.url = GURL("http://www.google.com/"); |
+ request.load_flags = 0; |
+ |
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); |
+ scoped_ptr<HttpTransaction> trans( |
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); |
+ |
+ // Defer on OnBeforeNetworkStart. |
+ BeforeNetworkStartHandler net_start_handler(true); // defer |
+ trans->SetBeforeNetworkStartCallback( |
+ base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart, |
+ base::Unretained(&net_start_handler))); |
+ |
+ MockRead data_reads[] = {MockRead("HTTP/1.0 200 OK\r\n"), |
+ MockRead("Connection: keep-alive\r\n"), |
+ MockRead("Content-Length: 100\r\n\r\n"), |
+ MockRead("hello"), |
+ MockRead(SYNCHRONOUS, 0), }; |
+ StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); |
+ session_deps_.socket_factory->AddSocketDataProvider(&data); |
+ |
+ TestCompletionCallback callback; |
+ |
+ int rv = trans->Start(&request, callback.callback(), BoundNetLog()); |
+ EXPECT_EQ(ERR_IO_PENDING, rv); |
+ base::MessageLoop::current()->RunUntilIdle(); |
+ |
+ // Should have deferred for network start. |
+ EXPECT_TRUE(net_start_handler.observed_before_network_start()); |
+ EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState()); |
+ EXPECT_TRUE(trans->GetResponseInfo() == NULL); |
+ |
+ trans->ResumeNetworkStart(); |
+ rv = callback.WaitForResult(); |
+ EXPECT_EQ(OK, rv); |
+ EXPECT_TRUE(trans->GetResponseInfo() != NULL); |
+ |
+ scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100)); |
+ rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback()); |
+ if (rv == ERR_IO_PENDING) |
+ rv = callback.WaitForResult(); |
+ EXPECT_EQ(5, rv); |
+ rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback()); |
+ EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv); |
+ |
+ trans.reset(); |
+ base::MessageLoop::current()->RunUntilIdle(); |
+ EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); |
+} |
+ |
+// Test that network use can be deferred and canceled. |
+TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) { |
+ HttpRequestInfo request; |
+ request.method = "GET"; |
+ request.url = GURL("http://www.google.com/"); |
+ request.load_flags = 0; |
+ |
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); |
+ scoped_ptr<HttpTransaction> trans( |
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); |
+ |
+ // Defer on OnBeforeNetworkStart. |
+ BeforeNetworkStartHandler net_start_handler(true); // defer |
+ trans->SetBeforeNetworkStartCallback( |
+ base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart, |
+ base::Unretained(&net_start_handler))); |
+ |
+ MockRead data_reads[] = {MockRead("HTTP/1.0 200 OK\r\n"), |
+ MockRead("Connection: keep-alive\r\n"), |
+ MockRead("Content-Length: 100\r\n\r\n"), |
+ MockRead("hello"), |
+ MockRead(SYNCHRONOUS, 0), }; |
+ StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); |
+ session_deps_.socket_factory->AddSocketDataProvider(&data); |
+ |
+ TestCompletionCallback callback; |
+ |
+ int rv = trans->Start(&request, callback.callback(), BoundNetLog()); |
+ EXPECT_EQ(ERR_IO_PENDING, rv); |
+ base::MessageLoop::current()->RunUntilIdle(); |
+ |
+ // Should have deferred for network start. |
+ EXPECT_TRUE(net_start_handler.observed_before_network_start()); |
+ EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState()); |
+ EXPECT_TRUE(trans->GetResponseInfo() == NULL); |
+ |
+ trans.reset(); // Cancel the transaction here. |
+ base::MessageLoop::current()->RunUntilIdle(); |
mmenke
2014/01/07 15:26:23
Are these needed? TearDown() already does its fai
jkarlin
2014/01/07 16:19:32
Fair enough. Removed.
|
+} |
+ |
// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression |
// tests. There was a bug causing HttpNetworkTransaction to hang in the |
// destructor in such situations. |