Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include <string> | |
| 6 | |
| 7 #include "base/memory/ref_counted.h" | |
| 8 #include "base/memory/scoped_vector.h" | |
| 9 #include "base/stringprintf.h" | |
| 10 #include "base/utf_string_conversions.h" | |
| 11 #include "net/base/address_list.h" | |
| 12 #include "net/base/host_cache.h" | |
| 13 #include "net/base/host_resolver_impl.h" | |
| 14 #include "net/base/host_resolver_proc.h" | |
| 15 #include "net/base/io_buffer.h" | |
| 16 #include "net/base/net_errors.h" | |
| 17 #include "net/base/net_util.h" | |
| 18 #include "net/base/request_priority.h" | |
| 19 #include "net/base/ssl_config_service_defaults.h" | |
| 20 #include "net/http/http_auth_handler_mock.h" | |
| 21 #include "net/http/http_network_session.h" | |
| 22 #include "net/http/http_network_transaction.h" | |
| 23 #include "net/http/http_request_info.h" | |
| 24 #include "net/http/http_server_properties.h" | |
| 25 #include "net/proxy/proxy_service.h" | |
| 26 #include "net/socket/client_socket_handle.h" | |
| 27 #include "net/socket/client_socket_pool_histograms.h" | |
| 28 #include "net/socket/socket_test_util.h" | |
| 29 #include "testing/gmock/include/gmock/gmock.h" | |
| 30 #include "testing/gtest/include/gtest/gtest.h" | |
| 31 | |
| 32 using testing::StrEq; | |
| 33 | |
| 34 namespace net { | |
| 35 | |
| 36 class DummySocketParams : public base::RefCounted<DummySocketParams> { | |
| 37 private: | |
| 38 friend class base::RefCounted<DummySocketParams>; | |
| 39 }; | |
| 40 | |
| 41 REGISTER_SOCKET_PARAMS_FOR_POOL(MockTransportClientSocketPool, | |
| 42 DummySocketParams); | |
| 43 | |
| 44 class DummyHttpServerProperties : public HttpServerProperties { | |
|
mmenke
2011/11/07 16:53:46
I don't think this class is necessary. We should
James Simonsen
2011/11/07 20:30:29
Done.
| |
| 45 public: | |
| 46 virtual void Clear() OVERRIDE { } | |
| 47 virtual bool SupportsSpdy(const HostPortPair& server) const OVERRIDE { | |
| 48 return false; | |
| 49 } | |
| 50 virtual void SetSupportsSpdy(const HostPortPair& server, | |
| 51 bool support_spdy) OVERRIDE { } | |
| 52 virtual bool HasAlternateProtocol(const HostPortPair& server) const OVERRIDE { | |
| 53 return false; | |
| 54 } | |
| 55 virtual PortAlternateProtocolPair GetAlternateProtocol( | |
| 56 const HostPortPair& server) const OVERRIDE { | |
| 57 return PortAlternateProtocolPair(); | |
| 58 } | |
| 59 virtual void SetAlternateProtocol( | |
| 60 const HostPortPair& server, uint16 alternate_port, | |
| 61 AlternateProtocol alternate_protocol) OVERRIDE { } | |
| 62 virtual void SetBrokenAlternateProtocol( | |
| 63 const HostPortPair& server) OVERRIDE { } | |
| 64 virtual const AlternateProtocolMap& alternate_protocol_map() const OVERRIDE { | |
| 65 return alternate_protocol_map_; | |
| 66 } | |
| 67 private: | |
| 68 AlternateProtocolMap alternate_protocol_map_; | |
| 69 }; | |
| 70 | |
| 71 class DummyHostResolverProc : public HostResolverProc { | |
|
mmenke
2011/11/07 16:53:46
I don't think this class is needed, either. We sh
James Simonsen
2011/11/07 20:30:29
Done.
| |
| 72 public: | |
| 73 DummyHostResolverProc() : HostResolverProc(NULL) { } | |
| 74 virtual int Resolve(const std::string& host, | |
| 75 AddressFamily address_family, | |
| 76 HostResolverFlags host_resolver_flags, | |
| 77 AddressList* addrlist, | |
| 78 int* os_error) OVERRIDE { | |
| 79 IPAddressNumber address; | |
| 80 address.push_back(0127); | |
| 81 address.push_back(00); | |
| 82 address.push_back(00); | |
| 83 address.push_back(01); | |
| 84 *addrlist = AddressList::CreateFromIPAddress(address, 123); | |
| 85 return OK; | |
| 86 } | |
| 87 }; | |
| 88 | |
| 89 class HttpPipelinedNetworkTransactionTest : public testing::Test { | |
| 90 public: | |
| 91 HttpPipelinedNetworkTransactionTest() | |
| 92 : histograms_("a"), | |
| 93 pool_(1, 1, &histograms_, &factory_) { | |
| 94 } | |
| 95 | |
| 96 void SetUp() { | |
|
mmenke
2011/11/07 16:53:46
virtual/OVERRIDE for this, and the next one, too.
James Simonsen
2011/11/07 20:30:29
Done.
| |
| 97 HttpStreamFactory::set_http_pipelining_enabled(true); | |
| 98 } | |
| 99 | |
| 100 void TearDown() { | |
| 101 MessageLoop::current()->RunAllPending(); | |
| 102 } | |
| 103 | |
| 104 void Initialize() { | |
|
mmenke
2011/11/07 16:53:46
Any reason not to do this in SetUp? It's called o
James Simonsen
2011/11/07 20:30:29
It's the ReusesOnSpaceAvailable test that screws i
mmenke
2011/11/08 18:12:41
You could just have a function to create the sessi
| |
| 105 HttpNetworkSession::Params session_params; | |
| 106 session_params.client_socket_factory = &factory_; | |
| 107 session_params.proxy_service = ProxyService::CreateDirect(); | |
| 108 session_params.host_resolver = new HostResolverImpl( | |
|
mmenke
2011/11/07 16:53:46
None of these will be owned by the HttpNetworkSess
James Simonsen
2011/11/07 20:30:29
Bah. I even ran valgrind ahead of time, but leak c
| |
| 109 new DummyHostResolverProc, HostCache::CreateDefaultCache(), 1, 1, NULL); | |
| 110 session_params.ssl_config_service = new SSLConfigServiceDefaults; | |
| 111 session_params.http_auth_handler_factory = auth_handler_factory_ = | |
| 112 new HttpAuthHandlerMock::Factory(); | |
| 113 session_params.http_server_properties = new DummyHttpServerProperties; | |
| 114 session_ = new HttpNetworkSession(session_params); | |
| 115 } | |
| 116 | |
| 117 void AddExpectedConnection(MockRead* reads, size_t reads_count, | |
| 118 MockWrite* writes, size_t writes_count) { | |
| 119 DeterministicSocketData* data = new DeterministicSocketData( | |
| 120 reads, reads_count, writes, writes_count); | |
| 121 data->set_connect_data(MockConnect(false, 0)); | |
| 122 if (reads_count || writes_count) { | |
| 123 data->StopAfter(reads_count + writes_count); | |
| 124 } | |
| 125 factory_.AddSocketDataProvider(data); | |
| 126 data_vector_.push_back(data); | |
| 127 } | |
| 128 | |
| 129 const HttpRequestInfo* GetRequestInfo(const char* filename) { | |
| 130 std::string url = StringPrintf("http://localhost/%s", filename); | |
| 131 HttpRequestInfo* request_info = new HttpRequestInfo; | |
| 132 request_info->url = GURL(url); | |
| 133 request_info->method = "GET"; | |
| 134 request_info_vector_.push_back(request_info); | |
| 135 return request_info; | |
| 136 } | |
| 137 | |
| 138 void ExpectResponse(const std::string& expected, | |
| 139 HttpNetworkTransaction& transaction) { | |
| 140 scoped_refptr<IOBuffer> buffer(new IOBuffer(expected.size())); | |
| 141 EXPECT_EQ(static_cast<int>(expected.size()), | |
| 142 transaction.Read(buffer.get(), expected.size(), &callback_)); | |
| 143 std::string actual(buffer->data(), expected.size()); | |
| 144 EXPECT_THAT(actual, StrEq(expected)); | |
| 145 EXPECT_EQ(OK, transaction.Read(buffer.get(), expected.size(), &callback_)); | |
| 146 } | |
| 147 | |
| 148 void PipelineTwoRequests() { | |
|
mmenke
2011/11/07 16:53:46
nit: CompleteTwoRequests, maybe? They're not exa
James Simonsen
2011/11/07 20:30:29
Done.
| |
| 149 HttpNetworkTransaction one_transaction(session_.get()); | |
| 150 TestOldCompletionCallback one_callback; | |
| 151 EXPECT_EQ(ERR_IO_PENDING, | |
| 152 one_transaction.Start(GetRequestInfo("one.html"), &one_callback, | |
| 153 BoundNetLog())); | |
| 154 EXPECT_EQ(OK, one_callback.WaitForResult()); | |
| 155 | |
| 156 HttpNetworkTransaction two_transaction(session_.get()); | |
| 157 TestOldCompletionCallback two_callback; | |
| 158 EXPECT_EQ(ERR_IO_PENDING, | |
| 159 two_transaction.Start(GetRequestInfo("two.html"), &two_callback, | |
| 160 BoundNetLog())); | |
| 161 | |
| 162 ExpectResponse("one.html", one_transaction); | |
| 163 EXPECT_EQ(OK, two_callback.WaitForResult()); | |
| 164 ExpectResponse("two.html", two_transaction); | |
| 165 } | |
| 166 | |
| 167 DeterministicMockClientSocketFactory factory_; | |
| 168 ClientSocketPoolHistograms histograms_; | |
| 169 MockTransportClientSocketPool pool_; | |
| 170 std::vector<scoped_refptr<DeterministicSocketData> > data_vector_; | |
| 171 HttpAuthHandlerMock::Factory* auth_handler_factory_; | |
| 172 scoped_refptr<HttpNetworkSession> session_; | |
| 173 | |
| 174 SSLConfig ssl_config_; | |
| 175 ProxyInfo proxy_info_; | |
| 176 TestOldCompletionCallback callback_; | |
| 177 ScopedVector<HttpRequestInfo> request_info_vector_; | |
| 178 }; | |
| 179 | |
| 180 TEST_F(HttpPipelinedNetworkTransactionTest, OneRequest) { | |
| 181 Initialize(); | |
| 182 | |
| 183 MockWrite writes[] = { | |
| 184 MockWrite(false, 0, "GET /test.html HTTP/1.1\r\n" | |
| 185 "Host: localhost\r\n" | |
| 186 "Connection: keep-alive\r\n\r\n"), | |
| 187 }; | |
| 188 MockRead reads[] = { | |
| 189 MockRead(false, 1, "HTTP/1.1 200 OK\r\n"), | |
| 190 MockRead(false, 2, "Content-Length: 9\r\n\r\n"), | |
| 191 MockRead(false, 3, "test.html"), | |
| 192 }; | |
| 193 AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes)); | |
| 194 | |
| 195 HttpNetworkTransaction transaction(session_.get()); | |
| 196 EXPECT_EQ(ERR_IO_PENDING, | |
| 197 transaction.Start(GetRequestInfo("test.html"), &callback_, | |
| 198 BoundNetLog())); | |
| 199 EXPECT_EQ(OK, callback_.WaitForResult()); | |
| 200 ExpectResponse("test.html", transaction); | |
| 201 } | |
| 202 | |
| 203 TEST_F(HttpPipelinedNetworkTransactionTest, ReusePipeline) { | |
| 204 Initialize(); | |
| 205 | |
| 206 MockWrite writes[] = { | |
| 207 MockWrite(false, 0, "GET /one.html HTTP/1.1\r\n" | |
| 208 "Host: localhost\r\n" | |
| 209 "Connection: keep-alive\r\n\r\n"), | |
| 210 MockWrite(false, 4, "GET /two.html HTTP/1.1\r\n" | |
| 211 "Host: localhost\r\n" | |
| 212 "Connection: keep-alive\r\n\r\n"), | |
| 213 }; | |
| 214 MockRead reads[] = { | |
| 215 MockRead(false, 1, "HTTP/1.1 200 OK\r\n"), | |
| 216 MockRead(false, 2, "Content-Length: 8\r\n\r\n"), | |
| 217 MockRead(false, 3, "one.html"), | |
| 218 MockRead(false, 5, "HTTP/1.1 200 OK\r\n"), | |
| 219 MockRead(false, 6, "Content-Length: 8\r\n\r\n"), | |
| 220 MockRead(false, 7, "two.html"), | |
| 221 }; | |
| 222 AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes)); | |
| 223 | |
| 224 PipelineTwoRequests(); | |
| 225 } | |
| 226 | |
| 227 TEST_F(HttpPipelinedNetworkTransactionTest, ReusesOnSpaceAvailable) { | |
| 228 int old_max_sockets = ClientSocketPoolManager::max_sockets_per_group(); | |
| 229 ClientSocketPoolManager::set_max_sockets_per_group(1); | |
| 230 Initialize(); | |
| 231 | |
| 232 MockWrite writes[] = { | |
| 233 MockWrite(false, 0, "GET /one.html HTTP/1.1\r\n" | |
| 234 "Host: localhost\r\n" | |
| 235 "Connection: keep-alive\r\n\r\n"), | |
| 236 MockWrite(false, 4, "GET /two.html HTTP/1.1\r\n" | |
| 237 "Host: localhost\r\n" | |
| 238 "Connection: keep-alive\r\n\r\n"), | |
| 239 MockWrite(false, 7, "GET /three.html HTTP/1.1\r\n" | |
| 240 "Host: localhost\r\n" | |
| 241 "Connection: keep-alive\r\n\r\n"), | |
| 242 MockWrite(false, 12, "GET /four.html HTTP/1.1\r\n" | |
| 243 "Host: localhost\r\n" | |
| 244 "Connection: keep-alive\r\n\r\n"), | |
| 245 }; | |
| 246 MockRead reads[] = { | |
| 247 MockRead(false, 1, "HTTP/1.1 200 OK\r\n"), | |
| 248 MockRead(false, 2, "Content-Length: 8\r\n\r\n"), | |
| 249 MockRead(false, 3, "one.html"), | |
| 250 MockRead(false, 5, "HTTP/1.1 200 OK\r\n"), | |
| 251 MockRead(false, 6, "Content-Length: 8\r\n\r\n"), | |
| 252 MockRead(false, 8, "two.html"), | |
| 253 MockRead(false, 9, "HTTP/1.1 200 OK\r\n"), | |
| 254 MockRead(false, 10, "Content-Length: 10\r\n\r\n"), | |
| 255 MockRead(false, 11, "three.html"), | |
| 256 MockRead(false, 13, "HTTP/1.1 200 OK\r\n"), | |
| 257 MockRead(false, 14, "Content-Length: 9\r\n\r\n"), | |
| 258 MockRead(false, 15, "four.html"), | |
| 259 }; | |
| 260 AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes)); | |
| 261 | |
| 262 scoped_ptr<HttpNetworkTransaction> one_transaction( | |
| 263 new HttpNetworkTransaction(session_.get())); | |
| 264 TestOldCompletionCallback one_callback; | |
| 265 EXPECT_EQ(ERR_IO_PENDING, | |
| 266 one_transaction->Start(GetRequestInfo("one.html"), &one_callback, | |
| 267 BoundNetLog())); | |
| 268 EXPECT_EQ(OK, one_callback.WaitForResult()); | |
| 269 | |
| 270 HttpNetworkTransaction two_transaction(session_.get()); | |
| 271 TestOldCompletionCallback two_callback; | |
| 272 EXPECT_EQ(ERR_IO_PENDING, | |
| 273 two_transaction.Start(GetRequestInfo("two.html"), &two_callback, | |
| 274 BoundNetLog())); | |
| 275 | |
| 276 HttpNetworkTransaction three_transaction(session_.get()); | |
| 277 TestOldCompletionCallback three_callback; | |
| 278 EXPECT_EQ(ERR_IO_PENDING, | |
| 279 three_transaction.Start(GetRequestInfo("three.html"), | |
| 280 &three_callback, BoundNetLog())); | |
| 281 | |
| 282 HttpNetworkTransaction four_transaction(session_.get()); | |
| 283 TestOldCompletionCallback four_callback; | |
| 284 EXPECT_EQ(ERR_IO_PENDING, | |
| 285 four_transaction.Start(GetRequestInfo("four.html"), &four_callback, | |
| 286 BoundNetLog())); | |
| 287 | |
| 288 ExpectResponse("one.html", *one_transaction.get()); | |
| 289 EXPECT_EQ(OK, two_callback.WaitForResult()); | |
| 290 ExpectResponse("two.html", two_transaction); | |
| 291 EXPECT_EQ(OK, three_callback.WaitForResult()); | |
| 292 ExpectResponse("three.html", three_transaction); | |
| 293 | |
| 294 one_transaction.reset(); | |
| 295 EXPECT_EQ(OK, four_callback.WaitForResult()); | |
| 296 ExpectResponse("four.html", four_transaction); | |
| 297 | |
| 298 ClientSocketPoolManager::set_max_sockets_per_group(old_max_sockets); | |
| 299 } | |
| 300 | |
| 301 TEST_F(HttpPipelinedNetworkTransactionTest, UnknownSizeEvictsToNewPipeline) { | |
| 302 Initialize(); | |
| 303 | |
| 304 MockWrite writes[] = { | |
| 305 MockWrite(false, 0, "GET /one.html HTTP/1.1\r\n" | |
| 306 "Host: localhost\r\n" | |
| 307 "Connection: keep-alive\r\n\r\n"), | |
| 308 MockWrite(false, 4, "GET /two.html HTTP/1.1\r\n" | |
| 309 "Host: localhost\r\n" | |
| 310 "Connection: keep-alive\r\n\r\n"), | |
| 311 }; | |
| 312 MockRead reads[] = { | |
| 313 MockRead(false, 1, "HTTP/1.1 200 OK\r\n\r\n"), | |
| 314 MockRead(false, 2, "one.html"), | |
| 315 MockRead(false, OK, 3), | |
| 316 }; | |
| 317 AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes)); | |
| 318 | |
| 319 MockWrite writes2[] = { | |
| 320 MockWrite(false, 0, "GET /two.html HTTP/1.1\r\n" | |
| 321 "Host: localhost\r\n" | |
| 322 "Connection: keep-alive\r\n\r\n"), | |
| 323 }; | |
| 324 MockRead reads2[] = { | |
| 325 MockRead(false, 1, "HTTP/1.1 200 OK\r\n"), | |
| 326 MockRead(false, 2, "Content-Length: 8\r\n\r\n"), | |
| 327 MockRead(false, 3, "two.html"), | |
| 328 }; | |
| 329 AddExpectedConnection(reads2, arraysize(reads2), writes2, arraysize(writes2)); | |
| 330 | |
| 331 PipelineTwoRequests(); | |
| 332 } | |
| 333 | |
| 334 TEST_F(HttpPipelinedNetworkTransactionTest, ConnectionCloseEvictToNewPipeline) { | |
| 335 Initialize(); | |
| 336 | |
| 337 MockWrite writes[] = { | |
| 338 MockWrite(false, 0, "GET /one.html HTTP/1.1\r\n" | |
| 339 "Host: localhost\r\n" | |
| 340 "Connection: keep-alive\r\n\r\n"), | |
| 341 MockWrite(false, 4, "GET /two.html HTTP/1.1\r\n" | |
| 342 "Host: localhost\r\n" | |
| 343 "Connection: keep-alive\r\n\r\n"), | |
| 344 }; | |
| 345 MockRead reads[] = { | |
| 346 MockRead(false, 1, "HTTP/1.1 200 OK\r\n"), | |
| 347 MockRead(false, 2, "Content-Length: 8\r\n\r\n"), | |
| 348 MockRead(false, 3, "one.html"), | |
| 349 MockRead(false, ERR_SOCKET_NOT_CONNECTED, 5), | |
| 350 }; | |
| 351 AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes)); | |
| 352 | |
| 353 MockWrite writes2[] = { | |
| 354 MockWrite(false, 0, "GET /two.html HTTP/1.1\r\n" | |
| 355 "Host: localhost\r\n" | |
| 356 "Connection: keep-alive\r\n\r\n"), | |
| 357 }; | |
| 358 MockRead reads2[] = { | |
| 359 MockRead(false, 1, "HTTP/1.1 200 OK\r\n"), | |
| 360 MockRead(false, 2, "Content-Length: 8\r\n\r\n"), | |
| 361 MockRead(false, 3, "two.html"), | |
| 362 }; | |
| 363 AddExpectedConnection(reads2, arraysize(reads2), writes2, arraysize(writes2)); | |
| 364 | |
| 365 PipelineTwoRequests(); | |
| 366 } | |
| 367 | |
| 368 TEST_F(HttpPipelinedNetworkTransactionTest, ErrorEvictsToNewPipeline) { | |
| 369 Initialize(); | |
| 370 | |
| 371 MockWrite writes[] = { | |
| 372 MockWrite(false, 0, "GET /one.html HTTP/1.1\r\n" | |
| 373 "Host: localhost\r\n" | |
| 374 "Connection: keep-alive\r\n\r\n"), | |
| 375 MockWrite(false, 3, "GET /two.html HTTP/1.1\r\n" | |
| 376 "Host: localhost\r\n" | |
| 377 "Connection: keep-alive\r\n\r\n"), | |
| 378 }; | |
| 379 MockRead reads[] = { | |
| 380 MockRead(false, 1, "HTTP/1.1 200 OK\r\n\r\n"), | |
| 381 MockRead(false, ERR_FAILED, 2), | |
| 382 }; | |
| 383 AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes)); | |
| 384 | |
| 385 MockWrite writes2[] = { | |
| 386 MockWrite(false, 0, "GET /two.html HTTP/1.1\r\n" | |
| 387 "Host: localhost\r\n" | |
| 388 "Connection: keep-alive\r\n\r\n"), | |
| 389 }; | |
| 390 MockRead reads2[] = { | |
| 391 MockRead(false, 1, "HTTP/1.1 200 OK\r\n"), | |
| 392 MockRead(false, 2, "Content-Length: 8\r\n\r\n"), | |
| 393 MockRead(false, 3, "two.html"), | |
| 394 }; | |
| 395 AddExpectedConnection(reads2, arraysize(reads2), writes2, arraysize(writes2)); | |
| 396 | |
| 397 HttpNetworkTransaction one_transaction(session_.get()); | |
| 398 TestOldCompletionCallback one_callback; | |
| 399 EXPECT_EQ(ERR_IO_PENDING, | |
| 400 one_transaction.Start(GetRequestInfo("one.html"), &one_callback, | |
| 401 BoundNetLog())); | |
| 402 EXPECT_EQ(OK, one_callback.WaitForResult()); | |
| 403 | |
| 404 HttpNetworkTransaction two_transaction(session_.get()); | |
| 405 TestOldCompletionCallback two_callback; | |
| 406 EXPECT_EQ(ERR_IO_PENDING, | |
| 407 two_transaction.Start(GetRequestInfo("two.html"), &two_callback, | |
| 408 BoundNetLog())); | |
| 409 | |
| 410 scoped_refptr<IOBuffer> buffer(new IOBuffer(1)); | |
| 411 EXPECT_EQ(ERR_FAILED, one_transaction.Read(buffer.get(), 1, &callback_)); | |
| 412 EXPECT_EQ(OK, two_callback.WaitForResult()); | |
| 413 ExpectResponse("two.html", two_transaction); | |
| 414 } | |
| 415 | |
| 416 TEST_F(HttpPipelinedNetworkTransactionTest, SendErrorEvictsToNewPipeline) { | |
| 417 Initialize(); | |
| 418 | |
| 419 MockWrite writes[] = { | |
| 420 MockWrite(true, ERR_FAILED, 0), | |
| 421 }; | |
| 422 AddExpectedConnection(NULL, 0, writes, arraysize(writes)); | |
| 423 | |
| 424 MockWrite writes2[] = { | |
| 425 MockWrite(false, 0, "GET /two.html HTTP/1.1\r\n" | |
| 426 "Host: localhost\r\n" | |
| 427 "Connection: keep-alive\r\n\r\n"), | |
| 428 }; | |
| 429 MockRead reads2[] = { | |
| 430 MockRead(false, 1, "HTTP/1.1 200 OK\r\n"), | |
| 431 MockRead(false, 2, "Content-Length: 8\r\n\r\n"), | |
| 432 MockRead(false, 3, "two.html"), | |
| 433 }; | |
| 434 AddExpectedConnection(reads2, arraysize(reads2), writes2, arraysize(writes2)); | |
| 435 | |
| 436 HttpNetworkTransaction one_transaction(session_.get()); | |
| 437 TestOldCompletionCallback one_callback; | |
| 438 EXPECT_EQ(ERR_IO_PENDING, | |
| 439 one_transaction.Start(GetRequestInfo("one.html"), &one_callback, | |
| 440 BoundNetLog())); | |
| 441 | |
| 442 HttpNetworkTransaction two_transaction(session_.get()); | |
| 443 TestOldCompletionCallback two_callback; | |
| 444 EXPECT_EQ(ERR_IO_PENDING, | |
| 445 two_transaction.Start(GetRequestInfo("two.html"), &two_callback, | |
| 446 BoundNetLog())); | |
| 447 | |
| 448 data_vector_[0]->RunFor(1); | |
| 449 EXPECT_EQ(ERR_FAILED, one_callback.WaitForResult()); | |
| 450 | |
| 451 EXPECT_EQ(OK, two_callback.WaitForResult()); | |
| 452 ExpectResponse("two.html", two_transaction); | |
| 453 } | |
| 454 | |
| 455 TEST_F(HttpPipelinedNetworkTransactionTest, BasicHttpAuthentication) { | |
| 456 Initialize(); | |
| 457 | |
| 458 MockWrite writes[] = { | |
| 459 MockWrite(false, 0, "GET /one.html HTTP/1.1\r\n" | |
| 460 "Host: localhost\r\n" | |
| 461 "Connection: keep-alive\r\n\r\n"), | |
| 462 MockWrite(false, 5, "GET /one.html HTTP/1.1\r\n" | |
| 463 "Host: localhost\r\n" | |
| 464 "Connection: keep-alive\r\n" | |
| 465 "Authorization: auth_token\r\n\r\n"), | |
| 466 }; | |
| 467 MockRead reads[] = { | |
| 468 MockRead(false, 1, "HTTP/1.1 401 Authentication Required\r\n"), | |
| 469 MockRead(false, 2, "WWW-Authenticate: Basic realm=\"Secure Area\"\r\n"), | |
| 470 MockRead(false, 3, "Content-Length: 20\r\n\r\n"), | |
| 471 MockRead(false, 4, "needs authentication"), | |
| 472 MockRead(false, 6, "HTTP/1.1 200 OK\r\n"), | |
| 473 MockRead(false, 7, "Content-Length: 8\r\n\r\n"), | |
| 474 MockRead(false, 8, "one.html"), | |
| 475 }; | |
| 476 AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes)); | |
| 477 | |
| 478 HttpAuthHandlerMock* mock_auth = new HttpAuthHandlerMock; | |
| 479 std::string challenge_text = "Basic"; | |
| 480 HttpAuth::ChallengeTokenizer challenge(challenge_text.begin(), | |
| 481 challenge_text.end()); | |
| 482 GURL origin("localhost"); | |
| 483 EXPECT_TRUE(mock_auth->InitFromChallenge(&challenge, | |
| 484 HttpAuth::AUTH_SERVER, | |
| 485 origin, | |
| 486 BoundNetLog())); | |
| 487 auth_handler_factory_->AddMockHandler(mock_auth, HttpAuth::AUTH_SERVER); | |
| 488 | |
| 489 HttpNetworkTransaction transaction(session_.get()); | |
| 490 EXPECT_EQ( | |
| 491 ERR_IO_PENDING, | |
| 492 transaction.Start(GetRequestInfo("one.html"), &callback_, BoundNetLog())); | |
| 493 EXPECT_EQ(OK, callback_.WaitForResult()); | |
| 494 | |
| 495 AuthCredentials credentials(ASCIIToUTF16("user"), ASCIIToUTF16("pass")); | |
| 496 EXPECT_EQ(OK, transaction.RestartWithAuth(credentials, &callback_)); | |
| 497 | |
| 498 ExpectResponse("one.html", transaction); | |
| 499 } | |
| 500 | |
| 501 } // namespace net | |
| OLD | NEW |