| OLD | NEW |
| 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2016 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_controller.h" | 5 #include "net/http/http_stream_factory_impl_job_controller.h" |
| 6 | 6 |
| 7 #include "base/strings/string_number_conversions.h" | 7 #include "base/strings/string_number_conversions.h" |
| 8 #include "base/strings/string_util.h" | 8 #include "base/strings/string_util.h" |
| 9 #include "net/base/host_mapping_rules.h" | 9 #include "net/base/host_mapping_rules.h" |
| 10 #include "net/http/bidirectional_stream_impl.h" | 10 #include "net/http/bidirectional_stream_impl.h" |
| 11 #include "net/http/http_stream_factory_impl.h" | 11 #include "net/http/http_stream_factory_impl.h" |
| 12 #include "net/http/http_stream_factory_impl_job.h" | 12 #include "net/http/http_stream_factory_impl_job.h" |
| 13 #include "net/http/http_stream_factory_impl_request.h" | 13 #include "net/http/http_stream_factory_impl_request.h" |
| 14 #include "net/http/transport_security_state.h" | 14 #include "net/http/transport_security_state.h" |
| 15 #include "net/spdy/spdy_session.h" | 15 #include "net/spdy/spdy_session.h" |
| 16 | 16 |
| 17 namespace net { | 17 namespace net { |
| 18 | 18 |
| 19 HttpStreamFactoryImpl::JobController::JobController( | 19 HttpStreamFactoryImpl::JobController::JobController( |
| 20 HttpStreamFactoryImpl* factory, | 20 HttpStreamFactoryImpl* factory, |
| 21 HttpStreamRequest::Delegate* delegate, | 21 HttpStreamRequest::Delegate* delegate, |
| 22 HttpNetworkSession* session) | 22 HttpNetworkSession* session) |
| 23 : factory_(factory), | 23 : factory_(factory), |
| 24 session_(session), | 24 session_(session), |
| 25 request_(nullptr), | 25 request_(nullptr), |
| 26 delegate_(delegate), | 26 delegate_(delegate), |
| 27 is_preconnect_(false), | 27 is_preconnect_(false), |
| 28 job_bounded_(false), | 28 job_bounded_(false), |
| 29 blocking_(false), |
| 29 bound_job_(nullptr) { | 30 bound_job_(nullptr) { |
| 30 DCHECK(factory); | 31 DCHECK(factory); |
| 31 } | 32 } |
| 32 | 33 |
| 33 HttpStreamFactoryImpl::JobController::~JobController() { | 34 HttpStreamFactoryImpl::JobController::~JobController() { |
| 34 main_job_.reset(); | 35 main_job_.reset(); |
| 35 alternative_job_.reset(); | 36 alternative_job_.reset(); |
| 36 bound_job_ = nullptr; | 37 bound_job_ = nullptr; |
| 37 } | 38 } |
| 38 | 39 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 void HttpStreamFactoryImpl::JobController::SetPriority( | 132 void HttpStreamFactoryImpl::JobController::SetPriority( |
| 132 RequestPriority priority) { | 133 RequestPriority priority) { |
| 133 if (main_job_) { | 134 if (main_job_) { |
| 134 main_job_->SetPriority(priority); | 135 main_job_->SetPriority(priority); |
| 135 } | 136 } |
| 136 if (alternative_job_) { | 137 if (alternative_job_) { |
| 137 alternative_job_->SetPriority(priority); | 138 alternative_job_->SetPriority(priority); |
| 138 } | 139 } |
| 139 } | 140 } |
| 140 | 141 |
| 142 int HttpStreamFactoryImpl::JobController::ScheduleJob(Job* job) { |
| 143 if ((job->job_type() == ALTERNATIVE || !blocking()) && |
| 144 job->wait_time().is_zero()) { |
| 145 // There is no blocking job and there is no |wait_time_|. |
| 146 job->SetNextState(STATE_INIT_CONNECTION); |
| 147 return OK; |
| 148 } |
| 149 |
| 150 job->SetNextState(STATE_WAIT_FOR_JOB_COMPLETE); |
| 151 if (!job->wait_time().is_zero()) { |
| 152 // If there is a waiting_time, then resume the job after the wait_time_. |
| 153 DCHECK((job->job_type() == ALTERNATIVE || !blocking())); |
| 154 job->ResumeAfterDelay(); |
| 155 } |
| 156 |
| 157 return ERR_IO_PENDING; |
| 158 } |
| 159 |
| 141 void HttpStreamFactoryImpl::JobController::OnStreamReady( | 160 void HttpStreamFactoryImpl::JobController::OnStreamReady( |
| 142 Job* job, | 161 Job* job, |
| 143 const SSLConfig& used_ssl_config, | 162 const SSLConfig& used_ssl_config, |
| 144 const ProxyInfo& used_proxy_info) { | 163 const ProxyInfo& used_proxy_info) { |
| 145 if (job_bounded_ && bound_job_ != job) { | 164 if (job_bounded_ && bound_job_ != job) { |
| 146 // We have bound a job to the associated Request, |job| has been orphaned. | 165 // We have bound a job to the associated Request, |job| has been orphaned. |
| 147 OnOrphanedJobComplete(job); | 166 OnOrphanedJobComplete(job); |
| 148 return; | 167 return; |
| 149 } | 168 } |
| 150 | 169 |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 used_proxy_info, was_npn_negotiated, | 401 used_proxy_info, was_npn_negotiated, |
| 383 protocol_negotiated, using_spdy, net_log); | 402 protocol_negotiated, using_spdy, net_log); |
| 384 } | 403 } |
| 385 if (is_job_orphaned) { | 404 if (is_job_orphaned) { |
| 386 OnOrphanedJobComplete(job); | 405 OnOrphanedJobComplete(job); |
| 387 } | 406 } |
| 388 } | 407 } |
| 389 | 408 |
| 390 void HttpStreamFactoryImpl::JobController::OnPreconnectsComplete(Job* job) { | 409 void HttpStreamFactoryImpl::JobController::OnPreconnectsComplete(Job* job) { |
| 391 DCHECK_EQ(main_job_.get(), job); | 410 DCHECK_EQ(main_job_.get(), job); |
| 411 DCHECK(!bound_job_); |
| 392 main_job_.reset(); | 412 main_job_.reset(); |
| 393 factory_->OnPreconnectsCompleteInternal(); | 413 factory_->OnPreconnectsCompleteInternal(); |
| 394 MaybeNotifyFactoryOfCompletion(); | 414 MaybeNotifyFactoryOfCompletion(); |
| 395 } | 415 } |
| 396 | 416 |
| 397 void HttpStreamFactoryImpl::JobController::OnOrphanedJobComplete( | 417 void HttpStreamFactoryImpl::JobController::OnOrphanedJobComplete( |
| 398 const Job* job) { | 418 const Job* job) { |
| 399 if (job->job_type() == MAIN) { | 419 if (job->job_type() == MAIN) { |
| 400 DCHECK_EQ(main_job_.get(), job); | 420 DCHECK_EQ(main_job_.get(), job); |
| 401 main_job_.reset(); | 421 main_job_.reset(); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 DCHECK(ContainsKey(spdy_session_request_map, *spdy_session_key)); | 471 DCHECK(ContainsKey(spdy_session_request_map, *spdy_session_key)); |
| 452 RequestSet& request_set = spdy_session_request_map[*spdy_session_key]; | 472 RequestSet& request_set = spdy_session_request_map[*spdy_session_key]; |
| 453 DCHECK(ContainsKey(request_set, request_)); | 473 DCHECK(ContainsKey(request_set, request_)); |
| 454 request_set.erase(request_); | 474 request_set.erase(request_); |
| 455 if (request_set.empty()) | 475 if (request_set.empty()) |
| 456 spdy_session_request_map.erase(*spdy_session_key); | 476 spdy_session_request_map.erase(*spdy_session_key); |
| 457 request_->ResetSpdySessionKey(); | 477 request_->ResetSpdySessionKey(); |
| 458 } | 478 } |
| 459 } | 479 } |
| 460 | 480 |
| 481 void HttpStreamFactoryImpl::JobController::MaybeResumeOtherJob( |
| 482 Job* job, |
| 483 const base::TimeDelta& delay) { |
| 484 if (!blocking_) |
| 485 return; |
| 486 |
| 487 if (job == alternative_job_.get() && main_job_) { |
| 488 main_job_->Resume(delay); |
| 489 } else if (job != main_job_.get() && job != alternative_job_.get()) { |
| 490 NOTREACHED(); |
| 491 } |
| 492 blocking_ = false; |
| 493 } |
| 494 |
| 461 const BoundNetLog* HttpStreamFactoryImpl::JobController::GetNetLog( | 495 const BoundNetLog* HttpStreamFactoryImpl::JobController::GetNetLog( |
| 462 Job* job) const { | 496 Job* job) const { |
| 463 if (is_preconnect_ || (job_bounded_ && bound_job_ != job)) | 497 if (is_preconnect_ || (job_bounded_ && bound_job_ != job)) |
| 464 return nullptr; | 498 return nullptr; |
| 465 DCHECK(request_); | 499 DCHECK(request_); |
| 466 return &request_->net_log(); | 500 return &request_->net_log(); |
| 467 } | 501 } |
| 468 | 502 |
| 469 WebSocketHandshakeStreamBase::CreateHelper* HttpStreamFactoryImpl:: | 503 WebSocketHandshakeStreamBase::CreateHelper* HttpStreamFactoryImpl:: |
| 470 JobController::websocket_handshake_stream_create_helper() { | 504 JobController::websocket_handshake_stream_create_helper() { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 504 HostPortPair alternative_destination(alternative_service.host_port_pair()); | 538 HostPortPair alternative_destination(alternative_service.host_port_pair()); |
| 505 ignore_result( | 539 ignore_result( |
| 506 ApplyHostMappingRules(request_info.url, &alternative_destination)); | 540 ApplyHostMappingRules(request_info.url, &alternative_destination)); |
| 507 | 541 |
| 508 alternative_job_.reset( | 542 alternative_job_.reset( |
| 509 new Job(this, ALTERNATIVE, session_, request_info, priority, | 543 new Job(this, ALTERNATIVE, session_, request_info, priority, |
| 510 server_ssl_config, proxy_ssl_config, alternative_destination, | 544 server_ssl_config, proxy_ssl_config, alternative_destination, |
| 511 origin_url, alternative_service, net_log.net_log())); | 545 origin_url, alternative_service, net_log.net_log())); |
| 512 AttachJob(alternative_job_.get()); | 546 AttachJob(alternative_job_.get()); |
| 513 | 547 |
| 514 main_job_->WaitFor(alternative_job_.get()); | 548 blocking_ = true; |
| 515 // Make sure to wait until we call WaitFor(), before starting | |
| 516 // |alternative_job|, otherwise |alternative_job| will not notify |job| | |
| 517 // appropriately. | |
| 518 alternative_job_->Start(request_->stream_type()); | 549 alternative_job_->Start(request_->stream_type()); |
| 519 } | 550 } |
| 520 // Even if |alternative_job| has already finished, it will not have notified | 551 // Even if |alternative_job| has already finished, it will not have notified |
| 521 // the request yet, since we defer that to the next iteration of the | 552 // the request yet, since we defer that to the next iteration of the |
| 522 // MessageLoop, so starting |main_job_| is always safe. | 553 // MessageLoop, so starting |main_job_| is always safe. |
| 523 main_job_->Start(request_->stream_type()); | 554 main_job_->Start(request_->stream_type()); |
| 524 } | 555 } |
| 525 | 556 |
| 526 void HttpStreamFactoryImpl::JobController::AttachJob(Job* job) { | 557 void HttpStreamFactoryImpl::JobController::AttachJob(Job* job) { |
| 527 DCHECK(job); | 558 DCHECK(job); |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 766 first_alternative_service = alternative_service; | 797 first_alternative_service = alternative_service; |
| 767 } | 798 } |
| 768 | 799 |
| 769 // Ask delegate to mark QUIC as broken for the origin. | 800 // Ask delegate to mark QUIC as broken for the origin. |
| 770 if (quic_advertised && quic_all_broken && delegate != nullptr) | 801 if (quic_advertised && quic_all_broken && delegate != nullptr) |
| 771 delegate->OnQuicBroken(); | 802 delegate->OnQuicBroken(); |
| 772 | 803 |
| 773 return first_alternative_service; | 804 return first_alternative_service; |
| 774 } | 805 } |
| 775 } | 806 } |
| OLD | NEW |