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 DCHECK(spdy_session); | |
298 if (!using_ssl_) { | |
299 return true; | |
Ryan Hamilton
2015/04/10 18:37:37
We only speak SPDY over TLS, right? I think this c
Bence
2015/04/10 19:55:16
Well, not quite, this member was called for non-ss
| |
300 } | |
301 if (origin_url_.host() == spdy_session->host_port_pair().host()) { | |
Ryan Hamilton
2015/04/10 18:37:36
It seems that this is simply a performance optimiz
Bence
2015/04/10 19:55:16
Not exactly. I added this test here because other
Ryan Hamilton
2015/04/11 02:40:41
Ah. I'm not a big fan of having "real" code that's
Bence
2015/04/13 17:52:40
I totally agree with you. It turns out that there
Ryan Hamilton
2015/04/13 18:29:56
It seems like it should be pretty easy to add a he
Bence
2015/04/15 21:07:46
Done.
| |
302 return true; | |
303 } | |
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 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
450 DCHECK(result == OK || waiting_job_ == NULL); | 462 DCHECK(result == OK || waiting_job_ == NULL); |
451 | 463 |
452 if (IsPreconnecting()) { | 464 if (IsPreconnecting()) { |
453 base::MessageLoop::current()->PostTask( | 465 base::MessageLoop::current()->PostTask( |
454 FROM_HERE, | 466 FROM_HERE, |
455 base::Bind(&HttpStreamFactoryImpl::Job::OnPreconnectsComplete, | 467 base::Bind(&HttpStreamFactoryImpl::Job::OnPreconnectsComplete, |
456 ptr_factory_.GetWeakPtr())); | 468 ptr_factory_.GetWeakPtr())); |
457 return ERR_IO_PENDING; | 469 return ERR_IO_PENDING; |
458 } | 470 } |
459 | 471 |
460 if (IsCertificateError(result)) { | 472 if (IsCertificateError(result) && |
473 result != ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN) { | |
Ryan Hamilton
2015/04/10 18:37:37
Yeah, definitely move this error out of the certif
Bence
2015/04/10 19:55:16
Done.
| |
461 // Retrieve SSL information from the socket. | 474 // Retrieve SSL information from the socket. |
462 GetSSLInfo(); | 475 GetSSLInfo(); |
463 | 476 |
464 next_state_ = STATE_WAITING_USER_ACTION; | 477 next_state_ = STATE_WAITING_USER_ACTION; |
465 base::MessageLoop::current()->PostTask( | 478 base::MessageLoop::current()->PostTask( |
466 FROM_HERE, | 479 FROM_HERE, |
467 base::Bind(&HttpStreamFactoryImpl::Job::OnCertificateErrorCallback, | 480 base::Bind(&HttpStreamFactoryImpl::Job::OnCertificateErrorCallback, |
468 ptr_factory_.GetWeakPtr(), result, ssl_info_)); | 481 ptr_factory_.GetWeakPtr(), result, ssl_info_)); |
469 return ERR_IO_PENDING; | 482 return ERR_IO_PENDING; |
470 } | 483 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
528 base::Bind(&Job::OnWebSocketHandshakeStreamReadyCallback, | 541 base::Bind(&Job::OnWebSocketHandshakeStreamReadyCallback, |
529 ptr_factory_.GetWeakPtr())); | 542 ptr_factory_.GetWeakPtr())); |
530 } else { | 543 } else { |
531 DCHECK(stream_.get()); | 544 DCHECK(stream_.get()); |
532 base::MessageLoop::current()->PostTask( | 545 base::MessageLoop::current()->PostTask( |
533 FROM_HERE, | 546 FROM_HERE, |
534 base::Bind(&Job::OnStreamReadyCallback, ptr_factory_.GetWeakPtr())); | 547 base::Bind(&Job::OnStreamReadyCallback, ptr_factory_.GetWeakPtr())); |
535 } | 548 } |
536 return ERR_IO_PENDING; | 549 return ERR_IO_PENDING; |
537 | 550 |
551 case ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN: | |
Ryan Hamilton
2015/04/10 18:37:36
This should only happen for a job that IsAlternate
Bence
2015/04/10 19:55:16
This wasn't actually true, but yes, now it can onl
| |
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. | |
Ryan Hamilton
2015/04/10 18:37:37
Is this a TODO (instead of being implemented) beca
Bence
2015/04/10 19:55:16
Correct.
| |
557 MaybeMarkAlternativeServiceBroken(); | |
558 } | |
559 base::MessageLoop::current()->PostTask( | |
560 FROM_HERE, | |
561 base::Bind(&Job::OnStreamFailedCallback, ptr_factory_.GetWeakPtr(), | |
562 ERR_CONNECTION_REFUSED)); | |
Ryan Hamilton
2015/04/10 18:37:37
Why ERR_CONNECTION_REFUSED? Actually, this looks a
Bence
2015/04/10 19:55:16
In fact, you are right, this is a lot like the def
Ryan Hamilton
2015/04/11 02:40:41
Is there a difference between the two cases? (defa
Bence
2015/04/13 17:52:40
Only the DCHECK (and the TODO), so I merged them f
| |
563 return ERR_IO_PENDING; | |
564 | |
538 default: | 565 default: |
539 if (job_status_ != STATUS_BROKEN) { | 566 if (job_status_ != STATUS_BROKEN) { |
540 DCHECK_EQ(STATUS_RUNNING, job_status_); | 567 DCHECK_EQ(STATUS_RUNNING, job_status_); |
541 job_status_ = STATUS_FAILED; | 568 job_status_ = STATUS_FAILED; |
542 MaybeMarkAlternativeServiceBroken(); | 569 MaybeMarkAlternativeServiceBroken(); |
543 } | 570 } |
544 base::MessageLoop::current()->PostTask( | 571 base::MessageLoop::current()->PostTask( |
545 FROM_HERE, | 572 FROM_HERE, |
546 base::Bind(&Job::OnStreamFailedCallback, ptr_factory_.GetWeakPtr(), | 573 base::Bind(&Job::OnStreamFailedCallback, ptr_factory_.GetWeakPtr(), |
547 result)); | 574 result)); |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
797 return rv; | 824 return rv; |
798 } | 825 } |
799 | 826 |
800 // Check first if we have a spdy session for this group. If so, then go | 827 // Check first if we have a spdy session for this group. If so, then go |
801 // straight to using that. | 828 // straight to using that. |
802 SpdySessionKey spdy_session_key = GetSpdySessionKey(); | 829 SpdySessionKey spdy_session_key = GetSpdySessionKey(); |
803 base::WeakPtr<SpdySession> spdy_session = | 830 base::WeakPtr<SpdySession> spdy_session = |
804 session_->spdy_session_pool()->FindAvailableSession( | 831 session_->spdy_session_pool()->FindAvailableSession( |
805 spdy_session_key, net_log_); | 832 spdy_session_key, net_log_); |
806 if (spdy_session && CanUseExistingSpdySession()) { | 833 if (spdy_session && CanUseExistingSpdySession()) { |
834 if (!IsAlternativeCertificateValidForOrigin(spdy_session)) { | |
Ryan Hamilton
2015/04/10 18:37:37
We don't need to do this call, unless this job is
Bence
2015/04/10 19:55:16
That is true. I think it might be easier to check
| |
835 return ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN; | |
836 } | |
807 // If we're preconnecting, but we already have a SpdySession, we don't | 837 // If we're preconnecting, but we already have a SpdySession, we don't |
808 // actually need to preconnect any sockets, so we're done. | 838 // actually need to preconnect any sockets, so we're done. |
809 if (IsPreconnecting()) | 839 if (IsPreconnecting()) |
810 return OK; | 840 return OK; |
811 using_spdy_ = true; | 841 using_spdy_ = true; |
812 next_state_ = STATE_CREATE_STREAM; | 842 next_state_ = STATE_CREATE_STREAM; |
813 existing_spdy_session_ = spdy_session; | 843 existing_spdy_session_ = spdy_session; |
814 return OK; | 844 return OK; |
815 } else if (request_ && !request_->HasSpdySessionKey() && using_ssl_) { | 845 } |
846 if (request_ && !request_->HasSpdySessionKey() && using_ssl_) { | |
816 // Update the spdy session key for the request that launched this job. | 847 // Update the spdy session key for the request that launched this job. |
817 request_->SetSpdySessionKey(spdy_session_key); | 848 request_->SetSpdySessionKey(spdy_session_key); |
818 } | 849 } |
819 | 850 |
820 // OK, there's no available SPDY session. Let |waiting_job_| resume if it's | 851 // OK, there's no available SPDY session. Let |waiting_job_| resume if it's |
821 // paused. | 852 // paused. |
822 | |
823 if (waiting_job_) { | 853 if (waiting_job_) { |
824 waiting_job_->Resume(this); | 854 waiting_job_->Resume(this); |
825 waiting_job_ = NULL; | 855 waiting_job_ = NULL; |
826 } | 856 } |
827 | 857 |
828 if (proxy_info_.is_http() || proxy_info_.is_https()) | 858 if (proxy_info_.is_http() || proxy_info_.is_https()) |
829 establishing_tunnel_ = using_ssl_; | 859 establishing_tunnel_ = using_ssl_; |
830 | 860 |
831 // TODO(bnc): s/want_spdy_over_npn/expect_spdy_over_npn/ | 861 // TODO(bnc): s/want_spdy_over_npn/expect_spdy_over_npn/ |
832 bool want_spdy_over_npn = IsAlternate(); | 862 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 | 1012 // puts the in progress HttpProxy socket into |connection_| in order to |
983 // complete the auth (or read the response body). The tunnel restart code | 1013 // 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 | 1014 // is careful to remove it before returning control to the rest of this |
985 // class. | 1015 // class. |
986 connection_.reset(connection_->release_pending_http_proxy_connection()); | 1016 connection_.reset(connection_->release_pending_http_proxy_connection()); |
987 return result; | 1017 return result; |
988 } | 1018 } |
989 | 1019 |
990 if (!ssl_started && result < 0 && IsAlternate()) { | 1020 if (!ssl_started && result < 0 && IsAlternate()) { |
991 job_status_ = STATUS_BROKEN; | 1021 job_status_ = STATUS_BROKEN; |
1022 // TODO(bnc): if (result == ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN), then | |
1023 // instead of marking alternative service broken, mark (origin, alternative | |
1024 // service) couple as invalid. | |
992 MaybeMarkAlternativeServiceBroken(); | 1025 MaybeMarkAlternativeServiceBroken(); |
993 return result; | 1026 return result; |
994 } | 1027 } |
995 | 1028 |
996 if (using_quic_) { | 1029 if (using_quic_) { |
997 if (result < 0) { | 1030 if (result < 0) { |
998 job_status_ = STATUS_BROKEN; | 1031 job_status_ = STATUS_BROKEN; |
999 MaybeMarkAlternativeServiceBroken(); | 1032 MaybeMarkAlternativeServiceBroken(); |
1000 return result; | 1033 return result; |
1001 } | 1034 } |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1124 spdy_session_key = SpdySessionKey(proxy_server.host_port_pair(), | 1157 spdy_session_key = SpdySessionKey(proxy_server.host_port_pair(), |
1125 ProxyServer::Direct(), | 1158 ProxyServer::Direct(), |
1126 PRIVACY_MODE_DISABLED); | 1159 PRIVACY_MODE_DISABLED); |
1127 } | 1160 } |
1128 | 1161 |
1129 SpdySessionPool* spdy_pool = session_->spdy_session_pool(); | 1162 SpdySessionPool* spdy_pool = session_->spdy_session_pool(); |
1130 base::WeakPtr<SpdySession> spdy_session = | 1163 base::WeakPtr<SpdySession> spdy_session = |
1131 spdy_pool->FindAvailableSession(spdy_session_key, net_log_); | 1164 spdy_pool->FindAvailableSession(spdy_session_key, net_log_); |
1132 | 1165 |
1133 if (spdy_session) { | 1166 if (spdy_session) { |
1167 if (!IsAlternativeCertificateValidForOrigin(spdy_session)) { | |
1168 return ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN; | |
1169 } | |
1134 return SetSpdyHttpStream(spdy_session, direct); | 1170 return SetSpdyHttpStream(spdy_session, direct); |
1135 } | 1171 } |
1136 | 1172 |
1137 spdy_session = | 1173 spdy_session = |
1138 spdy_pool->CreateAvailableSessionFromSocket(spdy_session_key, | 1174 spdy_pool->CreateAvailableSessionFromSocket(spdy_session_key, |
1139 connection_.Pass(), | 1175 connection_.Pass(), |
1140 net_log_, | 1176 net_log_, |
1141 spdy_certificate_error_, | 1177 spdy_certificate_error_, |
1142 using_ssl_); | 1178 using_ssl_); |
1143 if (!spdy_session->HasAcceptableTransportSecurity()) { | 1179 if (!spdy_session->HasAcceptableTransportSecurity()) { |
1144 spdy_session->CloseSessionOnError( | 1180 spdy_session->CloseSessionOnError( |
1145 ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY, ""); | 1181 ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY, ""); |
1146 return ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY; | 1182 return ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY; |
1147 } | 1183 } |
1148 | 1184 |
1185 if (!IsAlternativeCertificateValidForOrigin(spdy_session)) { | |
1186 return ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN; | |
Ryan Hamilton
2015/04/10 18:37:37
Hm. It seems like there are a lot of different pla
Bence
2015/04/10 19:55:16
I do agree with you. Please let me know if you ha
Ryan Hamilton
2015/04/11 02:40:41
So it looks like each time we get a SPDY session f
Bence
2015/04/13 17:52:40
I've done it, but it doesn't quite feel right. Th
| |
1187 } | |
1188 | |
1149 new_spdy_session_ = spdy_session; | 1189 new_spdy_session_ = spdy_session; |
1150 spdy_session_direct_ = direct; | 1190 spdy_session_direct_ = direct; |
1151 const HostPortPair& host_port_pair = spdy_session_key.host_port_pair(); | 1191 const HostPortPair& host_port_pair = spdy_session_key.host_port_pair(); |
1152 base::WeakPtr<HttpServerProperties> http_server_properties = | 1192 base::WeakPtr<HttpServerProperties> http_server_properties = |
1153 session_->http_server_properties(); | 1193 session_->http_server_properties(); |
1154 if (http_server_properties) | 1194 if (http_server_properties) |
1155 http_server_properties->SetSupportsSpdy(host_port_pair, true); | 1195 http_server_properties->SetSupportsSpdy(host_port_pair, true); |
1156 | 1196 |
1157 // Create a SpdyHttpStream attached to the session; | 1197 // Create a SpdyHttpStream attached to the session; |
1158 // OnNewSpdySessionReadyCallback is not called until an event loop | 1198 // 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()) | 1521 if (scheme == "https" || scheme == "wss" || IsSpdyAlternate()) |
1482 return ClientSocketPoolManager::SSL_GROUP; | 1522 return ClientSocketPoolManager::SSL_GROUP; |
1483 | 1523 |
1484 if (scheme == "ftp") | 1524 if (scheme == "ftp") |
1485 return ClientSocketPoolManager::FTP_GROUP; | 1525 return ClientSocketPoolManager::FTP_GROUP; |
1486 | 1526 |
1487 return ClientSocketPoolManager::NORMAL_GROUP; | 1527 return ClientSocketPoolManager::NORMAL_GROUP; |
1488 } | 1528 } |
1489 | 1529 |
1490 } // namespace net | 1530 } // namespace net |
OLD | NEW |