Chromium Code Reviews| 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 | |
| 2220 MockWrite data_writes2[] = { | |
| 2221 MockWrite("GET /foo HTTP/1.1\r\n" | |
| 2222 "Host: www.borked.com\r\n" | |
| 2223 "Connection: keep-alive\r\n\r\n"), | |
| 2224 }; | |
| 2225 | |
| 2226 MockRead data_reads2[] = { | |
| 2227 MockRead("HTTP/1.1 200 OK\r\n" | |
| 2228 "Content-Length: 3\r\n\r\n" | |
| 2229 "foo"), | |
| 2230 }; | |
| 2231 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), | |
| 2232 data_writes1, arraysize(data_writes1)); | |
| 2233 session_deps_.socket_factory->AddSocketDataProvider(&data1); | |
| 2234 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), | |
| 2235 data_writes2, arraysize(data_writes2)); | |
| 2236 session_deps_.socket_factory->AddSocketDataProvider(&data2); | |
| 2237 | |
| 2238 TestCompletionCallback callback; | |
| 2239 HttpRequestInfo request1; | |
| 2240 request1.method = "GET"; | |
| 2241 request1.url = GURL("http://www.borked.com/"); | |
| 2242 | |
| 2243 std::unique_ptr<HttpTransaction> trans1( | |
| 2244 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); | |
| 2245 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog()); | |
| 2246 EXPECT_EQ(OK, callback.GetResult(rv)); | |
| 2247 | |
| 2248 const HttpResponseInfo* response1 = trans1->GetResponseInfo(); | |
| 2249 ASSERT_TRUE(response1); | |
| 2250 ASSERT_TRUE(response1->headers); | |
| 2251 EXPECT_EQ(200, response1->headers->response_code()); | |
| 2252 EXPECT_TRUE(response1->headers->IsKeepAlive()); | |
| 2253 | |
| 2254 // Deleting the transaction creates an HttpResponseBodyDrainer to read the | |
| 2255 // response body. | |
| 2256 trans1.reset(); | |
| 2257 | |
| 2258 // Let the HttpResponseBodyDrainer drain the socket. It should determine the | |
| 2259 // socket can't be reused, rather than returning it to the socket pool. | |
| 2260 base::RunLoop().RunUntilIdle(); | |
|
asanka
2016/06/01 19:43:34
For consistency, shouldn't this be done for the ot
mmenke
2016/06/02 15:56:23
I don't think so. None of the other tests need it
| |
| 2261 | |
| 2262 HttpRequestInfo request2; | |
| 2263 request2.method = "GET"; | |
| 2264 request2.url = GURL("http://www.borked.com/foo"); | |
| 2265 | |
| 2266 std::unique_ptr<HttpTransaction> trans2( | |
| 2267 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); | |
| 2268 rv = trans2->Start(&request2, callback.callback(), BoundNetLog()); | |
| 2269 EXPECT_EQ(OK, callback.GetResult(rv)); | |
| 2270 | |
| 2271 const HttpResponseInfo* response2 = trans2->GetResponseInfo(); | |
| 2272 ASSERT_TRUE(response2); | |
| 2273 ASSERT_TRUE(response2->headers); | |
| 2274 EXPECT_EQ(200, response2->headers->response_code()); | |
| 2275 | |
| 2276 std::string response_data2; | |
| 2277 EXPECT_EQ(OK, ReadTransaction(trans2.get(), &response_data2)); | |
| 2278 EXPECT_EQ("foo", response_data2); | |
| 2279 } | |
| 2280 | |
| 1970 // Test the request-challenge-retry sequence for basic auth. | 2281 // Test the request-challenge-retry sequence for basic auth. |
| 1971 // (basic auth is the easiest to mock, because it has no randomness). | 2282 // (basic auth is the easiest to mock, because it has no randomness). |
| 1972 TEST_P(HttpNetworkTransactionTest, BasicAuth) { | 2283 TEST_P(HttpNetworkTransactionTest, BasicAuth) { |
| 1973 HttpRequestInfo request; | 2284 HttpRequestInfo request; |
| 1974 request.method = "GET"; | 2285 request.method = "GET"; |
| 1975 request.url = GURL("http://www.example.org/"); | 2286 request.url = GURL("http://www.example.org/"); |
| 1976 request.load_flags = 0; | 2287 request.load_flags = 0; |
| 1977 | 2288 |
| 1978 TestNetLog log; | 2289 TestNetLog log; |
| 1979 session_deps_.net_log = &log; | 2290 session_deps_.net_log = &log; |
| (...skipping 13993 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 15973 base::MessageLoop::current()->RunUntilIdle(); | 16284 base::MessageLoop::current()->RunUntilIdle(); |
| 15974 | 16285 |
| 15975 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy); | 16286 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy); |
| 15976 HttpRequestHeaders headers; | 16287 HttpRequestHeaders headers; |
| 15977 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers)); | 16288 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers)); |
| 15978 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding)); | 16289 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding)); |
| 15979 } | 16290 } |
| 15980 #endif // !defined(OS_IOS) | 16291 #endif // !defined(OS_IOS) |
| 15981 | 16292 |
| 15982 } // namespace net | 16293 } // namespace net |
| OLD | NEW |