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/io_buffer.h" | |
| 14 #include "net/base/mock_host_resolver.h" | |
| 15 #include "net/base/net_errors.h" | |
| 16 #include "net/base/net_util.h" | |
| 17 #include "net/base/request_priority.h" | |
| 18 #include "net/base/ssl_config_service_defaults.h" | |
| 19 #include "net/http/http_auth_handler_mock.h" | |
| 20 #include "net/http/http_network_session.h" | |
| 21 #include "net/http/http_network_transaction.h" | |
| 22 #include "net/http/http_request_info.h" | |
| 23 #include "net/http/http_server_properties_impl.h" | |
| 24 #include "net/proxy/proxy_service.h" | |
| 25 #include "net/socket/client_socket_handle.h" | |
| 26 #include "net/socket/client_socket_pool_histograms.h" | |
| 27 #include "net/socket/socket_test_util.h" | |
| 28 #include "testing/gmock/include/gmock/gmock.h" | |
| 29 #include "testing/gtest/include/gtest/gtest.h" | |
| 30 | |
| 31 using testing::StrEq; | |
| 32 | |
| 33 namespace net { | |
| 34 | |
|
willchan no longer on Chromium
2011/11/08 22:44:54
If nothing needs to be friended or otherwise exter
James Simonsen
2011/11/09 05:24:41
Done.
| |
| 35 class DummySocketParams : public base::RefCounted<DummySocketParams> { | |
|
mmenke
2011/11/08 18:12:41
Come to think of it, this isn't needed, either.
James Simonsen
2011/11/09 05:24:41
Done.
| |
| 36 private: | |
| 37 friend class base::RefCounted<DummySocketParams>; | |
| 38 }; | |
| 39 | |
| 40 REGISTER_SOCKET_PARAMS_FOR_POOL(MockTransportClientSocketPool, | |
| 41 DummySocketParams); | |
| 42 | |
| 43 class HttpPipelinedNetworkTransactionTest : public testing::Test { | |
| 44 public: | |
| 45 HttpPipelinedNetworkTransactionTest() | |
| 46 : histograms_("a"), | |
| 47 pool_(1, 1, &histograms_, &factory_) { | |
| 48 } | |
| 49 | |
| 50 virtual void SetUp() OVERRIDE { | |
| 51 HttpStreamFactory::set_http_pipelining_enabled(true); | |
|
mmenke
2011/11/08 18:12:41
This should be set to false again (Or restored to
James Simonsen
2011/11/09 05:24:41
Done.
| |
| 52 } | |
| 53 | |
| 54 virtual void TearDown() OVERRIDE { | |
| 55 MessageLoop::current()->RunAllPending(); | |
| 56 } | |
| 57 | |
| 58 void Initialize() { | |
| 59 proxy_service_.reset(ProxyService::CreateDirect()); | |
| 60 mock_resolver_.reset(new MockHostResolver); | |
|
mmenke
2011/11/08 18:12:41
nit: You don't need to use a scoped_ptr for eithe
James Simonsen
2011/11/09 05:24:41
I may be misunderstanding you... If I remove the s
mmenke
2011/11/09 16:10:58
HttpPipelinedNetworkTransactionTest doesn't need p
| |
| 61 mock_resolver_->rules()->AddRule("localhost", "127.0.0.1"); | |
|
mmenke
2011/11/08 18:12:41
nit: Not needed. By default, the MockHostResolve
James Simonsen
2011/11/09 05:24:41
Done.
| |
| 62 auth_handler_factory_.reset(new HttpAuthHandlerMock::Factory()); | |
| 63 http_server_properties_.reset(new HttpServerPropertiesImpl); | |
| 64 | |
| 65 HttpNetworkSession::Params session_params; | |
| 66 session_params.client_socket_factory = &factory_; | |
| 67 session_params.proxy_service = proxy_service_.get(); | |
| 68 session_params.host_resolver = mock_resolver_.get(); | |
| 69 session_params.ssl_config_service = new SSLConfigServiceDefaults; | |
|
mmenke
2011/11/08 18:12:41
|ssl_config_| should be a scoped_refptr, and you s
James Simonsen
2011/11/09 05:24:41
Done.
| |
| 70 session_params.http_auth_handler_factory = auth_handler_factory_.get(); | |
| 71 session_params.http_server_properties = http_server_properties_.get(); | |
| 72 session_ = new HttpNetworkSession(session_params); | |
| 73 } | |
| 74 | |
| 75 void AddExpectedConnection(MockRead* reads, size_t reads_count, | |
| 76 MockWrite* writes, size_t writes_count) { | |
| 77 DeterministicSocketData* data = new DeterministicSocketData( | |
| 78 reads, reads_count, writes, writes_count); | |
| 79 data->set_connect_data(MockConnect(false, 0)); | |
| 80 if (reads_count || writes_count) { | |
| 81 data->StopAfter(reads_count + writes_count); | |
| 82 } | |
| 83 factory_.AddSocketDataProvider(data); | |
| 84 data_vector_.push_back(data); | |
| 85 } | |
| 86 | |
| 87 const HttpRequestInfo* GetRequestInfo(const char* filename) { | |
| 88 std::string url = StringPrintf("http://localhost/%s", filename); | |
| 89 HttpRequestInfo* request_info = new HttpRequestInfo; | |
| 90 request_info->url = GURL(url); | |
| 91 request_info->method = "GET"; | |
| 92 request_info_vector_.push_back(request_info); | |
| 93 return request_info; | |
| 94 } | |
| 95 | |
| 96 void ExpectResponse(const std::string& expected, | |
| 97 HttpNetworkTransaction& transaction) { | |
| 98 scoped_refptr<IOBuffer> buffer(new IOBuffer(expected.size())); | |
| 99 EXPECT_EQ(static_cast<int>(expected.size()), | |
| 100 transaction.Read(buffer.get(), expected.size(), &callback_)); | |
| 101 std::string actual(buffer->data(), expected.size()); | |
| 102 EXPECT_THAT(actual, StrEq(expected)); | |
| 103 EXPECT_EQ(OK, transaction.Read(buffer.get(), expected.size(), &callback_)); | |
| 104 } | |
| 105 | |
| 106 void CompleteTwoRequests() { | |
| 107 HttpNetworkTransaction one_transaction(session_.get()); | |
| 108 TestOldCompletionCallback one_callback; | |
| 109 EXPECT_EQ(ERR_IO_PENDING, | |
| 110 one_transaction.Start(GetRequestInfo("one.html"), &one_callback, | |
| 111 BoundNetLog())); | |
| 112 EXPECT_EQ(OK, one_callback.WaitForResult()); | |
| 113 | |
| 114 HttpNetworkTransaction two_transaction(session_.get()); | |
| 115 TestOldCompletionCallback two_callback; | |
| 116 EXPECT_EQ(ERR_IO_PENDING, | |
| 117 two_transaction.Start(GetRequestInfo("two.html"), &two_callback, | |
| 118 BoundNetLog())); | |
| 119 | |
| 120 ExpectResponse("one.html", one_transaction); | |
| 121 EXPECT_EQ(OK, two_callback.WaitForResult()); | |
| 122 ExpectResponse("two.html", two_transaction); | |
| 123 } | |
| 124 | |
| 125 DeterministicMockClientSocketFactory factory_; | |
| 126 ClientSocketPoolHistograms histograms_; | |
| 127 MockTransportClientSocketPool pool_; | |
| 128 std::vector<scoped_refptr<DeterministicSocketData> > data_vector_; | |
| 129 | |
| 130 scoped_ptr<ProxyService> proxy_service_; | |
| 131 scoped_ptr<MockHostResolver> mock_resolver_; | |
| 132 scoped_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory_; | |
| 133 scoped_ptr<HttpServerPropertiesImpl> http_server_properties_; | |
| 134 scoped_refptr<HttpNetworkSession> session_; | |
| 135 | |
| 136 SSLConfig ssl_config_; | |
|
mmenke
2011/11/08 18:12:41
Once you use this (As per comment above), you shou
James Simonsen
2011/11/09 05:24:41
Done.
| |
| 137 ProxyInfo proxy_info_; | |
|
mmenke
2011/11/08 18:12:41
This is not used.
James Simonsen
2011/11/09 05:24:41
Done.
| |
| 138 TestOldCompletionCallback callback_; | |
| 139 ScopedVector<HttpRequestInfo> request_info_vector_; | |
| 140 }; | |
| 141 | |
| 142 TEST_F(HttpPipelinedNetworkTransactionTest, OneRequest) { | |
| 143 Initialize(); | |
| 144 | |
| 145 MockWrite writes[] = { | |
| 146 MockWrite(false, 0, "GET /test.html HTTP/1.1\r\n" | |
| 147 "Host: localhost\r\n" | |
| 148 "Connection: keep-alive\r\n\r\n"), | |
| 149 }; | |
| 150 MockRead reads[] = { | |
| 151 MockRead(false, 1, "HTTP/1.1 200 OK\r\n"), | |
| 152 MockRead(false, 2, "Content-Length: 9\r\n\r\n"), | |
| 153 MockRead(false, 3, "test.html"), | |
| 154 }; | |
| 155 AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes)); | |
| 156 | |
| 157 HttpNetworkTransaction transaction(session_.get()); | |
| 158 EXPECT_EQ(ERR_IO_PENDING, | |
| 159 transaction.Start(GetRequestInfo("test.html"), &callback_, | |
| 160 BoundNetLog())); | |
| 161 EXPECT_EQ(OK, callback_.WaitForResult()); | |
| 162 ExpectResponse("test.html", transaction); | |
| 163 } | |
| 164 | |
| 165 TEST_F(HttpPipelinedNetworkTransactionTest, ReusePipeline) { | |
| 166 Initialize(); | |
| 167 | |
| 168 MockWrite writes[] = { | |
| 169 MockWrite(false, 0, "GET /one.html HTTP/1.1\r\n" | |
| 170 "Host: localhost\r\n" | |
| 171 "Connection: keep-alive\r\n\r\n"), | |
| 172 MockWrite(false, 4, "GET /two.html HTTP/1.1\r\n" | |
|
mmenke
2011/11/08 18:12:41
I think it's a little odd that we always send the
James Simonsen
2011/11/09 05:24:41
Yeah, it makes the code uglier. But you're right,
| |
| 173 "Host: localhost\r\n" | |
| 174 "Connection: keep-alive\r\n\r\n"), | |
| 175 }; | |
| 176 MockRead reads[] = { | |
| 177 MockRead(false, 1, "HTTP/1.1 200 OK\r\n"), | |
| 178 MockRead(false, 2, "Content-Length: 8\r\n\r\n"), | |
| 179 MockRead(false, 3, "one.html"), | |
| 180 MockRead(false, 5, "HTTP/1.1 200 OK\r\n"), | |
| 181 MockRead(false, 6, "Content-Length: 8\r\n\r\n"), | |
| 182 MockRead(false, 7, "two.html"), | |
| 183 }; | |
| 184 AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes)); | |
| 185 | |
| 186 CompleteTwoRequests(); | |
| 187 } | |
| 188 | |
| 189 TEST_F(HttpPipelinedNetworkTransactionTest, ReusesOnSpaceAvailable) { | |
| 190 int old_max_sockets = ClientSocketPoolManager::max_sockets_per_group(); | |
| 191 ClientSocketPoolManager::set_max_sockets_per_group(1); | |
| 192 Initialize(); | |
| 193 | |
| 194 MockWrite writes[] = { | |
| 195 MockWrite(false, 0, "GET /one.html HTTP/1.1\r\n" | |
| 196 "Host: localhost\r\n" | |
| 197 "Connection: keep-alive\r\n\r\n"), | |
| 198 MockWrite(false, 4, "GET /two.html HTTP/1.1\r\n" | |
| 199 "Host: localhost\r\n" | |
| 200 "Connection: keep-alive\r\n\r\n"), | |
| 201 MockWrite(false, 7, "GET /three.html HTTP/1.1\r\n" | |
| 202 "Host: localhost\r\n" | |
| 203 "Connection: keep-alive\r\n\r\n"), | |
| 204 MockWrite(false, 12, "GET /four.html HTTP/1.1\r\n" | |
| 205 "Host: localhost\r\n" | |
| 206 "Connection: keep-alive\r\n\r\n"), | |
| 207 }; | |
| 208 MockRead reads[] = { | |
| 209 MockRead(false, 1, "HTTP/1.1 200 OK\r\n"), | |
| 210 MockRead(false, 2, "Content-Length: 8\r\n\r\n"), | |
| 211 MockRead(false, 3, "one.html"), | |
| 212 MockRead(false, 5, "HTTP/1.1 200 OK\r\n"), | |
| 213 MockRead(false, 6, "Content-Length: 8\r\n\r\n"), | |
| 214 MockRead(false, 8, "two.html"), | |
| 215 MockRead(false, 9, "HTTP/1.1 200 OK\r\n"), | |
| 216 MockRead(false, 10, "Content-Length: 10\r\n\r\n"), | |
| 217 MockRead(false, 11, "three.html"), | |
| 218 MockRead(false, 13, "HTTP/1.1 200 OK\r\n"), | |
| 219 MockRead(false, 14, "Content-Length: 9\r\n\r\n"), | |
| 220 MockRead(false, 15, "four.html"), | |
| 221 }; | |
| 222 AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes)); | |
| 223 | |
| 224 scoped_ptr<HttpNetworkTransaction> one_transaction( | |
| 225 new HttpNetworkTransaction(session_.get())); | |
| 226 TestOldCompletionCallback one_callback; | |
| 227 EXPECT_EQ(ERR_IO_PENDING, | |
| 228 one_transaction->Start(GetRequestInfo("one.html"), &one_callback, | |
| 229 BoundNetLog())); | |
| 230 EXPECT_EQ(OK, one_callback.WaitForResult()); | |
| 231 | |
| 232 HttpNetworkTransaction two_transaction(session_.get()); | |
| 233 TestOldCompletionCallback two_callback; | |
| 234 EXPECT_EQ(ERR_IO_PENDING, | |
| 235 two_transaction.Start(GetRequestInfo("two.html"), &two_callback, | |
| 236 BoundNetLog())); | |
| 237 | |
| 238 HttpNetworkTransaction three_transaction(session_.get()); | |
| 239 TestOldCompletionCallback three_callback; | |
| 240 EXPECT_EQ(ERR_IO_PENDING, | |
| 241 three_transaction.Start(GetRequestInfo("three.html"), | |
| 242 &three_callback, BoundNetLog())); | |
| 243 | |
| 244 HttpNetworkTransaction four_transaction(session_.get()); | |
| 245 TestOldCompletionCallback four_callback; | |
| 246 EXPECT_EQ(ERR_IO_PENDING, | |
| 247 four_transaction.Start(GetRequestInfo("four.html"), &four_callback, | |
| 248 BoundNetLog())); | |
| 249 | |
| 250 ExpectResponse("one.html", *one_transaction.get()); | |
| 251 EXPECT_EQ(OK, two_callback.WaitForResult()); | |
| 252 ExpectResponse("two.html", two_transaction); | |
| 253 EXPECT_EQ(OK, three_callback.WaitForResult()); | |
| 254 ExpectResponse("three.html", three_transaction); | |
| 255 | |
| 256 one_transaction.reset(); | |
| 257 EXPECT_EQ(OK, four_callback.WaitForResult()); | |
| 258 ExpectResponse("four.html", four_transaction); | |
| 259 | |
| 260 ClientSocketPoolManager::set_max_sockets_per_group(old_max_sockets); | |
| 261 } | |
| 262 | |
| 263 TEST_F(HttpPipelinedNetworkTransactionTest, UnknownSizeEvictsToNewPipeline) { | |
| 264 Initialize(); | |
| 265 | |
| 266 MockWrite writes[] = { | |
| 267 MockWrite(false, 0, "GET /one.html HTTP/1.1\r\n" | |
| 268 "Host: localhost\r\n" | |
| 269 "Connection: keep-alive\r\n\r\n"), | |
| 270 MockWrite(false, 4, "GET /two.html HTTP/1.1\r\n" | |
| 271 "Host: localhost\r\n" | |
| 272 "Connection: keep-alive\r\n\r\n"), | |
| 273 }; | |
| 274 MockRead reads[] = { | |
| 275 MockRead(false, 1, "HTTP/1.1 200 OK\r\n\r\n"), | |
| 276 MockRead(false, 2, "one.html"), | |
| 277 MockRead(false, OK, 3), | |
| 278 }; | |
| 279 AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes)); | |
| 280 | |
| 281 MockWrite writes2[] = { | |
| 282 MockWrite(false, 0, "GET /two.html HTTP/1.1\r\n" | |
| 283 "Host: localhost\r\n" | |
| 284 "Connection: keep-alive\r\n\r\n"), | |
| 285 }; | |
| 286 MockRead reads2[] = { | |
| 287 MockRead(false, 1, "HTTP/1.1 200 OK\r\n"), | |
| 288 MockRead(false, 2, "Content-Length: 8\r\n\r\n"), | |
| 289 MockRead(false, 3, "two.html"), | |
| 290 }; | |
| 291 AddExpectedConnection(reads2, arraysize(reads2), writes2, arraysize(writes2)); | |
| 292 | |
| 293 CompleteTwoRequests(); | |
| 294 } | |
| 295 | |
| 296 TEST_F(HttpPipelinedNetworkTransactionTest, ConnectionCloseEvictToNewPipeline) { | |
| 297 Initialize(); | |
| 298 | |
| 299 MockWrite writes[] = { | |
| 300 MockWrite(false, 0, "GET /one.html HTTP/1.1\r\n" | |
| 301 "Host: localhost\r\n" | |
| 302 "Connection: keep-alive\r\n\r\n"), | |
| 303 MockWrite(false, 4, "GET /two.html HTTP/1.1\r\n" | |
| 304 "Host: localhost\r\n" | |
| 305 "Connection: keep-alive\r\n\r\n"), | |
| 306 }; | |
| 307 MockRead reads[] = { | |
| 308 MockRead(false, 1, "HTTP/1.1 200 OK\r\n"), | |
| 309 MockRead(false, 2, "Content-Length: 8\r\n\r\n"), | |
| 310 MockRead(false, 3, "one.html"), | |
| 311 MockRead(false, ERR_SOCKET_NOT_CONNECTED, 5), | |
| 312 }; | |
| 313 AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes)); | |
| 314 | |
| 315 MockWrite writes2[] = { | |
| 316 MockWrite(false, 0, "GET /two.html HTTP/1.1\r\n" | |
| 317 "Host: localhost\r\n" | |
| 318 "Connection: keep-alive\r\n\r\n"), | |
| 319 }; | |
| 320 MockRead reads2[] = { | |
| 321 MockRead(false, 1, "HTTP/1.1 200 OK\r\n"), | |
| 322 MockRead(false, 2, "Content-Length: 8\r\n\r\n"), | |
| 323 MockRead(false, 3, "two.html"), | |
| 324 }; | |
| 325 AddExpectedConnection(reads2, arraysize(reads2), writes2, arraysize(writes2)); | |
| 326 | |
| 327 CompleteTwoRequests(); | |
| 328 } | |
| 329 | |
| 330 TEST_F(HttpPipelinedNetworkTransactionTest, ErrorEvictsToNewPipeline) { | |
| 331 Initialize(); | |
| 332 | |
| 333 MockWrite writes[] = { | |
| 334 MockWrite(false, 0, "GET /one.html HTTP/1.1\r\n" | |
| 335 "Host: localhost\r\n" | |
| 336 "Connection: keep-alive\r\n\r\n"), | |
| 337 MockWrite(false, 3, "GET /two.html HTTP/1.1\r\n" | |
| 338 "Host: localhost\r\n" | |
| 339 "Connection: keep-alive\r\n\r\n"), | |
| 340 }; | |
| 341 MockRead reads[] = { | |
| 342 MockRead(false, 1, "HTTP/1.1 200 OK\r\n\r\n"), | |
| 343 MockRead(false, ERR_FAILED, 2), | |
| 344 }; | |
| 345 AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes)); | |
| 346 | |
| 347 MockWrite writes2[] = { | |
| 348 MockWrite(false, 0, "GET /two.html HTTP/1.1\r\n" | |
| 349 "Host: localhost\r\n" | |
| 350 "Connection: keep-alive\r\n\r\n"), | |
| 351 }; | |
| 352 MockRead reads2[] = { | |
| 353 MockRead(false, 1, "HTTP/1.1 200 OK\r\n"), | |
| 354 MockRead(false, 2, "Content-Length: 8\r\n\r\n"), | |
| 355 MockRead(false, 3, "two.html"), | |
| 356 }; | |
| 357 AddExpectedConnection(reads2, arraysize(reads2), writes2, arraysize(writes2)); | |
| 358 | |
| 359 HttpNetworkTransaction one_transaction(session_.get()); | |
| 360 TestOldCompletionCallback one_callback; | |
| 361 EXPECT_EQ(ERR_IO_PENDING, | |
| 362 one_transaction.Start(GetRequestInfo("one.html"), &one_callback, | |
| 363 BoundNetLog())); | |
| 364 EXPECT_EQ(OK, one_callback.WaitForResult()); | |
| 365 | |
| 366 HttpNetworkTransaction two_transaction(session_.get()); | |
| 367 TestOldCompletionCallback two_callback; | |
| 368 EXPECT_EQ(ERR_IO_PENDING, | |
| 369 two_transaction.Start(GetRequestInfo("two.html"), &two_callback, | |
| 370 BoundNetLog())); | |
| 371 | |
| 372 scoped_refptr<IOBuffer> buffer(new IOBuffer(1)); | |
| 373 EXPECT_EQ(ERR_FAILED, one_transaction.Read(buffer.get(), 1, &callback_)); | |
| 374 EXPECT_EQ(OK, two_callback.WaitForResult()); | |
| 375 ExpectResponse("two.html", two_transaction); | |
| 376 } | |
| 377 | |
| 378 TEST_F(HttpPipelinedNetworkTransactionTest, SendErrorEvictsToNewPipeline) { | |
| 379 Initialize(); | |
| 380 | |
| 381 MockWrite writes[] = { | |
| 382 MockWrite(true, ERR_FAILED, 0), | |
| 383 }; | |
| 384 AddExpectedConnection(NULL, 0, writes, arraysize(writes)); | |
| 385 | |
| 386 MockWrite writes2[] = { | |
| 387 MockWrite(false, 0, "GET /two.html HTTP/1.1\r\n" | |
| 388 "Host: localhost\r\n" | |
| 389 "Connection: keep-alive\r\n\r\n"), | |
| 390 }; | |
| 391 MockRead reads2[] = { | |
| 392 MockRead(false, 1, "HTTP/1.1 200 OK\r\n"), | |
| 393 MockRead(false, 2, "Content-Length: 8\r\n\r\n"), | |
| 394 MockRead(false, 3, "two.html"), | |
| 395 }; | |
| 396 AddExpectedConnection(reads2, arraysize(reads2), writes2, arraysize(writes2)); | |
| 397 | |
| 398 HttpNetworkTransaction one_transaction(session_.get()); | |
| 399 TestOldCompletionCallback one_callback; | |
| 400 EXPECT_EQ(ERR_IO_PENDING, | |
| 401 one_transaction.Start(GetRequestInfo("one.html"), &one_callback, | |
| 402 BoundNetLog())); | |
| 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 data_vector_[0]->RunFor(1); | |
| 411 EXPECT_EQ(ERR_FAILED, one_callback.WaitForResult()); | |
| 412 | |
| 413 EXPECT_EQ(OK, two_callback.WaitForResult()); | |
| 414 ExpectResponse("two.html", two_transaction); | |
| 415 } | |
| 416 | |
| 417 TEST_F(HttpPipelinedNetworkTransactionTest, BasicHttpAuthentication) { | |
| 418 Initialize(); | |
| 419 | |
| 420 MockWrite writes[] = { | |
| 421 MockWrite(false, 0, "GET /one.html HTTP/1.1\r\n" | |
| 422 "Host: localhost\r\n" | |
| 423 "Connection: keep-alive\r\n\r\n"), | |
| 424 MockWrite(false, 5, "GET /one.html HTTP/1.1\r\n" | |
| 425 "Host: localhost\r\n" | |
| 426 "Connection: keep-alive\r\n" | |
| 427 "Authorization: auth_token\r\n\r\n"), | |
| 428 }; | |
| 429 MockRead reads[] = { | |
| 430 MockRead(false, 1, "HTTP/1.1 401 Authentication Required\r\n"), | |
| 431 MockRead(false, 2, "WWW-Authenticate: Basic realm=\"Secure Area\"\r\n"), | |
| 432 MockRead(false, 3, "Content-Length: 20\r\n\r\n"), | |
| 433 MockRead(false, 4, "needs authentication"), | |
| 434 MockRead(false, 6, "HTTP/1.1 200 OK\r\n"), | |
| 435 MockRead(false, 7, "Content-Length: 8\r\n\r\n"), | |
| 436 MockRead(false, 8, "one.html"), | |
| 437 }; | |
| 438 AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes)); | |
| 439 | |
| 440 HttpAuthHandlerMock* mock_auth = new HttpAuthHandlerMock; | |
| 441 std::string challenge_text = "Basic"; | |
| 442 HttpAuth::ChallengeTokenizer challenge(challenge_text.begin(), | |
| 443 challenge_text.end()); | |
| 444 GURL origin("localhost"); | |
| 445 EXPECT_TRUE(mock_auth->InitFromChallenge(&challenge, | |
| 446 HttpAuth::AUTH_SERVER, | |
| 447 origin, | |
| 448 BoundNetLog())); | |
| 449 auth_handler_factory_->AddMockHandler(mock_auth, HttpAuth::AUTH_SERVER); | |
| 450 | |
| 451 HttpNetworkTransaction transaction(session_.get()); | |
| 452 EXPECT_EQ( | |
| 453 ERR_IO_PENDING, | |
| 454 transaction.Start(GetRequestInfo("one.html"), &callback_, BoundNetLog())); | |
| 455 EXPECT_EQ(OK, callback_.WaitForResult()); | |
| 456 | |
| 457 AuthCredentials credentials(ASCIIToUTF16("user"), ASCIIToUTF16("pass")); | |
| 458 EXPECT_EQ(OK, transaction.RestartWithAuth(credentials, &callback_)); | |
| 459 | |
| 460 ExpectResponse("one.html", transaction); | |
| 461 } | |
| 462 | |
| 463 } // namespace net | |
| OLD | NEW |