Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "net/http/http_stream_factory_impl_job_controller.h" | |
| 6 | |
| 7 #include "net/http/bidirectional_stream_impl.h" | |
| 8 #include "net/http/http_stream_factory_impl_job.h" | |
| 9 #include "net/http/http_stream_factory_impl_request.h" | |
| 10 #include "net/spdy/spdy_session.h" | |
| 11 | |
| 12 namespace net { | |
| 13 | |
| 14 HttpStreamFactoryImpl::JobController::JobController( | |
| 15 HttpStreamFactoryImpl* factory) | |
| 16 : factory_(factory), | |
| 17 request_(NULL), | |
| 18 main_job_(NULL), | |
| 19 alternative_job_(NULL) { | |
| 20 DCHECK(factory); | |
| 21 } | |
| 22 | |
| 23 HttpStreamFactoryImpl::JobController::~JobController() { | |
| 24 std::set<const Job*> tmp_job_set; | |
| 25 tmp_job_set.swap(orphaned_job_set_); | |
| 26 STLDeleteContainerPointers(tmp_job_set.begin(), tmp_job_set.end()); | |
|
Ryan Hamilton
2016/05/06 20:49:01
Would this work:
STLDeleteContainerPointers(orpha
Zhongyi Shi
2016/05/12 07:26:23
Acknowledged.
| |
| 27 DCHECK(orphaned_job_set_.empty()); | |
| 28 } | |
| 29 | |
| 30 HttpStreamFactoryImpl::Request* | |
| 31 HttpStreamFactoryImpl::JobController::CreatRequest( | |
| 32 const HttpRequestInfo& request_info, | |
| 33 HttpStreamRequest::Delegate* delegate, | |
| 34 WebSocketHandshakeStreamBase::CreateHelper* | |
| 35 websocket_handshake_stream_create_helper, | |
| 36 const BoundNetLog& net_log, | |
| 37 HttpStreamRequest::StreamType stream_type) { | |
| 38 DCHECK(factory_); | |
| 39 DCHECK(!request_); | |
| 40 | |
| 41 request_ = new Request(request_info.url, this, delegate, | |
| 42 websocket_handshake_stream_create_helper, net_log, | |
| 43 stream_type); | |
| 44 return request_; | |
| 45 } | |
| 46 | |
| 47 void HttpStreamFactoryImpl::JobController::Start( | |
| 48 HttpNetworkSession* session, | |
| 49 const HttpRequestInfo& request_info, | |
| 50 RequestPriority priority, | |
| 51 const SSLConfig& server_ssl_config, | |
| 52 const SSLConfig& proxy_ssl_config, | |
| 53 HttpStreamRequest::Delegate* delegate, | |
| 54 HttpStreamRequest::StreamType stream_type, | |
| 55 const BoundNetLog& net_log) { | |
| 56 DCHECK(!main_job_); | |
| 57 DCHECK(!alternative_job_); | |
| 58 HostPortPair destination(HostPortPair::FromURL(request_info.url)); | |
| 59 GURL origin_url = | |
| 60 factory_->ApplyHostMappingRules(request_info.url, &destination); | |
| 61 | |
| 62 main_job_ = | |
| 63 new Job(this, session, request_info, priority, server_ssl_config, | |
| 64 proxy_ssl_config, destination, origin_url, net_log.net_log()); | |
| 65 jobs_.insert(main_job_); | |
| 66 AttachJob(main_job_); | |
| 67 | |
| 68 // Create an alternative job if alternative service is set up for this domain. | |
| 69 const AlternativeService alternative_service = | |
| 70 factory_->GetAlternativeServiceFor(request_info, delegate, stream_type); | |
| 71 | |
| 72 if (alternative_service.protocol != UNINITIALIZED_ALTERNATE_PROTOCOL) { | |
| 73 // Never share connection with other jobs for FTP requests. | |
| 74 DVLOG(1) << "Selected alternative service (host: " | |
| 75 << alternative_service.host_port_pair().host() | |
| 76 << " port: " << alternative_service.host_port_pair().port() << ")"; | |
| 77 | |
| 78 DCHECK(!request_info.url.SchemeIs("ftp")); | |
| 79 HostPortPair alternative_destination(alternative_service.host_port_pair()); | |
| 80 ignore_result(factory_->ApplyHostMappingRules(request_info.url, | |
|
Ryan Hamilton
2016/05/06 20:49:02
I wonder if GetAlternativeServiceFor and ApplyHost
Zhongyi Shi
2016/05/12 07:26:23
Done! They are all moved in the new patch.
| |
| 81 &alternative_destination)); | |
| 82 | |
| 83 alternative_job_ = | |
| 84 new Job(this, session, request_info, priority, server_ssl_config, | |
| 85 proxy_ssl_config, alternative_destination, origin_url, | |
| 86 alternative_service, net_log.net_log()); | |
| 87 jobs_.insert(alternative_job_); | |
| 88 AttachJob(alternative_job_); | |
| 89 | |
| 90 main_job_->WaitFor(alternative_job_); | |
| 91 // Make sure to wait until we call WaitFor(), before starting | |
| 92 // |alternative_job|, otherwise |alternative_job| will not notify |job| | |
| 93 // appropriately. | |
| 94 alternative_job_->Start(request_); | |
| 95 } | |
| 96 // Even if |alternative_job| has already finished, it will not have notified | |
| 97 // the request yet, since we defer that to the next iteration of the | |
| 98 // MessageLoop, so starting |job| is always safe. | |
| 99 main_job_->Start(request_); | |
| 100 } | |
| 101 | |
| 102 void HttpStreamFactoryImpl::JobController::Preconnect( | |
| 103 int num_streams, | |
| 104 HttpNetworkSession* session, | |
| 105 const HttpRequestInfo& request_info, | |
| 106 const SSLConfig& server_ssl_config, | |
| 107 const SSLConfig& proxy_ssl_config) { | |
| 108 DCHECK(!main_job_); | |
| 109 DCHECK(!alternative_job_); | |
| 110 | |
| 111 HostPortPair destination(HostPortPair::FromURL(request_info.url)); | |
| 112 GURL origin_url = | |
| 113 factory_->ApplyHostMappingRules(request_info.url, &destination); | |
| 114 | |
| 115 const AlternativeService alternative_service = | |
| 116 factory_->GetAlternativeServiceFor(request_info, nullptr, | |
| 117 HttpStreamRequest::HTTP_STREAM); | |
| 118 | |
| 119 if (alternative_service.protocol != UNINITIALIZED_ALTERNATE_PROTOCOL) { | |
| 120 if (session->params().quic_disable_preconnect_if_0rtt && | |
| 121 alternative_service.protocol == QUIC && | |
| 122 session->quic_stream_factory()->ZeroRTTEnabledFor(QuicServerId( | |
| 123 alternative_service.host_port_pair(), request_info.privacy_mode))) { | |
| 124 MaybeNotifyFactoryOfCompletion(); | |
| 125 return; | |
| 126 } | |
| 127 destination = alternative_service.host_port_pair(); | |
| 128 ignore_result( | |
| 129 factory_->ApplyHostMappingRules(request_info.url, &destination)); | |
| 130 } | |
| 131 | |
| 132 // Due to how the socket pools handle priorities and idle sockets, only IDLE | |
| 133 // priority currently makes sense for preconnects. The priority for | |
| 134 // preconnects is currently ignored (see RequestSocketsForPool()), but could | |
| 135 // be used at some point for proxy resolution or something. | |
| 136 main_job_ = new Job(this, session, request_info, IDLE, server_ssl_config, | |
| 137 proxy_ssl_config, destination, origin_url, | |
| 138 alternative_service, session->net_log()); | |
| 139 jobs_.insert(main_job_); | |
| 140 main_job_->Preconnect(num_streams); | |
| 141 } | |
| 142 | |
| 143 LoadState HttpStreamFactoryImpl::JobController::GetLoadState() const { | |
| 144 DCHECK(request_); | |
| 145 if (bound_job_.get()) | |
| 146 return bound_job_->GetLoadState(); | |
| 147 DCHECK(!jobs_.empty()); | |
| 148 | |
| 149 // Just pick the first one. | |
| 150 return (*jobs_.begin())->GetLoadState(); | |
| 151 } | |
| 152 | |
| 153 void HttpStreamFactoryImpl::JobController::SetPriority( | |
| 154 RequestPriority priority) { | |
| 155 for (std::set<HttpStreamFactoryImpl::Job*>::const_iterator it = jobs_.begin(); | |
| 156 it != jobs_.end(); ++it) { | |
|
Ryan Hamilton
2016/05/06 20:49:02
nit: I think you can do a C++ loop here:
for (aut
Zhongyi Shi
2016/05/12 07:26:23
Acknowledged.
| |
| 157 (*it)->SetPriority(priority); | |
| 158 } | |
| 159 if (bound_job_) | |
| 160 bound_job_->SetPriority(priority); | |
| 161 } | |
| 162 | |
| 163 int HttpStreamFactoryImpl::JobController::RestartTunnelWithProxyAuth( | |
| 164 const AuthCredentials& credentials) { | |
| 165 DCHECK(bound_job_.get()); | |
| 166 return bound_job_->RestartTunnelWithProxyAuth(credentials); | |
| 167 } | |
| 168 | |
| 169 void HttpStreamFactoryImpl::JobController::AttachJob(Job* job) { | |
| 170 DCHECK(job); | |
| 171 jobs_.insert(job); | |
| 172 factory_->request_map_[job] = request_; | |
|
Ryan Hamilton
2016/05/06 20:49:02
Is request_map_ still used in your new world? If s
Zhongyi Shi
2016/05/12 07:26:23
This is still used as it is in the old code to mak
| |
| 173 } | |
| 174 | |
| 175 void HttpStreamFactoryImpl::JobController::BindJob(Job* job) { | |
| 176 DCHECK(request_); | |
| 177 DCHECK(job); | |
| 178 DCHECK(!bound_job_.get()); | |
| 179 DCHECK(ContainsKey(jobs_, job)); | |
| 180 bound_job_.reset(job); | |
| 181 jobs_.erase(job); | |
| 182 factory_->request_map_.erase(job); | |
| 183 | |
| 184 request_->net_log().AddEvent( | |
| 185 NetLog::TYPE_HTTP_STREAM_REQUEST_BOUND_TO_JOB, | |
| 186 job->net_log().source().ToEventParametersCallback()); | |
| 187 job->net_log().AddEvent( | |
| 188 NetLog::TYPE_HTTP_STREAM_JOB_BOUND_TO_REQUEST, | |
| 189 request_->net_log().source().ToEventParametersCallback()); | |
| 190 | |
| 191 OrphanJobs(); | |
| 192 } | |
| 193 | |
| 194 void HttpStreamFactoryImpl::JobController::OrphanJobs() { | |
| 195 DCHECK(request_); | |
| 196 request_->RemoveRequestFromSpdySessionRequestMap(); | |
| 197 | |
| 198 std::set<Job*> tmp; | |
| 199 tmp.swap(jobs_); | |
| 200 | |
| 201 for (Job* job : tmp) { | |
| 202 DCHECK(ContainsKey(factory_->request_map_, job)); | |
| 203 DCHECK_EQ(factory_->request_map_[job], request_); | |
| 204 DCHECK(!ContainsKey(orphaned_job_set_, job)); | |
| 205 | |
| 206 factory_->request_map_.erase(job); | |
| 207 | |
| 208 orphaned_job_set_.insert(job); | |
| 209 job->Orphan(request_); | |
| 210 } | |
| 211 } | |
| 212 | |
| 213 void HttpStreamFactoryImpl::JobController::CancelJobs() { | |
| 214 DCHECK(request_); | |
| 215 request_->RemoveRequestFromSpdySessionRequestMap(); | |
| 216 std::set<Job*> tmp; | |
| 217 tmp.swap(jobs_); | |
| 218 | |
| 219 for (Job* job : tmp) { | |
| 220 factory_->request_map_.erase(job); | |
| 221 delete job; | |
| 222 } | |
| 223 } | |
| 224 | |
| 225 void HttpStreamFactoryImpl::JobController::OnJobSucceeded(Job* job) { | |
| 226 // |job| should only be NULL if we're being serviced by a late bound | |
| 227 // SpdySession (one that was not created by a job in our |jobs_| set). | |
| 228 if (!job) { | |
| 229 DCHECK(!bound_job_.get()); | |
| 230 DCHECK(!jobs_.empty()); | |
| 231 // NOTE(willchan): We do *NOT* call OrphanJobs() here. The reason is because | |
| 232 // we *WANT* to cancel the unnecessary Jobs from other requests if another | |
| 233 // Job completes first. | |
| 234 // TODO(mbelshe): Revisit this when we implement ip connection pooling of | |
| 235 // SpdySessions. Do we want to orphan the jobs for a different hostname so | |
| 236 // they complete? Or do we want to prevent connecting a new SpdySession if | |
| 237 // we've already got one available for a different hostname where the ip | |
| 238 // address matches up? | |
| 239 CancelJobs(); | |
| 240 return; | |
| 241 } | |
| 242 if (!bound_job_.get()) { | |
| 243 if (jobs_.size() > 1) | |
| 244 job->ReportJobSucceededForRequest(); | |
| 245 // Notify all the other jobs that this one succeeded. | |
| 246 for (std::set<Job*>::iterator it = jobs_.begin(); it != jobs_.end(); ++it) { | |
| 247 if (*it != job) { | |
| 248 (*it)->MarkOtherJobComplete(*job); | |
| 249 } | |
| 250 } | |
| 251 // We may have other jobs in |jobs_|. For example, if we start multiple jobs | |
| 252 // for Alternate-Protocol. | |
| 253 BindJob(job); | |
| 254 return; | |
| 255 } | |
| 256 DCHECK(jobs_.empty()); | |
| 257 } | |
| 258 | |
| 259 void HttpStreamFactoryImpl::JobController::OnRequestFinish() { | |
| 260 DCHECK(request_); | |
| 261 if (bound_job_.get()) { | |
| 262 DCHECK(jobs_.empty()); | |
| 263 } | |
| 264 request_ = NULL; | |
| 265 bound_job_.reset(); | |
| 266 MaybeNotifyFactoryOfCompletion(); | |
| 267 } | |
| 268 | |
| 269 void HttpStreamFactoryImpl::JobController::MarkRequestComplete( | |
| 270 bool was_npn_negotiated, | |
| 271 NextProto protocol_negotiated, | |
| 272 bool using_spdy) { | |
| 273 if (request_) | |
| 274 request_->Complete(was_npn_negotiated, protocol_negotiated, using_spdy); | |
| 275 } | |
| 276 | |
| 277 void HttpStreamFactoryImpl::JobController::OnStreamReady( | |
| 278 Job* job, | |
| 279 const SSLConfig& used_ssl_config, | |
| 280 const ProxyInfo& used_proxy_info, | |
| 281 HttpStream* stream) { | |
| 282 if (!request_) | |
| 283 return; | |
| 284 DCHECK(!factory_->for_websockets_); | |
| 285 DCHECK_EQ(HttpStreamRequest::HTTP_STREAM, request_->stream_type()); | |
| 286 DCHECK(stream); | |
| 287 | |
| 288 if (job) | |
| 289 OnJobSucceeded(job); | |
| 290 request_->OnStreamReady(used_ssl_config, used_proxy_info, stream); | |
| 291 } | |
| 292 | |
| 293 void HttpStreamFactoryImpl::JobController::OnBidirectionalStreamImplReady( | |
| 294 Job* job, | |
| 295 const SSLConfig& used_ssl_config, | |
| 296 const ProxyInfo& used_proxy_info, | |
| 297 BidirectionalStreamImpl* stream) { | |
| 298 if (!request_) | |
| 299 return; | |
| 300 DCHECK(!factory_->for_websockets_); | |
| 301 DCHECK_EQ(HttpStreamRequest::BIDIRECTIONAL_STREAM, request_->stream_type()); | |
| 302 DCHECK(stream); | |
| 303 | |
| 304 if (job) | |
| 305 OnJobSucceeded(job); | |
| 306 request_->OnBidirectionalStreamImplReady(used_ssl_config, used_proxy_info, | |
| 307 stream); | |
| 308 } | |
| 309 | |
| 310 void HttpStreamFactoryImpl::JobController::OnWebSocketHandshakeStreamReady( | |
| 311 Job* job, | |
| 312 const SSLConfig& used_ssl_config, | |
| 313 const ProxyInfo& used_proxy_info, | |
| 314 WebSocketHandshakeStreamBase* stream) { | |
| 315 if (!request_) | |
| 316 return; | |
| 317 DCHECK(factory_->for_websockets_); | |
| 318 DCHECK_EQ(HttpStreamRequest::HTTP_STREAM, request_->stream_type()); | |
| 319 DCHECK(stream); | |
| 320 | |
| 321 if (job) | |
| 322 OnJobSucceeded(job); | |
| 323 request_->OnWebSocketHandshakeStreamReady(used_ssl_config, used_proxy_info, | |
| 324 stream); | |
| 325 } | |
| 326 | |
| 327 void HttpStreamFactoryImpl::JobController::OnStreamFailed( | |
| 328 Job* job, | |
| 329 int status, | |
| 330 const SSLConfig& used_ssl_config, | |
| 331 SSLFailureState ssl_failure_state) { | |
| 332 if (!request_) | |
| 333 return; | |
| 334 DCHECK_NE(OK, status); | |
| 335 DCHECK(job); | |
| 336 | |
| 337 if (!bound_job_.get()) { | |
| 338 if (jobs_.size() > 1) { | |
| 339 // Hey, we've got other jobs! Maybe one of them will succeed, let's just | |
| 340 // ignore this failure. | |
| 341 jobs_.erase(job); | |
| 342 factory_->request_map_.erase(job); | |
| 343 // Notify all the other jobs that this one failed. | |
| 344 for (std::set<Job*>::iterator it = jobs_.begin(); it != jobs_.end(); ++it) | |
| 345 (*it)->MarkOtherJobComplete(*job); | |
| 346 delete job; | |
| 347 return; | |
| 348 } else { | |
| 349 BindJob(job); | |
| 350 } | |
| 351 } else { | |
| 352 DCHECK(jobs_.empty()); | |
| 353 } | |
| 354 | |
| 355 request_->OnStreamFailed(status, used_ssl_config, ssl_failure_state); | |
| 356 } | |
| 357 | |
| 358 void HttpStreamFactoryImpl::JobController::OnCertificateError( | |
| 359 Job* job, | |
| 360 int status, | |
| 361 const SSLConfig& used_ssl_config, | |
| 362 const SSLInfo& ssl_info) { | |
| 363 if (!request_) | |
| 364 return; | |
| 365 DCHECK_NE(OK, status); | |
| 366 if (!bound_job_.get()) | |
| 367 BindJob(job); | |
| 368 else | |
| 369 DCHECK(jobs_.empty()); | |
| 370 | |
| 371 request_->OnCertificateError(status, used_ssl_config, ssl_info); | |
| 372 } | |
| 373 | |
| 374 void HttpStreamFactoryImpl::JobController::OnNeedsProxyAuth( | |
| 375 Job* job, | |
| 376 const HttpResponseInfo& proxy_response, | |
| 377 const SSLConfig& used_ssl_config, | |
| 378 const ProxyInfo& used_proxy_info, | |
| 379 HttpAuthController* auth_controller) { | |
| 380 if (!request_) | |
| 381 return; | |
| 382 if (!bound_job_.get()) | |
| 383 BindJob(job); | |
| 384 else | |
| 385 DCHECK(jobs_.empty()); | |
| 386 request_->OnNeedsProxyAuth(proxy_response, used_ssl_config, used_proxy_info, | |
| 387 auth_controller); | |
| 388 } | |
| 389 | |
| 390 void HttpStreamFactoryImpl::JobController::OnNeedsClientAuth( | |
| 391 Job* job, | |
| 392 const SSLConfig& used_ssl_config, | |
| 393 SSLCertRequestInfo* cert_info) { | |
| 394 if (!request_) | |
| 395 return; | |
| 396 if (!bound_job_.get()) | |
| 397 BindJob(job); | |
| 398 else | |
| 399 DCHECK(jobs_.empty()); | |
| 400 | |
| 401 request_->OnNeedsClientAuth(used_ssl_config, cert_info); | |
| 402 } | |
| 403 | |
| 404 void HttpStreamFactoryImpl::JobController::OnHttpsProxyTunnelResponse( | |
| 405 Job* job, | |
| 406 const HttpResponseInfo& response_info, | |
| 407 const SSLConfig& used_ssl_config, | |
| 408 const ProxyInfo& used_proxy_info, | |
| 409 HttpStream* stream) { | |
| 410 if (!bound_job_.get()) | |
| 411 BindJob(job); | |
| 412 else | |
| 413 DCHECK(jobs_.empty()); | |
| 414 if (!request_) | |
| 415 return; | |
| 416 request_->OnHttpsProxyTunnelResponse(response_info, used_ssl_config, | |
| 417 used_proxy_info, stream); | |
| 418 } | |
| 419 | |
| 420 void HttpStreamFactoryImpl::JobController::OnNewSpdySessionReady( | |
| 421 Job* job, | |
| 422 std::unique_ptr<HttpStream> stream, | |
| 423 std::unique_ptr<BidirectionalStreamImpl> bidirectional_stream_impl, | |
| 424 const base::WeakPtr<SpdySession>& spdy_session, | |
| 425 bool direct) { | |
| 426 DCHECK(job); | |
| 427 DCHECK(job->using_spdy()); | |
| 428 | |
| 429 // Cache these values in case the job gets deleted. | |
| 430 const SSLConfig used_ssl_config = job->server_ssl_config(); | |
| 431 const ProxyInfo used_proxy_info = job->proxy_info(); | |
| 432 const bool was_npn_negotiated = job->was_npn_negotiated(); | |
| 433 const NextProto protocol_negotiated = job->protocol_negotiated(); | |
| 434 const bool using_spdy = job->using_spdy(); | |
| 435 const BoundNetLog net_log = job->net_log(); | |
| 436 | |
| 437 // Cache this so we can still use it if the JobController is deleted. | |
| 438 HttpStreamFactoryImpl* factory = factory_; | |
| 439 | |
| 440 // Notify |request_|. | |
| 441 if (!job->IsPreconnecting() && !job->IsOrphaned()) { | |
| 442 DCHECK(request_); | |
| 443 | |
| 444 // The first case is the usual case. | |
| 445 if (!bound_job_.get()) { | |
| 446 BindJob(job); | |
| 447 } else { // This is the case for HTTPS proxy tunneling. | |
| 448 DCHECK_EQ(bound_job_.get(), job); | |
| 449 DCHECK(jobs_.empty()); | |
| 450 } | |
| 451 | |
| 452 request_->Complete(was_npn_negotiated, protocol_negotiated, using_spdy); | |
| 453 | |
| 454 request_->OnNewSpdySessionReady( | |
| 455 std::move(stream), std::move(bidirectional_stream_impl), spdy_session, | |
| 456 used_ssl_config, used_proxy_info, was_npn_negotiated, | |
| 457 protocol_negotiated, using_spdy, net_log, direct); | |
| 458 } | |
| 459 | |
| 460 // Notify |factory_|. |request_| might be deleted already. | |
| 461 if (spdy_session && spdy_session->IsAvailable()) { | |
| 462 factory->OnNewSpdySessionReady(spdy_session, direct, used_ssl_config, | |
| 463 used_proxy_info, was_npn_negotiated, | |
| 464 protocol_negotiated, using_spdy, net_log); | |
| 465 } | |
| 466 } | |
| 467 | |
| 468 void HttpStreamFactoryImpl::JobController::OnPreconnectsComplete(Job* job) { | |
| 469 jobs_.erase(job); | |
| 470 delete job; | |
| 471 factory_->OnPreconnectsCompleteInternal(); | |
| 472 MaybeNotifyFactoryOfCompletion(); | |
| 473 } | |
| 474 | |
| 475 void HttpStreamFactoryImpl::JobController::OnOrphanedJobComplete( | |
| 476 const Job* job) { | |
| 477 orphaned_job_set_.erase(job); | |
| 478 delete job; | |
| 479 MaybeNotifyFactoryOfCompletion(); | |
| 480 } | |
| 481 | |
| 482 void HttpStreamFactoryImpl::JobController::AddConnectionAttemptsToRequest( | |
| 483 const ConnectionAttempts& attempts) { | |
| 484 DCHECK(request_); | |
| 485 request_->AddConnectionAttempts(attempts); | |
| 486 } | |
| 487 | |
| 488 void HttpStreamFactoryImpl::JobController::SetSpdySessionKey( | |
| 489 const SpdySessionKey& spdy_session_key) { | |
| 490 DCHECK(request_); | |
| 491 if (!request_->HasSpdySessionKey()) { | |
| 492 request_->SetSpdySessionKey(spdy_session_key); | |
| 493 } | |
| 494 } | |
| 495 | |
| 496 void HttpStreamFactoryImpl::JobController:: | |
| 497 RemoveRequestFromSpdySessionRequestMap() { | |
| 498 DCHECK(request_); | |
| 499 request_->RemoveRequestFromSpdySessionRequestMap(); | |
| 500 } | |
| 501 | |
| 502 void HttpStreamFactoryImpl::JobController::MaybeNotifyFactoryOfCompletion() { | |
| 503 if (!request_ && jobs_.empty() && orphaned_job_set_.empty()) { | |
| 504 DCHECK(jobs_.empty()); | |
| 505 factory_->OnJobControllerComplete(this); | |
| 506 } | |
| 507 } | |
| 508 | |
| 509 const BoundNetLog& HttpStreamFactoryImpl::JobController::GetNetLogFromRequest() | |
| 510 const { | |
| 511 DCHECK(request_); | |
| 512 return request_->net_log(); | |
| 513 } | |
| 514 | |
| 515 WebSocketHandshakeStreamBase::CreateHelper* HttpStreamFactoryImpl:: | |
| 516 JobController::websocket_handshake_stream_create_helper() { | |
| 517 DCHECK(request_); | |
| 518 return request_->websocket_handshake_stream_create_helper(); | |
| 519 } | |
| 520 } | |
| OLD | NEW |