| 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 <memory> | 7 #include <memory> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 : alternative_job_->GetLoadState(); | 138 : alternative_job_->GetLoadState(); |
| 139 } | 139 } |
| 140 | 140 |
| 141 void HttpStreamFactoryImpl::JobController::OnRequestComplete() { | 141 void HttpStreamFactoryImpl::JobController::OnRequestComplete() { |
| 142 CancelJobs(); | 142 CancelJobs(); |
| 143 DCHECK(request_); | 143 DCHECK(request_); |
| 144 request_ = nullptr; | 144 request_ = nullptr; |
| 145 if (bound_job_) { | 145 if (bound_job_) { |
| 146 if (bound_job_->job_type() == MAIN) { | 146 if (bound_job_->job_type() == MAIN) { |
| 147 main_job_.reset(); | 147 main_job_.reset(); |
| 148 // |alternative_job_| can be non-null if |main_job_| is resumed after |
| 149 // |main_job_wait_time_| has elapsed. Allow |alternative_job_| to run to |
| 150 // completion, rather than resetting it. OnOrphanedJobComplete() will |
| 151 // clean up |this| when the job completes. |
| 148 } else { | 152 } else { |
| 149 DCHECK(bound_job_->job_type() == ALTERNATIVE); | 153 DCHECK(bound_job_->job_type() == ALTERNATIVE); |
| 150 alternative_job_.reset(); | 154 alternative_job_.reset(); |
| 155 // If ResumeMainJob() is not executed, reset |main_job_|. Otherwise, |
| 156 // OnOrphanedJobComplete() will clean up |this| when the job completes. |
| 157 // Use |main_job_is_blocked_| and |!main_job_wait_time_.is_zero()| instead |
| 158 // of |main_job_|->is_waiting() because |main_job_| can be in proxy |
| 159 // resolution step. |
| 160 if (main_job_ && (main_job_is_blocked_ || !main_job_wait_time_.is_zero())) |
| 161 main_job_.reset(); |
| 151 } | 162 } |
| 152 bound_job_ = nullptr; | 163 bound_job_ = nullptr; |
| 153 } | 164 } |
| 154 MaybeNotifyFactoryOfCompletion(); | 165 MaybeNotifyFactoryOfCompletion(); |
| 155 } | 166 } |
| 156 | 167 |
| 157 int HttpStreamFactoryImpl::JobController::RestartTunnelWithProxyAuth( | 168 int HttpStreamFactoryImpl::JobController::RestartTunnelWithProxyAuth( |
| 158 const AuthCredentials& credentials) { | 169 const AuthCredentials& credentials) { |
| 159 DCHECK(bound_job_); | 170 DCHECK(bound_job_); |
| 160 return bound_job_->RestartTunnelWithProxyAuth(credentials); | 171 return bound_job_->RestartTunnelWithProxyAuth(credentials); |
| 161 } | 172 } |
| 162 | 173 |
| 163 void HttpStreamFactoryImpl::JobController::SetPriority( | 174 void HttpStreamFactoryImpl::JobController::SetPriority( |
| 164 RequestPriority priority) { | 175 RequestPriority priority) { |
| 165 if (main_job_) { | 176 if (main_job_) { |
| 166 main_job_->SetPriority(priority); | 177 main_job_->SetPriority(priority); |
| 167 } | 178 } |
| 168 if (alternative_job_) { | 179 if (alternative_job_) { |
| 169 alternative_job_->SetPriority(priority); | 180 alternative_job_->SetPriority(priority); |
| 170 } | 181 } |
| 171 } | 182 } |
| 172 | 183 |
| 173 void HttpStreamFactoryImpl::JobController::OnStreamReady( | 184 void HttpStreamFactoryImpl::JobController::OnStreamReady( |
| 174 Job* job, | 185 Job* job, |
| 175 const SSLConfig& used_ssl_config) { | 186 const SSLConfig& used_ssl_config) { |
| 176 DCHECK(job); | 187 DCHECK(job); |
| 177 | 188 |
| 178 factory_->OnStreamReady(job->proxy_info()); | 189 factory_->OnStreamReady(job->proxy_info()); |
| 179 | 190 |
| 180 if (job_bound_ && bound_job_ != job) { | 191 if (IsJobOrphaned(job)) { |
| 181 // We have bound a job to the associated Request, |job| has been orphaned. | 192 // We have bound a job to the associated Request, |job| has been orphaned. |
| 182 OnOrphanedJobComplete(job); | 193 OnOrphanedJobComplete(job); |
| 183 return; | 194 return; |
| 184 } | 195 } |
| 185 std::unique_ptr<HttpStream> stream = job->ReleaseStream(); | 196 std::unique_ptr<HttpStream> stream = job->ReleaseStream(); |
| 186 DCHECK(stream); | 197 DCHECK(stream); |
| 187 | 198 |
| 188 MarkRequestComplete(job->was_alpn_negotiated(), job->negotiated_protocol(), | 199 MarkRequestComplete(job->was_alpn_negotiated(), job->negotiated_protocol(), |
| 189 job->using_spdy()); | 200 job->using_spdy()); |
| 190 | 201 |
| 191 if (!request_) | 202 if (!request_) |
| 192 return; | 203 return; |
| 193 DCHECK(!factory_->for_websockets_); | 204 DCHECK(!factory_->for_websockets_); |
| 194 DCHECK_EQ(HttpStreamRequest::HTTP_STREAM, request_->stream_type()); | 205 DCHECK_EQ(HttpStreamRequest::HTTP_STREAM, request_->stream_type()); |
| 195 OnJobSucceeded(job); | 206 OnJobSucceeded(job); |
| 196 request_->OnStreamReady(used_ssl_config, job->proxy_info(), stream.release()); | 207 request_->OnStreamReady(used_ssl_config, job->proxy_info(), stream.release()); |
| 197 } | 208 } |
| 198 | 209 |
| 199 void HttpStreamFactoryImpl::JobController::OnBidirectionalStreamImplReady( | 210 void HttpStreamFactoryImpl::JobController::OnBidirectionalStreamImplReady( |
| 200 Job* job, | 211 Job* job, |
| 201 const SSLConfig& used_ssl_config, | 212 const SSLConfig& used_ssl_config, |
| 202 const ProxyInfo& used_proxy_info) { | 213 const ProxyInfo& used_proxy_info) { |
| 203 DCHECK(job); | 214 DCHECK(job); |
| 204 | 215 |
| 205 if (job_bound_ && bound_job_ != job) { | 216 if (IsJobOrphaned(job)) { |
| 206 // We have bound a job to the associated Request, |job| has been orphaned. | 217 // We have bound a job to the associated Request, |job| has been orphaned. |
| 207 OnOrphanedJobComplete(job); | 218 OnOrphanedJobComplete(job); |
| 208 return; | 219 return; |
| 209 } | 220 } |
| 210 | 221 |
| 211 MarkRequestComplete(job->was_alpn_negotiated(), job->negotiated_protocol(), | 222 MarkRequestComplete(job->was_alpn_negotiated(), job->negotiated_protocol(), |
| 212 job->using_spdy()); | 223 job->using_spdy()); |
| 213 | 224 |
| 214 if (!request_) | 225 if (!request_) |
| 215 return; | 226 return; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 246 | 257 |
| 247 void HttpStreamFactoryImpl::JobController::OnStreamFailed( | 258 void HttpStreamFactoryImpl::JobController::OnStreamFailed( |
| 248 Job* job, | 259 Job* job, |
| 249 int status, | 260 int status, |
| 250 const SSLConfig& used_ssl_config) { | 261 const SSLConfig& used_ssl_config) { |
| 251 if (job->job_type() == ALTERNATIVE) | 262 if (job->job_type() == ALTERNATIVE) |
| 252 OnAlternativeJobFailed(job); | 263 OnAlternativeJobFailed(job); |
| 253 | 264 |
| 254 MaybeResumeMainJob(job, base::TimeDelta()); | 265 MaybeResumeMainJob(job, base::TimeDelta()); |
| 255 | 266 |
| 256 if (job_bound_ && bound_job_ != job) { | 267 if (IsJobOrphaned(job)) { |
| 257 // We have bound a job to the associated Request, |job| has been orphaned. | 268 // We have bound a job to the associated Request, |job| has been orphaned. |
| 258 OnOrphanedJobComplete(job); | 269 OnOrphanedJobComplete(job); |
| 259 return; | 270 return; |
| 260 } | 271 } |
| 261 | 272 |
| 262 if (!request_) | 273 if (!request_) |
| 263 return; | 274 return; |
| 264 DCHECK_NE(OK, status); | 275 DCHECK_NE(OK, status); |
| 265 DCHECK(job); | 276 DCHECK(job); |
| 266 | 277 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 284 request_->OnStreamFailed(status, used_ssl_config); | 295 request_->OnStreamFailed(status, used_ssl_config); |
| 285 } | 296 } |
| 286 | 297 |
| 287 void HttpStreamFactoryImpl::JobController::OnCertificateError( | 298 void HttpStreamFactoryImpl::JobController::OnCertificateError( |
| 288 Job* job, | 299 Job* job, |
| 289 int status, | 300 int status, |
| 290 const SSLConfig& used_ssl_config, | 301 const SSLConfig& used_ssl_config, |
| 291 const SSLInfo& ssl_info) { | 302 const SSLInfo& ssl_info) { |
| 292 MaybeResumeMainJob(job, base::TimeDelta()); | 303 MaybeResumeMainJob(job, base::TimeDelta()); |
| 293 | 304 |
| 294 if (job_bound_ && bound_job_ != job) { | 305 if (IsJobOrphaned(job)) { |
| 295 // We have bound a job to the associated Request, |job| has been orphaned. | 306 // We have bound a job to the associated Request, |job| has been orphaned. |
| 296 OnOrphanedJobComplete(job); | 307 OnOrphanedJobComplete(job); |
| 297 return; | 308 return; |
| 298 } | 309 } |
| 299 | 310 |
| 300 if (!request_) | 311 if (!request_) |
| 301 return; | 312 return; |
| 302 DCHECK_NE(OK, status); | 313 DCHECK_NE(OK, status); |
| 303 if (!bound_job_) | 314 if (!bound_job_) |
| 304 BindJob(job); | 315 BindJob(job); |
| 305 | 316 |
| 306 request_->OnCertificateError(status, used_ssl_config, ssl_info); | 317 request_->OnCertificateError(status, used_ssl_config, ssl_info); |
| 307 } | 318 } |
| 308 | 319 |
| 309 void HttpStreamFactoryImpl::JobController::OnHttpsProxyTunnelResponse( | 320 void HttpStreamFactoryImpl::JobController::OnHttpsProxyTunnelResponse( |
| 310 Job* job, | 321 Job* job, |
| 311 const HttpResponseInfo& response_info, | 322 const HttpResponseInfo& response_info, |
| 312 const SSLConfig& used_ssl_config, | 323 const SSLConfig& used_ssl_config, |
| 313 const ProxyInfo& used_proxy_info, | 324 const ProxyInfo& used_proxy_info, |
| 314 HttpStream* stream) { | 325 HttpStream* stream) { |
| 315 MaybeResumeMainJob(job, base::TimeDelta()); | 326 MaybeResumeMainJob(job, base::TimeDelta()); |
| 316 | 327 |
| 317 if (job_bound_ && bound_job_ != job) { | 328 if (IsJobOrphaned(job)) { |
| 318 // We have bound a job to the associated Request, |job| has been orphaned. | 329 // We have bound a job to the associated Request, |job| has been orphaned. |
| 319 OnOrphanedJobComplete(job); | 330 OnOrphanedJobComplete(job); |
| 320 return; | 331 return; |
| 321 } | 332 } |
| 322 | 333 |
| 323 if (!bound_job_) | 334 if (!bound_job_) |
| 324 BindJob(job); | 335 BindJob(job); |
| 325 if (!request_) | 336 if (!request_) |
| 326 return; | 337 return; |
| 327 request_->OnHttpsProxyTunnelResponse(response_info, used_ssl_config, | 338 request_->OnHttpsProxyTunnelResponse(response_info, used_ssl_config, |
| 328 used_proxy_info, stream); | 339 used_proxy_info, stream); |
| 329 } | 340 } |
| 330 | 341 |
| 331 void HttpStreamFactoryImpl::JobController::OnNeedsClientAuth( | 342 void HttpStreamFactoryImpl::JobController::OnNeedsClientAuth( |
| 332 Job* job, | 343 Job* job, |
| 333 const SSLConfig& used_ssl_config, | 344 const SSLConfig& used_ssl_config, |
| 334 SSLCertRequestInfo* cert_info) { | 345 SSLCertRequestInfo* cert_info) { |
| 335 MaybeResumeMainJob(job, base::TimeDelta()); | 346 MaybeResumeMainJob(job, base::TimeDelta()); |
| 336 | 347 |
| 337 if (job_bound_ && bound_job_ != job) { | 348 if (IsJobOrphaned(job)) { |
| 338 // We have bound a job to the associated Request, |job| has been orphaned. | 349 // We have bound a job to the associated Request, |job| has been orphaned. |
| 339 OnOrphanedJobComplete(job); | 350 OnOrphanedJobComplete(job); |
| 340 return; | 351 return; |
| 341 } | 352 } |
| 342 if (!request_) | 353 if (!request_) |
| 343 return; | 354 return; |
| 344 if (!bound_job_) | 355 if (!bound_job_) |
| 345 BindJob(job); | 356 BindJob(job); |
| 346 | 357 |
| 347 request_->OnNeedsClientAuth(used_ssl_config, cert_info); | 358 request_->OnNeedsClientAuth(used_ssl_config, cert_info); |
| 348 } | 359 } |
| 349 | 360 |
| 350 void HttpStreamFactoryImpl::JobController::OnNeedsProxyAuth( | 361 void HttpStreamFactoryImpl::JobController::OnNeedsProxyAuth( |
| 351 Job* job, | 362 Job* job, |
| 352 const HttpResponseInfo& proxy_response, | 363 const HttpResponseInfo& proxy_response, |
| 353 const SSLConfig& used_ssl_config, | 364 const SSLConfig& used_ssl_config, |
| 354 const ProxyInfo& used_proxy_info, | 365 const ProxyInfo& used_proxy_info, |
| 355 HttpAuthController* auth_controller) { | 366 HttpAuthController* auth_controller) { |
| 356 MaybeResumeMainJob(job, base::TimeDelta()); | 367 MaybeResumeMainJob(job, base::TimeDelta()); |
| 357 | 368 |
| 358 if (job_bound_ && bound_job_ != job) { | 369 if (IsJobOrphaned(job)) { |
| 359 // We have bound a job to the associated Request, |job| has been orphaned. | 370 // We have bound a job to the associated Request, |job| has been orphaned. |
| 360 OnOrphanedJobComplete(job); | 371 OnOrphanedJobComplete(job); |
| 361 return; | 372 return; |
| 362 } | 373 } |
| 363 | 374 |
| 364 if (!request_) | 375 if (!request_) |
| 365 return; | 376 return; |
| 366 if (!bound_job_) | 377 if (!bound_job_) |
| 367 BindJob(job); | 378 BindJob(job); |
| 368 request_->OnNeedsProxyAuth(proxy_response, used_ssl_config, used_proxy_info, | 379 request_->OnNeedsProxyAuth(proxy_response, used_ssl_config, used_proxy_info, |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 } | 426 } |
| 416 | 427 |
| 417 void HttpStreamFactoryImpl::JobController::OnNewSpdySessionReady( | 428 void HttpStreamFactoryImpl::JobController::OnNewSpdySessionReady( |
| 418 Job* job, | 429 Job* job, |
| 419 const base::WeakPtr<SpdySession>& spdy_session, | 430 const base::WeakPtr<SpdySession>& spdy_session, |
| 420 bool direct) { | 431 bool direct) { |
| 421 DCHECK(job); | 432 DCHECK(job); |
| 422 DCHECK(job->using_spdy()); | 433 DCHECK(job->using_spdy()); |
| 423 DCHECK(!is_preconnect_); | 434 DCHECK(!is_preconnect_); |
| 424 | 435 |
| 425 bool is_job_orphaned = job_bound_ && bound_job_ != job; | 436 bool is_job_orphaned = IsJobOrphaned(job); |
| 426 | 437 |
| 427 // Cache these values in case the job gets deleted. | 438 // Cache these values in case the job gets deleted. |
| 428 const SSLConfig used_ssl_config = job->server_ssl_config(); | 439 const SSLConfig used_ssl_config = job->server_ssl_config(); |
| 429 const ProxyInfo used_proxy_info = job->proxy_info(); | 440 const ProxyInfo used_proxy_info = job->proxy_info(); |
| 430 const bool was_alpn_negotiated = job->was_alpn_negotiated(); | 441 const bool was_alpn_negotiated = job->was_alpn_negotiated(); |
| 431 const NextProto negotiated_protocol = job->negotiated_protocol(); | 442 const NextProto negotiated_protocol = job->negotiated_protocol(); |
| 432 const bool using_spdy = job->using_spdy(); | 443 const bool using_spdy = job->using_spdy(); |
| 433 const NetLogWithSource net_log = job->net_log(); | 444 const NetLogWithSource net_log = job->net_log(); |
| 434 | 445 |
| 435 // Cache this so we can still use it if the JobController is deleted. | 446 // Cache this so we can still use it if the JobController is deleted. |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 778 | 789 |
| 779 alternative_job_failed_ = true; | 790 alternative_job_failed_ = true; |
| 780 | 791 |
| 781 if (job->alternative_proxy_server().is_valid()) { | 792 if (job->alternative_proxy_server().is_valid()) { |
| 782 failed_alternative_proxy_server_ = job->alternative_proxy_server(); | 793 failed_alternative_proxy_server_ = job->alternative_proxy_server(); |
| 783 } else { | 794 } else { |
| 784 DCHECK(!failed_alternative_proxy_server_.is_valid()); | 795 DCHECK(!failed_alternative_proxy_server_.is_valid()); |
| 785 failed_alternative_service_ = job->alternative_service(); | 796 failed_alternative_service_ = job->alternative_service(); |
| 786 } | 797 } |
| 787 | 798 |
| 788 if (!request_ || (job_bound_ && bound_job_ != job)) { | 799 if (IsJobOrphaned(job)) { |
| 789 // If |request_| is gone then it must have been successfully served by | 800 // If |request_| is gone then it must have been successfully served by |
| 790 // |main_job_|. | 801 // |main_job_|. |
| 791 // If |request_| is bound to a different job, then it is being | 802 // If |request_| is bound to a different job, then it is being |
| 792 // successfully serverd by the main job. | 803 // successfully serverd by the main job. |
| 793 ReportBrokenAlternativeService(); | 804 ReportBrokenAlternativeService(); |
| 794 } | 805 } |
| 795 } | 806 } |
| 796 | 807 |
| 797 void HttpStreamFactoryImpl::JobController::ReportBrokenAlternativeService() { | 808 void HttpStreamFactoryImpl::JobController::ReportBrokenAlternativeService() { |
| 798 DCHECK(failed_alternative_service_.protocol != kProtoUnknown || | 809 DCHECK(failed_alternative_service_.protocol != kProtoUnknown || |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1078 proxy_server_used); | 1089 proxy_server_used); |
| 1079 } | 1090 } |
| 1080 | 1091 |
| 1081 void HttpStreamFactoryImpl::JobController::StartAlternativeProxyServerJob() { | 1092 void HttpStreamFactoryImpl::JobController::StartAlternativeProxyServerJob() { |
| 1082 if (!alternative_job_ || !request_) | 1093 if (!alternative_job_ || !request_) |
| 1083 return; | 1094 return; |
| 1084 DCHECK(alternative_job_->alternative_proxy_server().is_valid()); | 1095 DCHECK(alternative_job_->alternative_proxy_server().is_valid()); |
| 1085 alternative_job_->Start(request_->stream_type()); | 1096 alternative_job_->Start(request_->stream_type()); |
| 1086 } | 1097 } |
| 1087 | 1098 |
| 1099 bool HttpStreamFactoryImpl::JobController::IsJobOrphaned(Job* job) const { |
| 1100 return !request_ || (job_bound_ && bound_job_ != job); |
| 1101 } |
| 1102 |
| 1088 } // namespace net | 1103 } // namespace net |
| OLD | NEW |