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