| 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 | |
| 6518 } // namespace net | 6376 } // namespace net |
| OLD | NEW |