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 2476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2487 EXPECT_EQ("hello world", response_data); | 2487 EXPECT_EQ("hello world", response_data); |
2488 | 2488 |
2489 // Empty the current queue. This is necessary because idle sockets are | 2489 // Empty the current queue. This is necessary because idle sockets are |
2490 // added to the connection pool asynchronously with a PostTask. | 2490 // added to the connection pool asynchronously with a PostTask. |
2491 MessageLoop::current()->RunAllPending(); | 2491 MessageLoop::current()->RunAllPending(); |
2492 | 2492 |
2493 // We now check to make sure the socket was added back to the pool. | 2493 // We now check to make sure the socket was added back to the pool. |
2494 EXPECT_EQ(1, session->tcp_socket_pool()->IdleSocketCount()); | 2494 EXPECT_EQ(1, session->tcp_socket_pool()->IdleSocketCount()); |
2495 } | 2495 } |
2496 | 2496 |
| 2497 // Make sure that we recycle a SSL socket after reading all of the response |
| 2498 // body. |
| 2499 TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) { |
| 2500 SessionDependencies session_deps; |
| 2501 HttpRequestInfo request; |
| 2502 request.method = "GET"; |
| 2503 request.url = GURL("https://www.google.com/"); |
| 2504 request.load_flags = 0; |
| 2505 |
| 2506 MockWrite data_writes[] = { |
| 2507 MockWrite("GET / HTTP/1.1\r\n" |
| 2508 "Host: www.google.com\r\n" |
| 2509 "Connection: keep-alive\r\n\r\n"), |
| 2510 }; |
| 2511 |
| 2512 MockRead data_reads[] = { |
| 2513 MockRead("HTTP/1.1 200 OK\r\n"), |
| 2514 MockRead("Content-Length: 11\r\n\r\n"), |
| 2515 MockRead("hello world"), |
| 2516 MockRead(false, OK), |
| 2517 }; |
| 2518 |
| 2519 SSLSocketDataProvider ssl(true, OK); |
| 2520 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); |
| 2521 |
| 2522 StaticSocketDataProvider data(data_reads, arraysize(data_reads), |
| 2523 data_writes, arraysize(data_writes)); |
| 2524 session_deps.socket_factory.AddSocketDataProvider(&data); |
| 2525 |
| 2526 TestCompletionCallback callback; |
| 2527 |
| 2528 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); |
| 2529 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); |
| 2530 |
| 2531 int rv = trans->Start(&request, &callback, BoundNetLog()); |
| 2532 |
| 2533 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 2534 EXPECT_EQ(OK, callback.WaitForResult()); |
| 2535 |
| 2536 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 2537 ASSERT_TRUE(response != NULL); |
| 2538 ASSERT_TRUE(response->headers != NULL); |
| 2539 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); |
| 2540 |
| 2541 EXPECT_EQ(0, session->tcp_socket_pool()->IdleSocketCount()); |
| 2542 |
| 2543 std::string response_data; |
| 2544 rv = ReadTransaction(trans.get(), &response_data); |
| 2545 EXPECT_EQ(OK, rv); |
| 2546 EXPECT_EQ("hello world", response_data); |
| 2547 |
| 2548 // Empty the current queue. This is necessary because idle sockets are |
| 2549 // added to the connection pool asynchronously with a PostTask. |
| 2550 MessageLoop::current()->RunAllPending(); |
| 2551 |
| 2552 // We now check to make sure the socket was added back to the pool. |
| 2553 EXPECT_EQ(1, session->ssl_socket_pool()->IdleSocketCount()); |
| 2554 } |
| 2555 |
| 2556 // Grab a SSL socket, use it, and put it back into the pool. Then, reuse it |
| 2557 // from the pool and make sure that we recover okay. |
| 2558 TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) { |
| 2559 SessionDependencies session_deps; |
| 2560 HttpRequestInfo request; |
| 2561 request.method = "GET"; |
| 2562 request.url = GURL("https://www.google.com/"); |
| 2563 request.load_flags = 0; |
| 2564 |
| 2565 MockWrite data_writes[] = { |
| 2566 MockWrite("GET / HTTP/1.1\r\n" |
| 2567 "Host: www.google.com\r\n" |
| 2568 "Connection: keep-alive\r\n\r\n"), |
| 2569 MockWrite("GET / HTTP/1.1\r\n" |
| 2570 "Host: www.google.com\r\n" |
| 2571 "Connection: keep-alive\r\n\r\n"), |
| 2572 }; |
| 2573 |
| 2574 MockRead data_reads[] = { |
| 2575 MockRead("HTTP/1.1 200 OK\r\n"), |
| 2576 MockRead("Content-Length: 11\r\n\r\n"), |
| 2577 MockRead(false, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), |
| 2578 MockRead("hello world"), |
| 2579 MockRead(true, 0, 0) // EOF |
| 2580 }; |
| 2581 |
| 2582 SSLSocketDataProvider ssl(true, OK); |
| 2583 SSLSocketDataProvider ssl2(true, OK); |
| 2584 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); |
| 2585 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl2); |
| 2586 |
| 2587 StaticSocketDataProvider data(data_reads, arraysize(data_reads), |
| 2588 data_writes, arraysize(data_writes)); |
| 2589 StaticSocketDataProvider data2(data_reads, arraysize(data_reads), |
| 2590 data_writes, arraysize(data_writes)); |
| 2591 session_deps.socket_factory.AddSocketDataProvider(&data); |
| 2592 session_deps.socket_factory.AddSocketDataProvider(&data2); |
| 2593 |
| 2594 TestCompletionCallback callback; |
| 2595 |
| 2596 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); |
| 2597 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); |
| 2598 |
| 2599 int rv = trans->Start(&request, &callback, BoundNetLog()); |
| 2600 |
| 2601 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 2602 EXPECT_EQ(OK, callback.WaitForResult()); |
| 2603 |
| 2604 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 2605 ASSERT_TRUE(response != NULL); |
| 2606 ASSERT_TRUE(response->headers != NULL); |
| 2607 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); |
| 2608 |
| 2609 EXPECT_EQ(0, session->tcp_socket_pool()->IdleSocketCount()); |
| 2610 |
| 2611 std::string response_data; |
| 2612 rv = ReadTransaction(trans.get(), &response_data); |
| 2613 EXPECT_EQ(OK, rv); |
| 2614 EXPECT_EQ("hello world", response_data); |
| 2615 |
| 2616 // Empty the current queue. This is necessary because idle sockets are |
| 2617 // added to the connection pool asynchronously with a PostTask. |
| 2618 MessageLoop::current()->RunAllPending(); |
| 2619 |
| 2620 // We now check to make sure the socket was added back to the pool. |
| 2621 EXPECT_EQ(1, session->ssl_socket_pool()->IdleSocketCount()); |
| 2622 |
| 2623 // Now start the second transaction, which should reuse the previous socket. |
| 2624 |
| 2625 trans.reset(new HttpNetworkTransaction(session)); |
| 2626 |
| 2627 rv = trans->Start(&request, &callback, BoundNetLog()); |
| 2628 |
| 2629 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 2630 EXPECT_EQ(OK, callback.WaitForResult()); |
| 2631 |
| 2632 response = trans->GetResponseInfo(); |
| 2633 ASSERT_TRUE(response != NULL); |
| 2634 ASSERT_TRUE(response->headers != NULL); |
| 2635 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); |
| 2636 |
| 2637 EXPECT_EQ(0, session->tcp_socket_pool()->IdleSocketCount()); |
| 2638 |
| 2639 rv = ReadTransaction(trans.get(), &response_data); |
| 2640 EXPECT_EQ(OK, rv); |
| 2641 EXPECT_EQ("hello world", response_data); |
| 2642 |
| 2643 // Empty the current queue. This is necessary because idle sockets are |
| 2644 // added to the connection pool asynchronously with a PostTask. |
| 2645 MessageLoop::current()->RunAllPending(); |
| 2646 |
| 2647 // We now check to make sure the socket was added back to the pool. |
| 2648 EXPECT_EQ(1, session->ssl_socket_pool()->IdleSocketCount()); |
| 2649 } |
| 2650 |
2497 // Make sure that we recycle a socket after a zero-length response. | 2651 // Make sure that we recycle a socket after a zero-length response. |
2498 // http://crbug.com/9880 | 2652 // http://crbug.com/9880 |
2499 TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) { | 2653 TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) { |
2500 SessionDependencies session_deps; | 2654 SessionDependencies session_deps; |
2501 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); | 2655 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); |
2502 | 2656 |
2503 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); | 2657 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); |
2504 | 2658 |
2505 HttpRequestInfo request; | 2659 HttpRequestInfo request; |
2506 request.method = "GET"; | 2660 request.method = "GET"; |
(...skipping 4081 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6588 TestCompletionCallback callback; | 6742 TestCompletionCallback callback; |
6589 | 6743 |
6590 CapturingBoundNetLog log(CapturingNetLog::kUnbounded); | 6744 CapturingBoundNetLog log(CapturingNetLog::kUnbounded); |
6591 int rv = trans->Start(&request, &callback, log.bound()); | 6745 int rv = trans->Start(&request, &callback, log.bound()); |
6592 EXPECT_EQ(ERR_IO_PENDING, rv); | 6746 EXPECT_EQ(ERR_IO_PENDING, rv); |
6593 trans.reset(); // Cancel the transaction here. | 6747 trans.reset(); // Cancel the transaction here. |
6594 | 6748 |
6595 MessageLoop::current()->RunAllPending(); | 6749 MessageLoop::current()->RunAllPending(); |
6596 } | 6750 } |
6597 | 6751 |
| 6752 // Test a basic GET request through a proxy. |
| 6753 TEST_F(HttpNetworkTransactionTest, ProxyGet) { |
| 6754 SessionDependencies session_deps(CreateFixedProxyService("myproxy:70")); |
| 6755 CapturingBoundNetLog log(CapturingNetLog::kUnbounded); |
| 6756 session_deps.net_log = log.bound().net_log(); |
| 6757 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); |
| 6758 |
| 6759 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); |
| 6760 |
| 6761 HttpRequestInfo request; |
| 6762 request.method = "GET"; |
| 6763 request.url = GURL("http://www.google.com/"); |
| 6764 |
| 6765 MockWrite data_writes1[] = { |
| 6766 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" |
| 6767 "Host: www.google.com\r\n" |
| 6768 "Proxy-Connection: keep-alive\r\n\r\n"), |
| 6769 }; |
| 6770 |
| 6771 MockRead data_reads1[] = { |
| 6772 MockRead("HTTP/1.1 200 OK\r\n"), |
| 6773 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), |
| 6774 MockRead("Content-Length: 100\r\n\r\n"), |
| 6775 MockRead(false, OK), |
| 6776 }; |
| 6777 |
| 6778 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), |
| 6779 data_writes1, arraysize(data_writes1)); |
| 6780 session_deps.socket_factory.AddSocketDataProvider(&data1); |
| 6781 |
| 6782 TestCompletionCallback callback1; |
| 6783 |
| 6784 int rv = trans->Start(&request, &callback1, log.bound()); |
| 6785 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 6786 |
| 6787 rv = callback1.WaitForResult(); |
| 6788 EXPECT_EQ(OK, rv); |
| 6789 |
| 6790 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 6791 ASSERT_FALSE(response == NULL); |
| 6792 |
| 6793 EXPECT_TRUE(response->headers->IsKeepAlive()); |
| 6794 EXPECT_EQ(200, response->headers->response_code()); |
| 6795 EXPECT_EQ(100, response->headers->GetContentLength()); |
| 6796 EXPECT_TRUE(response->was_fetched_via_proxy); |
| 6797 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); |
| 6798 } |
| 6799 |
| 6800 // Test a basic HTTPS GET request through a proxy. |
| 6801 TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) { |
| 6802 SessionDependencies session_deps(CreateFixedProxyService("myproxy:70")); |
| 6803 CapturingBoundNetLog log(CapturingNetLog::kUnbounded); |
| 6804 session_deps.net_log = log.bound().net_log(); |
| 6805 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); |
| 6806 |
| 6807 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); |
| 6808 |
| 6809 HttpRequestInfo request; |
| 6810 request.method = "GET"; |
| 6811 request.url = GURL("https://www.google.com/"); |
| 6812 |
| 6813 // Since we have proxy, should try to establish tunnel. |
| 6814 MockWrite data_writes1[] = { |
| 6815 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" |
| 6816 "Host: www.google.com\r\n" |
| 6817 "Proxy-Connection: keep-alive\r\n\r\n"), |
| 6818 |
| 6819 MockWrite("GET / HTTP/1.1\r\n" |
| 6820 "Host: www.google.com\r\n" |
| 6821 "Connection: keep-alive\r\n\r\n"), |
| 6822 }; |
| 6823 |
| 6824 MockRead data_reads1[] = { |
| 6825 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"), |
| 6826 |
| 6827 MockRead("HTTP/1.1 200 OK\r\n"), |
| 6828 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), |
| 6829 MockRead("Content-Length: 100\r\n\r\n"), |
| 6830 MockRead(false, OK), |
| 6831 }; |
| 6832 |
| 6833 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), |
| 6834 data_writes1, arraysize(data_writes1)); |
| 6835 session_deps.socket_factory.AddSocketDataProvider(&data1); |
| 6836 SSLSocketDataProvider ssl(true, OK); |
| 6837 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); |
| 6838 |
| 6839 TestCompletionCallback callback1; |
| 6840 |
| 6841 int rv = trans->Start(&request, &callback1, log.bound()); |
| 6842 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 6843 |
| 6844 rv = callback1.WaitForResult(); |
| 6845 EXPECT_EQ(OK, rv); |
| 6846 size_t pos = ExpectLogContainsSomewhere( |
| 6847 log.entries(), 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, |
| 6848 NetLog::PHASE_NONE); |
| 6849 ExpectLogContainsSomewhere( |
| 6850 log.entries(), pos, |
| 6851 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, |
| 6852 NetLog::PHASE_NONE); |
| 6853 |
| 6854 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 6855 ASSERT_FALSE(response == NULL); |
| 6856 |
| 6857 EXPECT_TRUE(response->headers->IsKeepAlive()); |
| 6858 EXPECT_EQ(200, response->headers->response_code()); |
| 6859 EXPECT_EQ(100, response->headers->GetContentLength()); |
| 6860 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); |
| 6861 EXPECT_TRUE(response->was_fetched_via_proxy); |
| 6862 } |
| 6863 |
| 6864 // Test a basic HTTPS GET request through a proxy, but the server hangs up |
| 6865 // while establishing the tunnel. |
| 6866 TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) { |
| 6867 SessionDependencies session_deps(CreateFixedProxyService("myproxy:70")); |
| 6868 CapturingBoundNetLog log(CapturingNetLog::kUnbounded); |
| 6869 session_deps.net_log = log.bound().net_log(); |
| 6870 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); |
| 6871 |
| 6872 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); |
| 6873 |
| 6874 HttpRequestInfo request; |
| 6875 request.method = "GET"; |
| 6876 request.url = GURL("https://www.google.com/"); |
| 6877 |
| 6878 // Since we have proxy, should try to establish tunnel. |
| 6879 MockWrite data_writes1[] = { |
| 6880 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" |
| 6881 "Host: www.google.com\r\n" |
| 6882 "Proxy-Connection: keep-alive\r\n\r\n"), |
| 6883 |
| 6884 MockWrite("GET / HTTP/1.1\r\n" |
| 6885 "Host: www.google.com\r\n" |
| 6886 "Connection: keep-alive\r\n\r\n"), |
| 6887 }; |
| 6888 |
| 6889 MockRead data_reads1[] = { |
| 6890 MockRead(false, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), |
| 6891 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"), |
| 6892 MockRead(true, 0, 0), // EOF |
| 6893 }; |
| 6894 |
| 6895 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), |
| 6896 data_writes1, arraysize(data_writes1)); |
| 6897 session_deps.socket_factory.AddSocketDataProvider(&data1); |
| 6898 SSLSocketDataProvider ssl(true, OK); |
| 6899 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); |
| 6900 |
| 6901 TestCompletionCallback callback1; |
| 6902 |
| 6903 int rv = trans->Start(&request, &callback1, log.bound()); |
| 6904 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 6905 |
| 6906 rv = callback1.WaitForResult(); |
| 6907 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv); |
| 6908 size_t pos = ExpectLogContainsSomewhere( |
| 6909 log.entries(), 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, |
| 6910 NetLog::PHASE_NONE); |
| 6911 ExpectLogContainsSomewhere( |
| 6912 log.entries(), pos, |
| 6913 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, |
| 6914 NetLog::PHASE_NONE); |
| 6915 } |
| 6916 |
6598 } // namespace net | 6917 } // namespace net |
OLD | NEW |