Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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_factory_impl_job.h" | 5 #include "net/http/http_stream_factory_impl_job.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 285 // https://somehost/ that we don't use that session for http://somehost:443/. | 285 // https://somehost/ that we don't use that session for http://somehost:443/. |
| 286 // The only time we can use an existing session is if the request URL is | 286 // The only time we can use an existing session is if the request URL is |
| 287 // https (the normal case) or if we're connection to a SPDY proxy. | 287 // https (the normal case) or if we're connection to a SPDY proxy. |
| 288 // https://crbug.com/133176 | 288 // https://crbug.com/133176 |
| 289 // TODO(ricea): Add "wss" back to this list when SPDY WebSocket support is | 289 // TODO(ricea): Add "wss" back to this list when SPDY WebSocket support is |
| 290 // working. | 290 // working. |
| 291 return origin_url_.SchemeIs("https") || | 291 return origin_url_.SchemeIs("https") || |
| 292 proxy_info_.proxy_server().is_https() || IsSpdyAlternate(); | 292 proxy_info_.proxy_server().is_https() || IsSpdyAlternate(); |
| 293 } | 293 } |
| 294 | 294 |
| 295 bool HttpStreamFactoryImpl::Job::IsAlternativeCertificateValidForOrigin( | |
| 296 base::WeakPtr<SpdySession> spdy_session) { | |
| 297 if (!IsSpdyAlternate()) { | |
| 298 return true; | |
| 299 } | |
| 300 if (origin_url_.host() == spdy_session->host_port_pair().host()) { | |
| 301 return true; | |
| 302 } | |
| 303 DCHECK(spdy_session); | |
|
Ryan Hamilton
2015/04/11 02:40:41
I think it made more sense to do the DCHECK at the
Bence
2015/04/13 17:52:40
I moved the spdy_session == nullptr case to this m
| |
| 304 return spdy_session->VerifyDomainAuthentication(origin_url_.host()); | |
| 305 } | |
| 306 | |
| 295 void HttpStreamFactoryImpl::Job::OnStreamReadyCallback() { | 307 void HttpStreamFactoryImpl::Job::OnStreamReadyCallback() { |
| 296 DCHECK(stream_.get()); | 308 DCHECK(stream_.get()); |
| 297 DCHECK(!IsPreconnecting()); | 309 DCHECK(!IsPreconnecting()); |
| 298 DCHECK(!stream_factory_->for_websockets_); | 310 DCHECK(!stream_factory_->for_websockets_); |
| 299 if (IsOrphaned()) { | 311 if (IsOrphaned()) { |
| 300 stream_factory_->OnOrphanedJobComplete(this); | 312 stream_factory_->OnOrphanedJobComplete(this); |
| 301 } else { | 313 } else { |
| 302 request_->Complete(was_npn_negotiated(), | 314 request_->Complete(was_npn_negotiated(), |
| 303 protocol_negotiated(), | 315 protocol_negotiated(), |
| 304 using_spdy(), | 316 using_spdy(), |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 528 base::Bind(&Job::OnWebSocketHandshakeStreamReadyCallback, | 540 base::Bind(&Job::OnWebSocketHandshakeStreamReadyCallback, |
| 529 ptr_factory_.GetWeakPtr())); | 541 ptr_factory_.GetWeakPtr())); |
| 530 } else { | 542 } else { |
| 531 DCHECK(stream_.get()); | 543 DCHECK(stream_.get()); |
| 532 base::MessageLoop::current()->PostTask( | 544 base::MessageLoop::current()->PostTask( |
| 533 FROM_HERE, | 545 FROM_HERE, |
| 534 base::Bind(&Job::OnStreamReadyCallback, ptr_factory_.GetWeakPtr())); | 546 base::Bind(&Job::OnStreamReadyCallback, ptr_factory_.GetWeakPtr())); |
| 535 } | 547 } |
| 536 return ERR_IO_PENDING; | 548 return ERR_IO_PENDING; |
| 537 | 549 |
| 550 case ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN: | |
| 551 DCHECK(IsSpdyAlternate()); | |
| 552 if (job_status_ != STATUS_BROKEN) { | |
| 553 DCHECK_EQ(STATUS_RUNNING, job_status_); | |
| 554 job_status_ = STATUS_FAILED; | |
| 555 // TODO(bnc): Instead of marking alternative service broken, mark | |
| 556 // (origin, alternative service) couple as invalid. | |
| 557 MaybeMarkAlternativeServiceBroken(); | |
| 558 } | |
| 559 base::MessageLoop::current()->PostTask( | |
| 560 FROM_HERE, base::Bind(&Job::OnStreamFailedCallback, | |
| 561 ptr_factory_.GetWeakPtr(), result)); | |
| 562 return ERR_IO_PENDING; | |
| 563 | |
| 538 default: | 564 default: |
| 539 if (job_status_ != STATUS_BROKEN) { | 565 if (job_status_ != STATUS_BROKEN) { |
| 540 DCHECK_EQ(STATUS_RUNNING, job_status_); | 566 DCHECK_EQ(STATUS_RUNNING, job_status_); |
| 541 job_status_ = STATUS_FAILED; | 567 job_status_ = STATUS_FAILED; |
| 542 MaybeMarkAlternativeServiceBroken(); | 568 MaybeMarkAlternativeServiceBroken(); |
| 543 } | 569 } |
| 544 base::MessageLoop::current()->PostTask( | 570 base::MessageLoop::current()->PostTask( |
| 545 FROM_HERE, | 571 FROM_HERE, |
| 546 base::Bind(&Job::OnStreamFailedCallback, ptr_factory_.GetWeakPtr(), | 572 base::Bind(&Job::OnStreamFailedCallback, ptr_factory_.GetWeakPtr(), |
| 547 result)); | 573 result)); |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 797 return rv; | 823 return rv; |
| 798 } | 824 } |
| 799 | 825 |
| 800 // Check first if we have a spdy session for this group. If so, then go | 826 // Check first if we have a spdy session for this group. If so, then go |
| 801 // straight to using that. | 827 // straight to using that. |
| 802 SpdySessionKey spdy_session_key = GetSpdySessionKey(); | 828 SpdySessionKey spdy_session_key = GetSpdySessionKey(); |
| 803 base::WeakPtr<SpdySession> spdy_session = | 829 base::WeakPtr<SpdySession> spdy_session = |
| 804 session_->spdy_session_pool()->FindAvailableSession( | 830 session_->spdy_session_pool()->FindAvailableSession( |
| 805 spdy_session_key, net_log_); | 831 spdy_session_key, net_log_); |
| 806 if (spdy_session && CanUseExistingSpdySession()) { | 832 if (spdy_session && CanUseExistingSpdySession()) { |
| 833 if (!IsAlternativeCertificateValidForOrigin(spdy_session)) { | |
| 834 return ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN; | |
| 835 } | |
| 807 // If we're preconnecting, but we already have a SpdySession, we don't | 836 // If we're preconnecting, but we already have a SpdySession, we don't |
| 808 // actually need to preconnect any sockets, so we're done. | 837 // actually need to preconnect any sockets, so we're done. |
| 809 if (IsPreconnecting()) | 838 if (IsPreconnecting()) |
| 810 return OK; | 839 return OK; |
| 811 using_spdy_ = true; | 840 using_spdy_ = true; |
| 812 next_state_ = STATE_CREATE_STREAM; | 841 next_state_ = STATE_CREATE_STREAM; |
| 813 existing_spdy_session_ = spdy_session; | 842 existing_spdy_session_ = spdy_session; |
| 814 return OK; | 843 return OK; |
| 815 } else if (request_ && !request_->HasSpdySessionKey() && using_ssl_) { | 844 } |
| 845 if (request_ && !request_->HasSpdySessionKey() && using_ssl_) { | |
| 816 // Update the spdy session key for the request that launched this job. | 846 // Update the spdy session key for the request that launched this job. |
| 817 request_->SetSpdySessionKey(spdy_session_key); | 847 request_->SetSpdySessionKey(spdy_session_key); |
| 818 } | 848 } |
| 819 | 849 |
| 820 // OK, there's no available SPDY session. Let |waiting_job_| resume if it's | 850 // OK, there's no available SPDY session. Let |waiting_job_| resume if it's |
| 821 // paused. | 851 // paused. |
| 822 | |
| 823 if (waiting_job_) { | 852 if (waiting_job_) { |
| 824 waiting_job_->Resume(this); | 853 waiting_job_->Resume(this); |
| 825 waiting_job_ = NULL; | 854 waiting_job_ = NULL; |
| 826 } | 855 } |
| 827 | 856 |
| 828 if (proxy_info_.is_http() || proxy_info_.is_https()) | 857 if (proxy_info_.is_http() || proxy_info_.is_https()) |
| 829 establishing_tunnel_ = using_ssl_; | 858 establishing_tunnel_ = using_ssl_; |
| 830 | 859 |
| 831 // TODO(bnc): s/want_spdy_over_npn/expect_spdy_over_npn/ | 860 // TODO(bnc): s/want_spdy_over_npn/expect_spdy_over_npn/ |
| 832 bool want_spdy_over_npn = IsAlternate(); | 861 bool want_spdy_over_npn = IsAlternate(); |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 982 // puts the in progress HttpProxy socket into |connection_| in order to | 1011 // puts the in progress HttpProxy socket into |connection_| in order to |
| 983 // complete the auth (or read the response body). The tunnel restart code | 1012 // complete the auth (or read the response body). The tunnel restart code |
| 984 // is careful to remove it before returning control to the rest of this | 1013 // is careful to remove it before returning control to the rest of this |
| 985 // class. | 1014 // class. |
| 986 connection_.reset(connection_->release_pending_http_proxy_connection()); | 1015 connection_.reset(connection_->release_pending_http_proxy_connection()); |
| 987 return result; | 1016 return result; |
| 988 } | 1017 } |
| 989 | 1018 |
| 990 if (!ssl_started && result < 0 && IsAlternate()) { | 1019 if (!ssl_started && result < 0 && IsAlternate()) { |
| 991 job_status_ = STATUS_BROKEN; | 1020 job_status_ = STATUS_BROKEN; |
| 1021 // TODO(bnc): if (result == ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN), then | |
| 1022 // instead of marking alternative service broken, mark (origin, alternative | |
| 1023 // service) couple as invalid. | |
| 992 MaybeMarkAlternativeServiceBroken(); | 1024 MaybeMarkAlternativeServiceBroken(); |
| 993 return result; | 1025 return result; |
| 994 } | 1026 } |
| 995 | 1027 |
| 996 if (using_quic_) { | 1028 if (using_quic_) { |
| 997 if (result < 0) { | 1029 if (result < 0) { |
| 998 job_status_ = STATUS_BROKEN; | 1030 job_status_ = STATUS_BROKEN; |
| 999 MaybeMarkAlternativeServiceBroken(); | 1031 MaybeMarkAlternativeServiceBroken(); |
| 1000 return result; | 1032 return result; |
| 1001 } | 1033 } |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1124 spdy_session_key = SpdySessionKey(proxy_server.host_port_pair(), | 1156 spdy_session_key = SpdySessionKey(proxy_server.host_port_pair(), |
| 1125 ProxyServer::Direct(), | 1157 ProxyServer::Direct(), |
| 1126 PRIVACY_MODE_DISABLED); | 1158 PRIVACY_MODE_DISABLED); |
| 1127 } | 1159 } |
| 1128 | 1160 |
| 1129 SpdySessionPool* spdy_pool = session_->spdy_session_pool(); | 1161 SpdySessionPool* spdy_pool = session_->spdy_session_pool(); |
| 1130 base::WeakPtr<SpdySession> spdy_session = | 1162 base::WeakPtr<SpdySession> spdy_session = |
| 1131 spdy_pool->FindAvailableSession(spdy_session_key, net_log_); | 1163 spdy_pool->FindAvailableSession(spdy_session_key, net_log_); |
| 1132 | 1164 |
| 1133 if (spdy_session) { | 1165 if (spdy_session) { |
| 1166 if (!IsAlternativeCertificateValidForOrigin(spdy_session)) { | |
| 1167 return ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN; | |
| 1168 } | |
| 1134 return SetSpdyHttpStream(spdy_session, direct); | 1169 return SetSpdyHttpStream(spdy_session, direct); |
| 1135 } | 1170 } |
| 1136 | 1171 |
| 1137 spdy_session = | 1172 spdy_session = |
| 1138 spdy_pool->CreateAvailableSessionFromSocket(spdy_session_key, | 1173 spdy_pool->CreateAvailableSessionFromSocket(spdy_session_key, |
| 1139 connection_.Pass(), | 1174 connection_.Pass(), |
| 1140 net_log_, | 1175 net_log_, |
| 1141 spdy_certificate_error_, | 1176 spdy_certificate_error_, |
| 1142 using_ssl_); | 1177 using_ssl_); |
| 1143 if (!spdy_session->HasAcceptableTransportSecurity()) { | 1178 if (!spdy_session->HasAcceptableTransportSecurity()) { |
| 1144 spdy_session->CloseSessionOnError( | 1179 spdy_session->CloseSessionOnError( |
| 1145 ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY, ""); | 1180 ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY, ""); |
| 1146 return ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY; | 1181 return ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY; |
| 1147 } | 1182 } |
| 1148 | 1183 |
| 1184 if (!IsAlternativeCertificateValidForOrigin(spdy_session)) { | |
| 1185 return ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN; | |
| 1186 } | |
| 1187 | |
| 1149 new_spdy_session_ = spdy_session; | 1188 new_spdy_session_ = spdy_session; |
| 1150 spdy_session_direct_ = direct; | 1189 spdy_session_direct_ = direct; |
| 1151 const HostPortPair& host_port_pair = spdy_session_key.host_port_pair(); | 1190 const HostPortPair& host_port_pair = spdy_session_key.host_port_pair(); |
| 1152 base::WeakPtr<HttpServerProperties> http_server_properties = | 1191 base::WeakPtr<HttpServerProperties> http_server_properties = |
| 1153 session_->http_server_properties(); | 1192 session_->http_server_properties(); |
| 1154 if (http_server_properties) | 1193 if (http_server_properties) |
| 1155 http_server_properties->SetSupportsSpdy(host_port_pair, true); | 1194 http_server_properties->SetSupportsSpdy(host_port_pair, true); |
| 1156 | 1195 |
| 1157 // Create a SpdyHttpStream attached to the session; | 1196 // Create a SpdyHttpStream attached to the session; |
| 1158 // OnNewSpdySessionReadyCallback is not called until an event loop | 1197 // OnNewSpdySessionReadyCallback is not called until an event loop |
| (...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1481 if (scheme == "https" || scheme == "wss" || IsSpdyAlternate()) | 1520 if (scheme == "https" || scheme == "wss" || IsSpdyAlternate()) |
| 1482 return ClientSocketPoolManager::SSL_GROUP; | 1521 return ClientSocketPoolManager::SSL_GROUP; |
| 1483 | 1522 |
| 1484 if (scheme == "ftp") | 1523 if (scheme == "ftp") |
| 1485 return ClientSocketPoolManager::FTP_GROUP; | 1524 return ClientSocketPoolManager::FTP_GROUP; |
| 1486 | 1525 |
| 1487 return ClientSocketPoolManager::NORMAL_GROUP; | 1526 return ClientSocketPoolManager::NORMAL_GROUP; |
| 1488 } | 1527 } |
| 1489 | 1528 |
| 1490 } // namespace net | 1529 } // namespace net |
| OLD | NEW |