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 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 187 AlternativeService alternative_service, | 187 AlternativeService alternative_service, |
| 188 NetLog* net_log) | 188 NetLog* net_log) |
| 189 : request_info_(request_info), | 189 : request_info_(request_info), |
| 190 priority_(priority), | 190 priority_(priority), |
| 191 server_ssl_config_(server_ssl_config), | 191 server_ssl_config_(server_ssl_config), |
| 192 proxy_ssl_config_(proxy_ssl_config), | 192 proxy_ssl_config_(proxy_ssl_config), |
| 193 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_HTTP_STREAM_JOB)), | 193 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_HTTP_STREAM_JOB)), |
| 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 state_(STATE_NONE), | |
| 197 next_state_(STATE_NONE), | 198 next_state_(STATE_NONE), |
| 198 pac_request_(NULL), | 199 pac_request_(NULL), |
| 199 destination_(destination), | 200 destination_(destination), |
| 200 origin_url_(origin_url), | 201 origin_url_(origin_url), |
| 201 alternative_service_(alternative_service), | 202 alternative_service_(alternative_service), |
| 202 delegate_(delegate), | 203 delegate_(delegate), |
| 203 job_type_(job_type), | 204 job_type_(job_type), |
| 204 blocking_job_(NULL), | |
| 205 waiting_job_(NULL), | |
| 206 using_ssl_(false), | 205 using_ssl_(false), |
| 207 using_spdy_(false), | 206 using_spdy_(false), |
| 208 using_quic_(false), | 207 using_quic_(false), |
| 209 quic_request_(session_->quic_stream_factory()), | 208 quic_request_(session_->quic_stream_factory()), |
| 210 using_existing_quic_session_(false), | 209 using_existing_quic_session_(false), |
| 211 spdy_certificate_error_(OK), | 210 spdy_certificate_error_(OK), |
| 212 establishing_tunnel_(false), | 211 establishing_tunnel_(false), |
| 213 was_npn_negotiated_(false), | 212 was_npn_negotiated_(false), |
| 214 protocol_negotiated_(kProtoUnknown), | 213 protocol_negotiated_(kProtoUnknown), |
| 215 num_streams_(0), | 214 num_streams_(0), |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 281 case STATE_RESOLVE_PROXY_COMPLETE: | 280 case STATE_RESOLVE_PROXY_COMPLETE: |
| 282 return session_->proxy_service()->GetLoadState(pac_request_); | 281 return session_->proxy_service()->GetLoadState(pac_request_); |
| 283 case STATE_INIT_CONNECTION_COMPLETE: | 282 case STATE_INIT_CONNECTION_COMPLETE: |
| 284 case STATE_CREATE_STREAM_COMPLETE: | 283 case STATE_CREATE_STREAM_COMPLETE: |
| 285 return using_quic_ ? LOAD_STATE_CONNECTING : connection_->GetLoadState(); | 284 return using_quic_ ? LOAD_STATE_CONNECTING : connection_->GetLoadState(); |
| 286 default: | 285 default: |
| 287 return LOAD_STATE_IDLE; | 286 return LOAD_STATE_IDLE; |
| 288 } | 287 } |
| 289 } | 288 } |
| 290 | 289 |
| 291 void HttpStreamFactoryImpl::Job::WaitFor(Job* job) { | 290 void HttpStreamFactoryImpl::Job::ResumeAfterDelay( |
| 292 DCHECK_EQ(STATE_NONE, next_state_); | 291 const base::TimeDelta& delay) { |
| 293 DCHECK_EQ(STATE_NONE, job->next_state_); | 292 DCHECK((job_type_ == ALTERNATIVE || !delegate_->blocking())); |
| 294 DCHECK(!blocking_job_); | |
| 295 DCHECK(!job->waiting_job_); | |
| 296 | |
| 297 // Never share connection with other jobs for FTP requests. | |
| 298 DCHECK(!request_info_.url.SchemeIs("ftp")); | |
| 299 | |
| 300 blocking_job_ = job; | |
| 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 | 293 |
| 308 net_log_.AddEvent(NetLog::TYPE_HTTP_STREAM_JOB_DELAYED, | 294 net_log_.AddEvent(NetLog::TYPE_HTTP_STREAM_JOB_DELAYED, |
| 309 base::Bind(&NetLogHttpStreamJobDelayCallback, wait_time_)); | 295 base::Bind(&NetLogHttpStreamJobDelayCallback, delay)); |
| 310 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 296 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 311 FROM_HERE, base::Bind(&HttpStreamFactoryImpl::Job::OnIOComplete, | 297 FROM_HERE, base::Bind(&HttpStreamFactoryImpl::Job::OnIOComplete, |
| 312 ptr_factory_.GetWeakPtr(), OK), | 298 ptr_factory_.GetWeakPtr(), OK), |
| 313 wait_time_); | 299 delay); |
| 314 } | 300 } |
| 315 | 301 |
| 316 void HttpStreamFactoryImpl::Job::Resume(Job* job, | 302 void HttpStreamFactoryImpl::Job::Resume(const base::TimeDelta& delay) { |
| 317 const base::TimeDelta& delay) { | 303 DCHECK_EQ(job_type_, MAIN); |
| 318 DCHECK_EQ(blocking_job_, job); | 304 // If |this| job is not past STATE_WAIT_COMPLETE state, then it will |
| 319 blocking_job_ = NULL; | 305 // be delayed by the |delay| when it resumes. |
| 306 if (next_state_ == STATE_NONE || next_state_ <= STATE_WAIT_COMPLETE) | |
| 307 delegate_->set_wait_time_for_main_job(delay); | |
| 320 | 308 |
| 321 // If |this| job is not past STATE_WAIT_FOR_JOB_COMPLETE state, then it will | 309 // We know we're blocked if the next_state_ is STATE_WAIT_COMPLETE. |
| 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|. | 310 // Unblock |this|. |
| 328 if (next_state_ == STATE_WAIT_FOR_JOB_COMPLETE) | 311 if (next_state_ == STATE_WAIT_COMPLETE) |
| 329 ResumeAfterDelay(); | 312 ResumeAfterDelay(delegate_->wait_time_for_main_job()); |
|
Ryan Hamilton
2016/06/29 23:12:28
Can the delegate (the controller) simply call Resu
Zhongyi Shi
2016/06/30 22:53:39
Done. Yay!!
| |
| 330 } | 313 } |
| 331 | 314 |
| 332 void HttpStreamFactoryImpl::Job::Orphan() { | 315 void HttpStreamFactoryImpl::Job::Orphan() { |
| 333 net_log_.AddEvent(NetLog::TYPE_HTTP_STREAM_JOB_ORPHANED); | 316 net_log_.AddEvent(NetLog::TYPE_HTTP_STREAM_JOB_ORPHANED); |
| 334 if (blocking_job_) { | 317 |
| 335 // We've been orphaned, but there's a job we're blocked on. Don't bother | 318 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 | 319 // We cancel this job because a WebSocketHandshakeStream can't be created |
| 346 // without a WebSocketHandshakeStreamBase::CreateHelper which is stored in | 320 // without a WebSocketHandshakeStreamBase::CreateHelper which is stored in |
| 347 // the Request class and isn't retrievable by this job. | 321 // the Request class and isn't retrievable by this job. |
| 348 if (connection_ && connection_->socket()) { | 322 if (connection_ && connection_->socket()) { |
| 349 connection_->socket()->Disconnect(); | 323 connection_->socket()->Disconnect(); |
| 350 } | 324 } |
| 351 delegate_->OnOrphanedJobComplete(this); | 325 delegate_->OnOrphanedJobComplete(this); |
| 352 } | 326 } |
| 353 // |this| may be deleted after this call. | 327 // |this| may be deleted after this call. |
| 354 } | 328 } |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 548 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("net"), | 522 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("net"), |
| 549 "HttpStreamFactoryImpl::Job::OnIOComplete"); | 523 "HttpStreamFactoryImpl::Job::OnIOComplete"); |
| 550 RunLoop(result); | 524 RunLoop(result); |
| 551 } | 525 } |
| 552 | 526 |
| 553 int HttpStreamFactoryImpl::Job::RunLoop(int result) { | 527 int HttpStreamFactoryImpl::Job::RunLoop(int result) { |
| 554 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("net"), | 528 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("net"), |
| 555 "HttpStreamFactoryImpl::Job::RunLoop"); | 529 "HttpStreamFactoryImpl::Job::RunLoop"); |
| 556 result = DoLoop(result); | 530 result = DoLoop(result); |
| 557 | 531 |
| 558 if (result == ERR_IO_PENDING) | 532 if (result == ERR_IO_PENDING) { |
| 533 if (state_ == STATE_INIT_CONNECTION) { | |
| 534 delegate_->OnInitConnectionNotSuccessful(this, delay_); | |
| 535 delay_ = base::TimeDelta(); | |
| 536 } | |
| 559 return result; | 537 return result; |
| 560 | 538 } |
| 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 | 539 |
| 565 if (job_type_ == PRECONNECT) { | 540 if (job_type_ == PRECONNECT) { |
| 566 base::ThreadTaskRunnerHandle::Get()->PostTask( | 541 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 567 FROM_HERE, | 542 FROM_HERE, |
| 568 base::Bind(&HttpStreamFactoryImpl::Job::OnPreconnectsComplete, | 543 base::Bind(&HttpStreamFactoryImpl::Job::OnPreconnectsComplete, |
| 569 ptr_factory_.GetWeakPtr())); | 544 ptr_factory_.GetWeakPtr())); |
| 570 return ERR_IO_PENDING; | 545 return ERR_IO_PENDING; |
| 571 } | 546 } |
| 572 | 547 |
| 573 if (IsCertificateError(result)) { | 548 if (IsCertificateError(result)) { |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 674 FROM_HERE, base::Bind(&Job::OnStreamFailedCallback, | 649 FROM_HERE, base::Bind(&Job::OnStreamFailedCallback, |
| 675 ptr_factory_.GetWeakPtr(), result)); | 650 ptr_factory_.GetWeakPtr(), result)); |
| 676 return ERR_IO_PENDING; | 651 return ERR_IO_PENDING; |
| 677 } | 652 } |
| 678 } | 653 } |
| 679 | 654 |
| 680 int HttpStreamFactoryImpl::Job::DoLoop(int result) { | 655 int HttpStreamFactoryImpl::Job::DoLoop(int result) { |
| 681 DCHECK_NE(next_state_, STATE_NONE); | 656 DCHECK_NE(next_state_, STATE_NONE); |
| 682 int rv = result; | 657 int rv = result; |
| 683 do { | 658 do { |
| 684 State state = next_state_; | 659 state_ = next_state_; |
| 685 next_state_ = STATE_NONE; | 660 next_state_ = STATE_NONE; |
| 686 switch (state) { | 661 switch (state_) { |
| 687 case STATE_START: | 662 case STATE_START: |
| 688 DCHECK_EQ(OK, rv); | 663 DCHECK_EQ(OK, rv); |
| 689 rv = DoStart(); | 664 rv = DoStart(); |
| 690 break; | 665 break; |
| 691 case STATE_RESOLVE_PROXY: | 666 case STATE_RESOLVE_PROXY: |
| 692 DCHECK_EQ(OK, rv); | 667 DCHECK_EQ(OK, rv); |
| 693 rv = DoResolveProxy(); | 668 rv = DoResolveProxy(); |
| 694 break; | 669 break; |
| 695 case STATE_RESOLVE_PROXY_COMPLETE: | 670 case STATE_RESOLVE_PROXY_COMPLETE: |
| 696 rv = DoResolveProxyComplete(rv); | 671 rv = DoResolveProxyComplete(rv); |
| 697 break; | 672 break; |
| 698 case STATE_WAIT_FOR_JOB: | 673 case STATE_WAIT: |
| 699 DCHECK_EQ(OK, rv); | 674 DCHECK_EQ(OK, rv); |
| 700 rv = DoWaitForJob(); | 675 rv = DoWait(); |
| 701 break; | 676 break; |
| 702 case STATE_WAIT_FOR_JOB_COMPLETE: | 677 case STATE_WAIT_COMPLETE: |
| 703 rv = DoWaitForJobComplete(rv); | 678 rv = DoWaitComplete(rv); |
| 704 break; | 679 break; |
| 705 case STATE_INIT_CONNECTION: | 680 case STATE_INIT_CONNECTION: |
| 706 DCHECK_EQ(OK, rv); | 681 DCHECK_EQ(OK, rv); |
| 707 rv = DoInitConnection(); | 682 rv = DoInitConnection(); |
| 708 break; | 683 break; |
| 709 case STATE_INIT_CONNECTION_COMPLETE: | 684 case STATE_INIT_CONNECTION_COMPLETE: |
| 710 rv = DoInitConnectionComplete(rv); | 685 rv = DoInitConnectionComplete(rv); |
| 711 break; | 686 break; |
| 712 case STATE_WAITING_USER_ACTION: | 687 case STATE_WAITING_USER_ACTION: |
| 713 rv = DoWaitingUserAction(rv); | 688 rv = DoWaitingUserAction(rv); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 754 base::Bind(&NetLogHttpStreamJobCallback, net_log->source(), | 729 base::Bind(&NetLogHttpStreamJobCallback, net_log->source(), |
| 755 &request_info_.url, &origin_url_, &alternative_service_, | 730 &request_info_.url, &origin_url_, &alternative_service_, |
| 756 priority_)); | 731 priority_)); |
| 757 net_log->AddEvent(NetLog::TYPE_HTTP_STREAM_REQUEST_STARTED_JOB, | 732 net_log->AddEvent(NetLog::TYPE_HTTP_STREAM_REQUEST_STARTED_JOB, |
| 758 net_log_.source().ToEventParametersCallback()); | 733 net_log_.source().ToEventParametersCallback()); |
| 759 } | 734 } |
| 760 | 735 |
| 761 // Don't connect to restricted ports. | 736 // Don't connect to restricted ports. |
| 762 if (!IsPortAllowedForScheme(destination_.port(), | 737 if (!IsPortAllowedForScheme(destination_.port(), |
| 763 request_info_.url.scheme())) { | 738 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; | 739 return ERR_UNSAFE_PORT; |
| 769 } | 740 } |
| 770 | 741 |
| 771 next_state_ = STATE_RESOLVE_PROXY; | 742 next_state_ = STATE_RESOLVE_PROXY; |
| 772 return OK; | 743 return OK; |
| 773 } | 744 } |
| 774 | 745 |
| 775 int HttpStreamFactoryImpl::Job::DoResolveProxy() { | 746 int HttpStreamFactoryImpl::Job::DoResolveProxy() { |
| 776 DCHECK(!pac_request_); | 747 DCHECK(!pac_request_); |
| 777 DCHECK(session_); | 748 DCHECK(session_); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 830 result = ERR_NO_SUPPORTED_PROXIES; | 801 result = ERR_NO_SUPPORTED_PROXIES; |
| 831 } else if (using_quic_ && | 802 } else if (using_quic_ && |
| 832 (!proxy_info_.is_quic() && !proxy_info_.is_direct())) { | 803 (!proxy_info_.is_quic() && !proxy_info_.is_direct())) { |
| 833 // 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 |
| 834 // user visible, because the non-alternative Job should be resumed. | 805 // user visible, because the non-alternative Job should be resumed. |
| 835 result = ERR_NO_SUPPORTED_PROXIES; | 806 result = ERR_NO_SUPPORTED_PROXIES; |
| 836 } | 807 } |
| 837 } | 808 } |
| 838 | 809 |
| 839 if (result != OK) { | 810 if (result != OK) { |
| 840 if (waiting_job_) { | |
| 841 waiting_job_->Resume(this, base::TimeDelta()); | |
| 842 waiting_job_ = NULL; | |
| 843 } | |
| 844 return result; | 811 return result; |
| 845 } | 812 } |
| 846 | 813 |
| 847 next_state_ = STATE_WAIT_FOR_JOB; | 814 next_state_ = STATE_WAIT; |
| 848 return OK; | 815 return OK; |
| 849 } | 816 } |
| 850 | 817 |
| 851 bool HttpStreamFactoryImpl::Job::ShouldForceQuic() const { | 818 bool HttpStreamFactoryImpl::Job::ShouldForceQuic() const { |
| 852 return session_->params().enable_quic && | 819 return session_->params().enable_quic && |
| 853 ContainsKey(session_->params().origins_to_force_quic_on, | 820 ContainsKey(session_->params().origins_to_force_quic_on, |
| 854 destination_) && | 821 destination_) && |
| 855 proxy_info_.is_direct() && origin_url_.SchemeIs("https"); | 822 proxy_info_.is_direct() && origin_url_.SchemeIs("https"); |
| 856 } | 823 } |
| 857 | 824 |
| 858 int HttpStreamFactoryImpl::Job::DoWaitForJob() { | 825 int HttpStreamFactoryImpl::Job::DoWait() { |
| 859 if (!blocking_job_ && wait_time_.is_zero()) { | 826 if (delegate_->ShoudWait(this)) { |
| 860 // There is no |blocking_job_| and there is no |wait_time_|. | 827 next_state_ = STATE_WAIT_COMPLETE; |
| 861 next_state_ = STATE_INIT_CONNECTION; | 828 return ERR_IO_PENDING; |
| 862 return OK; | |
| 863 } | 829 } |
| 864 | 830 |
| 865 next_state_ = STATE_WAIT_FOR_JOB_COMPLETE; | |
| 866 if (!wait_time_.is_zero()) { | |
| 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 } | |
| 874 | |
| 875 int HttpStreamFactoryImpl::Job::DoWaitForJobComplete(int result) { | |
| 876 DCHECK(!blocking_job_); | |
| 877 DCHECK_EQ(OK, result); | |
| 878 wait_time_ = base::TimeDelta(); | |
| 879 next_state_ = STATE_INIT_CONNECTION; | 831 next_state_ = STATE_INIT_CONNECTION; |
| 880 return OK; | 832 return OK; |
| 881 } | 833 } |
| 834 | |
| 835 int HttpStreamFactoryImpl::Job::DoWaitComplete(int result) { | |
| 836 DCHECK((job_type_ == ALTERNATIVE || !delegate_->blocking())); | |
| 837 DCHECK_EQ(OK, result); | |
| 838 delegate_->set_wait_time_for_main_job(base::TimeDelta()); | |
| 839 next_state_ = STATE_INIT_CONNECTION; | |
| 840 return OK; | |
| 841 } | |
| 882 | 842 |
| 883 int HttpStreamFactoryImpl::Job::DoInitConnection() { | 843 int HttpStreamFactoryImpl::Job::DoInitConnection() { |
| 884 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462812 is fixed. | 844 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462812 is fixed. |
| 885 tracked_objects::ScopedTracker tracking_profile( | 845 tracked_objects::ScopedTracker tracking_profile( |
| 886 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 846 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 887 "462812 HttpStreamFactoryImpl::Job::DoInitConnection")); | 847 "462812 HttpStreamFactoryImpl::Job::DoInitConnection")); |
| 888 DCHECK(!blocking_job_); | 848 DCHECK((job_type_ == ALTERNATIVE || !delegate_->blocking())); |
| 889 DCHECK(!connection_->is_initialized()); | 849 DCHECK(!connection_->is_initialized()); |
| 890 DCHECK(proxy_info_.proxy_server().is_valid()); | 850 DCHECK(proxy_info_.proxy_server().is_valid()); |
| 891 next_state_ = STATE_INIT_CONNECTION_COMPLETE; | 851 next_state_ = STATE_INIT_CONNECTION_COMPLETE; |
| 892 | 852 |
| 893 using_ssl_ = origin_url_.SchemeIs("https") || origin_url_.SchemeIs("wss") || | 853 using_ssl_ = origin_url_.SchemeIs("https") || origin_url_.SchemeIs("wss") || |
| 894 IsSpdyAlternative(); | 854 IsSpdyAlternative(); |
| 895 using_spdy_ = false; | 855 using_spdy_ = false; |
| 896 | 856 |
| 897 if (ShouldForceQuic()) | 857 if (ShouldForceQuic()) |
| 898 using_quic_ = true; | 858 using_quic_ = true; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 950 destination = destination_; | 910 destination = destination_; |
| 951 ssl_config = &server_ssl_config_; | 911 ssl_config = &server_ssl_config_; |
| 952 } | 912 } |
| 953 int rv = | 913 int rv = |
| 954 quic_request_.Request(destination, request_info_.privacy_mode, | 914 quic_request_.Request(destination, request_info_.privacy_mode, |
| 955 ssl_config->GetCertVerifyFlags(), url, | 915 ssl_config->GetCertVerifyFlags(), url, |
| 956 request_info_.method, net_log_, io_callback_); | 916 request_info_.method, net_log_, io_callback_); |
| 957 if (rv == OK) { | 917 if (rv == OK) { |
| 958 using_existing_quic_session_ = true; | 918 using_existing_quic_session_ = true; |
| 959 } else { | 919 } else { |
| 960 // OK, there's no available QUIC session. Let |waiting_job_| resume | 920 base::TimeDelta delay; |
| 961 // if it's paused. | 921 // OK, there's no available QUIC session. Let JobController to resume |
| 962 if (waiting_job_) { | 922 // the waiting job if it's paused. |
| 963 if (rv == ERR_IO_PENDING) { | 923 if (rv == ERR_IO_PENDING) { |
| 964 // Start the |waiting_job_| after the delay returned by | 924 // Start the waiting job after the delay returned by |
| 965 // GetTimeDelayForWaitingJob(). | 925 // GetTimeDelayForWaitingJob(). |
| 966 // | 926 // |
| 967 // If QUIC request fails during handshake, then | 927 // If QUIC request fails during handshake, then |
| 968 // DoInitConnectionComplete() will start the |waiting_job_|. | 928 // DoInitConnectionComplete() will start the waiting job. |
| 969 waiting_job_->Resume(this, quic_request_.GetTimeDelayForWaitingJob()); | 929 delay_ = 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 } | 930 } |
| 976 } | 931 } |
| 977 return rv; | 932 return rv; |
| 978 } | 933 } |
| 979 | 934 |
| 980 SpdySessionKey spdy_session_key = GetSpdySessionKey(); | 935 SpdySessionKey spdy_session_key = GetSpdySessionKey(); |
| 981 | 936 |
| 982 // Check first if we have a spdy session for this group. If so, then go | 937 // Check first if we have a spdy session for this group. If so, then go |
| 983 // straight to using that. | 938 // straight to using that. |
| 984 if (CanUseExistingSpdySession()) { | 939 if (CanUseExistingSpdySession()) { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 997 existing_spdy_session_ = spdy_session; | 952 existing_spdy_session_ = spdy_session; |
| 998 return OK; | 953 return OK; |
| 999 } | 954 } |
| 1000 } | 955 } |
| 1001 if (using_ssl_) { | 956 if (using_ssl_) { |
| 1002 // Ask |delegate_delegate_| to update the spdy session key for the request | 957 // Ask |delegate_delegate_| to update the spdy session key for the request |
| 1003 // that launched this job. | 958 // that launched this job. |
| 1004 delegate_->SetSpdySessionKey(this, spdy_session_key); | 959 delegate_->SetSpdySessionKey(this, spdy_session_key); |
| 1005 } | 960 } |
| 1006 | 961 |
| 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()) | 962 if (proxy_info_.is_http() || proxy_info_.is_https()) |
| 1015 establishing_tunnel_ = using_ssl_; | 963 establishing_tunnel_ = using_ssl_; |
| 1016 | 964 |
| 1017 const bool expect_spdy = IsSpdyAlternative(); | 965 const bool expect_spdy = IsSpdyAlternative(); |
| 1018 | 966 |
| 1019 base::WeakPtr<HttpServerProperties> http_server_properties = | 967 base::WeakPtr<HttpServerProperties> http_server_properties = |
| 1020 session_->http_server_properties(); | 968 session_->http_server_properties(); |
| 1021 if (http_server_properties) { | 969 if (http_server_properties) { |
| 1022 http_server_properties->MaybeForceHTTP11(destination_, &server_ssl_config_); | 970 http_server_properties->MaybeForceHTTP11(destination_, &server_ssl_config_); |
| 1023 if (proxy_info_.is_http() || proxy_info_.is_https()) { | 971 if (proxy_info_.is_http() || proxy_info_.is_https()) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1056 } | 1004 } |
| 1057 | 1005 |
| 1058 return InitSocketHandleForHttpRequest( | 1006 return InitSocketHandleForHttpRequest( |
| 1059 GetSocketGroup(), destination_, request_info_.extra_headers, | 1007 GetSocketGroup(), destination_, request_info_.extra_headers, |
| 1060 request_info_.load_flags, priority_, session_, proxy_info_, expect_spdy, | 1008 request_info_.load_flags, priority_, session_, proxy_info_, expect_spdy, |
| 1061 server_ssl_config_, proxy_ssl_config_, request_info_.privacy_mode, | 1009 server_ssl_config_, proxy_ssl_config_, request_info_.privacy_mode, |
| 1062 net_log_, connection_.get(), resolution_callback, io_callback_); | 1010 net_log_, connection_.get(), resolution_callback, io_callback_); |
| 1063 } | 1011 } |
| 1064 | 1012 |
| 1065 int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) { | 1013 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) { | 1014 if (job_type_ == PRECONNECT) { |
| 1071 if (using_quic_) | 1015 if (using_quic_) |
| 1072 return result; | 1016 return result; |
| 1073 DCHECK_EQ(OK, result); | 1017 DCHECK_EQ(OK, result); |
| 1074 return OK; | 1018 return OK; |
| 1075 } | 1019 } |
| 1076 | 1020 |
| 1077 if (result == ERR_SPDY_SESSION_ALREADY_EXISTS) { | 1021 if (result == ERR_SPDY_SESSION_ALREADY_EXISTS) { |
| 1022 DCHECK(!using_quic_); | |
| 1078 // We found a SPDY connection after resolving the host. This is | 1023 // We found a SPDY connection after resolving the host. This is |
| 1079 // probably an IP pooled connection. | 1024 // probably an IP pooled connection. |
| 1080 SpdySessionKey spdy_session_key = GetSpdySessionKey(); | 1025 SpdySessionKey spdy_session_key = GetSpdySessionKey(); |
| 1081 existing_spdy_session_ = | 1026 existing_spdy_session_ = |
| 1082 session_->spdy_session_pool()->FindAvailableSession( | 1027 session_->spdy_session_pool()->FindAvailableSession( |
| 1083 spdy_session_key, origin_url_, net_log_); | 1028 spdy_session_key, origin_url_, net_log_); |
| 1084 if (existing_spdy_session_) { | 1029 if (existing_spdy_session_) { |
| 1085 using_spdy_ = true; | 1030 using_spdy_ = true; |
| 1086 next_state_ = STATE_CREATE_STREAM; | 1031 next_state_ = STATE_CREATE_STREAM; |
| 1087 } else { | 1032 } else { |
| 1088 // It is possible that the spdy session no longer exists. | 1033 // It is possible that the spdy session no longer exists. |
| 1089 ReturnToStateInitConnection(true /* close connection */); | 1034 ReturnToStateInitConnection(true /* close connection */); |
| 1090 } | 1035 } |
| 1091 return OK; | 1036 return OK; |
| 1092 } | 1037 } |
| 1093 | 1038 |
| 1039 // TODO(willchan): Make this a bit more exact. Maybe there are recoverable | |
| 1040 // errors, such as ignoring certificate errors for Alternate-Protocol. | |
| 1041 // Report failure to delegate as there's error in DoInitConnection. Delegate | |
| 1042 // might be able to resume the other job. | |
| 1043 if (result < 0) { | |
| 1044 delegate_->OnInitConnectionNotSuccessful(this, delay_); | |
| 1045 delay_ = base::TimeDelta(); | |
| 1046 } | |
| 1047 | |
| 1094 if (proxy_info_.is_quic() && using_quic_) { | 1048 if (proxy_info_.is_quic() && using_quic_) { |
| 1095 // Mark QUIC proxy as bad if QUIC got disabled on the destination port. | 1049 // Mark QUIC proxy as bad if QUIC got disabled on the destination port. |
| 1096 // Underlying QUIC layer would have closed the connection. | 1050 // Underlying QUIC layer would have closed the connection. |
| 1097 HostPortPair destination = proxy_info_.proxy_server().host_port_pair(); | 1051 HostPortPair destination = proxy_info_.proxy_server().host_port_pair(); |
| 1098 if (session_->quic_stream_factory()->IsQuicDisabled(destination.port())) { | 1052 if (session_->quic_stream_factory()->IsQuicDisabled(destination.port())) { |
| 1099 using_quic_ = false; | 1053 using_quic_ = false; |
| 1100 return ReconsiderProxyAfterError(ERR_QUIC_PROTOCOL_ERROR); | 1054 return ReconsiderProxyAfterError(ERR_QUIC_PROTOCOL_ERROR); |
| 1101 } | 1055 } |
| 1102 } | 1056 } |
| 1103 | 1057 |
| 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 | 1058 // |result| may be the result of any of the stacked pools. The following |
| 1112 // logic is used when determining how to interpret an error. | 1059 // logic is used when determining how to interpret an error. |
| 1113 // If |result| < 0: | 1060 // If |result| < 0: |
| 1114 // and connection_->socket() != NULL, then the SSL handshake ran and it | 1061 // and connection_->socket() != NULL, then the SSL handshake ran and it |
| 1115 // is a potentially recoverable error. | 1062 // is a potentially recoverable error. |
| 1116 // and connection_->socket == NULL and connection_->is_ssl_error() is true, | 1063 // and connection_->socket == NULL and connection_->is_ssl_error() is true, |
| 1117 // then the SSL handshake ran with an unrecoverable error. | 1064 // then the SSL handshake ran with an unrecoverable error. |
| 1118 // otherwise, the error came from one of the other pools. | 1065 // otherwise, the error came from one of the other pools. |
| 1119 bool ssl_started = using_ssl_ && (result == OK || connection_->socket() || | 1066 bool ssl_started = using_ssl_ && (result == OK || connection_->socket() || |
| 1120 connection_->is_ssl_error()); | 1067 connection_->is_ssl_error()); |
| (...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1731 | 1678 |
| 1732 ConnectionAttempts socket_attempts = connection_->connection_attempts(); | 1679 ConnectionAttempts socket_attempts = connection_->connection_attempts(); |
| 1733 if (connection_->socket()) { | 1680 if (connection_->socket()) { |
| 1734 connection_->socket()->GetConnectionAttempts(&socket_attempts); | 1681 connection_->socket()->GetConnectionAttempts(&socket_attempts); |
| 1735 } | 1682 } |
| 1736 | 1683 |
| 1737 delegate_->AddConnectionAttemptsToRequest(this, socket_attempts); | 1684 delegate_->AddConnectionAttemptsToRequest(this, socket_attempts); |
| 1738 } | 1685 } |
| 1739 | 1686 |
| 1740 } // namespace net | 1687 } // namespace net |
| OLD | NEW |