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 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 194 io_callback_(base::Bind(&Job::OnIOComplete, base::Unretained(this))), | 194 io_callback_(base::Bind(&Job::OnIOComplete, base::Unretained(this))), |
| 195 connection_(new ClientSocketHandle), | 195 connection_(new ClientSocketHandle), |
| 196 session_(session), | 196 session_(session), |
| 197 next_state_(STATE_NONE), | 197 next_state_(STATE_NONE), |
| 198 pac_request_(NULL), | 198 pac_request_(NULL), |
| 199 destination_(destination), | 199 destination_(destination), |
| 200 origin_url_(origin_url), | 200 origin_url_(origin_url), |
| 201 alternative_service_(alternative_service), | 201 alternative_service_(alternative_service), |
| 202 delegate_(delegate), | 202 delegate_(delegate), |
| 203 job_type_(job_type), | 203 job_type_(job_type), |
| 204 blocking_job_(NULL), | |
| 205 waiting_job_(NULL), | |
| 206 using_ssl_(false), | 204 using_ssl_(false), |
| 207 using_spdy_(false), | 205 using_spdy_(false), |
| 208 using_quic_(false), | 206 using_quic_(false), |
| 209 quic_request_(session_->quic_stream_factory()), | 207 quic_request_(session_->quic_stream_factory()), |
| 210 using_existing_quic_session_(false), | 208 using_existing_quic_session_(false), |
| 211 spdy_certificate_error_(OK), | 209 spdy_certificate_error_(OK), |
| 212 establishing_tunnel_(false), | 210 establishing_tunnel_(false), |
| 213 was_npn_negotiated_(false), | 211 was_npn_negotiated_(false), |
| 214 protocol_negotiated_(kProtoUnknown), | 212 protocol_negotiated_(kProtoUnknown), |
| 215 num_streams_(0), | 213 num_streams_(0), |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 281 case STATE_RESOLVE_PROXY_COMPLETE: | 279 case STATE_RESOLVE_PROXY_COMPLETE: |
| 282 return session_->proxy_service()->GetLoadState(pac_request_); | 280 return session_->proxy_service()->GetLoadState(pac_request_); |
| 283 case STATE_INIT_CONNECTION_COMPLETE: | 281 case STATE_INIT_CONNECTION_COMPLETE: |
| 284 case STATE_CREATE_STREAM_COMPLETE: | 282 case STATE_CREATE_STREAM_COMPLETE: |
| 285 return using_quic_ ? LOAD_STATE_CONNECTING : connection_->GetLoadState(); | 283 return using_quic_ ? LOAD_STATE_CONNECTING : connection_->GetLoadState(); |
| 286 default: | 284 default: |
| 287 return LOAD_STATE_IDLE; | 285 return LOAD_STATE_IDLE; |
| 288 } | 286 } |
| 289 } | 287 } |
| 290 | 288 |
| 291 void HttpStreamFactoryImpl::Job::WaitFor(Job* job) { | 289 void HttpStreamFactoryImpl::Job::Resume(const base::TimeDelta& delay) { |
|
Ryan Hamilton
2016/07/01 00:13:30
Discussed offline, let's do this:
void HttpStream
Zhongyi Shi
2016/07/11 23:04:56
Done. Yay!!! Much cleaner.
| |
| 292 DCHECK_EQ(STATE_NONE, next_state_); | 290 DCHECK_EQ(job_type_, MAIN); |
| 293 DCHECK_EQ(STATE_NONE, job->next_state_); | |
| 294 DCHECK(!blocking_job_); | |
| 295 DCHECK(!job->waiting_job_); | |
| 296 | 291 |
| 297 // Never share connection with other jobs for FTP requests. | 292 // If |this| job is not past STATE_WAIT_COMPLETE state, then it will |
| 298 DCHECK(!request_info_.url.SchemeIs("ftp")); | 293 // be delayed by the |delay| when it resumes. |
| 294 if (next_state_ == STATE_NONE || next_state_ <= STATE_WAIT_COMPLETE) | |
| 295 delegate_->set_wait_time_for_main_job(delay); | |
| 299 | 296 |
| 300 blocking_job_ = job; | 297 // We know we're blocked if the next_state_ is STATE_WAIT_COMPLETE. |
| 301 job->waiting_job_ = this; | |
| 302 } | |
| 303 | |
| 304 void HttpStreamFactoryImpl::Job::ResumeAfterDelay() { | |
| 305 DCHECK(!blocking_job_); | |
| 306 DCHECK_EQ(STATE_WAIT_FOR_JOB_COMPLETE, next_state_); | |
| 307 | |
| 308 net_log_.AddEvent(NetLog::TYPE_HTTP_STREAM_JOB_DELAYED, | |
| 309 base::Bind(&NetLogHttpStreamJobDelayCallback, wait_time_)); | |
| 310 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | |
| 311 FROM_HERE, base::Bind(&HttpStreamFactoryImpl::Job::OnIOComplete, | |
| 312 ptr_factory_.GetWeakPtr(), OK), | |
| 313 wait_time_); | |
| 314 } | |
| 315 | |
| 316 void HttpStreamFactoryImpl::Job::Resume(Job* job, | |
| 317 const base::TimeDelta& delay) { | |
| 318 DCHECK_EQ(blocking_job_, job); | |
| 319 blocking_job_ = NULL; | |
| 320 | |
| 321 // If |this| job is not past STATE_WAIT_FOR_JOB_COMPLETE state, then it will | |
| 322 // be delayed by the |wait_time_| when it resumes. | |
| 323 if (next_state_ == STATE_NONE || next_state_ <= STATE_WAIT_FOR_JOB_COMPLETE) | |
| 324 wait_time_ = delay; | |
| 325 | |
| 326 // We know we're blocked if the next_state_ is STATE_WAIT_FOR_JOB_COMPLETE. | |
| 327 // Unblock |this|. | 298 // Unblock |this|. |
| 328 if (next_state_ == STATE_WAIT_FOR_JOB_COMPLETE) | 299 if (next_state_ == STATE_WAIT_COMPLETE) { |
| 329 ResumeAfterDelay(); | 300 net_log_.AddEvent(NetLog::TYPE_HTTP_STREAM_JOB_DELAYED, |
| 301 base::Bind(&NetLogHttpStreamJobDelayCallback, delay)); | |
| 302 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | |
| 303 FROM_HERE, base::Bind(&HttpStreamFactoryImpl::Job::OnIOComplete, | |
| 304 ptr_factory_.GetWeakPtr(), OK), | |
| 305 delegate_->wait_time_for_main_job()); | |
| 306 } | |
| 330 } | 307 } |
| 331 | 308 |
| 332 void HttpStreamFactoryImpl::Job::Orphan() { | 309 void HttpStreamFactoryImpl::Job::Orphan() { |
| 333 net_log_.AddEvent(NetLog::TYPE_HTTP_STREAM_JOB_ORPHANED); | 310 net_log_.AddEvent(NetLog::TYPE_HTTP_STREAM_JOB_ORPHANED); |
| 334 if (blocking_job_) { | 311 |
| 335 // We've been orphaned, but there's a job we're blocked on. Don't bother | 312 if (delegate_->for_websockets()) { |
| 336 // racing, just cancel ourself. | |
| 337 DCHECK(blocking_job_->waiting_job_); | |
| 338 blocking_job_->waiting_job_ = NULL; | |
| 339 blocking_job_ = NULL; | |
| 340 if (delegate_->for_websockets() && connection_ && connection_->socket()) { | |
| 341 connection_->socket()->Disconnect(); | |
| 342 } | |
| 343 delegate_->OnOrphanedJobComplete(this); | |
| 344 } else if (delegate_->for_websockets()) { | |
| 345 // We cancel this job because a WebSocketHandshakeStream can't be created | 313 // We cancel this job because a WebSocketHandshakeStream can't be created |
| 346 // without a WebSocketHandshakeStreamBase::CreateHelper which is stored in | 314 // without a WebSocketHandshakeStreamBase::CreateHelper which is stored in |
| 347 // the Request class and isn't retrievable by this job. | 315 // the Request class and isn't retrievable by this job. |
| 348 if (connection_ && connection_->socket()) { | 316 if (connection_ && connection_->socket()) { |
| 349 connection_->socket()->Disconnect(); | 317 connection_->socket()->Disconnect(); |
| 350 } | 318 } |
| 351 delegate_->OnOrphanedJobComplete(this); | 319 delegate_->OnOrphanedJobComplete(this); |
| 352 } | 320 } |
| 353 // |this| may be deleted after this call. | 321 // |this| may be deleted after this call. |
| 354 } | 322 } |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 551 } | 519 } |
| 552 | 520 |
| 553 int HttpStreamFactoryImpl::Job::RunLoop(int result) { | 521 int HttpStreamFactoryImpl::Job::RunLoop(int result) { |
| 554 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("net"), | 522 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("net"), |
| 555 "HttpStreamFactoryImpl::Job::RunLoop"); | 523 "HttpStreamFactoryImpl::Job::RunLoop"); |
| 556 result = DoLoop(result); | 524 result = DoLoop(result); |
| 557 | 525 |
| 558 if (result == ERR_IO_PENDING) | 526 if (result == ERR_IO_PENDING) |
| 559 return result; | 527 return result; |
| 560 | 528 |
| 561 // If there was an error, we should have already resumed the |waiting_job_|, | |
| 562 // if there was one. | |
| 563 DCHECK(result == OK || waiting_job_ == NULL); | |
| 564 | |
| 565 if (job_type_ == PRECONNECT) { | 529 if (job_type_ == PRECONNECT) { |
| 566 base::ThreadTaskRunnerHandle::Get()->PostTask( | 530 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 567 FROM_HERE, | 531 FROM_HERE, |
| 568 base::Bind(&HttpStreamFactoryImpl::Job::OnPreconnectsComplete, | 532 base::Bind(&HttpStreamFactoryImpl::Job::OnPreconnectsComplete, |
| 569 ptr_factory_.GetWeakPtr())); | 533 ptr_factory_.GetWeakPtr())); |
| 570 return ERR_IO_PENDING; | 534 return ERR_IO_PENDING; |
| 571 } | 535 } |
| 572 | 536 |
| 573 if (IsCertificateError(result)) { | 537 if (IsCertificateError(result)) { |
| 574 // Retrieve SSL information from the socket. | 538 // Retrieve SSL information from the socket. |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 688 DCHECK_EQ(OK, rv); | 652 DCHECK_EQ(OK, rv); |
| 689 rv = DoStart(); | 653 rv = DoStart(); |
| 690 break; | 654 break; |
| 691 case STATE_RESOLVE_PROXY: | 655 case STATE_RESOLVE_PROXY: |
| 692 DCHECK_EQ(OK, rv); | 656 DCHECK_EQ(OK, rv); |
| 693 rv = DoResolveProxy(); | 657 rv = DoResolveProxy(); |
| 694 break; | 658 break; |
| 695 case STATE_RESOLVE_PROXY_COMPLETE: | 659 case STATE_RESOLVE_PROXY_COMPLETE: |
| 696 rv = DoResolveProxyComplete(rv); | 660 rv = DoResolveProxyComplete(rv); |
| 697 break; | 661 break; |
| 698 case STATE_WAIT_FOR_JOB: | 662 case STATE_WAIT: |
| 699 DCHECK_EQ(OK, rv); | 663 DCHECK_EQ(OK, rv); |
| 700 rv = DoWaitForJob(); | 664 rv = DoWait(); |
| 701 break; | 665 break; |
| 702 case STATE_WAIT_FOR_JOB_COMPLETE: | 666 case STATE_WAIT_COMPLETE: |
| 703 rv = DoWaitForJobComplete(rv); | 667 rv = DoWaitComplete(rv); |
| 704 break; | 668 break; |
| 705 case STATE_INIT_CONNECTION: | 669 case STATE_INIT_CONNECTION: |
| 706 DCHECK_EQ(OK, rv); | 670 DCHECK_EQ(OK, rv); |
| 707 rv = DoInitConnection(); | 671 rv = DoInitConnection(); |
| 708 break; | 672 break; |
| 709 case STATE_INIT_CONNECTION_COMPLETE: | 673 case STATE_INIT_CONNECTION_COMPLETE: |
| 710 rv = DoInitConnectionComplete(rv); | 674 rv = DoInitConnectionComplete(rv); |
| 711 break; | 675 break; |
| 712 case STATE_WAITING_USER_ACTION: | 676 case STATE_WAITING_USER_ACTION: |
| 713 rv = DoWaitingUserAction(rv); | 677 rv = DoWaitingUserAction(rv); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 754 base::Bind(&NetLogHttpStreamJobCallback, net_log->source(), | 718 base::Bind(&NetLogHttpStreamJobCallback, net_log->source(), |
| 755 &request_info_.url, &origin_url_, &alternative_service_, | 719 &request_info_.url, &origin_url_, &alternative_service_, |
| 756 priority_)); | 720 priority_)); |
| 757 net_log->AddEvent(NetLog::TYPE_HTTP_STREAM_REQUEST_STARTED_JOB, | 721 net_log->AddEvent(NetLog::TYPE_HTTP_STREAM_REQUEST_STARTED_JOB, |
| 758 net_log_.source().ToEventParametersCallback()); | 722 net_log_.source().ToEventParametersCallback()); |
| 759 } | 723 } |
| 760 | 724 |
| 761 // Don't connect to restricted ports. | 725 // Don't connect to restricted ports. |
| 762 if (!IsPortAllowedForScheme(destination_.port(), | 726 if (!IsPortAllowedForScheme(destination_.port(), |
| 763 request_info_.url.scheme())) { | 727 request_info_.url.scheme())) { |
| 764 if (waiting_job_) { | |
| 765 waiting_job_->Resume(this, base::TimeDelta()); | |
| 766 waiting_job_ = NULL; | |
| 767 } | |
| 768 return ERR_UNSAFE_PORT; | 728 return ERR_UNSAFE_PORT; |
| 769 } | 729 } |
| 770 | 730 |
| 771 next_state_ = STATE_RESOLVE_PROXY; | 731 next_state_ = STATE_RESOLVE_PROXY; |
| 772 return OK; | 732 return OK; |
| 773 } | 733 } |
| 774 | 734 |
| 775 int HttpStreamFactoryImpl::Job::DoResolveProxy() { | 735 int HttpStreamFactoryImpl::Job::DoResolveProxy() { |
| 776 DCHECK(!pac_request_); | 736 DCHECK(!pac_request_); |
| 777 DCHECK(session_); | 737 DCHECK(session_); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 830 result = ERR_NO_SUPPORTED_PROXIES; | 790 result = ERR_NO_SUPPORTED_PROXIES; |
| 831 } else if (using_quic_ && | 791 } else if (using_quic_ && |
| 832 (!proxy_info_.is_quic() && !proxy_info_.is_direct())) { | 792 (!proxy_info_.is_quic() && !proxy_info_.is_direct())) { |
| 833 // QUIC can not be spoken to non-QUIC proxies. This error should not be | 793 // QUIC can not be spoken to non-QUIC proxies. This error should not be |
| 834 // user visible, because the non-alternative Job should be resumed. | 794 // user visible, because the non-alternative Job should be resumed. |
| 835 result = ERR_NO_SUPPORTED_PROXIES; | 795 result = ERR_NO_SUPPORTED_PROXIES; |
| 836 } | 796 } |
| 837 } | 797 } |
| 838 | 798 |
| 839 if (result != OK) { | 799 if (result != OK) { |
| 840 if (waiting_job_) { | |
| 841 waiting_job_->Resume(this, base::TimeDelta()); | |
| 842 waiting_job_ = NULL; | |
| 843 } | |
| 844 return result; | 800 return result; |
| 845 } | 801 } |
| 846 | 802 |
| 847 next_state_ = STATE_WAIT_FOR_JOB; | 803 next_state_ = STATE_WAIT; |
| 848 return OK; | 804 return OK; |
| 849 } | 805 } |
| 850 | 806 |
| 851 bool HttpStreamFactoryImpl::Job::ShouldForceQuic() const { | 807 bool HttpStreamFactoryImpl::Job::ShouldForceQuic() const { |
| 852 return session_->params().enable_quic && | 808 return session_->params().enable_quic && |
| 853 ContainsKey(session_->params().origins_to_force_quic_on, | 809 ContainsKey(session_->params().origins_to_force_quic_on, |
| 854 destination_) && | 810 destination_) && |
| 855 proxy_info_.is_direct() && origin_url_.SchemeIs("https"); | 811 proxy_info_.is_direct() && origin_url_.SchemeIs("https"); |
| 856 } | 812 } |
| 857 | 813 |
| 858 int HttpStreamFactoryImpl::Job::DoWaitForJob() { | 814 int HttpStreamFactoryImpl::Job::DoWait() { |
| 859 if (!blocking_job_ && wait_time_.is_zero()) { | 815 next_state_ = STATE_WAIT_COMPLETE; |
| 860 // There is no |blocking_job_| and there is no |wait_time_|. | 816 if (delegate_->ShouldWait(this)) |
| 861 next_state_ = STATE_INIT_CONNECTION; | 817 return ERR_IO_PENDING; |
| 862 return OK; | |
| 863 } | |
| 864 | 818 |
| 865 next_state_ = STATE_WAIT_FOR_JOB_COMPLETE; | 819 next_state_ = STATE_INIT_CONNECTION; |
| 866 if (!wait_time_.is_zero()) { | 820 return OK; |
| 867 // If there is a waiting_time, then resume the job after the wait_time_. | |
| 868 DCHECK(!blocking_job_); | |
| 869 ResumeAfterDelay(); | |
| 870 } | |
| 871 | |
| 872 return ERR_IO_PENDING; | |
| 873 } | 821 } |
| 874 | 822 |
| 875 int HttpStreamFactoryImpl::Job::DoWaitForJobComplete(int result) { | 823 int HttpStreamFactoryImpl::Job::DoWaitComplete(int result) { |
| 876 DCHECK(!blocking_job_); | 824 DCHECK((job_type_ == ALTERNATIVE || !delegate_->main_job_is_blocked())); |
| 877 DCHECK_EQ(OK, result); | 825 DCHECK_EQ(OK, result); |
| 878 wait_time_ = base::TimeDelta(); | 826 delegate_->set_wait_time_for_main_job(base::TimeDelta()); |
|
Ryan Hamilton
2016/07/01 00:13:30
Why does this happen here? I would have thought th
Zhongyi Shi
2016/07/11 23:04:56
Added DoNotResumeMainJobWhenAltJobPending covers t
Zhongyi Shi
2016/07/11 23:04:56
This SetWaitTimeForMainJob is to clear the main_jo
| |
| 879 next_state_ = STATE_INIT_CONNECTION; | 827 next_state_ = STATE_INIT_CONNECTION; |
| 880 return OK; | 828 return OK; |
| 881 } | 829 } |
| 882 | 830 |
| 883 int HttpStreamFactoryImpl::Job::DoInitConnection() { | 831 int HttpStreamFactoryImpl::Job::DoInitConnection() { |
| 832 int result = DoInitConnectionImpl(); | |
| 833 // Report to delegate that this job has initialized the connection. | |
|
Ryan Hamilton
2016/07/01 00:13:30
nit: I'd just drop this since your method is prett
Zhongyi Shi
2016/07/11 23:04:56
Done.
| |
| 834 delegate_->OnConnectionInitialized(this, result); | |
| 835 | |
| 836 return result; | |
| 837 } | |
| 838 | |
| 839 int HttpStreamFactoryImpl::Job::DoInitConnectionImpl() { | |
| 884 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462812 is fixed. | 840 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462812 is fixed. |
| 885 tracked_objects::ScopedTracker tracking_profile( | 841 tracked_objects::ScopedTracker tracking_profile( |
| 886 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 842 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 887 "462812 HttpStreamFactoryImpl::Job::DoInitConnection")); | 843 "462812 HttpStreamFactoryImpl::Job::DoInitConnection")); |
| 888 DCHECK(!blocking_job_); | 844 DCHECK((job_type_ == ALTERNATIVE || !delegate_->main_job_is_blocked())); |
| 889 DCHECK(!connection_->is_initialized()); | 845 DCHECK(!connection_->is_initialized()); |
| 890 DCHECK(proxy_info_.proxy_server().is_valid()); | 846 DCHECK(proxy_info_.proxy_server().is_valid()); |
| 891 next_state_ = STATE_INIT_CONNECTION_COMPLETE; | 847 next_state_ = STATE_INIT_CONNECTION_COMPLETE; |
| 892 | 848 |
| 893 using_ssl_ = origin_url_.SchemeIs("https") || origin_url_.SchemeIs("wss") || | 849 using_ssl_ = origin_url_.SchemeIs("https") || origin_url_.SchemeIs("wss") || |
| 894 IsSpdyAlternative(); | 850 IsSpdyAlternative(); |
| 895 using_spdy_ = false; | 851 using_spdy_ = false; |
| 896 | 852 |
| 897 if (ShouldForceQuic()) | 853 if (ShouldForceQuic()) |
| 898 using_quic_ = true; | 854 using_quic_ = true; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 950 destination = destination_; | 906 destination = destination_; |
| 951 ssl_config = &server_ssl_config_; | 907 ssl_config = &server_ssl_config_; |
| 952 } | 908 } |
| 953 int rv = | 909 int rv = |
| 954 quic_request_.Request(destination, request_info_.privacy_mode, | 910 quic_request_.Request(destination, request_info_.privacy_mode, |
| 955 ssl_config->GetCertVerifyFlags(), url, | 911 ssl_config->GetCertVerifyFlags(), url, |
| 956 request_info_.method, net_log_, io_callback_); | 912 request_info_.method, net_log_, io_callback_); |
| 957 if (rv == OK) { | 913 if (rv == OK) { |
| 958 using_existing_quic_session_ = true; | 914 using_existing_quic_session_ = true; |
| 959 } else { | 915 } else { |
| 960 // OK, there's no available QUIC session. Let |waiting_job_| resume | 916 base::TimeDelta delay; |
| 961 // if it's paused. | 917 // OK, there's no available QUIC session. Let JobController to resume |
| 962 if (waiting_job_) { | 918 // the waiting job if it's paused. |
| 963 if (rv == ERR_IO_PENDING) { | 919 if (rv == ERR_IO_PENDING) { |
| 964 // Start the |waiting_job_| after the delay returned by | 920 // Set the wait time for main job if it is delayed TCP. |
| 965 // GetTimeDelayForWaitingJob(). | 921 delegate_->set_wait_time_for_main_job( |
|
Ryan Hamilton
2016/07/01 00:13:30
Yeah, this is the only place I'd expect this metho
| |
| 966 // | 922 quic_request_.GetTimeDelayForWaitingJob()); |
| 967 // If QUIC request fails during handshake, then | |
| 968 // DoInitConnectionComplete() will start the |waiting_job_|. | |
| 969 waiting_job_->Resume(this, quic_request_.GetTimeDelayForWaitingJob()); | |
| 970 } else { | |
| 971 // QUIC request has failed, resume the |waiting_job_|. | |
| 972 waiting_job_->Resume(this, base::TimeDelta()); | |
| 973 } | |
| 974 waiting_job_ = NULL; | |
| 975 } | 923 } |
| 976 } | 924 } |
| 977 return rv; | 925 return rv; |
| 978 } | 926 } |
| 979 | 927 |
| 980 SpdySessionKey spdy_session_key = GetSpdySessionKey(); | 928 SpdySessionKey spdy_session_key = GetSpdySessionKey(); |
| 981 | 929 |
| 982 // Check first if we have a spdy session for this group. If so, then go | 930 // Check first if we have a spdy session for this group. If so, then go |
| 983 // straight to using that. | 931 // straight to using that. |
| 984 if (CanUseExistingSpdySession()) { | 932 if (CanUseExistingSpdySession()) { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 997 existing_spdy_session_ = spdy_session; | 945 existing_spdy_session_ = spdy_session; |
| 998 return OK; | 946 return OK; |
| 999 } | 947 } |
| 1000 } | 948 } |
| 1001 if (using_ssl_) { | 949 if (using_ssl_) { |
| 1002 // Ask |delegate_delegate_| to update the spdy session key for the request | 950 // Ask |delegate_delegate_| to update the spdy session key for the request |
| 1003 // that launched this job. | 951 // that launched this job. |
| 1004 delegate_->SetSpdySessionKey(this, spdy_session_key); | 952 delegate_->SetSpdySessionKey(this, spdy_session_key); |
| 1005 } | 953 } |
| 1006 | 954 |
| 1007 // OK, there's no available SPDY session. Let |waiting_job_| resume if it's | |
| 1008 // paused. | |
| 1009 if (waiting_job_) { | |
| 1010 waiting_job_->Resume(this, base::TimeDelta()); | |
| 1011 waiting_job_ = NULL; | |
| 1012 } | |
| 1013 | |
| 1014 if (proxy_info_.is_http() || proxy_info_.is_https()) | 955 if (proxy_info_.is_http() || proxy_info_.is_https()) |
| 1015 establishing_tunnel_ = using_ssl_; | 956 establishing_tunnel_ = using_ssl_; |
| 1016 | 957 |
| 1017 const bool expect_spdy = IsSpdyAlternative(); | 958 const bool expect_spdy = IsSpdyAlternative(); |
| 1018 | 959 |
| 1019 base::WeakPtr<HttpServerProperties> http_server_properties = | 960 base::WeakPtr<HttpServerProperties> http_server_properties = |
| 1020 session_->http_server_properties(); | 961 session_->http_server_properties(); |
| 1021 if (http_server_properties) { | 962 if (http_server_properties) { |
| 1022 http_server_properties->MaybeForceHTTP11(destination_, &server_ssl_config_); | 963 http_server_properties->MaybeForceHTTP11(destination_, &server_ssl_config_); |
| 1023 if (proxy_info_.is_http() || proxy_info_.is_https()) { | 964 if (proxy_info_.is_http() || proxy_info_.is_https()) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1056 } | 997 } |
| 1057 | 998 |
| 1058 return InitSocketHandleForHttpRequest( | 999 return InitSocketHandleForHttpRequest( |
| 1059 GetSocketGroup(), destination_, request_info_.extra_headers, | 1000 GetSocketGroup(), destination_, request_info_.extra_headers, |
| 1060 request_info_.load_flags, priority_, session_, proxy_info_, expect_spdy, | 1001 request_info_.load_flags, priority_, session_, proxy_info_, expect_spdy, |
| 1061 server_ssl_config_, proxy_ssl_config_, request_info_.privacy_mode, | 1002 server_ssl_config_, proxy_ssl_config_, request_info_.privacy_mode, |
| 1062 net_log_, connection_.get(), resolution_callback, io_callback_); | 1003 net_log_, connection_.get(), resolution_callback, io_callback_); |
| 1063 } | 1004 } |
| 1064 | 1005 |
| 1065 int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) { | 1006 int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) { |
| 1066 if (using_quic_ && result < 0 && waiting_job_) { | |
| 1067 waiting_job_->Resume(this, base::TimeDelta()); | |
| 1068 waiting_job_ = NULL; | |
| 1069 } | |
| 1070 if (job_type_ == PRECONNECT) { | 1007 if (job_type_ == PRECONNECT) { |
| 1071 if (using_quic_) | 1008 if (using_quic_) |
| 1072 return result; | 1009 return result; |
| 1073 DCHECK_EQ(OK, result); | 1010 DCHECK_EQ(OK, result); |
| 1074 return OK; | 1011 return OK; |
| 1075 } | 1012 } |
| 1076 | 1013 |
| 1077 if (result == ERR_SPDY_SESSION_ALREADY_EXISTS) { | 1014 if (result == ERR_SPDY_SESSION_ALREADY_EXISTS) { |
| 1015 DCHECK(!using_quic_); | |
| 1078 // We found a SPDY connection after resolving the host. This is | 1016 // We found a SPDY connection after resolving the host. This is |
| 1079 // probably an IP pooled connection. | 1017 // probably an IP pooled connection. |
| 1080 SpdySessionKey spdy_session_key = GetSpdySessionKey(); | 1018 SpdySessionKey spdy_session_key = GetSpdySessionKey(); |
| 1081 existing_spdy_session_ = | 1019 existing_spdy_session_ = |
| 1082 session_->spdy_session_pool()->FindAvailableSession( | 1020 session_->spdy_session_pool()->FindAvailableSession( |
| 1083 spdy_session_key, origin_url_, net_log_); | 1021 spdy_session_key, origin_url_, net_log_); |
| 1084 if (existing_spdy_session_) { | 1022 if (existing_spdy_session_) { |
| 1085 using_spdy_ = true; | 1023 using_spdy_ = true; |
| 1086 next_state_ = STATE_CREATE_STREAM; | 1024 next_state_ = STATE_CREATE_STREAM; |
| 1087 } else { | 1025 } else { |
| 1088 // It is possible that the spdy session no longer exists. | 1026 // It is possible that the spdy session no longer exists. |
| 1089 ReturnToStateInitConnection(true /* close connection */); | 1027 ReturnToStateInitConnection(true /* close connection */); |
| 1090 } | 1028 } |
| 1091 return OK; | 1029 return OK; |
| 1092 } | 1030 } |
| 1093 | 1031 |
| 1094 if (proxy_info_.is_quic() && using_quic_) { | 1032 if (proxy_info_.is_quic() && using_quic_) { |
| 1095 // Mark QUIC proxy as bad if QUIC got disabled on the destination port. | 1033 // Mark QUIC proxy as bad if QUIC got disabled on the destination port. |
| 1096 // Underlying QUIC layer would have closed the connection. | 1034 // Underlying QUIC layer would have closed the connection. |
| 1097 HostPortPair destination = proxy_info_.proxy_server().host_port_pair(); | 1035 HostPortPair destination = proxy_info_.proxy_server().host_port_pair(); |
| 1098 if (session_->quic_stream_factory()->IsQuicDisabled(destination.port())) { | 1036 if (session_->quic_stream_factory()->IsQuicDisabled(destination.port())) { |
| 1099 using_quic_ = false; | 1037 using_quic_ = false; |
| 1100 return ReconsiderProxyAfterError(ERR_QUIC_PROTOCOL_ERROR); | 1038 return ReconsiderProxyAfterError(ERR_QUIC_PROTOCOL_ERROR); |
| 1101 } | 1039 } |
| 1102 } | 1040 } |
| 1103 | 1041 |
| 1104 // TODO(willchan): Make this a bit more exact. Maybe there are recoverable | |
| 1105 // errors, such as ignoring certificate errors for Alternate-Protocol. | |
| 1106 if (result < 0 && waiting_job_) { | |
| 1107 waiting_job_->Resume(this, base::TimeDelta()); | |
| 1108 waiting_job_ = NULL; | |
| 1109 } | |
| 1110 | |
| 1111 // |result| may be the result of any of the stacked pools. The following | 1042 // |result| may be the result of any of the stacked pools. The following |
| 1112 // logic is used when determining how to interpret an error. | 1043 // logic is used when determining how to interpret an error. |
| 1113 // If |result| < 0: | 1044 // If |result| < 0: |
| 1114 // and connection_->socket() != NULL, then the SSL handshake ran and it | 1045 // and connection_->socket() != NULL, then the SSL handshake ran and it |
| 1115 // is a potentially recoverable error. | 1046 // is a potentially recoverable error. |
| 1116 // and connection_->socket == NULL and connection_->is_ssl_error() is true, | 1047 // and connection_->socket == NULL and connection_->is_ssl_error() is true, |
| 1117 // then the SSL handshake ran with an unrecoverable error. | 1048 // then the SSL handshake ran with an unrecoverable error. |
| 1118 // otherwise, the error came from one of the other pools. | 1049 // otherwise, the error came from one of the other pools. |
| 1119 bool ssl_started = using_ssl_ && (result == OK || connection_->socket() || | 1050 bool ssl_started = using_ssl_ && (result == OK || connection_->socket() || |
| 1120 connection_->is_ssl_error()); | 1051 connection_->is_ssl_error()); |
| (...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1731 | 1662 |
| 1732 ConnectionAttempts socket_attempts = connection_->connection_attempts(); | 1663 ConnectionAttempts socket_attempts = connection_->connection_attempts(); |
| 1733 if (connection_->socket()) { | 1664 if (connection_->socket()) { |
| 1734 connection_->socket()->GetConnectionAttempts(&socket_attempts); | 1665 connection_->socket()->GetConnectionAttempts(&socket_attempts); |
| 1735 } | 1666 } |
| 1736 | 1667 |
| 1737 delegate_->AddConnectionAttemptsToRequest(this, socket_attempts); | 1668 delegate_->AddConnectionAttemptsToRequest(this, socket_attempts); |
| 1738 } | 1669 } |
| 1739 | 1670 |
| 1740 } // namespace net | 1671 } // namespace net |
| OLD | NEW |