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_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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 | |
OLD | NEW |