| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "net/http/http_network_transaction.h" | 5 #include "net/http/http_network_transaction.h" |
| 6 | 6 |
| 7 #include <math.h> // ceil | 7 #include <math.h> // ceil |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| (...skipping 6355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6366 scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session)); | 6366 scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session)); |
| 6367 | 6367 |
| 6368 int rv = trans->Start(&request, &callback, BoundNetLog()); | 6368 int rv = trans->Start(&request, &callback, BoundNetLog()); |
| 6369 EXPECT_EQ(ERR_IO_PENDING, rv); | 6369 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 6370 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult()); | 6370 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult()); |
| 6371 | 6371 |
| 6372 HttpNetworkTransaction::SetNextProtos(""); | 6372 HttpNetworkTransaction::SetNextProtos(""); |
| 6373 HttpNetworkTransaction::SetUseAlternateProtocols(false); | 6373 HttpNetworkTransaction::SetUseAlternateProtocols(false); |
| 6374 } | 6374 } |
| 6375 | 6375 |
| 6376 TEST_F(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) { |
| 6377 // This test ensures that the URL passed into the proxy is upgraded |
| 6378 // to https when doing an Alternate Protocol upgrade. |
| 6379 HttpNetworkTransaction::SetUseAlternateProtocols(true); |
| 6380 HttpNetworkTransaction::SetNextProtos( |
| 6381 "\x08http/1.1\x07http1.1\x06spdy/2\x04spdy"); |
| 6382 |
| 6383 SessionDependencies session_deps(CreateFixedProxyService("myproxy:70")); |
| 6384 HttpAuthHandlerMock::Factory* auth_factory = |
| 6385 new HttpAuthHandlerMock::Factory(); |
| 6386 HttpAuthHandlerMock* auth_handler = new HttpAuthHandlerMock(); |
| 6387 auth_factory->set_mock_handler(auth_handler, HttpAuth::AUTH_PROXY); |
| 6388 auth_factory->set_do_init_from_challenge(true); |
| 6389 session_deps.http_auth_handler_factory.reset(auth_factory); |
| 6390 |
| 6391 HttpRequestInfo request; |
| 6392 request.method = "GET"; |
| 6393 request.url = GURL("http://www.google.com"); |
| 6394 request.load_flags = 0; |
| 6395 |
| 6396 // First round goes unauthenticated through the proxy. |
| 6397 MockWrite data_writes_1[] = { |
| 6398 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" |
| 6399 "Host: www.google.com\r\n" |
| 6400 "Proxy-Connection: keep-alive\r\n" |
| 6401 "\r\n"), |
| 6402 }; |
| 6403 MockRead data_reads_1[] = { |
| 6404 MockRead(false, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), |
| 6405 MockRead("HTTP/1.1 200 OK\r\n" |
| 6406 "Alternate-Protocol: 443:npn-spdy/2\r\n" |
| 6407 "Proxy-Connection: close\r\n" |
| 6408 "\r\n"), |
| 6409 }; |
| 6410 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1), |
| 6411 data_writes_1, arraysize(data_writes_1)); |
| 6412 |
| 6413 // Second round tries to tunnel to www.google.com due to the |
| 6414 // Alternate-Protocol announcement in the first round. It fails due |
| 6415 // to a proxy authentication challenge. |
| 6416 // After the failure, a tunnel is established to www.google.com using |
| 6417 // Proxy-Authorization headers. There is then a SPDY request round. |
| 6418 // |
| 6419 // NOTE: Despite the "Proxy-Connection: Close", these are done on the |
| 6420 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket |
| 6421 // does a Disconnect and Connect on the same socket, rather than trying |
| 6422 // to obtain a new one. |
| 6423 // |
| 6424 // NOTE: Originally, the proxy response to the second CONNECT request |
| 6425 // simply returned another 407 so the unit test could skip the SSL connection |
| 6426 // establishment and SPDY framing issues. Alas, the |
| 6427 // retry-http-when-alternate-protocol fails logic kicks in, which was more |
| 6428 // complicated to set up expectations for than the SPDY session. |
| 6429 |
| 6430 scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); |
| 6431 scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); |
| 6432 scoped_ptr<spdy::SpdyFrame> data(ConstructSpdyBodyFrame(1, true)); |
| 6433 |
| 6434 MockWrite data_writes_2[] = { |
| 6435 // First connection attempt without Proxy-Authorization. |
| 6436 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" |
| 6437 "Host: www.google.com\r\n" |
| 6438 "Proxy-Connection: keep-alive\r\n" |
| 6439 "\r\n"), |
| 6440 |
| 6441 // Second connection attempt with Proxy-Authorization. |
| 6442 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" |
| 6443 "Host: www.google.com\r\n" |
| 6444 "Proxy-Connection: keep-alive\r\n" |
| 6445 "Proxy-Authorization: auth_token\r\n" |
| 6446 "\r\n"), |
| 6447 |
| 6448 // SPDY request |
| 6449 CreateMockWrite(*req), |
| 6450 }; |
| 6451 const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n" |
| 6452 "Proxy-Authenticate: Mock\r\n" |
| 6453 "Proxy-Connection: close\r\n" |
| 6454 "\r\n"); |
| 6455 const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n"; |
| 6456 MockRead data_reads_2[] = { |
| 6457 // First connection attempt fails |
| 6458 MockRead(false, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1), |
| 6459 MockRead(true, kRejectConnectResponse, |
| 6460 arraysize(kRejectConnectResponse) - 1, 1), |
| 6461 |
| 6462 // Second connection attempt passes |
| 6463 MockRead(true, kAcceptConnectResponse, |
| 6464 arraysize(kAcceptConnectResponse) -1, 4), |
| 6465 |
| 6466 // SPDY response |
| 6467 CreateMockRead(*resp.get(), 6), |
| 6468 CreateMockRead(*data.get(), 6), |
| 6469 MockRead(true, 0, 0, 6), |
| 6470 }; |
| 6471 scoped_refptr<OrderedSocketData> data_2( |
| 6472 new OrderedSocketData(data_reads_2, arraysize(data_reads_2), |
| 6473 data_writes_2, arraysize(data_writes_2))); |
| 6474 |
| 6475 SSLSocketDataProvider ssl(true, OK); |
| 6476 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated; |
| 6477 ssl.next_proto = "spdy/2"; |
| 6478 ssl.was_npn_negotiated = true; |
| 6479 |
| 6480 session_deps.socket_factory.AddSocketDataProvider(&data_1); |
| 6481 session_deps.socket_factory.AddSocketDataProvider(data_2.get()); |
| 6482 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); |
| 6483 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); |
| 6484 |
| 6485 // First round should work and provide the Alternate-Protocol state. |
| 6486 TestCompletionCallback callback_1; |
| 6487 scoped_ptr<HttpTransaction> trans_1(new HttpNetworkTransaction(session)); |
| 6488 int rv = trans_1->Start(&request, &callback_1, BoundNetLog()); |
| 6489 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 6490 EXPECT_EQ(OK, callback_1.WaitForResult()); |
| 6491 |
| 6492 // Second round should attempt a tunnel connect and get an auth challenge. |
| 6493 TestCompletionCallback callback_2; |
| 6494 scoped_ptr<HttpTransaction> trans_2(new HttpNetworkTransaction(session)); |
| 6495 rv = trans_2->Start(&request, &callback_2, BoundNetLog()); |
| 6496 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 6497 EXPECT_EQ(OK, callback_2.WaitForResult()); |
| 6498 const HttpResponseInfo* response = trans_2->GetResponseInfo(); |
| 6499 ASSERT_FALSE(response == NULL); |
| 6500 ASSERT_FALSE(response->auth_challenge.get() == NULL); |
| 6501 |
| 6502 // Restart with auth. Tunnel should work and response received. |
| 6503 TestCompletionCallback callback_3; |
| 6504 rv = trans_2->RestartWithAuth(kFoo, kBar, &callback_3); |
| 6505 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 6506 EXPECT_EQ(OK, callback_3.WaitForResult()); |
| 6507 |
| 6508 // After all that work, these two lines (or actually, just the scheme) are |
| 6509 // what this test is all about. Make sure it happens correctly. |
| 6510 const GURL& request_url = auth_handler->request_url(); |
| 6511 EXPECT_EQ("https", request_url.scheme()); |
| 6512 EXPECT_EQ("www.google.com", request_url.host()); |
| 6513 |
| 6514 HttpNetworkTransaction::SetNextProtos(""); |
| 6515 HttpNetworkTransaction::SetUseAlternateProtocols(false); |
| 6516 } |
| 6517 |
| 6376 } // namespace net | 6518 } // namespace net |
| OLD | NEW |