| 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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 122 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
| 123 if (source.IsValid()) | 123 if (source.IsValid()) |
| 124 source.AddToEventParameters(dict.get()); | 124 source.AddToEventParameters(dict.get()); |
| 125 dict->SetString("original_url", original_url->GetOrigin().spec()); | 125 dict->SetString("original_url", original_url->GetOrigin().spec()); |
| 126 dict->SetString("url", url->GetOrigin().spec()); | 126 dict->SetString("url", url->GetOrigin().spec()); |
| 127 dict->SetString("alternative_service", alternative_service->ToString()); | 127 dict->SetString("alternative_service", alternative_service->ToString()); |
| 128 dict->SetString("priority", RequestPriorityToString(priority)); | 128 dict->SetString("priority", RequestPriorityToString(priority)); |
| 129 return std::move(dict); | 129 return std::move(dict); |
| 130 } | 130 } |
| 131 | 131 |
| 132 // Returns parameters associated with the delay of the HTTP stream job. | |
| 133 std::unique_ptr<base::Value> NetLogHttpStreamJobDelayCallback( | |
| 134 base::TimeDelta delay, | |
| 135 NetLogCaptureMode /* capture_mode */) { | |
| 136 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | |
| 137 dict->SetInteger("resume_after_ms", static_cast<int>(delay.InMilliseconds())); | |
| 138 return std::move(dict); | |
| 139 } | |
| 140 | |
| 141 // Returns parameters associated with the Proto (with NPN negotiation) of a HTTP | 132 // Returns parameters associated with the Proto (with NPN negotiation) of a HTTP |
| 142 // stream. | 133 // stream. |
| 143 std::unique_ptr<base::Value> NetLogHttpStreamProtoCallback( | 134 std::unique_ptr<base::Value> NetLogHttpStreamProtoCallback( |
| 144 const SSLClientSocket::NextProtoStatus status, | 135 const SSLClientSocket::NextProtoStatus status, |
| 145 const std::string* proto, | 136 const std::string* proto, |
| 146 NetLogCaptureMode /* capture_mode */) { | 137 NetLogCaptureMode /* capture_mode */) { |
| 147 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 138 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
| 148 | 139 |
| 149 dict->SetString("next_proto_status", | 140 dict->SetString("next_proto_status", |
| 150 SSLClientSocket::NextProtoStatusToString(status)); | 141 SSLClientSocket::NextProtoStatusToString(status)); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 io_callback_(base::Bind(&Job::OnIOComplete, base::Unretained(this))), | 184 io_callback_(base::Bind(&Job::OnIOComplete, base::Unretained(this))), |
| 194 connection_(new ClientSocketHandle), | 185 connection_(new ClientSocketHandle), |
| 195 session_(session), | 186 session_(session), |
| 196 next_state_(STATE_NONE), | 187 next_state_(STATE_NONE), |
| 197 pac_request_(NULL), | 188 pac_request_(NULL), |
| 198 destination_(destination), | 189 destination_(destination), |
| 199 origin_url_(origin_url), | 190 origin_url_(origin_url), |
| 200 alternative_service_(alternative_service), | 191 alternative_service_(alternative_service), |
| 201 delegate_(delegate), | 192 delegate_(delegate), |
| 202 job_type_(job_type), | 193 job_type_(job_type), |
| 203 blocking_job_(NULL), | |
| 204 waiting_job_(NULL), | |
| 205 using_ssl_(false), | 194 using_ssl_(false), |
| 206 using_spdy_(false), | 195 using_spdy_(false), |
| 207 using_quic_(false), | 196 using_quic_(false), |
| 208 quic_request_(session_->quic_stream_factory()), | 197 quic_request_(session_->quic_stream_factory()), |
| 209 using_existing_quic_session_(false), | 198 using_existing_quic_session_(false), |
| 210 spdy_certificate_error_(OK), | 199 spdy_certificate_error_(OK), |
| 211 establishing_tunnel_(false), | 200 establishing_tunnel_(false), |
| 212 was_npn_negotiated_(false), | 201 was_npn_negotiated_(false), |
| 213 protocol_negotiated_(kProtoUnknown), | 202 protocol_negotiated_(kProtoUnknown), |
| 214 num_streams_(0), | 203 num_streams_(0), |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 279 case STATE_RESOLVE_PROXY_COMPLETE: | 268 case STATE_RESOLVE_PROXY_COMPLETE: |
| 280 return session_->proxy_service()->GetLoadState(pac_request_); | 269 return session_->proxy_service()->GetLoadState(pac_request_); |
| 281 case STATE_INIT_CONNECTION_COMPLETE: | 270 case STATE_INIT_CONNECTION_COMPLETE: |
| 282 case STATE_CREATE_STREAM_COMPLETE: | 271 case STATE_CREATE_STREAM_COMPLETE: |
| 283 return using_quic_ ? LOAD_STATE_CONNECTING : connection_->GetLoadState(); | 272 return using_quic_ ? LOAD_STATE_CONNECTING : connection_->GetLoadState(); |
| 284 default: | 273 default: |
| 285 return LOAD_STATE_IDLE; | 274 return LOAD_STATE_IDLE; |
| 286 } | 275 } |
| 287 } | 276 } |
| 288 | 277 |
| 289 void HttpStreamFactoryImpl::Job::WaitFor(Job* job) { | 278 void HttpStreamFactoryImpl::Job::Resume() { |
| 290 DCHECK_EQ(STATE_NONE, next_state_); | 279 DCHECK_EQ(job_type_, MAIN); |
| 291 DCHECK_EQ(STATE_NONE, job->next_state_); | 280 DCHECK_EQ(next_state_, STATE_WAIT_COMPLETE); |
| 292 DCHECK(!blocking_job_); | 281 OnIOComplete(OK); |
| 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 | |
| 306 net_log_.AddEvent(NetLog::TYPE_HTTP_STREAM_JOB_DELAYED, | |
| 307 base::Bind(&NetLogHttpStreamJobDelayCallback, wait_time_)); | |
| 308 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | |
| 309 FROM_HERE, base::Bind(&HttpStreamFactoryImpl::Job::OnIOComplete, | |
| 310 ptr_factory_.GetWeakPtr(), OK), | |
| 311 wait_time_); | |
| 312 } | |
| 313 | |
| 314 void HttpStreamFactoryImpl::Job::Resume(Job* job, | |
| 315 const base::TimeDelta& delay) { | |
| 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 | |
| 320 // be delayed by the |wait_time_| when it resumes. | |
| 321 if (next_state_ == STATE_NONE || next_state_ <= STATE_WAIT_FOR_JOB_COMPLETE) | |
| 322 wait_time_ = delay; | |
| 323 | |
| 324 // We know we're blocked if the next_state_ is STATE_WAIT_FOR_JOB_COMPLETE. | |
| 325 // Unblock |this|. | |
| 326 if (next_state_ == STATE_WAIT_FOR_JOB_COMPLETE) | |
| 327 ResumeAfterDelay(); | |
| 328 } | 282 } |
| 329 | 283 |
| 330 void HttpStreamFactoryImpl::Job::Orphan() { | 284 void HttpStreamFactoryImpl::Job::Orphan() { |
| 331 net_log_.AddEvent(NetLog::TYPE_HTTP_STREAM_JOB_ORPHANED); | 285 net_log_.AddEvent(NetLog::TYPE_HTTP_STREAM_JOB_ORPHANED); |
| 332 if (blocking_job_) { | 286 |
| 333 // We've been orphaned, but there's a job we're blocked on. Don't bother | 287 if (delegate_->for_websockets()) { |
| 334 // racing, just cancel ourself. | |
| 335 DCHECK(blocking_job_->waiting_job_); | |
| 336 blocking_job_->waiting_job_ = NULL; | |
| 337 blocking_job_ = NULL; | |
| 338 if (delegate_->for_websockets() && connection_ && connection_->socket()) { | |
| 339 connection_->socket()->Disconnect(); | |
| 340 } | |
| 341 delegate_->OnOrphanedJobComplete(this); | |
| 342 } else if (delegate_->for_websockets()) { | |
| 343 // We cancel this job because a WebSocketHandshakeStream can't be created | 288 // We cancel this job because a WebSocketHandshakeStream can't be created |
| 344 // without a WebSocketHandshakeStreamBase::CreateHelper which is stored in | 289 // without a WebSocketHandshakeStreamBase::CreateHelper which is stored in |
| 345 // the Request class and isn't retrievable by this job. | 290 // the Request class and isn't retrievable by this job. |
| 346 if (connection_ && connection_->socket()) { | 291 if (connection_ && connection_->socket()) { |
| 347 connection_->socket()->Disconnect(); | 292 connection_->socket()->Disconnect(); |
| 348 } | 293 } |
| 349 delegate_->OnOrphanedJobComplete(this); | 294 delegate_->OnOrphanedJobComplete(this); |
| 350 } | 295 } |
| 351 // |this| may be deleted after this call. | 296 // |this| may be deleted after this call. |
| 352 } | 297 } |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 545 } | 490 } |
| 546 | 491 |
| 547 int HttpStreamFactoryImpl::Job::RunLoop(int result) { | 492 int HttpStreamFactoryImpl::Job::RunLoop(int result) { |
| 548 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("net"), | 493 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("net"), |
| 549 "HttpStreamFactoryImpl::Job::RunLoop"); | 494 "HttpStreamFactoryImpl::Job::RunLoop"); |
| 550 result = DoLoop(result); | 495 result = DoLoop(result); |
| 551 | 496 |
| 552 if (result == ERR_IO_PENDING) | 497 if (result == ERR_IO_PENDING) |
| 553 return result; | 498 return result; |
| 554 | 499 |
| 555 // If there was an error, we should have already resumed the |waiting_job_|, | |
| 556 // if there was one. | |
| 557 DCHECK(result == OK || waiting_job_ == NULL); | |
| 558 | |
| 559 if (job_type_ == PRECONNECT) { | 500 if (job_type_ == PRECONNECT) { |
| 560 base::ThreadTaskRunnerHandle::Get()->PostTask( | 501 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 561 FROM_HERE, | 502 FROM_HERE, |
| 562 base::Bind(&HttpStreamFactoryImpl::Job::OnPreconnectsComplete, | 503 base::Bind(&HttpStreamFactoryImpl::Job::OnPreconnectsComplete, |
| 563 ptr_factory_.GetWeakPtr())); | 504 ptr_factory_.GetWeakPtr())); |
| 564 return ERR_IO_PENDING; | 505 return ERR_IO_PENDING; |
| 565 } | 506 } |
| 566 | 507 |
| 567 if (IsCertificateError(result)) { | 508 if (IsCertificateError(result)) { |
| 568 // Retrieve SSL information from the socket. | 509 // Retrieve SSL information from the socket. |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 677 DCHECK_EQ(OK, rv); | 618 DCHECK_EQ(OK, rv); |
| 678 rv = DoStart(); | 619 rv = DoStart(); |
| 679 break; | 620 break; |
| 680 case STATE_RESOLVE_PROXY: | 621 case STATE_RESOLVE_PROXY: |
| 681 DCHECK_EQ(OK, rv); | 622 DCHECK_EQ(OK, rv); |
| 682 rv = DoResolveProxy(); | 623 rv = DoResolveProxy(); |
| 683 break; | 624 break; |
| 684 case STATE_RESOLVE_PROXY_COMPLETE: | 625 case STATE_RESOLVE_PROXY_COMPLETE: |
| 685 rv = DoResolveProxyComplete(rv); | 626 rv = DoResolveProxyComplete(rv); |
| 686 break; | 627 break; |
| 687 case STATE_WAIT_FOR_JOB: | 628 case STATE_WAIT: |
| 688 DCHECK_EQ(OK, rv); | 629 DCHECK_EQ(OK, rv); |
| 689 rv = DoWaitForJob(); | 630 rv = DoWait(); |
| 690 break; | 631 break; |
| 691 case STATE_WAIT_FOR_JOB_COMPLETE: | 632 case STATE_WAIT_COMPLETE: |
| 692 rv = DoWaitForJobComplete(rv); | 633 rv = DoWaitComplete(rv); |
| 693 break; | 634 break; |
| 694 case STATE_INIT_CONNECTION: | 635 case STATE_INIT_CONNECTION: |
| 695 DCHECK_EQ(OK, rv); | 636 DCHECK_EQ(OK, rv); |
| 696 rv = DoInitConnection(); | 637 rv = DoInitConnection(); |
| 697 break; | 638 break; |
| 698 case STATE_INIT_CONNECTION_COMPLETE: | 639 case STATE_INIT_CONNECTION_COMPLETE: |
| 699 rv = DoInitConnectionComplete(rv); | 640 rv = DoInitConnectionComplete(rv); |
| 700 break; | 641 break; |
| 701 case STATE_WAITING_USER_ACTION: | 642 case STATE_WAITING_USER_ACTION: |
| 702 rv = DoWaitingUserAction(rv); | 643 rv = DoWaitingUserAction(rv); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 741 base::Bind(&NetLogHttpStreamJobCallback, net_log->source(), | 682 base::Bind(&NetLogHttpStreamJobCallback, net_log->source(), |
| 742 &request_info_.url, &origin_url_, &alternative_service_, | 683 &request_info_.url, &origin_url_, &alternative_service_, |
| 743 priority_)); | 684 priority_)); |
| 744 net_log->AddEvent(NetLog::TYPE_HTTP_STREAM_REQUEST_STARTED_JOB, | 685 net_log->AddEvent(NetLog::TYPE_HTTP_STREAM_REQUEST_STARTED_JOB, |
| 745 net_log_.source().ToEventParametersCallback()); | 686 net_log_.source().ToEventParametersCallback()); |
| 746 } | 687 } |
| 747 | 688 |
| 748 // Don't connect to restricted ports. | 689 // Don't connect to restricted ports. |
| 749 if (!IsPortAllowedForScheme(destination_.port(), | 690 if (!IsPortAllowedForScheme(destination_.port(), |
| 750 request_info_.url.scheme())) { | 691 request_info_.url.scheme())) { |
| 751 if (waiting_job_) { | |
| 752 waiting_job_->Resume(this, base::TimeDelta()); | |
| 753 waiting_job_ = NULL; | |
| 754 } | |
| 755 return ERR_UNSAFE_PORT; | 692 return ERR_UNSAFE_PORT; |
| 756 } | 693 } |
| 757 | 694 |
| 758 next_state_ = STATE_RESOLVE_PROXY; | 695 next_state_ = STATE_RESOLVE_PROXY; |
| 759 return OK; | 696 return OK; |
| 760 } | 697 } |
| 761 | 698 |
| 762 int HttpStreamFactoryImpl::Job::DoResolveProxy() { | 699 int HttpStreamFactoryImpl::Job::DoResolveProxy() { |
| 763 DCHECK(!pac_request_); | 700 DCHECK(!pac_request_); |
| 764 DCHECK(session_); | 701 DCHECK(session_); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 816 result = ERR_NO_SUPPORTED_PROXIES; | 753 result = ERR_NO_SUPPORTED_PROXIES; |
| 817 } else if (using_quic_ && | 754 } else if (using_quic_ && |
| 818 (!proxy_info_.is_quic() && !proxy_info_.is_direct())) { | 755 (!proxy_info_.is_quic() && !proxy_info_.is_direct())) { |
| 819 // QUIC can not be spoken to non-QUIC proxies. This error should not be | 756 // QUIC can not be spoken to non-QUIC proxies. This error should not be |
| 820 // user visible, because the non-alternative Job should be resumed. | 757 // user visible, because the non-alternative Job should be resumed. |
| 821 result = ERR_NO_SUPPORTED_PROXIES; | 758 result = ERR_NO_SUPPORTED_PROXIES; |
| 822 } | 759 } |
| 823 } | 760 } |
| 824 | 761 |
| 825 if (result != OK) { | 762 if (result != OK) { |
| 826 if (waiting_job_) { | |
| 827 waiting_job_->Resume(this, base::TimeDelta()); | |
| 828 waiting_job_ = NULL; | |
| 829 } | |
| 830 return result; | 763 return result; |
| 831 } | 764 } |
| 832 | 765 |
| 833 next_state_ = STATE_WAIT_FOR_JOB; | 766 next_state_ = STATE_WAIT; |
| 834 return OK; | 767 return OK; |
| 835 } | 768 } |
| 836 | 769 |
| 837 bool HttpStreamFactoryImpl::Job::ShouldForceQuic() const { | 770 bool HttpStreamFactoryImpl::Job::ShouldForceQuic() const { |
| 838 return session_->params().enable_quic && | 771 return session_->params().enable_quic && |
| 839 (ContainsKey(session_->params().origins_to_force_quic_on, | 772 (ContainsKey(session_->params().origins_to_force_quic_on, |
| 840 HostPortPair()) || | 773 HostPortPair()) || |
| 841 ContainsKey(session_->params().origins_to_force_quic_on, | 774 ContainsKey(session_->params().origins_to_force_quic_on, |
| 842 destination_)) && | 775 destination_)) && |
| 843 proxy_info_.is_direct() && origin_url_.SchemeIs("https"); | 776 proxy_info_.is_direct() && origin_url_.SchemeIs("https"); |
| 844 } | 777 } |
| 845 | 778 |
| 846 int HttpStreamFactoryImpl::Job::DoWaitForJob() { | 779 int HttpStreamFactoryImpl::Job::DoWait() { |
| 847 if (!blocking_job_ && wait_time_.is_zero()) { | 780 next_state_ = STATE_WAIT_COMPLETE; |
| 848 // There is no |blocking_job_| and there is no |wait_time_|. | 781 if (delegate_->ShouldWait(this)) |
| 849 next_state_ = STATE_INIT_CONNECTION; | 782 return ERR_IO_PENDING; |
| 850 return OK; | |
| 851 } | |
| 852 | 783 |
| 853 next_state_ = STATE_WAIT_FOR_JOB_COMPLETE; | 784 return OK; |
| 854 if (!wait_time_.is_zero()) { | |
| 855 // If there is a waiting_time, then resume the job after the wait_time_. | |
| 856 DCHECK(!blocking_job_); | |
| 857 ResumeAfterDelay(); | |
| 858 } | |
| 859 | |
| 860 return ERR_IO_PENDING; | |
| 861 } | 785 } |
| 862 | 786 |
| 863 int HttpStreamFactoryImpl::Job::DoWaitForJobComplete(int result) { | 787 int HttpStreamFactoryImpl::Job::DoWaitComplete(int result) { |
| 864 DCHECK(!blocking_job_); | |
| 865 DCHECK_EQ(OK, result); | 788 DCHECK_EQ(OK, result); |
| 866 wait_time_ = base::TimeDelta(); | |
| 867 next_state_ = STATE_INIT_CONNECTION; | 789 next_state_ = STATE_INIT_CONNECTION; |
| 868 return OK; | 790 return OK; |
| 869 } | 791 } |
| 870 | 792 |
| 871 int HttpStreamFactoryImpl::Job::DoInitConnection() { | 793 int HttpStreamFactoryImpl::Job::DoInitConnection() { |
| 794 int result = DoInitConnectionImpl(); |
| 795 if (result != ERR_SPDY_SESSION_ALREADY_EXISTS) |
| 796 delegate_->OnConnectionInitialized(this, result); |
| 797 |
| 798 return result; |
| 799 } |
| 800 |
| 801 int HttpStreamFactoryImpl::Job::DoInitConnectionImpl() { |
| 872 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462812 is fixed. | 802 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462812 is fixed. |
| 873 tracked_objects::ScopedTracker tracking_profile( | 803 tracked_objects::ScopedTracker tracking_profile( |
| 874 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 804 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 875 "462812 HttpStreamFactoryImpl::Job::DoInitConnection")); | 805 "462812 HttpStreamFactoryImpl::Job::DoInitConnection")); |
| 876 DCHECK(!blocking_job_); | |
| 877 DCHECK(!connection_->is_initialized()); | 806 DCHECK(!connection_->is_initialized()); |
| 878 DCHECK(proxy_info_.proxy_server().is_valid()); | 807 DCHECK(proxy_info_.proxy_server().is_valid()); |
| 879 next_state_ = STATE_INIT_CONNECTION_COMPLETE; | 808 next_state_ = STATE_INIT_CONNECTION_COMPLETE; |
| 880 | 809 |
| 881 using_ssl_ = origin_url_.SchemeIs("https") || origin_url_.SchemeIs("wss") || | 810 using_ssl_ = origin_url_.SchemeIs("https") || origin_url_.SchemeIs("wss") || |
| 882 IsSpdyAlternative(); | 811 IsSpdyAlternative(); |
| 883 using_spdy_ = false; | 812 using_spdy_ = false; |
| 884 | 813 |
| 885 if (ShouldForceQuic()) | 814 if (ShouldForceQuic()) |
| 886 using_quic_ = true; | 815 using_quic_ = true; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 938 destination = destination_; | 867 destination = destination_; |
| 939 ssl_config = &server_ssl_config_; | 868 ssl_config = &server_ssl_config_; |
| 940 } | 869 } |
| 941 int rv = | 870 int rv = |
| 942 quic_request_.Request(destination, request_info_.privacy_mode, | 871 quic_request_.Request(destination, request_info_.privacy_mode, |
| 943 ssl_config->GetCertVerifyFlags(), url, | 872 ssl_config->GetCertVerifyFlags(), url, |
| 944 request_info_.method, net_log_, io_callback_); | 873 request_info_.method, net_log_, io_callback_); |
| 945 if (rv == OK) { | 874 if (rv == OK) { |
| 946 using_existing_quic_session_ = true; | 875 using_existing_quic_session_ = true; |
| 947 } else { | 876 } else { |
| 948 // OK, there's no available QUIC session. Let |waiting_job_| resume | 877 // There's no available QUIC session. Inform the delegate how long to |
| 949 // if it's paused. | 878 // delay the main job. |
| 950 if (waiting_job_) { | 879 if (rv == ERR_IO_PENDING) { |
| 951 if (rv == ERR_IO_PENDING) { | 880 delegate_->MaybeSetWaitTimeForMainJob( |
| 952 // Start the |waiting_job_| after the delay returned by | 881 quic_request_.GetTimeDelayForWaitingJob()); |
| 953 // GetTimeDelayForWaitingJob(). | |
| 954 // | |
| 955 // If QUIC request fails during handshake, then | |
| 956 // DoInitConnectionComplete() will start the |waiting_job_|. | |
| 957 waiting_job_->Resume(this, quic_request_.GetTimeDelayForWaitingJob()); | |
| 958 } else { | |
| 959 // QUIC request has failed, resume the |waiting_job_|. | |
| 960 waiting_job_->Resume(this, base::TimeDelta()); | |
| 961 } | |
| 962 waiting_job_ = NULL; | |
| 963 } | 882 } |
| 964 } | 883 } |
| 965 return rv; | 884 return rv; |
| 966 } | 885 } |
| 967 | 886 |
| 968 SpdySessionKey spdy_session_key = GetSpdySessionKey(); | 887 SpdySessionKey spdy_session_key = GetSpdySessionKey(); |
| 969 | 888 |
| 970 // Check first if we have a spdy session for this group. If so, then go | 889 // Check first if we have a spdy session for this group. If so, then go |
| 971 // straight to using that. | 890 // straight to using that. |
| 972 if (CanUseExistingSpdySession()) { | 891 if (CanUseExistingSpdySession()) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 983 existing_spdy_session_ = spdy_session; | 902 existing_spdy_session_ = spdy_session; |
| 984 return OK; | 903 return OK; |
| 985 } | 904 } |
| 986 } | 905 } |
| 987 if (using_ssl_) { | 906 if (using_ssl_) { |
| 988 // Ask |delegate_delegate_| to update the spdy session key for the request | 907 // Ask |delegate_delegate_| to update the spdy session key for the request |
| 989 // that launched this job. | 908 // that launched this job. |
| 990 delegate_->SetSpdySessionKey(this, spdy_session_key); | 909 delegate_->SetSpdySessionKey(this, spdy_session_key); |
| 991 } | 910 } |
| 992 | 911 |
| 993 // OK, there's no available SPDY session. Let |waiting_job_| resume if it's | |
| 994 // paused. | |
| 995 if (waiting_job_) { | |
| 996 waiting_job_->Resume(this, base::TimeDelta()); | |
| 997 waiting_job_ = NULL; | |
| 998 } | |
| 999 | |
| 1000 if (proxy_info_.is_http() || proxy_info_.is_https()) | 912 if (proxy_info_.is_http() || proxy_info_.is_https()) |
| 1001 establishing_tunnel_ = using_ssl_; | 913 establishing_tunnel_ = using_ssl_; |
| 1002 | 914 |
| 1003 const bool expect_spdy = IsSpdyAlternative(); | 915 const bool expect_spdy = IsSpdyAlternative(); |
| 1004 | 916 |
| 1005 HttpServerProperties* http_server_properties = | 917 HttpServerProperties* http_server_properties = |
| 1006 session_->http_server_properties(); | 918 session_->http_server_properties(); |
| 1007 if (http_server_properties) { | 919 if (http_server_properties) { |
| 1008 http_server_properties->MaybeForceHTTP11(destination_, &server_ssl_config_); | 920 http_server_properties->MaybeForceHTTP11(destination_, &server_ssl_config_); |
| 1009 if (proxy_info_.is_http() || proxy_info_.is_https()) { | 921 if (proxy_info_.is_http() || proxy_info_.is_https()) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1042 } | 954 } |
| 1043 | 955 |
| 1044 return InitSocketHandleForHttpRequest( | 956 return InitSocketHandleForHttpRequest( |
| 1045 GetSocketGroup(), destination_, request_info_.extra_headers, | 957 GetSocketGroup(), destination_, request_info_.extra_headers, |
| 1046 request_info_.load_flags, priority_, session_, proxy_info_, expect_spdy, | 958 request_info_.load_flags, priority_, session_, proxy_info_, expect_spdy, |
| 1047 server_ssl_config_, proxy_ssl_config_, request_info_.privacy_mode, | 959 server_ssl_config_, proxy_ssl_config_, request_info_.privacy_mode, |
| 1048 net_log_, connection_.get(), resolution_callback, io_callback_); | 960 net_log_, connection_.get(), resolution_callback, io_callback_); |
| 1049 } | 961 } |
| 1050 | 962 |
| 1051 int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) { | 963 int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) { |
| 1052 if (using_quic_ && result < 0 && waiting_job_) { | |
| 1053 waiting_job_->Resume(this, base::TimeDelta()); | |
| 1054 waiting_job_ = NULL; | |
| 1055 } | |
| 1056 if (job_type_ == PRECONNECT) { | 964 if (job_type_ == PRECONNECT) { |
| 1057 if (using_quic_) | 965 if (using_quic_) |
| 1058 return result; | 966 return result; |
| 1059 DCHECK_EQ(OK, result); | 967 DCHECK_EQ(OK, result); |
| 1060 return OK; | 968 return OK; |
| 1061 } | 969 } |
| 1062 | 970 |
| 1063 if (result == ERR_SPDY_SESSION_ALREADY_EXISTS) { | 971 if (result == ERR_SPDY_SESSION_ALREADY_EXISTS) { |
| 1064 // We found a SPDY connection after resolving the host. This is | 972 // We found a SPDY connection after resolving the host. This is |
| 1065 // probably an IP pooled connection. | 973 // probably an IP pooled connection. |
| 1066 SpdySessionKey spdy_session_key = GetSpdySessionKey(); | 974 SpdySessionKey spdy_session_key = GetSpdySessionKey(); |
| 1067 existing_spdy_session_ = | 975 existing_spdy_session_ = |
| 1068 session_->spdy_session_pool()->FindAvailableSession( | 976 session_->spdy_session_pool()->FindAvailableSession( |
| 1069 spdy_session_key, origin_url_, net_log_); | 977 spdy_session_key, origin_url_, net_log_); |
| 1070 if (existing_spdy_session_) { | 978 if (existing_spdy_session_) { |
| 1071 using_spdy_ = true; | 979 using_spdy_ = true; |
| 1072 next_state_ = STATE_CREATE_STREAM; | 980 next_state_ = STATE_CREATE_STREAM; |
| 1073 } else { | 981 } else { |
| 1074 // It is possible that the spdy session no longer exists. | 982 // It is possible that the spdy session no longer exists. |
| 1075 ReturnToStateInitConnection(true /* close connection */); | 983 ReturnToStateInitConnection(true /* close connection */); |
| 1076 } | 984 } |
| 1077 return OK; | 985 return OK; |
| 1078 } | 986 } |
| 1079 | 987 |
| 1080 if (proxy_info_.is_quic() && using_quic_) { | 988 if (proxy_info_.is_quic() && using_quic_) { |
| 1081 // Mark QUIC proxy as bad if QUIC got disabled on the destination port. | 989 // Mark QUIC proxy as bad if QUIC got disabled on the destination port. |
| 1082 // Underlying QUIC layer would have closed the connection. | 990 // Underlying QUIC layer would have closed the connection. |
| 1083 HostPortPair destination = proxy_info_.proxy_server().host_port_pair(); | 991 HostPortPair destination = proxy_info_.proxy_server().host_port_pair(); |
| 1084 if (session_->quic_stream_factory()->IsQuicDisabled(destination.port())) { | 992 if (session_->quic_stream_factory()->IsQuicDisabled(destination.port())) { |
| 1085 using_quic_ = false; | 993 using_quic_ = false; |
| 1086 return ReconsiderProxyAfterError(ERR_QUIC_PROTOCOL_ERROR); | 994 return ReconsiderProxyAfterError(ERR_QUIC_PROTOCOL_ERROR); |
| 1087 } | 995 } |
| 1088 } | 996 } |
| 1089 | 997 |
| 1090 // TODO(willchan): Make this a bit more exact. Maybe there are recoverable | |
| 1091 // errors, such as ignoring certificate errors for Alternate-Protocol. | |
| 1092 if (result < 0 && waiting_job_) { | |
| 1093 waiting_job_->Resume(this, base::TimeDelta()); | |
| 1094 waiting_job_ = NULL; | |
| 1095 } | |
| 1096 | |
| 1097 // |result| may be the result of any of the stacked pools. The following | 998 // |result| may be the result of any of the stacked pools. The following |
| 1098 // logic is used when determining how to interpret an error. | 999 // logic is used when determining how to interpret an error. |
| 1099 // If |result| < 0: | 1000 // If |result| < 0: |
| 1100 // and connection_->socket() != NULL, then the SSL handshake ran and it | 1001 // and connection_->socket() != NULL, then the SSL handshake ran and it |
| 1101 // is a potentially recoverable error. | 1002 // is a potentially recoverable error. |
| 1102 // and connection_->socket == NULL and connection_->is_ssl_error() is true, | 1003 // and connection_->socket == NULL and connection_->is_ssl_error() is true, |
| 1103 // then the SSL handshake ran with an unrecoverable error. | 1004 // then the SSL handshake ran with an unrecoverable error. |
| 1104 // otherwise, the error came from one of the other pools. | 1005 // otherwise, the error came from one of the other pools. |
| 1105 bool ssl_started = using_ssl_ && (result == OK || connection_->socket() || | 1006 bool ssl_started = using_ssl_ && (result == OK || connection_->socket() || |
| 1106 connection_->is_ssl_error()); | 1007 connection_->is_ssl_error()); |
| (...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1664 | 1565 |
| 1665 ConnectionAttempts socket_attempts = connection_->connection_attempts(); | 1566 ConnectionAttempts socket_attempts = connection_->connection_attempts(); |
| 1666 if (connection_->socket()) { | 1567 if (connection_->socket()) { |
| 1667 connection_->socket()->GetConnectionAttempts(&socket_attempts); | 1568 connection_->socket()->GetConnectionAttempts(&socket_attempts); |
| 1668 } | 1569 } |
| 1669 | 1570 |
| 1670 delegate_->AddConnectionAttemptsToRequest(this, socket_attempts); | 1571 delegate_->AddConnectionAttemptsToRequest(this, socket_attempts); |
| 1671 } | 1572 } |
| 1672 | 1573 |
| 1673 } // namespace net | 1574 } // namespace net |
| OLD | NEW |