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_proxy_client_socket_pool.h" | 5 #include "net/http/http_proxy_client_socket_pool.h" |
6 | 6 |
7 #include "base/callback.h" | 7 #include "base/callback.h" |
8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
11 #include "net/base/mock_host_resolver.h" | 11 #include "net/base/mock_host_resolver.h" |
12 #include "net/base/net_errors.h" | 12 #include "net/base/net_errors.h" |
13 #include "net/base/ssl_config_service_defaults.h" | 13 #include "net/base/ssl_config_service_defaults.h" |
14 #include "net/base/test_completion_callback.h" | 14 #include "net/base/test_completion_callback.h" |
15 #include "net/http/http_auth_handler_factory.h" | 15 #include "net/http/http_auth_handler_factory.h" |
16 #include "net/http/http_network_session.h" | 16 #include "net/http/http_network_session.h" |
17 #include "net/http/http_proxy_client_socket.h" | 17 #include "net/http/http_proxy_client_socket.h" |
18 #include "net/proxy/proxy_service.h" | 18 #include "net/proxy/proxy_service.h" |
19 #include "net/socket/client_socket_handle.h" | 19 #include "net/socket/client_socket_handle.h" |
20 #include "net/socket/client_socket_pool_histograms.h" | 20 #include "net/socket/client_socket_pool_histograms.h" |
21 #include "net/socket/socket_test_util.h" | 21 #include "net/socket/socket_test_util.h" |
| 22 #include "net/spdy/spdy_protocol.h" |
22 #include "net/spdy/spdy_session_pool.h" | 23 #include "net/spdy/spdy_session_pool.h" |
| 24 #include "net/spdy/spdy_test_util.h" |
23 #include "testing/gtest/include/gtest/gtest.h" | 25 #include "testing/gtest/include/gtest/gtest.h" |
24 | 26 |
25 namespace net { | 27 namespace net { |
26 | 28 |
27 namespace { | 29 namespace { |
28 | 30 |
29 const int kMaxSockets = 32; | 31 const int kMaxSockets = 32; |
30 const int kMaxSocketsPerGroup = 6; | 32 const int kMaxSocketsPerGroup = 6; |
| 33 const char * const kAuthHeaders[] = { |
| 34 "proxy-authorization", "Basic Zm9vOmJhcg==" |
| 35 }; |
| 36 const int kAuthHeadersSize = arraysize(kAuthHeaders) / 2; |
31 | 37 |
32 enum HttpProxyType { | 38 enum HttpProxyType { |
33 HTTP, | 39 HTTP, |
34 HTTPS | 40 HTTPS, |
| 41 SPDY |
35 }; | 42 }; |
36 | 43 |
37 typedef ::testing::TestWithParam<HttpProxyType> TestWithHttpParam; | 44 typedef ::testing::TestWithParam<HttpProxyType> TestWithHttpParam; |
38 | 45 |
| 46 } // namespace |
| 47 |
39 class HttpProxyClientSocketPoolTest : public TestWithHttpParam { | 48 class HttpProxyClientSocketPoolTest : public TestWithHttpParam { |
40 protected: | 49 protected: |
41 HttpProxyClientSocketPoolTest() | 50 HttpProxyClientSocketPoolTest() |
42 : ssl_config_(), | 51 : ssl_config_(), |
43 ignored_tcp_socket_params_(new TCPSocketParams( | 52 ignored_tcp_socket_params_(new TCPSocketParams( |
44 HostPortPair("proxy", 80), MEDIUM, GURL(), false)), | 53 HostPortPair("proxy", 80), LOWEST, GURL(), false)), |
45 ignored_ssl_socket_params_(new SSLSocketParams( | 54 ignored_ssl_socket_params_(new SSLSocketParams( |
46 ignored_tcp_socket_params_, NULL, NULL, ProxyServer::SCHEME_DIRECT, | 55 ignored_tcp_socket_params_, NULL, NULL, ProxyServer::SCHEME_DIRECT, |
47 "host", ssl_config_, 0, false, false)), | 56 "www.google.com", ssl_config_, 0, false, false)), |
48 tcp_histograms_("MockTCP"), | 57 tcp_histograms_("MockTCP"), |
49 tcp_socket_pool_( | 58 tcp_socket_pool_( |
50 kMaxSockets, kMaxSocketsPerGroup, | 59 kMaxSockets, kMaxSocketsPerGroup, |
51 &tcp_histograms_, | 60 &tcp_histograms_, |
52 &tcp_client_socket_factory_), | 61 &socket_factory_), |
53 ssl_histograms_("MockSSL"), | 62 ssl_histograms_("MockSSL"), |
| 63 ssl_config_service_(new SSLConfigServiceDefaults), |
| 64 host_resolver_(new MockHostResolver), |
54 ssl_socket_pool_(kMaxSockets, kMaxSocketsPerGroup, | 65 ssl_socket_pool_(kMaxSockets, kMaxSocketsPerGroup, |
55 &ssl_histograms_, | 66 &ssl_histograms_, |
56 &tcp_client_socket_factory_, | 67 host_resolver_.get(), |
57 &tcp_socket_pool_), | 68 NULL /* dnsrr_resolver */, |
58 host_resolver_(new MockHostResolver), | 69 &socket_factory_, |
| 70 &tcp_socket_pool_, |
| 71 NULL, |
| 72 NULL, |
| 73 ssl_config_service_.get(), |
| 74 BoundNetLog().net_log()), |
59 http_auth_handler_factory_( | 75 http_auth_handler_factory_( |
60 HttpAuthHandlerFactory::CreateDefault(host_resolver_.get())), | 76 HttpAuthHandlerFactory::CreateDefault(host_resolver_.get())), |
61 session_(new HttpNetworkSession(host_resolver_.get(), | 77 session_(new HttpNetworkSession(host_resolver_.get(), |
62 NULL /* dnsrr_resolver */, | 78 NULL /* dnsrr_resolver */, |
63 ProxyService::CreateDirect(), | 79 ProxyService::CreateDirect(), |
64 &socket_factory_, | 80 &socket_factory_, |
65 new SSLConfigServiceDefaults, | 81 new SSLConfigServiceDefaults, |
66 new SpdySessionPool(NULL), | 82 new SpdySessionPool(NULL), |
67 http_auth_handler_factory_.get(), | 83 http_auth_handler_factory_.get(), |
68 NULL, | 84 NULL, |
69 NULL)), | 85 NULL)), |
70 http_proxy_histograms_("HttpProxyUnitTest"), | 86 http_proxy_histograms_("HttpProxyUnitTest"), |
| 87 ssl_data_(NULL), |
| 88 data_(NULL), |
71 pool_(kMaxSockets, kMaxSocketsPerGroup, | 89 pool_(kMaxSockets, kMaxSocketsPerGroup, |
72 &http_proxy_histograms_, | 90 &http_proxy_histograms_, |
73 NULL, | 91 NULL, |
74 &tcp_socket_pool_, | 92 &tcp_socket_pool_, |
75 &ssl_socket_pool_, | 93 &ssl_socket_pool_, |
76 NULL) { | 94 NULL) { |
77 } | 95 } |
78 | 96 |
79 virtual ~HttpProxyClientSocketPoolTest() { | 97 virtual ~HttpProxyClientSocketPoolTest() { |
80 } | 98 } |
81 | 99 |
82 void AddAuthToCache() { | 100 void AddAuthToCache() { |
83 const string16 kFoo(ASCIIToUTF16("foo")); | 101 const string16 kFoo(ASCIIToUTF16("foo")); |
84 const string16 kBar(ASCIIToUTF16("bar")); | 102 const string16 kBar(ASCIIToUTF16("bar")); |
85 session_->auth_cache()->Add(GURL("http://proxy/"), "MyRealm1", "Basic", | 103 session_->auth_cache()->Add(GURL("http://proxy/"), "MyRealm1", "Basic", |
86 "Basic realm=MyRealm1", kFoo, kBar, "/"); | 104 "Basic realm=MyRealm1", kFoo, kBar, "/"); |
87 } | 105 } |
88 | 106 |
89 scoped_refptr<TCPSocketParams> GetTcpParams() { | 107 scoped_refptr<TCPSocketParams> GetTcpParams() { |
90 if (GetParam() == HTTPS) | 108 if (GetParam() != HTTP) |
91 return scoped_refptr<TCPSocketParams>(); | 109 return scoped_refptr<TCPSocketParams>(); |
92 return ignored_tcp_socket_params_; | 110 return ignored_tcp_socket_params_; |
93 } | 111 } |
94 | 112 |
95 scoped_refptr<SSLSocketParams> GetSslParams() { | 113 scoped_refptr<SSLSocketParams> GetSslParams() { |
96 if (GetParam() == HTTP) | 114 if (GetParam() == HTTP) |
97 return scoped_refptr<SSLSocketParams>(); | 115 return scoped_refptr<SSLSocketParams>(); |
98 return ignored_ssl_socket_params_; | 116 return ignored_ssl_socket_params_; |
99 } | 117 } |
100 | 118 |
101 // Returns the a correctly constructed HttpProxyParms | 119 // Returns the a correctly constructed HttpProxyParms |
102 // for the HTTP or HTTPS proxy. | 120 // for the HTTP or HTTPS proxy. |
103 scoped_refptr<HttpProxySocketParams> GetParams(bool tunnel) { | 121 scoped_refptr<HttpProxySocketParams> GetParams(bool tunnel) { |
104 return scoped_refptr<HttpProxySocketParams>( | 122 return scoped_refptr<HttpProxySocketParams>( |
105 new HttpProxySocketParams( | 123 new HttpProxySocketParams( |
106 GetTcpParams(), | 124 GetTcpParams(), |
107 GetSslParams(), | 125 GetSslParams(), |
108 GURL("http://host/"), | 126 GURL(tunnel ? "https://www.google.com/" : "http://www.google.com"), |
109 "", | 127 "", |
110 HostPortPair("host", 80), | 128 HostPortPair("www.google.com", tunnel ? 443 : 80), |
111 session_->auth_cache(), | 129 session_->auth_cache(), |
112 session_->http_auth_handler_factory(), | 130 session_->http_auth_handler_factory(), |
| 131 session_->spdy_session_pool(), |
| 132 session_->mutable_spdy_settings(), |
113 tunnel)); | 133 tunnel)); |
114 } | 134 } |
115 | 135 |
116 scoped_refptr<HttpProxySocketParams> GetTunnelParams() { | 136 scoped_refptr<HttpProxySocketParams> GetTunnelParams() { |
117 return GetParams(true); | 137 return GetParams(true); |
118 } | 138 } |
119 | 139 |
120 scoped_refptr<HttpProxySocketParams> GetNoTunnelParams() { | 140 scoped_refptr<HttpProxySocketParams> GetNoTunnelParams() { |
121 return GetParams(false); | 141 return GetParams(false); |
122 } | 142 } |
123 | 143 |
| 144 DeterministicMockClientSocketFactory& socket_factory() { |
| 145 return socket_factory_; |
| 146 } |
| 147 |
| 148 void Initialize(bool async, MockRead* reads, size_t reads_count, |
| 149 MockWrite* writes, size_t writes_count, |
| 150 MockRead* spdy_reads, size_t spdy_reads_count, |
| 151 MockWrite* spdy_writes, size_t spdy_writes_count) { |
| 152 if (GetParam() == SPDY) |
| 153 data_ = new DeterministicSocketData(spdy_reads, spdy_reads_count, |
| 154 spdy_writes, spdy_writes_count); |
| 155 else |
| 156 data_ = new DeterministicSocketData(reads, reads_count, writes, |
| 157 writes_count); |
| 158 |
| 159 data_->set_connect_data(MockConnect(async, 0)); |
| 160 data_->StopAfter(2); // Request / Response |
| 161 |
| 162 socket_factory_.AddSocketDataProvider(data_.get()); |
| 163 |
| 164 if (GetParam() != HTTP) { |
| 165 ssl_data_.reset(new SSLSocketDataProvider(async, OK)); |
| 166 if (GetParam() == SPDY) { |
| 167 InitializeSpdySsl(); |
| 168 } |
| 169 socket_factory_.AddSSLSocketDataProvider(ssl_data_.get()); |
| 170 } |
| 171 } |
| 172 |
| 173 void InitializeSpdySsl() { |
| 174 spdy::SpdyFramer::set_enable_compression_default(false); |
| 175 ssl_data_->next_proto_status = SSLClientSocket::kNextProtoNegotiated; |
| 176 ssl_data_->next_proto = "spdy/2"; |
| 177 ssl_data_->was_npn_negotiated = true; |
| 178 } |
| 179 |
| 180 private: |
124 SSLConfig ssl_config_; | 181 SSLConfig ssl_config_; |
125 | 182 |
126 scoped_refptr<TCPSocketParams> ignored_tcp_socket_params_; | 183 scoped_refptr<TCPSocketParams> ignored_tcp_socket_params_; |
127 scoped_refptr<SSLSocketParams> ignored_ssl_socket_params_; | 184 scoped_refptr<SSLSocketParams> ignored_ssl_socket_params_; |
128 ClientSocketPoolHistograms tcp_histograms_; | 185 ClientSocketPoolHistograms tcp_histograms_; |
129 MockClientSocketFactory tcp_client_socket_factory_; | 186 DeterministicMockClientSocketFactory socket_factory_; |
130 MockTCPClientSocketPool tcp_socket_pool_; | 187 MockTCPClientSocketPool tcp_socket_pool_; |
131 ClientSocketPoolHistograms ssl_histograms_; | 188 ClientSocketPoolHistograms ssl_histograms_; |
132 MockSSLClientSocketPool ssl_socket_pool_; | 189 scoped_refptr<SSLConfigService> ssl_config_service_; |
133 | |
134 MockClientSocketFactory socket_factory_; | |
135 scoped_ptr<HostResolver> host_resolver_; | 190 scoped_ptr<HostResolver> host_resolver_; |
| 191 SSLClientSocketPool ssl_socket_pool_; |
| 192 |
136 scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory_; | 193 scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory_; |
137 scoped_refptr<HttpNetworkSession> session_; | 194 scoped_refptr<HttpNetworkSession> session_; |
138 ClientSocketPoolHistograms http_proxy_histograms_; | 195 ClientSocketPoolHistograms http_proxy_histograms_; |
| 196 |
| 197 protected: |
| 198 scoped_ptr<SSLSocketDataProvider> ssl_data_; |
| 199 scoped_refptr<DeterministicSocketData> data_; |
139 HttpProxyClientSocketPool pool_; | 200 HttpProxyClientSocketPool pool_; |
| 201 ClientSocketHandle handle_; |
| 202 TestCompletionCallback callback_; |
140 }; | 203 }; |
141 | 204 |
142 //----------------------------------------------------------------------------- | 205 //----------------------------------------------------------------------------- |
143 // All tests are run with three different connection types: SPDY after NPN | 206 // All tests are run with three different proxy types: HTTP, HTTPS (non-SPDY) |
144 // negotiation, SPDY without SSL, and SPDY with SSL. | 207 // and SPDY. |
145 INSTANTIATE_TEST_CASE_P(HttpProxyClientSocketPoolTests, | 208 INSTANTIATE_TEST_CASE_P(HttpProxyClientSocketPoolTests, |
146 HttpProxyClientSocketPoolTest, | 209 HttpProxyClientSocketPoolTest, |
147 ::testing::Values(HTTP, HTTPS)); | 210 ::testing::Values(HTTP, HTTPS, SPDY)); |
148 | 211 |
149 TEST_P(HttpProxyClientSocketPoolTest, NoTunnel) { | 212 TEST_P(HttpProxyClientSocketPoolTest, NoTunnel) { |
150 StaticSocketDataProvider data; | 213 Initialize(false, NULL, 0, NULL, 0, NULL, 0, NULL, 0); |
151 data.set_connect_data(MockConnect(false, 0)); | 214 |
152 tcp_client_socket_factory_.AddSocketDataProvider(&data); | 215 int rv = handle_.Init("a", GetNoTunnelParams(), LOW, NULL, &pool_, |
153 | |
154 ClientSocketHandle handle; | |
155 int rv = handle.Init("a", GetNoTunnelParams(), LOW, NULL, &pool_, | |
156 BoundNetLog()); | 216 BoundNetLog()); |
157 EXPECT_EQ(OK, rv); | 217 EXPECT_EQ(OK, rv); |
158 EXPECT_TRUE(handle.is_initialized()); | 218 EXPECT_TRUE(handle_.is_initialized()); |
159 EXPECT_TRUE(handle.socket()); | 219 ASSERT_TRUE(handle_.socket()); |
160 HttpProxyClientSocket* tunnel_socket = | 220 HttpProxyClientSocket* tunnel_socket = |
161 static_cast<HttpProxyClientSocket*>(handle.socket()); | 221 static_cast<HttpProxyClientSocket*>(handle_.socket()); |
162 EXPECT_TRUE(tunnel_socket->IsConnected()); | 222 EXPECT_TRUE(tunnel_socket->IsConnected()); |
163 } | 223 } |
164 | 224 |
165 TEST_P(HttpProxyClientSocketPoolTest, NeedAuth) { | 225 TEST_P(HttpProxyClientSocketPoolTest, NeedAuth) { |
166 MockWrite writes[] = { | 226 MockWrite writes[] = { |
167 MockWrite("CONNECT host:80 HTTP/1.1\r\n" | 227 MockWrite(true, 0, "CONNECT www.google.com:443 HTTP/1.1\r\n" |
168 "Host: host\r\n" | 228 "Host: www.google.com\r\n" |
169 "Proxy-Connection: keep-alive\r\n\r\n"), | 229 "Proxy-Connection: keep-alive\r\n\r\n"), |
170 }; | 230 }; |
171 MockRead reads[] = { | 231 MockRead reads[] = { |
172 // No credentials. | 232 // No credentials. |
173 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), | 233 MockRead(true, 1, "HTTP/1.1 407 Proxy Authentication Required\r\n"), |
174 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), | 234 MockRead(true, 2, "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), |
175 MockRead("Content-Length: 10\r\n\r\n"), | 235 MockRead(true, 3, "Content-Length: 10\r\n\r\n"), |
176 MockRead("0123456789"), | 236 MockRead(true, 4, "0123456789"), |
177 }; | 237 }; |
178 StaticSocketDataProvider data(reads, arraysize(reads), writes, | 238 scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyConnect(NULL, 0, 1)); |
179 arraysize(writes)); | 239 scoped_ptr<spdy::SpdyFrame> rst(ConstructSpdyRstStream(1, spdy::CANCEL)); |
180 | 240 MockWrite spdy_writes[] = { |
181 tcp_client_socket_factory_.AddSocketDataProvider(&data); | 241 CreateMockWrite(*req, 0, true), |
182 | 242 CreateMockWrite(*rst, 2, true), |
183 ClientSocketHandle handle; | 243 }; |
184 TestCompletionCallback callback; | 244 scoped_ptr<spdy::SpdyFrame> resp( |
185 int rv = handle.Init("a", GetTunnelParams(), LOW, &callback, &pool_, | 245 ConstructSpdySynReplyError("407 Proxy Authentication Required", 1)); |
186 BoundNetLog()); | 246 MockRead spdy_reads[] = { |
187 EXPECT_EQ(ERR_IO_PENDING, rv); | 247 CreateMockWrite(*resp, 1, true), |
188 EXPECT_FALSE(handle.is_initialized()); | 248 MockRead(true, 0, 3) |
189 EXPECT_FALSE(handle.socket()); | 249 }; |
190 | 250 |
191 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult()); | 251 Initialize(false, reads, arraysize(reads), writes, arraysize(writes), |
192 EXPECT_TRUE(handle.is_initialized()); | 252 spdy_reads, arraysize(spdy_reads), spdy_writes, |
193 EXPECT_TRUE(handle.socket()); | 253 arraysize(spdy_writes)); |
| 254 |
| 255 data_->StopAfter(4); |
| 256 int rv = handle_.Init("a", GetTunnelParams(), LOW, &callback_, &pool_, |
| 257 BoundNetLog()); |
| 258 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 259 EXPECT_FALSE(handle_.is_initialized()); |
| 260 EXPECT_FALSE(handle_.socket()); |
| 261 |
| 262 data_->RunFor(4); |
| 263 rv = callback_.WaitForResult(); |
| 264 if (GetParam() != SPDY) { |
| 265 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, rv); |
| 266 EXPECT_TRUE(handle_.is_initialized()); |
| 267 ASSERT_TRUE(handle_.socket()); |
| 268 HttpProxyClientSocket* tunnel_socket = |
| 269 static_cast<HttpProxyClientSocket*>(handle_.socket()); |
| 270 EXPECT_FALSE(tunnel_socket->IsConnected()); |
| 271 EXPECT_FALSE(tunnel_socket->using_spdy()); |
| 272 } else { |
| 273 // Proxy auth is not really implemented for SPDY yet |
| 274 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv); |
| 275 EXPECT_FALSE(handle_.is_initialized()); |
| 276 EXPECT_FALSE(handle_.socket()); |
| 277 } |
| 278 } |
| 279 |
| 280 TEST_P(HttpProxyClientSocketPoolTest, HaveAuth) { |
| 281 // It's pretty much impossible to make the SPDY case becave synchronously |
| 282 // so we skip this test for SPDY |
| 283 if (GetParam() == SPDY) |
| 284 return; |
| 285 MockWrite writes[] = { |
| 286 MockWrite(false, 0, |
| 287 "CONNECT www.google.com:443 HTTP/1.1\r\n" |
| 288 "Host: www.google.com\r\n" |
| 289 "Proxy-Connection: keep-alive\r\n" |
| 290 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), |
| 291 }; |
| 292 MockRead reads[] = { |
| 293 MockRead(false, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"), |
| 294 }; |
| 295 |
| 296 Initialize(false, reads, arraysize(reads), writes, arraysize(writes), NULL, 0, |
| 297 NULL, 0); |
| 298 AddAuthToCache(); |
| 299 |
| 300 int rv = handle_.Init("a", GetTunnelParams(), LOW, &callback_, &pool_, |
| 301 BoundNetLog()); |
| 302 EXPECT_EQ(OK, rv); |
| 303 EXPECT_TRUE(handle_.is_initialized()); |
| 304 ASSERT_TRUE(handle_.socket()); |
194 HttpProxyClientSocket* tunnel_socket = | 305 HttpProxyClientSocket* tunnel_socket = |
195 static_cast<HttpProxyClientSocket*>(handle.socket()); | 306 static_cast<HttpProxyClientSocket*>(handle_.socket()); |
196 EXPECT_FALSE(tunnel_socket->IsConnected()); | 307 EXPECT_TRUE(tunnel_socket->IsConnected()); |
197 } | 308 } |
198 | 309 |
199 TEST_P(HttpProxyClientSocketPoolTest, HaveAuth) { | 310 TEST_P(HttpProxyClientSocketPoolTest, AsyncHaveAuth) { |
200 MockWrite writes[] = { | 311 MockWrite writes[] = { |
201 MockWrite(false, | 312 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" |
202 "CONNECT host:80 HTTP/1.1\r\n" | 313 "Host: www.google.com\r\n" |
203 "Host: host\r\n" | 314 "Proxy-Connection: keep-alive\r\n" |
204 "Proxy-Connection: keep-alive\r\n" | 315 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), |
205 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), | 316 }; |
206 }; | 317 MockRead reads[] = { |
207 MockRead reads[] = { | 318 MockRead(false, "HTTP/1.1 200 Connection Established\r\n\r\n"), |
208 MockRead(false, "HTTP/1.1 200 Connection Established\r\n\r\n"), | 319 }; |
209 }; | 320 |
210 StaticSocketDataProvider data(reads, arraysize(reads), writes, | 321 scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyConnect(kAuthHeaders, |
211 arraysize(writes)); | 322 kAuthHeadersSize, 1)); |
212 data.set_connect_data(MockConnect(false, 0)); | 323 MockWrite spdy_writes[] = { |
213 | 324 CreateMockWrite(*req, 0, true) |
214 tcp_client_socket_factory_.AddSocketDataProvider(&data); | 325 }; |
| 326 scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); |
| 327 MockRead spdy_reads[] = { |
| 328 CreateMockRead(*resp, 1, true), |
| 329 MockRead(true, 0, 2) |
| 330 }; |
| 331 |
| 332 Initialize(false, reads, arraysize(reads), writes, arraysize(writes), |
| 333 spdy_reads, arraysize(spdy_reads), spdy_writes, |
| 334 arraysize(spdy_writes)); |
215 AddAuthToCache(); | 335 AddAuthToCache(); |
216 | 336 |
217 ClientSocketHandle handle; | 337 int rv = handle_.Init("a", GetTunnelParams(), LOW, &callback_, &pool_, |
218 TestCompletionCallback callback; | 338 BoundNetLog()); |
219 int rv = handle.Init("a", GetTunnelParams(), LOW, &callback, &pool_, | 339 EXPECT_EQ(ERR_IO_PENDING, rv); |
220 BoundNetLog()); | 340 EXPECT_FALSE(handle_.is_initialized()); |
221 EXPECT_EQ(OK, rv); | 341 EXPECT_FALSE(handle_.socket()); |
222 EXPECT_TRUE(handle.is_initialized()); | 342 |
223 EXPECT_TRUE(handle.socket()); | 343 data_->RunFor(2); |
| 344 EXPECT_EQ(OK, callback_.WaitForResult()); |
| 345 EXPECT_TRUE(handle_.is_initialized()); |
| 346 ASSERT_TRUE(handle_.socket()); |
224 HttpProxyClientSocket* tunnel_socket = | 347 HttpProxyClientSocket* tunnel_socket = |
225 static_cast<HttpProxyClientSocket*>(handle.socket()); | 348 static_cast<HttpProxyClientSocket*>(handle_.socket()); |
226 EXPECT_TRUE(tunnel_socket->IsConnected()); | 349 EXPECT_TRUE(tunnel_socket->IsConnected()); |
227 } | 350 } |
228 | 351 |
229 TEST_P(HttpProxyClientSocketPoolTest, AsyncHaveAuth) { | 352 TEST_P(HttpProxyClientSocketPoolTest, TCPError) { |
230 MockWrite writes[] = { | 353 if (GetParam() == SPDY) return; |
231 MockWrite("CONNECT host:80 HTTP/1.1\r\n" | 354 data_ = new DeterministicSocketData(NULL, 0, NULL, 0); |
232 "Host: host\r\n" | 355 data_->set_connect_data(MockConnect(true, ERR_CONNECTION_CLOSED)); |
233 "Proxy-Connection: keep-alive\r\n" | 356 |
234 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), | 357 socket_factory().AddSocketDataProvider(data_.get()); |
235 }; | 358 |
236 MockRead reads[] = { | 359 int rv = handle_.Init("a", GetTunnelParams(), LOW, &callback_, &pool_, |
237 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"), | 360 BoundNetLog()); |
238 }; | 361 EXPECT_EQ(ERR_IO_PENDING, rv); |
239 StaticSocketDataProvider data(reads, arraysize(reads), writes, | 362 EXPECT_FALSE(handle_.is_initialized()); |
240 arraysize(writes)); | 363 EXPECT_FALSE(handle_.socket()); |
241 | 364 |
242 tcp_client_socket_factory_.AddSocketDataProvider(&data); | 365 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, callback_.WaitForResult()); |
| 366 |
| 367 EXPECT_FALSE(handle_.is_initialized()); |
| 368 EXPECT_FALSE(handle_.socket()); |
| 369 } |
| 370 |
| 371 TEST_P(HttpProxyClientSocketPoolTest, SSLError) { |
| 372 if (GetParam() == HTTP) return; |
| 373 data_ = new DeterministicSocketData(NULL, 0, NULL, 0); |
| 374 data_->set_connect_data(MockConnect(true, OK)); |
| 375 socket_factory().AddSocketDataProvider(data_.get()); |
| 376 |
| 377 ssl_data_.reset(new SSLSocketDataProvider(true, |
| 378 ERR_CERT_AUTHORITY_INVALID)); |
| 379 if (GetParam() == SPDY) { |
| 380 InitializeSpdySsl(); |
| 381 } |
| 382 socket_factory().AddSSLSocketDataProvider(ssl_data_.get()); |
| 383 |
| 384 int rv = handle_.Init("a", GetTunnelParams(), LOW, &callback_, &pool_, |
| 385 BoundNetLog()); |
| 386 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 387 EXPECT_FALSE(handle_.is_initialized()); |
| 388 EXPECT_FALSE(handle_.socket()); |
| 389 |
| 390 EXPECT_EQ(ERR_PROXY_CERTIFICATE_INVALID, callback_.WaitForResult()); |
| 391 |
| 392 EXPECT_FALSE(handle_.is_initialized()); |
| 393 EXPECT_FALSE(handle_.socket()); |
| 394 } |
| 395 |
| 396 TEST_P(HttpProxyClientSocketPoolTest, SslClientAuth) { |
| 397 if (GetParam() == HTTP) return; |
| 398 data_ = new DeterministicSocketData(NULL, 0, NULL, 0); |
| 399 data_->set_connect_data(MockConnect(true, OK)); |
| 400 socket_factory().AddSocketDataProvider(data_.get()); |
| 401 |
| 402 ssl_data_.reset(new SSLSocketDataProvider(true, |
| 403 ERR_SSL_CLIENT_AUTH_CERT_NEEDED)); |
| 404 if (GetParam() == SPDY) { |
| 405 InitializeSpdySsl(); |
| 406 } |
| 407 socket_factory().AddSSLSocketDataProvider(ssl_data_.get()); |
| 408 |
| 409 int rv = handle_.Init("a", GetTunnelParams(), LOW, &callback_, &pool_, |
| 410 BoundNetLog()); |
| 411 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 412 EXPECT_FALSE(handle_.is_initialized()); |
| 413 EXPECT_FALSE(handle_.socket()); |
| 414 |
| 415 EXPECT_EQ(ERR_PROXY_AUTH_UNSUPPORTED, callback_.WaitForResult()); |
| 416 |
| 417 EXPECT_FALSE(handle_.is_initialized()); |
| 418 EXPECT_FALSE(handle_.socket()); |
| 419 } |
| 420 |
| 421 TEST_P(HttpProxyClientSocketPoolTest, TunnelUnexpectedClose) { |
| 422 MockWrite writes[] = { |
| 423 MockWrite(true, 0, |
| 424 "CONNECT www.google.com:443 HTTP/1.1\r\n" |
| 425 "Host: www.google.com\r\n" |
| 426 "Proxy-Connection: keep-alive\r\n" |
| 427 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), |
| 428 }; |
| 429 MockRead reads[] = { |
| 430 MockRead(true, 1, "HTTP/1.1 200 Conn"), |
| 431 MockRead(true, ERR_CONNECTION_CLOSED, 2), |
| 432 }; |
| 433 scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyConnect(kAuthHeaders, |
| 434 kAuthHeadersSize, 1)); |
| 435 MockWrite spdy_writes[] = { |
| 436 CreateMockWrite(*req, 0, true) |
| 437 }; |
| 438 MockRead spdy_reads[] = { |
| 439 MockRead(true, ERR_CONNECTION_CLOSED, 1), |
| 440 }; |
| 441 |
| 442 Initialize(false, reads, arraysize(reads), writes, arraysize(writes), |
| 443 spdy_reads, arraysize(spdy_reads), spdy_writes, |
| 444 arraysize(spdy_writes)); |
243 AddAuthToCache(); | 445 AddAuthToCache(); |
244 | 446 |
245 ClientSocketHandle handle; | 447 int rv = handle_.Init("a", GetTunnelParams(), LOW, &callback_, &pool_, |
246 TestCompletionCallback callback; | 448 BoundNetLog()); |
247 int rv = handle.Init("a", GetTunnelParams(), LOW, &callback, &pool_, | 449 EXPECT_EQ(ERR_IO_PENDING, rv); |
248 BoundNetLog()); | 450 EXPECT_FALSE(handle_.is_initialized()); |
249 EXPECT_EQ(ERR_IO_PENDING, rv); | 451 EXPECT_FALSE(handle_.socket()); |
250 EXPECT_FALSE(handle.is_initialized()); | 452 |
251 EXPECT_FALSE(handle.socket()); | 453 data_->RunFor(3); |
252 | 454 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback_.WaitForResult()); |
253 EXPECT_EQ(OK, callback.WaitForResult()); | 455 EXPECT_FALSE(handle_.is_initialized()); |
254 EXPECT_TRUE(handle.is_initialized()); | 456 EXPECT_FALSE(handle_.socket()); |
255 EXPECT_TRUE(handle.socket()); | 457 } |
256 HttpProxyClientSocket* tunnel_socket = | 458 |
257 static_cast<HttpProxyClientSocket*>(handle.socket()); | 459 TEST_P(HttpProxyClientSocketPoolTest, TunnelSetupError) { |
258 EXPECT_TRUE(tunnel_socket->IsConnected()); | 460 MockWrite writes[] = { |
259 } | 461 MockWrite(true, 0, |
260 | 462 "CONNECT www.google.com:443 HTTP/1.1\r\n" |
261 TEST_P(HttpProxyClientSocketPoolTest, TCPError) { | 463 "Host: www.google.com\r\n" |
262 StaticSocketDataProvider data; | 464 "Proxy-Connection: keep-alive\r\n" |
263 data.set_connect_data(MockConnect(true, ERR_CONNECTION_CLOSED)); | 465 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), |
264 | 466 }; |
265 tcp_client_socket_factory_.AddSocketDataProvider(&data); | 467 MockRead reads[] = { |
266 | 468 MockRead(true, 1, "HTTP/1.1 304 Not Modified\r\n\r\n"), |
267 ClientSocketHandle handle; | 469 }; |
268 TestCompletionCallback callback; | 470 scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyConnect(kAuthHeaders, |
269 int rv = handle.Init("a", GetTunnelParams(), LOW, &callback, &pool_, | 471 kAuthHeadersSize, 1)); |
270 BoundNetLog()); | 472 scoped_ptr<spdy::SpdyFrame> rst(ConstructSpdyRstStream(1, spdy::CANCEL)); |
271 EXPECT_EQ(ERR_IO_PENDING, rv); | 473 MockWrite spdy_writes[] = { |
272 EXPECT_FALSE(handle.is_initialized()); | 474 CreateMockWrite(*req, 0, true), |
273 EXPECT_FALSE(handle.socket()); | 475 CreateMockWrite(*rst, 2, true), |
274 | 476 }; |
275 if (GetParam() == HTTP) | 477 scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdySynReplyError(1)); |
276 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, callback.WaitForResult()); | 478 MockRead spdy_reads[] = { |
277 else | 479 CreateMockRead(*resp, 1, true), |
278 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult()); | 480 MockRead(true, 0, 3), |
279 | 481 }; |
280 EXPECT_FALSE(handle.is_initialized()); | 482 |
281 EXPECT_FALSE(handle.socket()); | 483 Initialize(false, reads, arraysize(reads), writes, arraysize(writes), |
282 } | 484 spdy_reads, arraysize(spdy_reads), spdy_writes, |
283 | 485 arraysize(spdy_writes)); |
284 TEST_P(HttpProxyClientSocketPoolTest, TunnelUnexpectedClose) { | |
285 MockWrite writes[] = { | |
286 MockWrite("CONNECT host:80 HTTP/1.1\r\n" | |
287 "Host: host\r\n" | |
288 "Proxy-Connection: keep-alive\r\n" | |
289 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), | |
290 }; | |
291 MockRead reads[] = { | |
292 MockRead("HTTP/1.1 200 Conn"), | |
293 MockRead(true, ERR_CONNECTION_CLOSED), | |
294 }; | |
295 StaticSocketDataProvider data(reads, arraysize(reads), writes, | |
296 arraysize(writes)); | |
297 | |
298 tcp_client_socket_factory_.AddSocketDataProvider(&data); | |
299 AddAuthToCache(); | 486 AddAuthToCache(); |
300 | 487 |
301 ClientSocketHandle handle; | 488 int rv = handle_.Init("a", GetTunnelParams(), LOW, &callback_, &pool_, |
302 TestCompletionCallback callback; | 489 BoundNetLog()); |
303 int rv = handle.Init("a", GetTunnelParams(), LOW, &callback, &pool_, | 490 EXPECT_EQ(ERR_IO_PENDING, rv); |
304 BoundNetLog()); | 491 EXPECT_FALSE(handle_.is_initialized()); |
305 EXPECT_EQ(ERR_IO_PENDING, rv); | 492 EXPECT_FALSE(handle_.socket()); |
306 EXPECT_FALSE(handle.is_initialized()); | 493 |
307 EXPECT_FALSE(handle.socket()); | 494 data_->RunFor(2); |
308 | 495 |
309 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult()); | 496 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback_.WaitForResult()); |
310 EXPECT_FALSE(handle.is_initialized()); | 497 EXPECT_FALSE(handle_.is_initialized()); |
311 EXPECT_FALSE(handle.socket()); | 498 EXPECT_FALSE(handle_.socket()); |
312 } | |
313 | |
314 TEST_P(HttpProxyClientSocketPoolTest, TunnelSetupError) { | |
315 MockWrite writes[] = { | |
316 MockWrite("CONNECT host:80 HTTP/1.1\r\n" | |
317 "Host: host\r\n" | |
318 "Proxy-Connection: keep-alive\r\n" | |
319 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), | |
320 }; | |
321 MockRead reads[] = { | |
322 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"), | |
323 }; | |
324 StaticSocketDataProvider data(reads, arraysize(reads), writes, | |
325 arraysize(writes)); | |
326 | |
327 tcp_client_socket_factory_.AddSocketDataProvider(&data); | |
328 AddAuthToCache(); | |
329 | |
330 ClientSocketHandle handle; | |
331 TestCompletionCallback callback; | |
332 int rv = handle.Init("a", GetTunnelParams(), LOW, &callback, &pool_, | |
333 BoundNetLog()); | |
334 EXPECT_EQ(ERR_IO_PENDING, rv); | |
335 EXPECT_FALSE(handle.is_initialized()); | |
336 EXPECT_FALSE(handle.socket()); | |
337 | |
338 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult()); | |
339 EXPECT_FALSE(handle.is_initialized()); | |
340 EXPECT_FALSE(handle.socket()); | |
341 } | 499 } |
342 | 500 |
343 // It would be nice to also test the timeouts in HttpProxyClientSocketPool. | 501 // It would be nice to also test the timeouts in HttpProxyClientSocketPool. |
344 | 502 |
345 } // namespace | |
346 | |
347 } // namespace net | 503 } // namespace net |
OLD | NEW |