OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 <stdarg.h> | 8 #include <stdarg.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 | 10 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 #include "net/http/http_auth_challenge_tokenizer.h" | 47 #include "net/http/http_auth_challenge_tokenizer.h" |
48 #include "net/http/http_auth_handler_digest.h" | 48 #include "net/http/http_auth_handler_digest.h" |
49 #include "net/http/http_auth_handler_mock.h" | 49 #include "net/http/http_auth_handler_mock.h" |
50 #include "net/http/http_auth_handler_ntlm.h" | 50 #include "net/http/http_auth_handler_ntlm.h" |
51 #include "net/http/http_auth_scheme.h" | 51 #include "net/http/http_auth_scheme.h" |
52 #include "net/http/http_basic_state.h" | 52 #include "net/http/http_basic_state.h" |
53 #include "net/http/http_basic_stream.h" | 53 #include "net/http/http_basic_stream.h" |
54 #include "net/http/http_network_session.h" | 54 #include "net/http/http_network_session.h" |
55 #include "net/http/http_network_session_peer.h" | 55 #include "net/http/http_network_session_peer.h" |
56 #include "net/http/http_request_headers.h" | 56 #include "net/http/http_request_headers.h" |
| 57 #include "net/http/http_response_info.h" |
57 #include "net/http/http_server_properties_impl.h" | 58 #include "net/http/http_server_properties_impl.h" |
58 #include "net/http/http_stream.h" | 59 #include "net/http/http_stream.h" |
59 #include "net/http/http_stream_factory.h" | 60 #include "net/http/http_stream_factory.h" |
60 #include "net/http/http_stream_parser.h" | 61 #include "net/http/http_stream_parser.h" |
61 #include "net/http/http_transaction_test_util.h" | 62 #include "net/http/http_transaction_test_util.h" |
62 #include "net/log/net_log.h" | 63 #include "net/log/net_log.h" |
63 #include "net/log/test_net_log.h" | 64 #include "net/log/test_net_log.h" |
64 #include "net/log/test_net_log_entry.h" | 65 #include "net/log/test_net_log_entry.h" |
65 #include "net/log/test_net_log_util.h" | 66 #include "net/log/test_net_log_util.h" |
66 #include "net/proxy/mock_proxy_resolver.h" | 67 #include "net/proxy/mock_proxy_resolver.h" |
(...skipping 1893 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1960 const HttpResponseInfo* response = trans->GetResponseInfo(); | 1961 const HttpResponseInfo* response = trans->GetResponseInfo(); |
1961 ASSERT_TRUE(response); | 1962 ASSERT_TRUE(response); |
1962 ASSERT_TRUE(response->headers); | 1963 ASSERT_TRUE(response->headers); |
1963 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); | 1964 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); |
1964 std::string response_data; | 1965 std::string response_data; |
1965 rv = ReadTransaction(trans.get(), &response_data); | 1966 rv = ReadTransaction(trans.get(), &response_data); |
1966 EXPECT_EQ(OK, rv); | 1967 EXPECT_EQ(OK, rv); |
1967 EXPECT_EQ("hello", response_data); | 1968 EXPECT_EQ("hello", response_data); |
1968 } | 1969 } |
1969 | 1970 |
| 1971 // Sockets that receive extra data after a response is complete should not be |
| 1972 // reused. |
| 1973 TEST_P(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) { |
| 1974 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); |
| 1975 MockWrite data_writes1[] = { |
| 1976 MockWrite("HEAD / HTTP/1.1\r\n" |
| 1977 "Host: www.borked.com\r\n" |
| 1978 "Connection: keep-alive\r\n\r\n"), |
| 1979 }; |
| 1980 |
| 1981 MockRead data_reads1[] = { |
| 1982 MockRead("HTTP/1.1 200 OK\r\n" |
| 1983 "Connection: keep-alive\r\n" |
| 1984 "Content-Length: 22\r\n\r\n" |
| 1985 "This server is borked."), |
| 1986 }; |
| 1987 |
| 1988 MockWrite data_writes2[] = { |
| 1989 MockWrite("GET /foo HTTP/1.1\r\n" |
| 1990 "Host: www.borked.com\r\n" |
| 1991 "Connection: keep-alive\r\n\r\n"), |
| 1992 }; |
| 1993 |
| 1994 MockRead data_reads2[] = { |
| 1995 MockRead("HTTP/1.1 200 OK\r\n" |
| 1996 "Content-Length: 3\r\n\r\n" |
| 1997 "foo"), |
| 1998 }; |
| 1999 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), |
| 2000 data_writes1, arraysize(data_writes1)); |
| 2001 session_deps_.socket_factory->AddSocketDataProvider(&data1); |
| 2002 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), |
| 2003 data_writes2, arraysize(data_writes2)); |
| 2004 session_deps_.socket_factory->AddSocketDataProvider(&data2); |
| 2005 |
| 2006 TestCompletionCallback callback; |
| 2007 HttpRequestInfo request1; |
| 2008 request1.method = "HEAD"; |
| 2009 request1.url = GURL("http://www.borked.com/"); |
| 2010 |
| 2011 std::unique_ptr<HttpTransaction> trans1( |
| 2012 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); |
| 2013 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog()); |
| 2014 EXPECT_EQ(OK, callback.GetResult(rv)); |
| 2015 |
| 2016 const HttpResponseInfo* response1 = trans1->GetResponseInfo(); |
| 2017 ASSERT_TRUE(response1); |
| 2018 ASSERT_TRUE(response1->headers); |
| 2019 EXPECT_EQ(200, response1->headers->response_code()); |
| 2020 EXPECT_TRUE(response1->headers->IsKeepAlive()); |
| 2021 |
| 2022 std::string response_data1; |
| 2023 EXPECT_EQ(OK, ReadTransaction(trans1.get(), &response_data1)); |
| 2024 EXPECT_EQ("", response_data1); |
| 2025 // Deleting the transaction attempts to release the socket back into the |
| 2026 // socket pool. |
| 2027 trans1.reset(); |
| 2028 |
| 2029 HttpRequestInfo request2; |
| 2030 request2.method = "GET"; |
| 2031 request2.url = GURL("http://www.borked.com/foo"); |
| 2032 |
| 2033 std::unique_ptr<HttpTransaction> trans2( |
| 2034 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); |
| 2035 rv = trans2->Start(&request2, callback.callback(), BoundNetLog()); |
| 2036 EXPECT_EQ(OK, callback.GetResult(rv)); |
| 2037 |
| 2038 const HttpResponseInfo* response2 = trans2->GetResponseInfo(); |
| 2039 ASSERT_TRUE(response2); |
| 2040 ASSERT_TRUE(response2->headers); |
| 2041 EXPECT_EQ(200, response2->headers->response_code()); |
| 2042 |
| 2043 std::string response_data2; |
| 2044 EXPECT_EQ(OK, ReadTransaction(trans2.get(), &response_data2)); |
| 2045 EXPECT_EQ("foo", response_data2); |
| 2046 } |
| 2047 |
| 2048 TEST_P(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) { |
| 2049 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); |
| 2050 MockWrite data_writes1[] = { |
| 2051 MockWrite("GET / HTTP/1.1\r\n" |
| 2052 "Host: www.borked.com\r\n" |
| 2053 "Connection: keep-alive\r\n\r\n"), |
| 2054 }; |
| 2055 |
| 2056 MockRead data_reads1[] = { |
| 2057 MockRead("HTTP/1.1 200 OK\r\n" |
| 2058 "Connection: keep-alive\r\n" |
| 2059 "Content-Length: 22\r\n\r\n" |
| 2060 "This server is borked." |
| 2061 "Bonus data!"), |
| 2062 }; |
| 2063 |
| 2064 MockWrite data_writes2[] = { |
| 2065 MockWrite("GET /foo HTTP/1.1\r\n" |
| 2066 "Host: www.borked.com\r\n" |
| 2067 "Connection: keep-alive\r\n\r\n"), |
| 2068 }; |
| 2069 |
| 2070 MockRead data_reads2[] = { |
| 2071 MockRead("HTTP/1.1 200 OK\r\n" |
| 2072 "Content-Length: 3\r\n\r\n" |
| 2073 "foo"), |
| 2074 }; |
| 2075 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), |
| 2076 data_writes1, arraysize(data_writes1)); |
| 2077 session_deps_.socket_factory->AddSocketDataProvider(&data1); |
| 2078 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), |
| 2079 data_writes2, arraysize(data_writes2)); |
| 2080 session_deps_.socket_factory->AddSocketDataProvider(&data2); |
| 2081 |
| 2082 TestCompletionCallback callback; |
| 2083 HttpRequestInfo request1; |
| 2084 request1.method = "GET"; |
| 2085 request1.url = GURL("http://www.borked.com/"); |
| 2086 |
| 2087 std::unique_ptr<HttpTransaction> trans1( |
| 2088 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); |
| 2089 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog()); |
| 2090 EXPECT_EQ(OK, callback.GetResult(rv)); |
| 2091 |
| 2092 const HttpResponseInfo* response1 = trans1->GetResponseInfo(); |
| 2093 ASSERT_TRUE(response1); |
| 2094 ASSERT_TRUE(response1->headers); |
| 2095 EXPECT_EQ(200, response1->headers->response_code()); |
| 2096 EXPECT_TRUE(response1->headers->IsKeepAlive()); |
| 2097 |
| 2098 std::string response_data1; |
| 2099 EXPECT_EQ(OK, ReadTransaction(trans1.get(), &response_data1)); |
| 2100 EXPECT_EQ("This server is borked.", response_data1); |
| 2101 // Deleting the transaction attempts to release the socket back into the |
| 2102 // socket pool. |
| 2103 trans1.reset(); |
| 2104 |
| 2105 HttpRequestInfo request2; |
| 2106 request2.method = "GET"; |
| 2107 request2.url = GURL("http://www.borked.com/foo"); |
| 2108 |
| 2109 std::unique_ptr<HttpTransaction> trans2( |
| 2110 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); |
| 2111 rv = trans2->Start(&request2, callback.callback(), BoundNetLog()); |
| 2112 EXPECT_EQ(OK, callback.GetResult(rv)); |
| 2113 |
| 2114 const HttpResponseInfo* response2 = trans2->GetResponseInfo(); |
| 2115 ASSERT_TRUE(response2); |
| 2116 ASSERT_TRUE(response2->headers); |
| 2117 EXPECT_EQ(200, response2->headers->response_code()); |
| 2118 |
| 2119 std::string response_data2; |
| 2120 EXPECT_EQ(OK, ReadTransaction(trans2.get(), &response_data2)); |
| 2121 EXPECT_EQ("foo", response_data2); |
| 2122 } |
| 2123 |
| 2124 TEST_P(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) { |
| 2125 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); |
| 2126 MockWrite data_writes1[] = { |
| 2127 MockWrite("GET / HTTP/1.1\r\n" |
| 2128 "Host: www.borked.com\r\n" |
| 2129 "Connection: keep-alive\r\n\r\n"), |
| 2130 }; |
| 2131 |
| 2132 MockRead data_reads1[] = { |
| 2133 MockRead("HTTP/1.1 200 OK\r\n" |
| 2134 "Connection: keep-alive\r\n" |
| 2135 "Transfer-Encoding: chunked\r\n\r\n"), |
| 2136 MockRead("16\r\nThis server is borked.\r\n"), |
| 2137 MockRead("0\r\n\r\nBonus data!"), |
| 2138 }; |
| 2139 |
| 2140 MockWrite data_writes2[] = { |
| 2141 MockWrite("GET /foo HTTP/1.1\r\n" |
| 2142 "Host: www.borked.com\r\n" |
| 2143 "Connection: keep-alive\r\n\r\n"), |
| 2144 }; |
| 2145 |
| 2146 MockRead data_reads2[] = { |
| 2147 MockRead("HTTP/1.1 200 OK\r\n" |
| 2148 "Content-Length: 3\r\n\r\n" |
| 2149 "foo"), |
| 2150 }; |
| 2151 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), |
| 2152 data_writes1, arraysize(data_writes1)); |
| 2153 session_deps_.socket_factory->AddSocketDataProvider(&data1); |
| 2154 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), |
| 2155 data_writes2, arraysize(data_writes2)); |
| 2156 session_deps_.socket_factory->AddSocketDataProvider(&data2); |
| 2157 |
| 2158 TestCompletionCallback callback; |
| 2159 HttpRequestInfo request1; |
| 2160 request1.method = "GET"; |
| 2161 request1.url = GURL("http://www.borked.com/"); |
| 2162 |
| 2163 std::unique_ptr<HttpTransaction> trans1( |
| 2164 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); |
| 2165 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog()); |
| 2166 EXPECT_EQ(OK, callback.GetResult(rv)); |
| 2167 |
| 2168 const HttpResponseInfo* response1 = trans1->GetResponseInfo(); |
| 2169 ASSERT_TRUE(response1); |
| 2170 ASSERT_TRUE(response1->headers); |
| 2171 EXPECT_EQ(200, response1->headers->response_code()); |
| 2172 EXPECT_TRUE(response1->headers->IsKeepAlive()); |
| 2173 |
| 2174 std::string response_data1; |
| 2175 EXPECT_EQ(OK, ReadTransaction(trans1.get(), &response_data1)); |
| 2176 EXPECT_EQ("This server is borked.", response_data1); |
| 2177 // Deleting the transaction attempts to release the socket back into the |
| 2178 // socket pool. |
| 2179 trans1.reset(); |
| 2180 |
| 2181 HttpRequestInfo request2; |
| 2182 request2.method = "GET"; |
| 2183 request2.url = GURL("http://www.borked.com/foo"); |
| 2184 |
| 2185 std::unique_ptr<HttpTransaction> trans2( |
| 2186 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); |
| 2187 rv = trans2->Start(&request2, callback.callback(), BoundNetLog()); |
| 2188 EXPECT_EQ(OK, callback.GetResult(rv)); |
| 2189 |
| 2190 const HttpResponseInfo* response2 = trans2->GetResponseInfo(); |
| 2191 ASSERT_TRUE(response2); |
| 2192 ASSERT_TRUE(response2->headers); |
| 2193 EXPECT_EQ(200, response2->headers->response_code()); |
| 2194 |
| 2195 std::string response_data2; |
| 2196 EXPECT_EQ(OK, ReadTransaction(trans2.get(), &response_data2)); |
| 2197 EXPECT_EQ("foo", response_data2); |
| 2198 } |
| 2199 |
| 2200 // This is a little different from the others - it tests the case that the |
| 2201 // HttpStreamParser doesn't know if there's extra data on a socket or not when |
| 2202 // the HttpNetworkTransaction is torn down, because the response body hasn't |
| 2203 // been read from yet, but the request goes through the HttpResponseBodyDrainer. |
| 2204 TEST_P(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) { |
| 2205 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); |
| 2206 MockWrite data_writes1[] = { |
| 2207 MockWrite("GET / HTTP/1.1\r\n" |
| 2208 "Host: www.borked.com\r\n" |
| 2209 "Connection: keep-alive\r\n\r\n"), |
| 2210 }; |
| 2211 |
| 2212 MockRead data_reads1[] = { |
| 2213 MockRead("HTTP/1.1 200 OK\r\n" |
| 2214 "Connection: keep-alive\r\n" |
| 2215 "Transfer-Encoding: chunked\r\n\r\n"), |
| 2216 MockRead("16\r\nThis server is borked.\r\n"), |
| 2217 MockRead("0\r\n\r\nBonus data!"), |
| 2218 }; |
| 2219 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), |
| 2220 data_writes1, arraysize(data_writes1)); |
| 2221 session_deps_.socket_factory->AddSocketDataProvider(&data1); |
| 2222 |
| 2223 TestCompletionCallback callback; |
| 2224 HttpRequestInfo request1; |
| 2225 request1.method = "GET"; |
| 2226 request1.url = GURL("http://www.borked.com/"); |
| 2227 |
| 2228 std::unique_ptr<HttpTransaction> trans1( |
| 2229 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); |
| 2230 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog()); |
| 2231 EXPECT_EQ(OK, callback.GetResult(rv)); |
| 2232 |
| 2233 const HttpResponseInfo* response1 = trans1->GetResponseInfo(); |
| 2234 ASSERT_TRUE(response1); |
| 2235 ASSERT_TRUE(response1->headers); |
| 2236 EXPECT_EQ(200, response1->headers->response_code()); |
| 2237 EXPECT_TRUE(response1->headers->IsKeepAlive()); |
| 2238 |
| 2239 // Deleting the transaction creates an HttpResponseBodyDrainer to read the |
| 2240 // response body. |
| 2241 trans1.reset(); |
| 2242 |
| 2243 // Let the HttpResponseBodyDrainer drain the socket. It should determine the |
| 2244 // socket can't be reused, rather than returning it to the socket pool. |
| 2245 base::RunLoop().RunUntilIdle(); |
| 2246 |
| 2247 // There should be no idle sockets in the pool. |
| 2248 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); |
| 2249 } |
| 2250 |
1970 // Test the request-challenge-retry sequence for basic auth. | 2251 // Test the request-challenge-retry sequence for basic auth. |
1971 // (basic auth is the easiest to mock, because it has no randomness). | 2252 // (basic auth is the easiest to mock, because it has no randomness). |
1972 TEST_P(HttpNetworkTransactionTest, BasicAuth) { | 2253 TEST_P(HttpNetworkTransactionTest, BasicAuth) { |
1973 HttpRequestInfo request; | 2254 HttpRequestInfo request; |
1974 request.method = "GET"; | 2255 request.method = "GET"; |
1975 request.url = GURL("http://www.example.org/"); | 2256 request.url = GURL("http://www.example.org/"); |
1976 request.load_flags = 0; | 2257 request.load_flags = 0; |
1977 | 2258 |
1978 TestNetLog log; | 2259 TestNetLog log; |
1979 session_deps_.net_log = &log; | 2260 session_deps_.net_log = &log; |
(...skipping 13993 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15973 base::MessageLoop::current()->RunUntilIdle(); | 16254 base::MessageLoop::current()->RunUntilIdle(); |
15974 | 16255 |
15975 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy); | 16256 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy); |
15976 HttpRequestHeaders headers; | 16257 HttpRequestHeaders headers; |
15977 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers)); | 16258 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers)); |
15978 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding)); | 16259 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding)); |
15979 } | 16260 } |
15980 #endif // !defined(OS_IOS) | 16261 #endif // !defined(OS_IOS) |
15981 | 16262 |
15982 } // namespace net | 16263 } // namespace net |
OLD | NEW |