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 |