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 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 196 io_callback_(base::Bind(&Job::OnIOComplete, base::Unretained(this))), | 196 io_callback_(base::Bind(&Job::OnIOComplete, base::Unretained(this))), |
| 197 connection_(new ClientSocketHandle), | 197 connection_(new ClientSocketHandle), |
| 198 session_(session), | 198 session_(session), |
| 199 next_state_(STATE_NONE), | 199 next_state_(STATE_NONE), |
| 200 pac_request_(NULL), | 200 pac_request_(NULL), |
| 201 destination_(destination), | 201 destination_(destination), |
| 202 origin_url_(origin_url), | 202 origin_url_(origin_url), |
| 203 alternative_service_(alternative_service), | 203 alternative_service_(alternative_service), |
| 204 job_controller_(job_controller), | 204 job_controller_(job_controller), |
| 205 job_type_(job_type), | 205 job_type_(job_type), |
| 206 blocking_job_(NULL), | |
| 207 waiting_job_(NULL), | |
| 208 using_ssl_(false), | 206 using_ssl_(false), |
| 209 using_spdy_(false), | 207 using_spdy_(false), |
| 210 using_quic_(false), | 208 using_quic_(false), |
| 211 quic_request_(session_->quic_stream_factory()), | 209 quic_request_(session_->quic_stream_factory()), |
| 212 using_existing_quic_session_(false), | 210 using_existing_quic_session_(false), |
| 213 spdy_certificate_error_(OK), | 211 spdy_certificate_error_(OK), |
| 214 establishing_tunnel_(false), | 212 establishing_tunnel_(false), |
| 215 was_npn_negotiated_(false), | 213 was_npn_negotiated_(false), |
| 216 protocol_negotiated_(kProtoUnknown), | 214 protocol_negotiated_(kProtoUnknown), |
| 217 num_streams_(0), | 215 num_streams_(0), |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 279 case STATE_RESOLVE_PROXY_COMPLETE: | 277 case STATE_RESOLVE_PROXY_COMPLETE: |
| 280 return session_->proxy_service()->GetLoadState(pac_request_); | 278 return session_->proxy_service()->GetLoadState(pac_request_); |
| 281 case STATE_INIT_CONNECTION_COMPLETE: | 279 case STATE_INIT_CONNECTION_COMPLETE: |
| 282 case STATE_CREATE_STREAM_COMPLETE: | 280 case STATE_CREATE_STREAM_COMPLETE: |
| 283 return using_quic_ ? LOAD_STATE_CONNECTING : connection_->GetLoadState(); | 281 return using_quic_ ? LOAD_STATE_CONNECTING : connection_->GetLoadState(); |
| 284 default: | 282 default: |
| 285 return LOAD_STATE_IDLE; | 283 return LOAD_STATE_IDLE; |
| 286 } | 284 } |
| 287 } | 285 } |
| 288 | 286 |
| 289 void HttpStreamFactoryImpl::Job::WaitFor(Job* job) { | 287 void HttpStreamFactoryImpl::Job::ResumeAfterDelay( |
| 290 DCHECK_EQ(STATE_NONE, next_state_); | 288 const base::TimeDelta& delay) { |
| 291 DCHECK_EQ(STATE_NONE, job->next_state_); | 289 DCHECK((job_type_ == ALTERNATIVE || !job_controller_->blocking())); |
| 292 DCHECK(!blocking_job_); | |
| 293 DCHECK(!job->waiting_job_); | |
| 294 | |
| 295 // Never share connection with other jobs for FTP requests. | |
| 296 DCHECK(!request_info_.url.SchemeIs("ftp")); | |
| 297 | |
| 298 blocking_job_ = job; | |
| 299 job->waiting_job_ = this; | |
| 300 } | |
| 301 | |
| 302 void HttpStreamFactoryImpl::Job::ResumeAfterDelay() { | |
| 303 DCHECK(!blocking_job_); | |
| 304 DCHECK_EQ(STATE_WAIT_FOR_JOB_COMPLETE, next_state_); | |
| 305 | 290 |
| 306 net_log_.AddEvent(NetLog::TYPE_HTTP_STREAM_JOB_DELAYED, | 291 net_log_.AddEvent(NetLog::TYPE_HTTP_STREAM_JOB_DELAYED, |
| 307 base::Bind(&NetLogHttpStreamJobDelayCallback, wait_time_)); | 292 base::Bind(&NetLogHttpStreamJobDelayCallback, delay)); |
| 308 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 293 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 309 FROM_HERE, base::Bind(&HttpStreamFactoryImpl::Job::OnIOComplete, | 294 FROM_HERE, base::Bind(&HttpStreamFactoryImpl::Job::OnIOComplete, |
| 310 ptr_factory_.GetWeakPtr(), OK), | 295 ptr_factory_.GetWeakPtr(), OK), |
| 311 wait_time_); | 296 delay); |
| 312 } | 297 } |
| 313 | 298 |
| 314 void HttpStreamFactoryImpl::Job::Resume(Job* job, | 299 void HttpStreamFactoryImpl::Job::Resume(const base::TimeDelta& delay) { |
| 315 const base::TimeDelta& delay) { | 300 DCHECK_EQ(job_type_, MAIN); |
| 316 DCHECK_EQ(blocking_job_, job); | |
| 317 blocking_job_ = NULL; | |
| 318 | |
| 319 // If |this| job is not past STATE_WAIT_FOR_JOB_COMPLETE state, then it will | 301 // If |this| job is not past STATE_WAIT_FOR_JOB_COMPLETE state, then it will |
| 320 // be delayed by the |wait_time_| when it resumes. | 302 // be delayed by the |delay| when it resumes. |
| 321 if (next_state_ == STATE_NONE || next_state_ <= STATE_WAIT_FOR_JOB_COMPLETE) | 303 if (next_state_ == STATE_NONE || next_state_ <= STATE_WAIT_FOR_JOB_COMPLETE) |
| 322 wait_time_ = delay; | 304 job_controller_->SetWaitTimeForMainJob(delay); |
| 323 | 305 |
| 324 // We know we're blocked if the next_state_ is STATE_WAIT_FOR_JOB_COMPLETE. | 306 // We know we're blocked if the next_state_ is STATE_WAIT_FOR_JOB_COMPLETE. |
| 325 // Unblock |this|. | 307 // Unblock |this|. |
| 326 if (next_state_ == STATE_WAIT_FOR_JOB_COMPLETE) | 308 if (next_state_ == STATE_WAIT_FOR_JOB_COMPLETE) |
| 327 ResumeAfterDelay(); | 309 ResumeAfterDelay(job_controller_->GetWaitTime()); |
| 328 } | 310 } |
| 329 | 311 |
| 330 void HttpStreamFactoryImpl::Job::Orphan() { | 312 void HttpStreamFactoryImpl::Job::Orphan() { |
| 331 net_log_.AddEvent(NetLog::TYPE_HTTP_STREAM_JOB_ORPHANED); | 313 net_log_.AddEvent(NetLog::TYPE_HTTP_STREAM_JOB_ORPHANED); |
| 332 if (blocking_job_) { | 314 |
| 333 // We've been orphaned, but there's a job we're blocked on. Don't bother | 315 job_controller_->MaybeResumeOtherJob(this, base::TimeDelta()); |
| 334 // racing, just cancel ourself. | 316 if (job_controller_->for_websockets()) { |
| 335 DCHECK(blocking_job_->waiting_job_); | |
| 336 blocking_job_->waiting_job_ = NULL; | |
| 337 blocking_job_ = NULL; | |
| 338 if (job_controller_->for_websockets() && connection_ && | |
| 339 connection_->socket()) { | |
| 340 connection_->socket()->Disconnect(); | |
| 341 } | |
| 342 job_controller_->OnOrphanedJobComplete(this); | |
| 343 } else if (job_controller_->for_websockets()) { | |
| 344 // We cancel this job because a WebSocketHandshakeStream can't be created | 317 // We cancel this job because a WebSocketHandshakeStream can't be created |
| 345 // without a WebSocketHandshakeStreamBase::CreateHelper which is stored in | 318 // without a WebSocketHandshakeStreamBase::CreateHelper which is stored in |
| 346 // the Request class and isn't retrievable by this job. | 319 // the Request class and isn't retrievable by this job. |
| 347 if (connection_ && connection_->socket()) { | 320 if (connection_ && connection_->socket()) { |
| 348 connection_->socket()->Disconnect(); | 321 connection_->socket()->Disconnect(); |
| 349 } | 322 } |
| 350 job_controller_->OnOrphanedJobComplete(this); | 323 job_controller_->OnOrphanedJobComplete(this); |
| 351 } | 324 } |
| 352 // |this| may be deleted after this call. | 325 // |this| may be deleted after this call. |
| 353 } | 326 } |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 552 } | 525 } |
| 553 | 526 |
| 554 int HttpStreamFactoryImpl::Job::RunLoop(int result) { | 527 int HttpStreamFactoryImpl::Job::RunLoop(int result) { |
| 555 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("net"), | 528 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("net"), |
| 556 "HttpStreamFactoryImpl::Job::RunLoop"); | 529 "HttpStreamFactoryImpl::Job::RunLoop"); |
| 557 result = DoLoop(result); | 530 result = DoLoop(result); |
| 558 | 531 |
| 559 if (result == ERR_IO_PENDING) | 532 if (result == ERR_IO_PENDING) |
| 560 return result; | 533 return result; |
| 561 | 534 |
| 562 // If there was an error, we should have already resumed the |waiting_job_|, | 535 // If there was an error, we should have already resumed the other waiting |
| 563 // if there was one. | 536 // job, if there was one. |
| 564 DCHECK(result == OK || waiting_job_ == NULL); | 537 DCHECK(result == OK || job_type_ == MAIN || !job_controller_->blocking()); |
| 565 | 538 |
| 566 if (job_type_ == PRECONNECT) { | 539 if (job_type_ == PRECONNECT) { |
| 567 base::ThreadTaskRunnerHandle::Get()->PostTask( | 540 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 568 FROM_HERE, | 541 FROM_HERE, |
| 569 base::Bind(&HttpStreamFactoryImpl::Job::OnPreconnectsComplete, | 542 base::Bind(&HttpStreamFactoryImpl::Job::OnPreconnectsComplete, |
| 570 ptr_factory_.GetWeakPtr())); | 543 ptr_factory_.GetWeakPtr())); |
| 571 return ERR_IO_PENDING; | 544 return ERR_IO_PENDING; |
| 572 } | 545 } |
| 573 | 546 |
| 574 if (IsCertificateError(result)) { | 547 if (IsCertificateError(result)) { |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 755 base::Bind(&NetLogHttpStreamJobCallback, net_log->source(), | 728 base::Bind(&NetLogHttpStreamJobCallback, net_log->source(), |
| 756 &request_info_.url, &origin_url_, &alternative_service_, | 729 &request_info_.url, &origin_url_, &alternative_service_, |
| 757 priority_)); | 730 priority_)); |
| 758 net_log->AddEvent(NetLog::TYPE_HTTP_STREAM_REQUEST_STARTED_JOB, | 731 net_log->AddEvent(NetLog::TYPE_HTTP_STREAM_REQUEST_STARTED_JOB, |
| 759 net_log_.source().ToEventParametersCallback()); | 732 net_log_.source().ToEventParametersCallback()); |
| 760 } | 733 } |
| 761 | 734 |
| 762 // Don't connect to restricted ports. | 735 // Don't connect to restricted ports. |
| 763 if (!IsPortAllowedForScheme(destination_.port(), | 736 if (!IsPortAllowedForScheme(destination_.port(), |
| 764 request_info_.url.scheme())) { | 737 request_info_.url.scheme())) { |
| 765 if (waiting_job_) { | 738 job_controller_->MaybeResumeOtherJob(this, base::TimeDelta()); |
|
Ryan Hamilton
2016/05/17 22:14:09
As discussed offline, I *think* we can move the lo
Randy Smith (Not in Mondays)
2016/05/25 21:22:21
+1; one of my reactions to this CL is that we're n
| |
| 766 waiting_job_->Resume(this, base::TimeDelta()); | |
| 767 waiting_job_ = NULL; | |
| 768 } | |
| 769 return ERR_UNSAFE_PORT; | 739 return ERR_UNSAFE_PORT; |
| 770 } | 740 } |
| 771 | 741 |
| 772 next_state_ = STATE_RESOLVE_PROXY; | 742 next_state_ = STATE_RESOLVE_PROXY; |
| 773 return OK; | 743 return OK; |
| 774 } | 744 } |
| 775 | 745 |
| 776 int HttpStreamFactoryImpl::Job::DoResolveProxy() { | 746 int HttpStreamFactoryImpl::Job::DoResolveProxy() { |
| 777 DCHECK(!pac_request_); | 747 DCHECK(!pac_request_); |
| 778 DCHECK(session_); | 748 DCHECK(session_); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 831 result = ERR_NO_SUPPORTED_PROXIES; | 801 result = ERR_NO_SUPPORTED_PROXIES; |
| 832 } else if (using_quic_ && | 802 } else if (using_quic_ && |
| 833 (!proxy_info_.is_quic() && !proxy_info_.is_direct())) { | 803 (!proxy_info_.is_quic() && !proxy_info_.is_direct())) { |
| 834 // QUIC can not be spoken to non-QUIC proxies. This error should not be | 804 // QUIC can not be spoken to non-QUIC proxies. This error should not be |
| 835 // user visible, because the non-alternative Job should be resumed. | 805 // user visible, because the non-alternative Job should be resumed. |
| 836 result = ERR_NO_SUPPORTED_PROXIES; | 806 result = ERR_NO_SUPPORTED_PROXIES; |
| 837 } | 807 } |
| 838 } | 808 } |
| 839 | 809 |
| 840 if (result != OK) { | 810 if (result != OK) { |
| 841 if (waiting_job_) { | 811 job_controller_->MaybeResumeOtherJob(this, base::TimeDelta()); |
| 842 waiting_job_->Resume(this, base::TimeDelta()); | |
| 843 waiting_job_ = NULL; | |
| 844 } | |
| 845 return result; | 812 return result; |
| 846 } | 813 } |
| 847 | 814 |
| 848 next_state_ = STATE_WAIT_FOR_JOB; | 815 next_state_ = STATE_WAIT_FOR_JOB; |
| 849 return OK; | 816 return OK; |
| 850 } | 817 } |
| 851 | 818 |
| 852 bool HttpStreamFactoryImpl::Job::ShouldForceQuic() const { | 819 bool HttpStreamFactoryImpl::Job::ShouldForceQuic() const { |
| 853 return session_->params().enable_quic && | 820 return session_->params().enable_quic && |
| 854 ContainsKey(session_->params().origins_to_force_quic_on, | 821 ContainsKey(session_->params().origins_to_force_quic_on, |
| 855 destination_) && | 822 destination_) && |
| 856 proxy_info_.is_direct() && origin_url_.SchemeIs("https"); | 823 proxy_info_.is_direct() && origin_url_.SchemeIs("https"); |
| 857 } | 824 } |
| 858 | 825 |
| 859 int HttpStreamFactoryImpl::Job::DoWaitForJob() { | 826 int HttpStreamFactoryImpl::Job::DoWaitForJob() { |
| 860 if (!blocking_job_ && wait_time_.is_zero()) { | 827 if (job_controller_->ResumeJobWithDelay(this)) { |
|
Ryan Hamilton
2016/05/17 22:14:09
I'm quite happy with the logic here. Yay!
It'd be
Zhongyi Shi
2016/06/29 21:49:03
Done.
| |
| 861 // There is no |blocking_job_| and there is no |wait_time_|. | 828 next_state_ = STATE_WAIT_FOR_JOB_COMPLETE; |
| 829 return ERR_IO_PENDING; | |
| 830 } else { | |
|
Ryan Hamilton
2016/05/17 22:14:09
nit: no need for else since if() returned.
Zhongyi Shi
2016/06/29 21:49:03
Done.
| |
| 862 next_state_ = STATE_INIT_CONNECTION; | 831 next_state_ = STATE_INIT_CONNECTION; |
| 863 return OK; | 832 return OK; |
| 864 } | 833 } |
| 865 | |
| 866 next_state_ = STATE_WAIT_FOR_JOB_COMPLETE; | |
| 867 if (!wait_time_.is_zero()) { | |
| 868 // If there is a waiting_time, then resume the job after the wait_time_. | |
| 869 DCHECK(!blocking_job_); | |
| 870 ResumeAfterDelay(); | |
| 871 } | |
| 872 | |
| 873 return ERR_IO_PENDING; | |
| 874 } | 834 } |
| 875 | 835 |
| 876 int HttpStreamFactoryImpl::Job::DoWaitForJobComplete(int result) { | 836 int HttpStreamFactoryImpl::Job::DoWaitForJobComplete(int result) { |
| 877 DCHECK(!blocking_job_); | 837 DCHECK((job_type_ == ALTERNATIVE || !job_controller_->blocking())); |
| 878 DCHECK_EQ(OK, result); | 838 DCHECK_EQ(OK, result); |
| 879 wait_time_ = base::TimeDelta(); | 839 job_controller_->SetWaitTimeForMainJob(base::TimeDelta()); |
| 880 next_state_ = STATE_INIT_CONNECTION; | 840 next_state_ = STATE_INIT_CONNECTION; |
| 881 return OK; | 841 return OK; |
| 882 } | 842 } |
| 883 | 843 |
| 884 int HttpStreamFactoryImpl::Job::DoInitConnection() { | 844 int HttpStreamFactoryImpl::Job::DoInitConnection() { |
| 885 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462812 is fixed. | 845 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462812 is fixed. |
| 886 tracked_objects::ScopedTracker tracking_profile( | 846 tracked_objects::ScopedTracker tracking_profile( |
| 887 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 847 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 888 "462812 HttpStreamFactoryImpl::Job::DoInitConnection")); | 848 "462812 HttpStreamFactoryImpl::Job::DoInitConnection")); |
| 889 DCHECK(!blocking_job_); | 849 DCHECK((job_type_ == ALTERNATIVE || !job_controller_->blocking())); |
| 890 DCHECK(!connection_->is_initialized()); | 850 DCHECK(!connection_->is_initialized()); |
| 891 DCHECK(proxy_info_.proxy_server().is_valid()); | 851 DCHECK(proxy_info_.proxy_server().is_valid()); |
| 892 next_state_ = STATE_INIT_CONNECTION_COMPLETE; | 852 next_state_ = STATE_INIT_CONNECTION_COMPLETE; |
| 893 | 853 |
| 894 using_ssl_ = origin_url_.SchemeIs("https") || origin_url_.SchemeIs("wss") || | 854 using_ssl_ = origin_url_.SchemeIs("https") || origin_url_.SchemeIs("wss") || |
| 895 IsSpdyAlternative(); | 855 IsSpdyAlternative(); |
| 896 using_spdy_ = false; | 856 using_spdy_ = false; |
| 897 | 857 |
| 898 if (ShouldForceQuic()) | 858 if (ShouldForceQuic()) |
| 899 using_quic_ = true; | 859 using_quic_ = true; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 951 destination = destination_; | 911 destination = destination_; |
| 952 ssl_config = &server_ssl_config_; | 912 ssl_config = &server_ssl_config_; |
| 953 } | 913 } |
| 954 int rv = | 914 int rv = |
| 955 quic_request_.Request(destination, request_info_.privacy_mode, | 915 quic_request_.Request(destination, request_info_.privacy_mode, |
| 956 ssl_config->GetCertVerifyFlags(), url, | 916 ssl_config->GetCertVerifyFlags(), url, |
| 957 request_info_.method, net_log_, io_callback_); | 917 request_info_.method, net_log_, io_callback_); |
| 958 if (rv == OK) { | 918 if (rv == OK) { |
| 959 using_existing_quic_session_ = true; | 919 using_existing_quic_session_ = true; |
| 960 } else { | 920 } else { |
| 961 // OK, there's no available QUIC session. Let |waiting_job_| resume | 921 base::TimeDelta delay; |
| 962 // if it's paused. | 922 // OK, there's no available QUIC session. Let JobController to resume |
| 963 if (waiting_job_) { | 923 // the waiting job if it's paused. |
| 964 if (rv == ERR_IO_PENDING) { | 924 if (rv == ERR_IO_PENDING) { |
| 965 // Start the |waiting_job_| after the delay returned by | 925 // Start the waiting job after the delay returned by |
| 966 // GetTimeDelayForWaitingJob(). | 926 // GetTimeDelayForWaitingJob(). |
| 967 // | 927 // |
| 968 // If QUIC request fails during handshake, then | 928 // If QUIC request fails during handshake, then |
| 969 // DoInitConnectionComplete() will start the |waiting_job_|. | 929 // DoInitConnectionComplete() will start the waiting job. |
| 970 waiting_job_->Resume(this, quic_request_.GetTimeDelayForWaitingJob()); | 930 delay = quic_request_.GetTimeDelayForWaitingJob(); |
| 971 } else { | |
| 972 // QUIC request has failed, resume the |waiting_job_|. | |
| 973 waiting_job_->Resume(this, base::TimeDelta()); | |
| 974 } | |
| 975 waiting_job_ = NULL; | |
| 976 } | 931 } |
| 932 job_controller_->MaybeResumeOtherJob(this, delay); | |
|
Ryan Hamilton
2016/05/17 22:14:09
Looking at this line (and the line below in this s
| |
| 977 } | 933 } |
| 978 return rv; | 934 return rv; |
| 979 } | 935 } |
| 980 | 936 |
| 981 SpdySessionKey spdy_session_key = GetSpdySessionKey(); | 937 SpdySessionKey spdy_session_key = GetSpdySessionKey(); |
| 982 | 938 |
| 983 // Check first if we have a spdy session for this group. If so, then go | 939 // Check first if we have a spdy session for this group. If so, then go |
| 984 // straight to using that. | 940 // straight to using that. |
| 985 if (CanUseExistingSpdySession()) { | 941 if (CanUseExistingSpdySession()) { |
| 986 base::WeakPtr<SpdySession> spdy_session; | 942 base::WeakPtr<SpdySession> spdy_session; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 998 existing_spdy_session_ = spdy_session; | 954 existing_spdy_session_ = spdy_session; |
| 999 return OK; | 955 return OK; |
| 1000 } | 956 } |
| 1001 } | 957 } |
| 1002 if (using_ssl_) { | 958 if (using_ssl_) { |
| 1003 // Ask |job_controller_| to update the spdy session key for the request | 959 // Ask |job_controller_| to update the spdy session key for the request |
| 1004 // that launched this job. | 960 // that launched this job. |
| 1005 job_controller_->SetSpdySessionKey(this, spdy_session_key); | 961 job_controller_->SetSpdySessionKey(this, spdy_session_key); |
| 1006 } | 962 } |
| 1007 | 963 |
| 1008 // OK, there's no available SPDY session. Let |waiting_job_| resume if it's | 964 // OK, there's no available SPDY session. Let JobController to resume the |
| 1009 // paused. | 965 // non-alternative job if it's paused. |
| 1010 if (waiting_job_) { | 966 job_controller_->MaybeResumeOtherJob(this, base::TimeDelta()); |
| 1011 waiting_job_->Resume(this, base::TimeDelta()); | |
| 1012 waiting_job_ = NULL; | |
| 1013 } | |
| 1014 | 967 |
| 1015 if (proxy_info_.is_http() || proxy_info_.is_https()) | 968 if (proxy_info_.is_http() || proxy_info_.is_https()) |
| 1016 establishing_tunnel_ = using_ssl_; | 969 establishing_tunnel_ = using_ssl_; |
| 1017 | 970 |
| 1018 const bool expect_spdy = IsSpdyAlternative(); | 971 const bool expect_spdy = IsSpdyAlternative(); |
| 1019 | 972 |
| 1020 base::WeakPtr<HttpServerProperties> http_server_properties = | 973 base::WeakPtr<HttpServerProperties> http_server_properties = |
| 1021 session_->http_server_properties(); | 974 session_->http_server_properties(); |
| 1022 if (http_server_properties) { | 975 if (http_server_properties) { |
| 1023 http_server_properties->MaybeForceHTTP11(destination_, &server_ssl_config_); | 976 http_server_properties->MaybeForceHTTP11(destination_, &server_ssl_config_); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1057 } | 1010 } |
| 1058 | 1011 |
| 1059 return InitSocketHandleForHttpRequest( | 1012 return InitSocketHandleForHttpRequest( |
| 1060 GetSocketGroup(), destination_, request_info_.extra_headers, | 1013 GetSocketGroup(), destination_, request_info_.extra_headers, |
| 1061 request_info_.load_flags, priority_, session_, proxy_info_, expect_spdy, | 1014 request_info_.load_flags, priority_, session_, proxy_info_, expect_spdy, |
| 1062 server_ssl_config_, proxy_ssl_config_, request_info_.privacy_mode, | 1015 server_ssl_config_, proxy_ssl_config_, request_info_.privacy_mode, |
| 1063 net_log_, connection_.get(), resolution_callback, io_callback_); | 1016 net_log_, connection_.get(), resolution_callback, io_callback_); |
| 1064 } | 1017 } |
| 1065 | 1018 |
| 1066 int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) { | 1019 int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) { |
| 1067 if (using_quic_ && result < 0 && waiting_job_) { | 1020 if (using_quic_ && result < 0) { |
| 1068 waiting_job_->Resume(this, base::TimeDelta()); | 1021 job_controller_->MaybeResumeOtherJob(this, base::TimeDelta()); |
| 1069 waiting_job_ = NULL; | |
| 1070 } | 1022 } |
| 1071 if (job_type_ == PRECONNECT) { | 1023 if (job_type_ == PRECONNECT) { |
| 1072 if (using_quic_) | 1024 if (using_quic_) |
| 1073 return result; | 1025 return result; |
| 1074 DCHECK_EQ(OK, result); | 1026 DCHECK_EQ(OK, result); |
| 1075 return OK; | 1027 return OK; |
| 1076 } | 1028 } |
| 1077 | 1029 |
| 1078 if (result == ERR_SPDY_SESSION_ALREADY_EXISTS) { | 1030 if (result == ERR_SPDY_SESSION_ALREADY_EXISTS) { |
| 1079 // We found a SPDY connection after resolving the host. This is | 1031 // We found a SPDY connection after resolving the host. This is |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 1097 // Underlying QUIC layer would have closed the connection. | 1049 // Underlying QUIC layer would have closed the connection. |
| 1098 HostPortPair destination = proxy_info_.proxy_server().host_port_pair(); | 1050 HostPortPair destination = proxy_info_.proxy_server().host_port_pair(); |
| 1099 if (session_->quic_stream_factory()->IsQuicDisabled(destination.port())) { | 1051 if (session_->quic_stream_factory()->IsQuicDisabled(destination.port())) { |
| 1100 using_quic_ = false; | 1052 using_quic_ = false; |
| 1101 return ReconsiderProxyAfterError(ERR_QUIC_PROTOCOL_ERROR); | 1053 return ReconsiderProxyAfterError(ERR_QUIC_PROTOCOL_ERROR); |
| 1102 } | 1054 } |
| 1103 } | 1055 } |
| 1104 | 1056 |
| 1105 // TODO(willchan): Make this a bit more exact. Maybe there are recoverable | 1057 // TODO(willchan): Make this a bit more exact. Maybe there are recoverable |
| 1106 // errors, such as ignoring certificate errors for Alternate-Protocol. | 1058 // errors, such as ignoring certificate errors for Alternate-Protocol. |
| 1107 if (result < 0 && waiting_job_) { | 1059 if (result < 0) { |
| 1108 waiting_job_->Resume(this, base::TimeDelta()); | 1060 job_controller_->MaybeResumeOtherJob(this, base::TimeDelta()); |
| 1109 waiting_job_ = NULL; | |
| 1110 } | 1061 } |
| 1111 | 1062 |
| 1112 // |result| may be the result of any of the stacked pools. The following | 1063 // |result| may be the result of any of the stacked pools. The following |
| 1113 // logic is used when determining how to interpret an error. | 1064 // logic is used when determining how to interpret an error. |
| 1114 // If |result| < 0: | 1065 // If |result| < 0: |
| 1115 // and connection_->socket() != NULL, then the SSL handshake ran and it | 1066 // and connection_->socket() != NULL, then the SSL handshake ran and it |
| 1116 // is a potentially recoverable error. | 1067 // is a potentially recoverable error. |
| 1117 // and connection_->socket == NULL and connection_->is_ssl_error() is true, | 1068 // and connection_->socket == NULL and connection_->is_ssl_error() is true, |
| 1118 // then the SSL handshake ran with an unrecoverable error. | 1069 // then the SSL handshake ran with an unrecoverable error. |
| 1119 // otherwise, the error came from one of the other pools. | 1070 // otherwise, the error came from one of the other pools. |
| (...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1636 } else { | 1587 } else { |
| 1637 // This Job was the normal Job, and hence the alternative Job lost the race. | 1588 // This Job was the normal Job, and hence the alternative Job lost the race. |
| 1638 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_LOST_RACE); | 1589 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_LOST_RACE); |
| 1639 } | 1590 } |
| 1640 } | 1591 } |
| 1641 | 1592 |
| 1642 void HttpStreamFactoryImpl::Job::MarkOtherJobComplete(const Job& job) { | 1593 void HttpStreamFactoryImpl::Job::MarkOtherJobComplete(const Job& job) { |
| 1643 DCHECK_EQ(STATUS_RUNNING, other_job_status_); | 1594 DCHECK_EQ(STATUS_RUNNING, other_job_status_); |
| 1644 other_job_status_ = job.job_status_; | 1595 other_job_status_ = job.job_status_; |
| 1645 other_job_alternative_service_ = job.alternative_service_; | 1596 other_job_alternative_service_ = job.alternative_service_; |
| 1646 MaybeMarkAlternativeServiceBroken(); | 1597 MaybeMarkAlternativeServiceBroken(); |
|
Ryan Hamilton
2016/05/17 22:14:09
Can we move all of this logic up to the controller
| |
| 1647 } | 1598 } |
| 1648 | 1599 |
| 1649 void HttpStreamFactoryImpl::Job::MaybeMarkAlternativeServiceBroken() { | 1600 void HttpStreamFactoryImpl::Job::MaybeMarkAlternativeServiceBroken() { |
| 1650 if (job_status_ == STATUS_RUNNING || other_job_status_ == STATUS_RUNNING) | 1601 if (job_status_ == STATUS_RUNNING || other_job_status_ == STATUS_RUNNING) |
| 1651 return; | 1602 return; |
| 1652 | 1603 |
| 1653 if (IsSpdyAlternative() || IsQuicAlternative()) { | 1604 if (IsSpdyAlternative() || IsQuicAlternative()) { |
| 1654 if (job_status_ == STATUS_BROKEN && other_job_status_ == STATUS_SUCCEEDED) { | 1605 if (job_status_ == STATUS_BROKEN && other_job_status_ == STATUS_SUCCEEDED) { |
| 1655 HistogramBrokenAlternateProtocolLocation( | 1606 HistogramBrokenAlternateProtocolLocation( |
| 1656 BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_IMPL_JOB_ALT); | 1607 BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_IMPL_JOB_ALT); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1740 | 1691 |
| 1741 ConnectionAttempts socket_attempts = connection_->connection_attempts(); | 1692 ConnectionAttempts socket_attempts = connection_->connection_attempts(); |
| 1742 if (connection_->socket()) { | 1693 if (connection_->socket()) { |
| 1743 connection_->socket()->GetConnectionAttempts(&socket_attempts); | 1694 connection_->socket()->GetConnectionAttempts(&socket_attempts); |
| 1744 } | 1695 } |
| 1745 | 1696 |
| 1746 job_controller_->AddConnectionAttemptsToRequest(this, socket_attempts); | 1697 job_controller_->AddConnectionAttemptsToRequest(this, socket_attempts); |
| 1747 } | 1698 } |
| 1748 | 1699 |
| 1749 } // namespace net | 1700 } // namespace net |
| OLD | NEW |