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 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 |