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

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

Issue 3110006: Add support for speaking SSL to an HTTP Proxy, to HttpProxyClientSocketPool (and friends) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 3 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 | Annotate | Revision Log
« no previous file with comments | « net/http/http_stream_request.h ('k') | net/socket/socket_test_util.h » ('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 (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_stream_request.h" 5 #include "net/http/http_stream_request.h"
6 6
7 #include "base/stl_util-inl.h" 7 #include "base/stl_util-inl.h"
8 #include "base/string_number_conversions.h" 8 #include "base/string_number_conversions.h"
9 #include "base/string_util.h" 9 #include "base/string_util.h"
10 #include "net/base/connection_type_histograms.h" 10 #include "net/base/connection_type_histograms.h"
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 pac_request_ = NULL; 388 pac_request_ = NULL;
389 389
390 if (result != OK) 390 if (result != OK)
391 return result; 391 return result;
392 392
393 // TODO(mbelshe): consider retrying ResolveProxy if we came here via use of 393 // TODO(mbelshe): consider retrying ResolveProxy if we came here via use of
394 // AlternateProtocol. 394 // AlternateProtocol.
395 395
396 // Remove unsupported proxies from the list. 396 // Remove unsupported proxies from the list.
397 proxy_info()->RemoveProxiesWithoutScheme( 397 proxy_info()->RemoveProxiesWithoutScheme(
398 ProxyServer::SCHEME_DIRECT | ProxyServer::SCHEME_HTTP | 398 ProxyServer::SCHEME_DIRECT |
399 ProxyServer::SCHEME_HTTP | ProxyServer::SCHEME_HTTPS |
399 ProxyServer::SCHEME_SOCKS4 | ProxyServer::SCHEME_SOCKS5); 400 ProxyServer::SCHEME_SOCKS4 | ProxyServer::SCHEME_SOCKS5);
400 401
401 if (proxy_info()->is_empty()) { 402 if (proxy_info()->is_empty()) {
402 // No proxies/direct to choose from. This happens when we don't support any 403 // No proxies/direct to choose from. This happens when we don't support any
403 // of the proxies in the returned list. 404 // of the proxies in the returned list.
404 return ERR_NO_SUPPORTED_PROXIES; 405 return ERR_NO_SUPPORTED_PROXIES;
405 } 406 }
406 407
407 next_state_ = STATE_INIT_CONNECTION; 408 next_state_ = STATE_INIT_CONNECTION;
408 return OK; 409 return OK;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 tcp_params = new TCPSocketParams(endpoint_, request_info().priority, 455 tcp_params = new TCPSocketParams(endpoint_, request_info().priority,
455 request_info().referrer, 456 request_info().referrer,
456 disable_resolver_cache); 457 disable_resolver_cache);
457 } else { 458 } else {
458 ProxyServer proxy_server = proxy_info()->proxy_server(); 459 ProxyServer proxy_server = proxy_info()->proxy_server();
459 proxy_host_port.reset(new HostPortPair(proxy_server.host_port_pair())); 460 proxy_host_port.reset(new HostPortPair(proxy_server.host_port_pair()));
460 scoped_refptr<TCPSocketParams> proxy_tcp_params = 461 scoped_refptr<TCPSocketParams> proxy_tcp_params =
461 new TCPSocketParams(*proxy_host_port, request_info().priority, 462 new TCPSocketParams(*proxy_host_port, request_info().priority,
462 request_info().referrer, disable_resolver_cache); 463 request_info().referrer, disable_resolver_cache);
463 464
464 if (proxy_info()->is_http()) { 465 if (proxy_info()->is_http() || proxy_info()->is_https()) {
465 GURL authentication_url = request_info().url; 466 GURL authentication_url = request_info().url;
466 if (using_ssl_ && !authentication_url.SchemeIs("https")) { 467 if (using_ssl_ && !authentication_url.SchemeIs("https")) {
467 // If a proxy tunnel connection needs to be established due to 468 // If a proxy tunnel connection needs to be established due to
468 // an Alternate-Protocol, the URL needs to be changed to indicate 469 // an Alternate-Protocol, the URL needs to be changed to indicate
469 // https or digest authentication attempts will fail. 470 // https or digest authentication attempts will fail.
470 // For example, suppose the initial request was for 471 // For example, suppose the initial request was for
471 // "http://www.example.com/index.html". If this is an SSL 472 // "http://www.example.com/index.html". If this is an SSL
472 // upgrade due to alternate protocol, the digest authorization 473 // upgrade due to alternate protocol, the digest authorization
473 // should have a uri="www.example.com:443" field rather than a 474 // should have a uri="www.example.com:443" field rather than a
474 // "/index.html" entry, even though the original request URL has not 475 // "/index.html" entry, even though the original request URL has not
475 // changed. 476 // changed.
476 authentication_url = UpgradeUrlToHttps(authentication_url); 477 authentication_url = UpgradeUrlToHttps(authentication_url);
477 } 478 }
478 establishing_tunnel_ = using_ssl_; 479 establishing_tunnel_ = using_ssl_;
479 std::string user_agent; 480 std::string user_agent;
480 request_info().extra_headers.GetHeader(HttpRequestHeaders::kUserAgent, 481 request_info().extra_headers.GetHeader(HttpRequestHeaders::kUserAgent,
481 &user_agent); 482 &user_agent);
483 scoped_refptr<SSLSocketParams> ssl_params;
484 if (proxy_info()->is_https())
485 // Set ssl_params, and unset proxy_tcp_params
486 ssl_params = GenerateSslParams(proxy_tcp_params.release(), NULL, NULL,
487 ProxyServer::SCHEME_DIRECT,
488 want_spdy_over_npn);
489
482 http_proxy_params = new HttpProxySocketParams(proxy_tcp_params, 490 http_proxy_params = new HttpProxySocketParams(proxy_tcp_params,
491 ssl_params,
483 authentication_url, 492 authentication_url,
484 user_agent, 493 user_agent,
485 endpoint_, 494 endpoint_,
486 session_, using_ssl_); 495 session_, using_ssl_);
487 } else { 496 } else {
488 DCHECK(proxy_info()->is_socks()); 497 DCHECK(proxy_info()->is_socks());
489 char socks_version; 498 char socks_version;
490 if (proxy_server.scheme() == ProxyServer::SCHEME_SOCKS5) 499 if (proxy_server.scheme() == ProxyServer::SCHEME_SOCKS5)
491 socks_version = '5'; 500 socks_version = '5';
492 else 501 else
493 socks_version = '4'; 502 socks_version = '4';
494 connection_group = 503 connection_group =
495 StringPrintf("socks%c/%s", socks_version, connection_group.c_str()); 504 StringPrintf("socks%c/%s", socks_version, connection_group.c_str());
496 505
497 socks_params = new SOCKSSocketParams(proxy_tcp_params, 506 socks_params = new SOCKSSocketParams(proxy_tcp_params,
498 socks_version == '5', 507 socks_version == '5',
499 endpoint_, 508 endpoint_,
500 request_info().priority, 509 request_info().priority,
501 request_info().referrer); 510 request_info().referrer);
502 } 511 }
503 } 512 }
504 513
505 // Deal with SSL - which layers on top of any given proxy. 514 // Deal with SSL - which layers on top of any given proxy.
506 if (using_ssl_) { 515 if (using_ssl_) {
507 if (factory_->IsTLSIntolerantServer(request_info().url)) {
508 LOG(WARNING) << "Falling back to SSLv3 because host is TLS intolerant: "
509 << GetHostAndPort(request_info().url);
510 ssl_config()->ssl3_fallback = true;
511 ssl_config()->tls1_enabled = false;
512 }
513
514 UMA_HISTOGRAM_ENUMERATION("Net.ConnectionUsedSSLv3Fallback",
515 static_cast<int>(ssl_config()->ssl3_fallback), 2);
516
517 int load_flags = request_info().load_flags;
518 if (factory_->ignore_certificate_errors())
519 load_flags |= LOAD_IGNORE_ALL_CERT_ERRORS;
520 if (request_info().load_flags & LOAD_VERIFY_EV_CERT)
521 ssl_config()->verify_ev_cert = true;
522
523 if (proxy_info()->proxy_server().scheme() == ProxyServer::SCHEME_HTTP ||
524 proxy_info()->proxy_server().scheme() == ProxyServer::SCHEME_HTTPS) {
525 ssl_config()->mitm_proxies_allowed = true;
526 }
527
528 scoped_refptr<SSLSocketParams> ssl_params = 516 scoped_refptr<SSLSocketParams> ssl_params =
529 new SSLSocketParams(tcp_params, http_proxy_params, socks_params, 517 GenerateSslParams(tcp_params, http_proxy_params, socks_params,
530 proxy_info()->proxy_server().scheme(), 518 proxy_info()->proxy_server().scheme(),
531 request_info().url.HostNoBrackets(), *ssl_config(), 519 want_spdy_over_npn);
532 load_flags,
533 force_spdy_always_ && force_spdy_over_ssl_,
534 want_spdy_over_npn);
535
536 scoped_refptr<SSLClientSocketPool> ssl_pool; 520 scoped_refptr<SSLClientSocketPool> ssl_pool;
537 if (proxy_info()->is_direct()) 521 if (proxy_info()->is_direct())
538 ssl_pool = session_->ssl_socket_pool(); 522 ssl_pool = session_->ssl_socket_pool();
539 else 523 else
540 ssl_pool = session_->GetSocketPoolForSSLWithProxy(*proxy_host_port); 524 ssl_pool = session_->GetSocketPoolForSSLWithProxy(*proxy_host_port);
541 525
542 return connection_->Init(connection_group, ssl_params, 526 return connection_->Init(connection_group, ssl_params,
543 request_info().priority, &io_callback_, ssl_pool, 527 request_info().priority, &io_callback_, ssl_pool,
544 net_log_); 528 net_log_);
545 } 529 }
546 530
547 // Finally, get the connection started. 531 // Finally, get the connection started.
548 if (proxy_info()->is_http()) { 532 if (proxy_info()->is_http() || proxy_info()->is_https()) {
549 return connection_->Init( 533 return connection_->Init(
550 connection_group, http_proxy_params, request_info().priority, 534 connection_group, http_proxy_params, request_info().priority,
551 &io_callback_, session_->GetSocketPoolForHTTPProxy(*proxy_host_port), 535 &io_callback_, session_->GetSocketPoolForHTTPProxy(*proxy_host_port),
552 net_log_); 536 net_log_);
553 } 537 }
554 538
555 if (proxy_info()->is_socks()) { 539 if (proxy_info()->is_socks()) {
556 return connection_->Init( 540 return connection_->Init(
557 connection_group, socks_params, request_info().priority, &io_callback_, 541 connection_group, socks_params, request_info().priority, &io_callback_,
558 session_->GetSocketPoolForSOCKSProxy(*proxy_host_port), net_log_); 542 session_->GetSocketPoolForSOCKSProxy(*proxy_host_port), net_log_);
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 // socket, but there will be forward progress. 720 // socket, but there will be forward progress.
737 connection_->Reset(); 721 connection_->Reset();
738 establishing_tunnel_ = false; 722 establishing_tunnel_ = false;
739 next_state_ = STATE_INIT_CONNECTION; 723 next_state_ = STATE_INIT_CONNECTION;
740 return OK; 724 return OK;
741 } 725 }
742 726
743 return ReconsiderProxyAfterError(result); 727 return ReconsiderProxyAfterError(result);
744 } 728 }
745 729
730 // Returns a newly create SSLSocketParams, and sets several
731 // fields of ssl_config_.
732 scoped_refptr<SSLSocketParams> HttpStreamRequest::GenerateSslParams(
733 scoped_refptr<TCPSocketParams> tcp_params,
734 scoped_refptr<HttpProxySocketParams> http_proxy_params,
735 scoped_refptr<SOCKSSocketParams> socks_params,
736 ProxyServer::Scheme proxy_scheme,
737 bool want_spdy_over_npn) {
738
739 if (factory_->IsTLSIntolerantServer(request_info().url)) {
740 LOG(WARNING) << "Falling back to SSLv3 because host is TLS intolerant: "
741 << GetHostAndPort(request_info().url);
742 ssl_config()->ssl3_fallback = true;
743 ssl_config()->tls1_enabled = false;
744 }
745
746 UMA_HISTOGRAM_ENUMERATION("Net.ConnectionUsedSSLv3Fallback",
747 static_cast<int>(ssl_config()->ssl3_fallback), 2);
748
749 int load_flags = request_info().load_flags;
750 if (factory_->ignore_certificate_errors())
751 load_flags |= LOAD_IGNORE_ALL_CERT_ERRORS;
752 if (request_info().load_flags & LOAD_VERIFY_EV_CERT)
753 ssl_config()->verify_ev_cert = true;
754
755 if (proxy_info()->proxy_server().scheme() == ProxyServer::SCHEME_HTTP ||
756 proxy_info()->proxy_server().scheme() == ProxyServer::SCHEME_HTTPS) {
757 ssl_config()->mitm_proxies_allowed = true;
758 }
759
760 scoped_refptr<SSLSocketParams> ssl_params =
761 new SSLSocketParams(tcp_params, http_proxy_params, socks_params,
762 proxy_scheme, request_info().url.HostNoBrackets(),
763 *ssl_config(), load_flags,
764 force_spdy_always_ && force_spdy_over_ssl_,
765 want_spdy_over_npn);
766
767 return ssl_params;
768 }
769
770
746 void HttpStreamRequest::MarkBrokenAlternateProtocolAndFallback() { 771 void HttpStreamRequest::MarkBrokenAlternateProtocolAndFallback() {
747 // We have to: 772 // We have to:
748 // * Reset the endpoint to be the unmodified URL specified destination. 773 // * Reset the endpoint to be the unmodified URL specified destination.
749 // * Mark the endpoint as broken so we don't try again. 774 // * Mark the endpoint as broken so we don't try again.
750 // * Set the alternate protocol mode to kDoNotUseAlternateProtocol so we 775 // * Set the alternate protocol mode to kDoNotUseAlternateProtocol so we
751 // ignore future Alternate-Protocol headers from the HostPortPair. 776 // ignore future Alternate-Protocol headers from the HostPortPair.
752 // * Reset the connection and go back to STATE_INIT_CONNECTION. 777 // * Reset the connection and go back to STATE_INIT_CONNECTION.
753 778
754 endpoint_ = HostPortPair(request_info().url.HostNoBrackets(), 779 endpoint_ = HostPortPair(request_info().url.HostNoBrackets(),
755 request_info().url.EffectiveIntPort()); 780 request_info().url.EffectiveIntPort());
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
908 base::TimeDelta::FromMinutes(6), 933 base::TimeDelta::FromMinutes(6),
909 100); 934 100);
910 break; 935 break;
911 default: 936 default:
912 NOTREACHED(); 937 NOTREACHED();
913 break; 938 break;
914 } 939 }
915 } 940 }
916 941
917 } // namespace net 942 } // namespace net
918
OLDNEW
« no previous file with comments | « net/http/http_stream_request.h ('k') | net/socket/socket_test_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698