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