| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <string> | 5 #include <string> |
| 6 | 6 |
| 7 #include "base/memory/ref_counted.h" | 7 #include "base/memory/ref_counted.h" |
| 8 #include "base/memory/scoped_vector.h" | 8 #include "base/memory/scoped_vector.h" |
| 9 #include "base/stringprintf.h" | 9 #include "base/stringprintf.h" |
| 10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 virtual void SetUp() OVERRIDE { | 44 virtual void SetUp() OVERRIDE { |
| 45 default_pipelining_enabled_ = HttpStreamFactory::http_pipelining_enabled(); | 45 default_pipelining_enabled_ = HttpStreamFactory::http_pipelining_enabled(); |
| 46 HttpStreamFactory::set_http_pipelining_enabled(true); | 46 HttpStreamFactory::set_http_pipelining_enabled(true); |
| 47 } | 47 } |
| 48 | 48 |
| 49 virtual void TearDown() OVERRIDE { | 49 virtual void TearDown() OVERRIDE { |
| 50 MessageLoop::current()->RunAllPending(); | 50 MessageLoop::current()->RunAllPending(); |
| 51 HttpStreamFactory::set_http_pipelining_enabled(default_pipelining_enabled_); | 51 HttpStreamFactory::set_http_pipelining_enabled(default_pipelining_enabled_); |
| 52 } | 52 } |
| 53 | 53 |
| 54 void Initialize() { | 54 void Initialize(bool force_http_pipelining) { |
| 55 // Normally, this code could just go in SetUp(). For a few of these tests, |
| 56 // we change the default number of sockets per group. That needs to be done |
| 57 // before we construct the HttpNetworkSession. |
| 55 proxy_service_.reset(ProxyService::CreateDirect()); | 58 proxy_service_.reset(ProxyService::CreateDirect()); |
| 56 ssl_config_ = new SSLConfigServiceDefaults; | 59 ssl_config_ = new SSLConfigServiceDefaults; |
| 57 auth_handler_factory_.reset(new HttpAuthHandlerMock::Factory()); | 60 auth_handler_factory_.reset(new HttpAuthHandlerMock::Factory()); |
| 58 | 61 |
| 59 HttpNetworkSession::Params session_params; | 62 HttpNetworkSession::Params session_params; |
| 60 session_params.client_socket_factory = &factory_; | 63 session_params.client_socket_factory = &factory_; |
| 61 session_params.proxy_service = proxy_service_.get(); | 64 session_params.proxy_service = proxy_service_.get(); |
| 62 session_params.host_resolver = &mock_resolver_; | 65 session_params.host_resolver = &mock_resolver_; |
| 63 session_params.ssl_config_service = ssl_config_.get(); | 66 session_params.ssl_config_service = ssl_config_.get(); |
| 64 session_params.http_auth_handler_factory = auth_handler_factory_.get(); | 67 session_params.http_auth_handler_factory = auth_handler_factory_.get(); |
| 65 session_params.http_server_properties = &http_server_properties_; | 68 session_params.http_server_properties = &http_server_properties_; |
| 69 session_params.force_http_pipelining = force_http_pipelining; |
| 66 session_ = new HttpNetworkSession(session_params); | 70 session_ = new HttpNetworkSession(session_params); |
| 67 } | 71 } |
| 68 | 72 |
| 69 void AddExpectedConnection(MockRead* reads, size_t reads_count, | 73 void AddExpectedConnection(MockRead* reads, size_t reads_count, |
| 70 MockWrite* writes, size_t writes_count) { | 74 MockWrite* writes, size_t writes_count) { |
| 71 DeterministicSocketData* data = new DeterministicSocketData( | 75 DeterministicSocketData* data = new DeterministicSocketData( |
| 72 reads, reads_count, writes, writes_count); | 76 reads, reads_count, writes, writes_count); |
| 73 data->set_connect_data(MockConnect(SYNCHRONOUS, OK)); | 77 data->set_connect_data(MockConnect(SYNCHRONOUS, OK)); |
| 74 if (reads_count || writes_count) { | 78 if (reads_count || writes_count) { |
| 75 data->StopAfter(reads_count + writes_count); | 79 data->StopAfter(reads_count + writes_count); |
| 76 } | 80 } |
| 77 factory_.AddSocketDataProvider(data); | 81 factory_.AddSocketDataProvider(data); |
| 78 data_vector_.push_back(data); | 82 data_vector_.push_back(data); |
| 79 } | 83 } |
| 80 | 84 |
| 81 const HttpRequestInfo* GetRequestInfo(const char* filename) { | 85 HttpRequestInfo* GetRequestInfo(const char* filename) { |
| 82 std::string url = StringPrintf("http://localhost/%s", filename); | 86 std::string url = StringPrintf("http://localhost/%s", filename); |
| 83 HttpRequestInfo* request_info = new HttpRequestInfo; | 87 HttpRequestInfo* request_info = new HttpRequestInfo; |
| 84 request_info->url = GURL(url); | 88 request_info->url = GURL(url); |
| 85 request_info->method = "GET"; | 89 request_info->method = "GET"; |
| 86 request_info_vector_.push_back(request_info); | 90 request_info_vector_.push_back(request_info); |
| 87 return request_info; | 91 return request_info; |
| 88 } | 92 } |
| 89 | 93 |
| 90 void ExpectResponse(const std::string& expected, | 94 void ExpectResponse(const std::string& expected, |
| 91 HttpNetworkTransaction& transaction) { | 95 HttpNetworkTransaction& transaction, |
| 96 IoMode io_mode) { |
| 92 scoped_refptr<IOBuffer> buffer(new IOBuffer(expected.size())); | 97 scoped_refptr<IOBuffer> buffer(new IOBuffer(expected.size())); |
| 93 EXPECT_EQ(static_cast<int>(expected.size()), | 98 if (io_mode == ASYNC) { |
| 94 transaction.Read(buffer.get(), expected.size(), | 99 EXPECT_EQ(ERR_IO_PENDING, transaction.Read(buffer.get(), expected.size(), |
| 95 callback_.callback())); | 100 callback_.callback())); |
| 101 data_vector_[0]->RunFor(1); |
| 102 EXPECT_EQ(static_cast<int>(expected.length()), callback_.WaitForResult()); |
| 103 } else { |
| 104 EXPECT_EQ(static_cast<int>(expected.size()), |
| 105 transaction.Read(buffer.get(), expected.size(), |
| 106 callback_.callback())); |
| 107 } |
| 96 std::string actual(buffer->data(), expected.size()); | 108 std::string actual(buffer->data(), expected.size()); |
| 97 EXPECT_THAT(actual, StrEq(expected)); | 109 EXPECT_THAT(actual, StrEq(expected)); |
| 98 EXPECT_EQ(OK, transaction.Read(buffer.get(), expected.size(), | 110 EXPECT_EQ(OK, transaction.Read(buffer.get(), expected.size(), |
| 99 callback_.callback())); | 111 callback_.callback())); |
| 100 } | 112 } |
| 101 | 113 |
| 102 void CompleteTwoRequests(int data_index, int stop_at_step) { | 114 void CompleteTwoRequests(int data_index, int stop_at_step) { |
| 103 scoped_ptr<HttpNetworkTransaction> one_transaction( | 115 scoped_ptr<HttpNetworkTransaction> one_transaction( |
| 104 new HttpNetworkTransaction(session_.get())); | 116 new HttpNetworkTransaction(session_.get())); |
| 105 TestCompletionCallback one_callback; | 117 TestCompletionCallback one_callback; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 123 data_vector_[data_index]->SetStop(stop_at_step); | 135 data_vector_[data_index]->SetStop(stop_at_step); |
| 124 data_vector_[data_index]->Run(); | 136 data_vector_[data_index]->Run(); |
| 125 EXPECT_EQ(8, one_read_callback.WaitForResult()); | 137 EXPECT_EQ(8, one_read_callback.WaitForResult()); |
| 126 data_vector_[data_index]->SetStop(10); | 138 data_vector_[data_index]->SetStop(10); |
| 127 std::string actual(buffer->data(), 8); | 139 std::string actual(buffer->data(), 8); |
| 128 EXPECT_THAT(actual, StrEq("one.html")); | 140 EXPECT_THAT(actual, StrEq("one.html")); |
| 129 EXPECT_EQ(OK, one_transaction->Read(buffer.get(), 8, | 141 EXPECT_EQ(OK, one_transaction->Read(buffer.get(), 8, |
| 130 one_read_callback.callback())); | 142 one_read_callback.callback())); |
| 131 | 143 |
| 132 EXPECT_EQ(OK, two_callback.WaitForResult()); | 144 EXPECT_EQ(OK, two_callback.WaitForResult()); |
| 133 ExpectResponse("two.html", two_transaction); | 145 ExpectResponse("two.html", two_transaction, SYNCHRONOUS); |
| 134 } | 146 } |
| 135 | 147 |
| 136 void CompleteFourRequests() { | 148 void CompleteFourRequests() { |
| 137 scoped_ptr<HttpNetworkTransaction> one_transaction( | 149 scoped_ptr<HttpNetworkTransaction> one_transaction( |
| 138 new HttpNetworkTransaction(session_.get())); | 150 new HttpNetworkTransaction(session_.get())); |
| 139 TestCompletionCallback one_callback; | 151 TestCompletionCallback one_callback; |
| 140 EXPECT_EQ(ERR_IO_PENDING, | 152 EXPECT_EQ(ERR_IO_PENDING, |
| 141 one_transaction->Start(GetRequestInfo("one.html"), | 153 one_transaction->Start(GetRequestInfo("one.html"), |
| 142 one_callback.callback(), BoundNetLog())); | 154 one_callback.callback(), BoundNetLog())); |
| 143 EXPECT_EQ(OK, one_callback.WaitForResult()); | 155 EXPECT_EQ(OK, one_callback.WaitForResult()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 154 three_transaction.Start(GetRequestInfo("three.html"), | 166 three_transaction.Start(GetRequestInfo("three.html"), |
| 155 three_callback.callback(), | 167 three_callback.callback(), |
| 156 BoundNetLog())); | 168 BoundNetLog())); |
| 157 | 169 |
| 158 HttpNetworkTransaction four_transaction(session_.get()); | 170 HttpNetworkTransaction four_transaction(session_.get()); |
| 159 TestCompletionCallback four_callback; | 171 TestCompletionCallback four_callback; |
| 160 EXPECT_EQ(ERR_IO_PENDING, | 172 EXPECT_EQ(ERR_IO_PENDING, |
| 161 four_transaction.Start(GetRequestInfo("four.html"), | 173 four_transaction.Start(GetRequestInfo("four.html"), |
| 162 four_callback.callback(), BoundNetLog())); | 174 four_callback.callback(), BoundNetLog())); |
| 163 | 175 |
| 164 ExpectResponse("one.html", *one_transaction.get()); | 176 ExpectResponse("one.html", *one_transaction.get(), SYNCHRONOUS); |
| 165 EXPECT_EQ(OK, two_callback.WaitForResult()); | 177 EXPECT_EQ(OK, two_callback.WaitForResult()); |
| 166 ExpectResponse("two.html", two_transaction); | 178 ExpectResponse("two.html", two_transaction, SYNCHRONOUS); |
| 167 EXPECT_EQ(OK, three_callback.WaitForResult()); | 179 EXPECT_EQ(OK, three_callback.WaitForResult()); |
| 168 ExpectResponse("three.html", three_transaction); | 180 ExpectResponse("three.html", three_transaction, SYNCHRONOUS); |
| 169 | 181 |
| 170 one_transaction.reset(); | 182 one_transaction.reset(); |
| 171 EXPECT_EQ(OK, four_callback.WaitForResult()); | 183 EXPECT_EQ(OK, four_callback.WaitForResult()); |
| 172 ExpectResponse("four.html", four_transaction); | 184 ExpectResponse("four.html", four_transaction, SYNCHRONOUS); |
| 173 } | 185 } |
| 174 | 186 |
| 175 DeterministicMockClientSocketFactory factory_; | 187 DeterministicMockClientSocketFactory factory_; |
| 176 ClientSocketPoolHistograms histograms_; | 188 ClientSocketPoolHistograms histograms_; |
| 177 MockTransportClientSocketPool pool_; | 189 MockTransportClientSocketPool pool_; |
| 178 std::vector<scoped_refptr<DeterministicSocketData> > data_vector_; | 190 std::vector<scoped_refptr<DeterministicSocketData> > data_vector_; |
| 179 TestCompletionCallback callback_; | 191 TestCompletionCallback callback_; |
| 180 ScopedVector<HttpRequestInfo> request_info_vector_; | 192 ScopedVector<HttpRequestInfo> request_info_vector_; |
| 181 bool default_pipelining_enabled_; | 193 bool default_pipelining_enabled_; |
| 182 | 194 |
| 183 scoped_ptr<ProxyService> proxy_service_; | 195 scoped_ptr<ProxyService> proxy_service_; |
| 184 MockHostResolver mock_resolver_; | 196 MockHostResolver mock_resolver_; |
| 185 scoped_refptr<SSLConfigService> ssl_config_; | 197 scoped_refptr<SSLConfigService> ssl_config_; |
| 186 scoped_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory_; | 198 scoped_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory_; |
| 187 HttpServerPropertiesImpl http_server_properties_; | 199 HttpServerPropertiesImpl http_server_properties_; |
| 188 scoped_refptr<HttpNetworkSession> session_; | 200 scoped_refptr<HttpNetworkSession> session_; |
| 189 }; | 201 }; |
| 190 | 202 |
| 191 TEST_F(HttpPipelinedNetworkTransactionTest, OneRequest) { | 203 TEST_F(HttpPipelinedNetworkTransactionTest, OneRequest) { |
| 192 Initialize(); | 204 Initialize(false); |
| 193 | 205 |
| 194 MockWrite writes[] = { | 206 MockWrite writes[] = { |
| 195 MockWrite(SYNCHRONOUS, 0, "GET /test.html HTTP/1.1\r\n" | 207 MockWrite(SYNCHRONOUS, 0, "GET /test.html HTTP/1.1\r\n" |
| 196 "Host: localhost\r\n" | 208 "Host: localhost\r\n" |
| 197 "Connection: keep-alive\r\n\r\n"), | 209 "Connection: keep-alive\r\n\r\n"), |
| 198 }; | 210 }; |
| 199 MockRead reads[] = { | 211 MockRead reads[] = { |
| 200 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"), | 212 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"), |
| 201 MockRead(SYNCHRONOUS, 2, "Content-Length: 9\r\n\r\n"), | 213 MockRead(SYNCHRONOUS, 2, "Content-Length: 9\r\n\r\n"), |
| 202 MockRead(SYNCHRONOUS, 3, "test.html"), | 214 MockRead(SYNCHRONOUS, 3, "test.html"), |
| 203 }; | 215 }; |
| 204 AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes)); | 216 AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes)); |
| 205 | 217 |
| 206 HttpNetworkTransaction transaction(session_.get()); | 218 HttpNetworkTransaction transaction(session_.get()); |
| 207 EXPECT_EQ(ERR_IO_PENDING, | 219 EXPECT_EQ(ERR_IO_PENDING, |
| 208 transaction.Start(GetRequestInfo("test.html"), callback_.callback(), | 220 transaction.Start(GetRequestInfo("test.html"), callback_.callback(), |
| 209 BoundNetLog())); | 221 BoundNetLog())); |
| 210 EXPECT_EQ(OK, callback_.WaitForResult()); | 222 EXPECT_EQ(OK, callback_.WaitForResult()); |
| 211 ExpectResponse("test.html", transaction); | 223 ExpectResponse("test.html", transaction, SYNCHRONOUS); |
| 212 } | 224 } |
| 213 | 225 |
| 214 TEST_F(HttpPipelinedNetworkTransactionTest, ReusePipeline) { | 226 TEST_F(HttpPipelinedNetworkTransactionTest, ReusePipeline) { |
| 215 Initialize(); | 227 Initialize(false); |
| 216 | 228 |
| 217 MockWrite writes[] = { | 229 MockWrite writes[] = { |
| 218 MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n" | 230 MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n" |
| 219 "Host: localhost\r\n" | 231 "Host: localhost\r\n" |
| 220 "Connection: keep-alive\r\n\r\n"), | 232 "Connection: keep-alive\r\n\r\n"), |
| 221 MockWrite(SYNCHRONOUS, 3, "GET /two.html HTTP/1.1\r\n" | 233 MockWrite(SYNCHRONOUS, 3, "GET /two.html HTTP/1.1\r\n" |
| 222 "Host: localhost\r\n" | 234 "Host: localhost\r\n" |
| 223 "Connection: keep-alive\r\n\r\n"), | 235 "Connection: keep-alive\r\n\r\n"), |
| 224 }; | 236 }; |
| 225 MockRead reads[] = { | 237 MockRead reads[] = { |
| 226 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"), | 238 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"), |
| 227 MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"), | 239 MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"), |
| 228 MockRead(ASYNC, 4, "one.html"), | 240 MockRead(ASYNC, 4, "one.html"), |
| 229 MockRead(SYNCHRONOUS, 5, "HTTP/1.1 200 OK\r\n"), | 241 MockRead(SYNCHRONOUS, 5, "HTTP/1.1 200 OK\r\n"), |
| 230 MockRead(SYNCHRONOUS, 6, "Content-Length: 8\r\n\r\n"), | 242 MockRead(SYNCHRONOUS, 6, "Content-Length: 8\r\n\r\n"), |
| 231 MockRead(SYNCHRONOUS, 7, "two.html"), | 243 MockRead(SYNCHRONOUS, 7, "two.html"), |
| 232 }; | 244 }; |
| 233 AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes)); | 245 AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes)); |
| 234 | 246 |
| 235 CompleteTwoRequests(0, 5); | 247 CompleteTwoRequests(0, 5); |
| 236 } | 248 } |
| 237 | 249 |
| 238 TEST_F(HttpPipelinedNetworkTransactionTest, ReusesOnSpaceAvailable) { | 250 TEST_F(HttpPipelinedNetworkTransactionTest, ReusesOnSpaceAvailable) { |
| 239 int old_max_sockets = ClientSocketPoolManager::max_sockets_per_group(); | 251 int old_max_sockets = ClientSocketPoolManager::max_sockets_per_group(); |
| 240 ClientSocketPoolManager::set_max_sockets_per_group(1); | 252 ClientSocketPoolManager::set_max_sockets_per_group(1); |
| 241 Initialize(); | 253 Initialize(false); |
| 242 | 254 |
| 243 MockWrite writes[] = { | 255 MockWrite writes[] = { |
| 244 MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n" | 256 MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n" |
| 245 "Host: localhost\r\n" | 257 "Host: localhost\r\n" |
| 246 "Connection: keep-alive\r\n\r\n"), | 258 "Connection: keep-alive\r\n\r\n"), |
| 247 MockWrite(SYNCHRONOUS, 4, "GET /two.html HTTP/1.1\r\n" | 259 MockWrite(SYNCHRONOUS, 4, "GET /two.html HTTP/1.1\r\n" |
| 248 "Host: localhost\r\n" | 260 "Host: localhost\r\n" |
| 249 "Connection: keep-alive\r\n\r\n"), | 261 "Connection: keep-alive\r\n\r\n"), |
| 250 MockWrite(SYNCHRONOUS, 7, "GET /three.html HTTP/1.1\r\n" | 262 MockWrite(SYNCHRONOUS, 7, "GET /three.html HTTP/1.1\r\n" |
| 251 "Host: localhost\r\n" | 263 "Host: localhost\r\n" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 269 MockRead(SYNCHRONOUS, 15, "four.html"), | 281 MockRead(SYNCHRONOUS, 15, "four.html"), |
| 270 }; | 282 }; |
| 271 AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes)); | 283 AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes)); |
| 272 | 284 |
| 273 CompleteFourRequests(); | 285 CompleteFourRequests(); |
| 274 | 286 |
| 275 ClientSocketPoolManager::set_max_sockets_per_group(old_max_sockets); | 287 ClientSocketPoolManager::set_max_sockets_per_group(old_max_sockets); |
| 276 } | 288 } |
| 277 | 289 |
| 278 TEST_F(HttpPipelinedNetworkTransactionTest, UnknownSizeEvictsToNewPipeline) { | 290 TEST_F(HttpPipelinedNetworkTransactionTest, UnknownSizeEvictsToNewPipeline) { |
| 279 Initialize(); | 291 Initialize(false); |
| 280 | 292 |
| 281 MockWrite writes[] = { | 293 MockWrite writes[] = { |
| 282 MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n" | 294 MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n" |
| 283 "Host: localhost\r\n" | 295 "Host: localhost\r\n" |
| 284 "Connection: keep-alive\r\n\r\n"), | 296 "Connection: keep-alive\r\n\r\n"), |
| 285 }; | 297 }; |
| 286 MockRead reads[] = { | 298 MockRead reads[] = { |
| 287 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n\r\n"), | 299 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n\r\n"), |
| 288 MockRead(ASYNC, 2, "one.html"), | 300 MockRead(ASYNC, 2, "one.html"), |
| 289 MockRead(SYNCHRONOUS, OK, 3), | 301 MockRead(SYNCHRONOUS, OK, 3), |
| 290 }; | 302 }; |
| 291 AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes)); | 303 AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes)); |
| 292 | 304 |
| 293 MockWrite writes2[] = { | 305 MockWrite writes2[] = { |
| 294 MockWrite(SYNCHRONOUS, 0, "GET /two.html HTTP/1.1\r\n" | 306 MockWrite(SYNCHRONOUS, 0, "GET /two.html HTTP/1.1\r\n" |
| 295 "Host: localhost\r\n" | 307 "Host: localhost\r\n" |
| 296 "Connection: keep-alive\r\n\r\n"), | 308 "Connection: keep-alive\r\n\r\n"), |
| 297 }; | 309 }; |
| 298 MockRead reads2[] = { | 310 MockRead reads2[] = { |
| 299 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"), | 311 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"), |
| 300 MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"), | 312 MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"), |
| 301 MockRead(SYNCHRONOUS, 3, "two.html"), | 313 MockRead(SYNCHRONOUS, 3, "two.html"), |
| 302 }; | 314 }; |
| 303 AddExpectedConnection(reads2, arraysize(reads2), writes2, arraysize(writes2)); | 315 AddExpectedConnection(reads2, arraysize(reads2), writes2, arraysize(writes2)); |
| 304 | 316 |
| 305 CompleteTwoRequests(0, 3); | 317 CompleteTwoRequests(0, 3); |
| 306 } | 318 } |
| 307 | 319 |
| 308 TEST_F(HttpPipelinedNetworkTransactionTest, ConnectionCloseEvictToNewPipeline) { | 320 TEST_F(HttpPipelinedNetworkTransactionTest, ConnectionCloseEvictToNewPipeline) { |
| 309 Initialize(); | 321 Initialize(false); |
| 310 | 322 |
| 311 MockWrite writes[] = { | 323 MockWrite writes[] = { |
| 312 MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n" | 324 MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n" |
| 313 "Host: localhost\r\n" | 325 "Host: localhost\r\n" |
| 314 "Connection: keep-alive\r\n\r\n"), | 326 "Connection: keep-alive\r\n\r\n"), |
| 315 MockWrite(SYNCHRONOUS, 3, "GET /two.html HTTP/1.1\r\n" | 327 MockWrite(SYNCHRONOUS, 3, "GET /two.html HTTP/1.1\r\n" |
| 316 "Host: localhost\r\n" | 328 "Host: localhost\r\n" |
| 317 "Connection: keep-alive\r\n\r\n"), | 329 "Connection: keep-alive\r\n\r\n"), |
| 318 }; | 330 }; |
| 319 MockRead reads[] = { | 331 MockRead reads[] = { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 333 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"), | 345 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"), |
| 334 MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"), | 346 MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"), |
| 335 MockRead(SYNCHRONOUS, 3, "two.html"), | 347 MockRead(SYNCHRONOUS, 3, "two.html"), |
| 336 }; | 348 }; |
| 337 AddExpectedConnection(reads2, arraysize(reads2), writes2, arraysize(writes2)); | 349 AddExpectedConnection(reads2, arraysize(reads2), writes2, arraysize(writes2)); |
| 338 | 350 |
| 339 CompleteTwoRequests(0, 5); | 351 CompleteTwoRequests(0, 5); |
| 340 } | 352 } |
| 341 | 353 |
| 342 TEST_F(HttpPipelinedNetworkTransactionTest, ErrorEvictsToNewPipeline) { | 354 TEST_F(HttpPipelinedNetworkTransactionTest, ErrorEvictsToNewPipeline) { |
| 343 Initialize(); | 355 Initialize(false); |
| 344 | 356 |
| 345 MockWrite writes[] = { | 357 MockWrite writes[] = { |
| 346 MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n" | 358 MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n" |
| 347 "Host: localhost\r\n" | 359 "Host: localhost\r\n" |
| 348 "Connection: keep-alive\r\n\r\n"), | 360 "Connection: keep-alive\r\n\r\n"), |
| 349 MockWrite(SYNCHRONOUS, 3, "GET /two.html HTTP/1.1\r\n" | 361 MockWrite(SYNCHRONOUS, 3, "GET /two.html HTTP/1.1\r\n" |
| 350 "Host: localhost\r\n" | 362 "Host: localhost\r\n" |
| 351 "Connection: keep-alive\r\n\r\n"), | 363 "Connection: keep-alive\r\n\r\n"), |
| 352 }; | 364 }; |
| 353 MockRead reads[] = { | 365 MockRead reads[] = { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 378 HttpNetworkTransaction two_transaction(session_.get()); | 390 HttpNetworkTransaction two_transaction(session_.get()); |
| 379 TestCompletionCallback two_callback; | 391 TestCompletionCallback two_callback; |
| 380 EXPECT_EQ(ERR_IO_PENDING, | 392 EXPECT_EQ(ERR_IO_PENDING, |
| 381 two_transaction.Start(GetRequestInfo("two.html"), | 393 two_transaction.Start(GetRequestInfo("two.html"), |
| 382 two_callback.callback(), BoundNetLog())); | 394 two_callback.callback(), BoundNetLog())); |
| 383 | 395 |
| 384 scoped_refptr<IOBuffer> buffer(new IOBuffer(1)); | 396 scoped_refptr<IOBuffer> buffer(new IOBuffer(1)); |
| 385 EXPECT_EQ(ERR_FAILED, | 397 EXPECT_EQ(ERR_FAILED, |
| 386 one_transaction.Read(buffer.get(), 1, callback_.callback())); | 398 one_transaction.Read(buffer.get(), 1, callback_.callback())); |
| 387 EXPECT_EQ(OK, two_callback.WaitForResult()); | 399 EXPECT_EQ(OK, two_callback.WaitForResult()); |
| 388 ExpectResponse("two.html", two_transaction); | 400 ExpectResponse("two.html", two_transaction, SYNCHRONOUS); |
| 389 } | 401 } |
| 390 | 402 |
| 391 TEST_F(HttpPipelinedNetworkTransactionTest, SendErrorEvictsToNewPipeline) { | 403 TEST_F(HttpPipelinedNetworkTransactionTest, SendErrorEvictsToNewPipeline) { |
| 392 Initialize(); | 404 Initialize(false); |
| 393 | 405 |
| 394 MockWrite writes[] = { | 406 MockWrite writes[] = { |
| 395 MockWrite(ASYNC, ERR_FAILED, 0), | 407 MockWrite(ASYNC, ERR_FAILED, 0), |
| 396 }; | 408 }; |
| 397 AddExpectedConnection(NULL, 0, writes, arraysize(writes)); | 409 AddExpectedConnection(NULL, 0, writes, arraysize(writes)); |
| 398 | 410 |
| 399 MockWrite writes2[] = { | 411 MockWrite writes2[] = { |
| 400 MockWrite(SYNCHRONOUS, 0, "GET /two.html HTTP/1.1\r\n" | 412 MockWrite(SYNCHRONOUS, 0, "GET /two.html HTTP/1.1\r\n" |
| 401 "Host: localhost\r\n" | 413 "Host: localhost\r\n" |
| 402 "Connection: keep-alive\r\n\r\n"), | 414 "Connection: keep-alive\r\n\r\n"), |
| (...skipping 14 matching lines...) Expand all Loading... |
| 417 HttpNetworkTransaction two_transaction(session_.get()); | 429 HttpNetworkTransaction two_transaction(session_.get()); |
| 418 TestCompletionCallback two_callback; | 430 TestCompletionCallback two_callback; |
| 419 EXPECT_EQ(ERR_IO_PENDING, | 431 EXPECT_EQ(ERR_IO_PENDING, |
| 420 two_transaction.Start(GetRequestInfo("two.html"), | 432 two_transaction.Start(GetRequestInfo("two.html"), |
| 421 two_callback.callback(), BoundNetLog())); | 433 two_callback.callback(), BoundNetLog())); |
| 422 | 434 |
| 423 data_vector_[0]->RunFor(1); | 435 data_vector_[0]->RunFor(1); |
| 424 EXPECT_EQ(ERR_FAILED, one_callback.WaitForResult()); | 436 EXPECT_EQ(ERR_FAILED, one_callback.WaitForResult()); |
| 425 | 437 |
| 426 EXPECT_EQ(OK, two_callback.WaitForResult()); | 438 EXPECT_EQ(OK, two_callback.WaitForResult()); |
| 427 ExpectResponse("two.html", two_transaction); | 439 ExpectResponse("two.html", two_transaction, SYNCHRONOUS); |
| 428 } | 440 } |
| 429 | 441 |
| 430 TEST_F(HttpPipelinedNetworkTransactionTest, RedirectDrained) { | 442 TEST_F(HttpPipelinedNetworkTransactionTest, RedirectDrained) { |
| 431 Initialize(); | 443 Initialize(false); |
| 432 | 444 |
| 433 MockWrite writes[] = { | 445 MockWrite writes[] = { |
| 434 MockWrite(SYNCHRONOUS, 0, "GET /redirect.html HTTP/1.1\r\n" | 446 MockWrite(SYNCHRONOUS, 0, "GET /redirect.html HTTP/1.1\r\n" |
| 435 "Host: localhost\r\n" | 447 "Host: localhost\r\n" |
| 436 "Connection: keep-alive\r\n\r\n"), | 448 "Connection: keep-alive\r\n\r\n"), |
| 437 MockWrite(SYNCHRONOUS, 3, "GET /two.html HTTP/1.1\r\n" | 449 MockWrite(SYNCHRONOUS, 3, "GET /two.html HTTP/1.1\r\n" |
| 438 "Host: localhost\r\n" | 450 "Host: localhost\r\n" |
| 439 "Connection: keep-alive\r\n\r\n"), | 451 "Connection: keep-alive\r\n\r\n"), |
| 440 }; | 452 }; |
| 441 MockRead reads[] = { | 453 MockRead reads[] = { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 460 TestCompletionCallback two_callback; | 472 TestCompletionCallback two_callback; |
| 461 EXPECT_EQ(ERR_IO_PENDING, | 473 EXPECT_EQ(ERR_IO_PENDING, |
| 462 two_transaction.Start(GetRequestInfo("two.html"), | 474 two_transaction.Start(GetRequestInfo("two.html"), |
| 463 two_callback.callback(), BoundNetLog())); | 475 two_callback.callback(), BoundNetLog())); |
| 464 | 476 |
| 465 one_transaction.reset(); | 477 one_transaction.reset(); |
| 466 data_vector_[0]->RunFor(2); | 478 data_vector_[0]->RunFor(2); |
| 467 data_vector_[0]->SetStop(10); | 479 data_vector_[0]->SetStop(10); |
| 468 | 480 |
| 469 EXPECT_EQ(OK, two_callback.WaitForResult()); | 481 EXPECT_EQ(OK, two_callback.WaitForResult()); |
| 470 ExpectResponse("two.html", two_transaction); | 482 ExpectResponse("two.html", two_transaction, SYNCHRONOUS); |
| 471 } | 483 } |
| 472 | 484 |
| 473 TEST_F(HttpPipelinedNetworkTransactionTest, BasicHttpAuthentication) { | 485 TEST_F(HttpPipelinedNetworkTransactionTest, BasicHttpAuthentication) { |
| 474 Initialize(); | 486 Initialize(false); |
| 475 | 487 |
| 476 MockWrite writes[] = { | 488 MockWrite writes[] = { |
| 477 MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n" | 489 MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n" |
| 478 "Host: localhost\r\n" | 490 "Host: localhost\r\n" |
| 479 "Connection: keep-alive\r\n\r\n"), | 491 "Connection: keep-alive\r\n\r\n"), |
| 480 MockWrite(SYNCHRONOUS, 5, "GET /one.html HTTP/1.1\r\n" | 492 MockWrite(SYNCHRONOUS, 5, "GET /one.html HTTP/1.1\r\n" |
| 481 "Host: localhost\r\n" | 493 "Host: localhost\r\n" |
| 482 "Connection: keep-alive\r\n" | 494 "Connection: keep-alive\r\n" |
| 483 "Authorization: auth_token\r\n\r\n"), | 495 "Authorization: auth_token\r\n\r\n"), |
| 484 }; | 496 }; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 507 | 519 |
| 508 HttpNetworkTransaction transaction(session_.get()); | 520 HttpNetworkTransaction transaction(session_.get()); |
| 509 EXPECT_EQ(ERR_IO_PENDING, | 521 EXPECT_EQ(ERR_IO_PENDING, |
| 510 transaction.Start(GetRequestInfo("one.html"), callback_.callback(), | 522 transaction.Start(GetRequestInfo("one.html"), callback_.callback(), |
| 511 BoundNetLog())); | 523 BoundNetLog())); |
| 512 EXPECT_EQ(OK, callback_.WaitForResult()); | 524 EXPECT_EQ(OK, callback_.WaitForResult()); |
| 513 | 525 |
| 514 AuthCredentials credentials(ASCIIToUTF16("user"), ASCIIToUTF16("pass")); | 526 AuthCredentials credentials(ASCIIToUTF16("user"), ASCIIToUTF16("pass")); |
| 515 EXPECT_EQ(OK, transaction.RestartWithAuth(credentials, callback_.callback())); | 527 EXPECT_EQ(OK, transaction.RestartWithAuth(credentials, callback_.callback())); |
| 516 | 528 |
| 517 ExpectResponse("one.html", transaction); | 529 ExpectResponse("one.html", transaction, SYNCHRONOUS); |
| 518 } | 530 } |
| 519 | 531 |
| 520 TEST_F(HttpPipelinedNetworkTransactionTest, OldVersionDisablesPipelining) { | 532 TEST_F(HttpPipelinedNetworkTransactionTest, OldVersionDisablesPipelining) { |
| 521 Initialize(); | 533 Initialize(false); |
| 522 | 534 |
| 523 MockWrite writes[] = { | 535 MockWrite writes[] = { |
| 524 MockWrite(SYNCHRONOUS, 0, "GET /pipelined.html HTTP/1.1\r\n" | 536 MockWrite(SYNCHRONOUS, 0, "GET /pipelined.html HTTP/1.1\r\n" |
| 525 "Host: localhost\r\n" | 537 "Host: localhost\r\n" |
| 526 "Connection: keep-alive\r\n\r\n"), | 538 "Connection: keep-alive\r\n\r\n"), |
| 527 }; | 539 }; |
| 528 MockRead reads[] = { | 540 MockRead reads[] = { |
| 529 MockRead(SYNCHRONOUS, 1, "HTTP/1.0 200 OK\r\n"), | 541 MockRead(SYNCHRONOUS, 1, "HTTP/1.0 200 OK\r\n"), |
| 530 MockRead(SYNCHRONOUS, 2, "Content-Length: 14\r\n\r\n"), | 542 MockRead(SYNCHRONOUS, 2, "Content-Length: 14\r\n\r\n"), |
| 531 MockRead(SYNCHRONOUS, 3, "pipelined.html"), | 543 MockRead(SYNCHRONOUS, 3, "pipelined.html"), |
| (...skipping 25 matching lines...) Expand all Loading... |
| 557 MockRead(SYNCHRONOUS, OK, 4), | 569 MockRead(SYNCHRONOUS, OK, 4), |
| 558 }; | 570 }; |
| 559 AddExpectedConnection(reads3, arraysize(reads3), writes3, arraysize(writes3)); | 571 AddExpectedConnection(reads3, arraysize(reads3), writes3, arraysize(writes3)); |
| 560 | 572 |
| 561 HttpNetworkTransaction one_transaction(session_.get()); | 573 HttpNetworkTransaction one_transaction(session_.get()); |
| 562 TestCompletionCallback one_callback; | 574 TestCompletionCallback one_callback; |
| 563 EXPECT_EQ(ERR_IO_PENDING, | 575 EXPECT_EQ(ERR_IO_PENDING, |
| 564 one_transaction.Start(GetRequestInfo("pipelined.html"), | 576 one_transaction.Start(GetRequestInfo("pipelined.html"), |
| 565 one_callback.callback(), BoundNetLog())); | 577 one_callback.callback(), BoundNetLog())); |
| 566 EXPECT_EQ(OK, one_callback.WaitForResult()); | 578 EXPECT_EQ(OK, one_callback.WaitForResult()); |
| 567 ExpectResponse("pipelined.html", one_transaction); | 579 ExpectResponse("pipelined.html", one_transaction, SYNCHRONOUS); |
| 568 | 580 |
| 569 CompleteTwoRequests(1, 4); | 581 CompleteTwoRequests(1, 4); |
| 570 } | 582 } |
| 571 | 583 |
| 572 TEST_F(HttpPipelinedNetworkTransactionTest, PipelinesImmediatelyIfKnownGood) { | 584 TEST_F(HttpPipelinedNetworkTransactionTest, PipelinesImmediatelyIfKnownGood) { |
| 573 // The first request gets us an HTTP/1.1. The next 3 test pipelining. When the | 585 // The first request gets us an HTTP/1.1. The next 3 test pipelining. When the |
| 574 // 3rd request completes, we know pipelining is safe. After the first 4 | 586 // 3rd request completes, we know pipelining is safe. After the first 4 |
| 575 // complete, the 5th and 6th should then be immediately sent pipelined on a | 587 // complete, the 5th and 6th should then be immediately sent pipelined on a |
| 576 // new HttpPipelinedConnection. | 588 // new HttpPipelinedConnection. |
| 577 int old_max_sockets = ClientSocketPoolManager::max_sockets_per_group(); | 589 int old_max_sockets = ClientSocketPoolManager::max_sockets_per_group(); |
| 578 ClientSocketPoolManager::set_max_sockets_per_group(1); | 590 ClientSocketPoolManager::set_max_sockets_per_group(1); |
| 579 Initialize(); | 591 Initialize(false); |
| 580 | 592 |
| 581 MockWrite writes[] = { | 593 MockWrite writes[] = { |
| 582 MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n" | 594 MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n" |
| 583 "Host: localhost\r\n" | 595 "Host: localhost\r\n" |
| 584 "Connection: keep-alive\r\n\r\n"), | 596 "Connection: keep-alive\r\n\r\n"), |
| 585 MockWrite(SYNCHRONOUS, 4, "GET /two.html HTTP/1.1\r\n" | 597 MockWrite(SYNCHRONOUS, 4, "GET /two.html HTTP/1.1\r\n" |
| 586 "Host: localhost\r\n" | 598 "Host: localhost\r\n" |
| 587 "Connection: keep-alive\r\n\r\n"), | 599 "Connection: keep-alive\r\n\r\n"), |
| 588 MockWrite(SYNCHRONOUS, 7, "GET /three.html HTTP/1.1\r\n" | 600 MockWrite(SYNCHRONOUS, 7, "GET /three.html HTTP/1.1\r\n" |
| 589 "Host: localhost\r\n" | 601 "Host: localhost\r\n" |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 633 HttpNetworkTransaction second_two_transaction(session_.get()); | 645 HttpNetworkTransaction second_two_transaction(session_.get()); |
| 634 TestCompletionCallback second_two_callback; | 646 TestCompletionCallback second_two_callback; |
| 635 EXPECT_EQ(ERR_IO_PENDING, | 647 EXPECT_EQ(ERR_IO_PENDING, |
| 636 second_two_transaction.Start( | 648 second_two_transaction.Start( |
| 637 GetRequestInfo("second-pipeline-two.html"), | 649 GetRequestInfo("second-pipeline-two.html"), |
| 638 second_two_callback.callback(), BoundNetLog())); | 650 second_two_callback.callback(), BoundNetLog())); |
| 639 | 651 |
| 640 data_vector_[0]->RunFor(3); | 652 data_vector_[0]->RunFor(3); |
| 641 EXPECT_EQ(OK, second_one_callback.WaitForResult()); | 653 EXPECT_EQ(OK, second_one_callback.WaitForResult()); |
| 642 data_vector_[0]->StopAfter(100); | 654 data_vector_[0]->StopAfter(100); |
| 643 ExpectResponse("second-pipeline-one.html", second_one_transaction); | 655 ExpectResponse("second-pipeline-one.html", second_one_transaction, |
| 656 SYNCHRONOUS); |
| 644 EXPECT_EQ(OK, second_two_callback.WaitForResult()); | 657 EXPECT_EQ(OK, second_two_callback.WaitForResult()); |
| 645 ExpectResponse("second-pipeline-two.html", second_two_transaction); | 658 ExpectResponse("second-pipeline-two.html", second_two_transaction, |
| 659 SYNCHRONOUS); |
| 646 | 660 |
| 647 ClientSocketPoolManager::set_max_sockets_per_group(old_max_sockets); | 661 ClientSocketPoolManager::set_max_sockets_per_group(old_max_sockets); |
| 648 } | 662 } |
| 649 | 663 |
| 650 class DataRunnerObserver : public MessageLoop::TaskObserver { | 664 class DataRunnerObserver : public MessageLoop::TaskObserver { |
| 651 public: | 665 public: |
| 652 DataRunnerObserver(DeterministicSocketData* data, int run_before_task) | 666 DataRunnerObserver(DeterministicSocketData* data, int run_before_task) |
| 653 : data_(data), | 667 : data_(data), |
| 654 run_before_task_(run_before_task), | 668 run_before_task_(run_before_task), |
| 655 current_task_(0) { } | 669 current_task_(0) { } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 677 // 2. HttpStreamFactoryImpl::Job tries to bind a pending request to a new | 691 // 2. HttpStreamFactoryImpl::Job tries to bind a pending request to a new |
| 678 // pipeline and queues a task to do so. | 692 // pipeline and queues a task to do so. |
| 679 // 3. Before that task runs, the first request receives its headers and | 693 // 3. Before that task runs, the first request receives its headers and |
| 680 // determines this host is probably capable of pipelining. | 694 // determines this host is probably capable of pipelining. |
| 681 // 4. All of the hosts' pipelines are notified they have capacity in a loop. | 695 // 4. All of the hosts' pipelines are notified they have capacity in a loop. |
| 682 // 5. On the first iteration, the first pipeline is opened up to accept new | 696 // 5. On the first iteration, the first pipeline is opened up to accept new |
| 683 // requests and steals the request from step #2. | 697 // requests and steals the request from step #2. |
| 684 // 6. The pipeline from #2 is deleted because it has no streams. | 698 // 6. The pipeline from #2 is deleted because it has no streams. |
| 685 // 7. On the second iteration, the host tries to notify the pipeline from step | 699 // 7. On the second iteration, the host tries to notify the pipeline from step |
| 686 // #2 that it has capacity. This is a use-after-free. | 700 // #2 that it has capacity. This is a use-after-free. |
| 687 Initialize(); | 701 Initialize(false); |
| 688 | 702 |
| 689 MockWrite writes[] = { | 703 MockWrite writes[] = { |
| 690 MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n" | 704 MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n" |
| 691 "Host: localhost\r\n" | 705 "Host: localhost\r\n" |
| 692 "Connection: keep-alive\r\n\r\n"), | 706 "Connection: keep-alive\r\n\r\n"), |
| 693 MockWrite(ASYNC, 3, "GET /two.html HTTP/1.1\r\n" | 707 MockWrite(ASYNC, 3, "GET /two.html HTTP/1.1\r\n" |
| 694 "Host: localhost\r\n" | 708 "Host: localhost\r\n" |
| 695 "Connection: keep-alive\r\n\r\n"), | 709 "Connection: keep-alive\r\n\r\n"), |
| 696 }; | 710 }; |
| 697 MockRead reads[] = { | 711 MockRead reads[] = { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 728 // We need to make sure that the response that triggers OnPipelineFeedback(OK) | 742 // We need to make sure that the response that triggers OnPipelineFeedback(OK) |
| 729 // is called in between when task #3 is scheduled and when it runs. The | 743 // is called in between when task #3 is scheduled and when it runs. The |
| 730 // DataRunnerObserver does that. | 744 // DataRunnerObserver does that. |
| 731 DataRunnerObserver observer(data_vector_[0].get(), 3); | 745 DataRunnerObserver observer(data_vector_[0].get(), 3); |
| 732 MessageLoop::current()->AddTaskObserver(&observer); | 746 MessageLoop::current()->AddTaskObserver(&observer); |
| 733 data_vector_[0]->SetStop(4); | 747 data_vector_[0]->SetStop(4); |
| 734 MessageLoop::current()->RunAllPending(); | 748 MessageLoop::current()->RunAllPending(); |
| 735 data_vector_[0]->SetStop(10); | 749 data_vector_[0]->SetStop(10); |
| 736 | 750 |
| 737 EXPECT_EQ(OK, one_callback.WaitForResult()); | 751 EXPECT_EQ(OK, one_callback.WaitForResult()); |
| 738 ExpectResponse("one.html", one_transaction); | 752 ExpectResponse("one.html", one_transaction, SYNCHRONOUS); |
| 739 EXPECT_EQ(OK, two_callback.WaitForResult()); | 753 EXPECT_EQ(OK, two_callback.WaitForResult()); |
| 740 ExpectResponse("two.html", two_transaction); | 754 ExpectResponse("two.html", two_transaction, SYNCHRONOUS); |
| 755 } |
| 756 |
| 757 TEST_F(HttpPipelinedNetworkTransactionTest, ForcedPipelineSharesConnection) { |
| 758 Initialize(true); |
| 759 |
| 760 MockWrite writes[] = { |
| 761 MockWrite(ASYNC, 0, "GET /one.html HTTP/1.1\r\n" |
| 762 "Host: localhost\r\n" |
| 763 "Connection: keep-alive\r\n\r\n" |
| 764 "GET /two.html HTTP/1.1\r\n" |
| 765 "Host: localhost\r\n" |
| 766 "Connection: keep-alive\r\n\r\n"), |
| 767 }; |
| 768 MockRead reads[] = { |
| 769 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n"), |
| 770 MockRead(ASYNC, 2, "Content-Length: 8\r\n\r\n"), |
| 771 MockRead(ASYNC, 3, "one.html"), |
| 772 MockRead(ASYNC, 4, "HTTP/1.1 200 OK\r\n"), |
| 773 MockRead(ASYNC, 5, "Content-Length: 8\r\n\r\n"), |
| 774 MockRead(ASYNC, 6, "two.html"), |
| 775 }; |
| 776 AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes)); |
| 777 |
| 778 scoped_ptr<HttpNetworkTransaction> one_transaction( |
| 779 new HttpNetworkTransaction(session_.get())); |
| 780 TestCompletionCallback one_callback; |
| 781 EXPECT_EQ(ERR_IO_PENDING, |
| 782 one_transaction->Start(GetRequestInfo("one.html"), |
| 783 one_callback.callback(), BoundNetLog())); |
| 784 |
| 785 HttpNetworkTransaction two_transaction(session_.get()); |
| 786 TestCompletionCallback two_callback; |
| 787 EXPECT_EQ(ERR_IO_PENDING, |
| 788 two_transaction.Start(GetRequestInfo("two.html"), |
| 789 two_callback.callback(), BoundNetLog())); |
| 790 |
| 791 data_vector_[0]->RunFor(3); // Send + 2 lines of headers. |
| 792 EXPECT_EQ(OK, one_callback.WaitForResult()); |
| 793 ExpectResponse("one.html", *one_transaction.get(), ASYNC); |
| 794 one_transaction.reset(); |
| 795 |
| 796 data_vector_[0]->RunFor(2); // 2 lines of headers. |
| 797 EXPECT_EQ(OK, two_callback.WaitForResult()); |
| 798 ExpectResponse("two.html", two_transaction, ASYNC); |
| 799 } |
| 800 |
| 801 TEST_F(HttpPipelinedNetworkTransactionTest, |
| 802 ForcedPipelineConnectionErrorFailsBoth) { |
| 803 Initialize(true); |
| 804 |
| 805 scoped_refptr<DeterministicSocketData> data( |
| 806 new DeterministicSocketData(NULL, 0, NULL, 0)); |
| 807 data->set_connect_data(MockConnect(ASYNC, ERR_FAILED)); |
| 808 factory_.AddSocketDataProvider(data); |
| 809 |
| 810 scoped_ptr<HttpNetworkTransaction> one_transaction( |
| 811 new HttpNetworkTransaction(session_.get())); |
| 812 TestCompletionCallback one_callback; |
| 813 EXPECT_EQ(ERR_IO_PENDING, |
| 814 one_transaction->Start(GetRequestInfo("one.html"), |
| 815 one_callback.callback(), BoundNetLog())); |
| 816 |
| 817 HttpNetworkTransaction two_transaction(session_.get()); |
| 818 TestCompletionCallback two_callback; |
| 819 EXPECT_EQ(ERR_IO_PENDING, |
| 820 two_transaction.Start(GetRequestInfo("two.html"), |
| 821 two_callback.callback(), BoundNetLog())); |
| 822 |
| 823 data->Run(); |
| 824 EXPECT_EQ(ERR_FAILED, one_callback.WaitForResult()); |
| 825 EXPECT_EQ(ERR_FAILED, two_callback.WaitForResult()); |
| 826 } |
| 827 |
| 828 TEST_F(HttpPipelinedNetworkTransactionTest, ForcedPipelineEvictionIsFatal) { |
| 829 Initialize(true); |
| 830 |
| 831 MockWrite writes[] = { |
| 832 MockWrite(ASYNC, 0, "GET /one.html HTTP/1.1\r\n" |
| 833 "Host: localhost\r\n" |
| 834 "Connection: keep-alive\r\n\r\n" |
| 835 "GET /two.html HTTP/1.1\r\n" |
| 836 "Host: localhost\r\n" |
| 837 "Connection: keep-alive\r\n\r\n"), |
| 838 }; |
| 839 MockRead reads[] = { |
| 840 MockRead(ASYNC, ERR_FAILED, 1), |
| 841 }; |
| 842 AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes)); |
| 843 |
| 844 scoped_ptr<HttpNetworkTransaction> one_transaction( |
| 845 new HttpNetworkTransaction(session_.get())); |
| 846 TestCompletionCallback one_callback; |
| 847 EXPECT_EQ(ERR_IO_PENDING, |
| 848 one_transaction->Start(GetRequestInfo("one.html"), |
| 849 one_callback.callback(), BoundNetLog())); |
| 850 |
| 851 HttpNetworkTransaction two_transaction(session_.get()); |
| 852 TestCompletionCallback two_callback; |
| 853 EXPECT_EQ(ERR_IO_PENDING, |
| 854 two_transaction.Start(GetRequestInfo("two.html"), |
| 855 two_callback.callback(), BoundNetLog())); |
| 856 |
| 857 data_vector_[0]->RunFor(2); |
| 858 EXPECT_EQ(ERR_FAILED, one_callback.WaitForResult()); |
| 859 one_transaction.reset(); |
| 860 EXPECT_EQ(ERR_PIPELINE_EVICTION, two_callback.WaitForResult()); |
| 741 } | 861 } |
| 742 | 862 |
| 743 } // anonymous namespace | 863 } // anonymous namespace |
| 744 | 864 |
| 745 } // namespace net | 865 } // namespace net |
| OLD | NEW |