Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Side by Side Diff: net/http/http_network_transaction_unittest.cc

Issue 1884943003: HttpStreamParser: Don't reuse sockets which receive unparsed data. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: oops Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | net/http/http_response_body_drainer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | net/http/http_response_body_drainer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698