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 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/bind_helpers.h" | 11 #include "base/bind_helpers.h" |
| 12 #include "base/location.h" | 12 #include "base/location.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/metrics/histogram_macros.h" | 14 #include "base/metrics/histogram_macros.h" |
| 15 #include "base/profiler/scoped_tracker.h" | 15 #include "base/profiler/scoped_tracker.h" |
| 16 #include "base/single_thread_task_runner.h" | 16 #include "base/single_thread_task_runner.h" |
| 17 #include "base/stl_util.h" | 17 #include "base/stl_util.h" |
| 18 #include "base/strings/string_number_conversions.h" | 18 #include "base/strings/string_number_conversions.h" |
| 19 #include "base/strings/string_util.h" | 19 #include "base/strings/string_util.h" |
| 20 #include "base/strings/stringprintf.h" | 20 #include "base/strings/stringprintf.h" |
| 21 #include "base/thread_task_runner_handle.h" | 21 #include "base/thread_task_runner_handle.h" |
| 22 #include "base/values.h" | 22 #include "base/values.h" |
| 23 #include "build/build_config.h" | 23 #include "build/build_config.h" |
| 24 #include "net/base/connection_type_histograms.h" | 24 #include "net/base/connection_type_histograms.h" |
| 25 #include "net/base/net_util.h" | 25 #include "net/base/net_util.h" |
| 26 #include "net/base/port_util.h" | 26 #include "net/base/port_util.h" |
| 27 #include "net/cert/cert_verifier.h" | 27 #include "net/cert/cert_verifier.h" |
| 28 #include "net/http/bidirectional_stream.h" | |
| 28 #include "net/http/http_basic_stream.h" | 29 #include "net/http/http_basic_stream.h" |
| 29 #include "net/http/http_network_session.h" | 30 #include "net/http/http_network_session.h" |
| 30 #include "net/http/http_proxy_client_socket.h" | 31 #include "net/http/http_proxy_client_socket.h" |
| 31 #include "net/http/http_proxy_client_socket_pool.h" | 32 #include "net/http/http_proxy_client_socket_pool.h" |
| 32 #include "net/http/http_request_info.h" | 33 #include "net/http/http_request_info.h" |
| 33 #include "net/http/http_server_properties.h" | 34 #include "net/http/http_server_properties.h" |
| 34 #include "net/http/http_stream_factory.h" | 35 #include "net/http/http_stream_factory.h" |
| 35 #include "net/http/http_stream_factory_impl_request.h" | 36 #include "net/http/http_stream_factory_impl_request.h" |
| 36 #include "net/log/net_log.h" | 37 #include "net/log/net_log.h" |
| 37 #include "net/quic/quic_http_stream.h" | 38 #include "net/quic/quic_http_stream.h" |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 127 quic_request_(session_->quic_stream_factory()), | 128 quic_request_(session_->quic_stream_factory()), |
| 128 using_existing_quic_session_(false), | 129 using_existing_quic_session_(false), |
| 129 spdy_certificate_error_(OK), | 130 spdy_certificate_error_(OK), |
| 130 establishing_tunnel_(false), | 131 establishing_tunnel_(false), |
| 131 was_npn_negotiated_(false), | 132 was_npn_negotiated_(false), |
| 132 protocol_negotiated_(kProtoUnknown), | 133 protocol_negotiated_(kProtoUnknown), |
| 133 num_streams_(0), | 134 num_streams_(0), |
| 134 spdy_session_direct_(false), | 135 spdy_session_direct_(false), |
| 135 job_status_(STATUS_RUNNING), | 136 job_status_(STATUS_RUNNING), |
| 136 other_job_status_(STATUS_RUNNING), | 137 other_job_status_(STATUS_RUNNING), |
| 138 for_bidirectional_(false), | |
| 137 ptr_factory_(this) { | 139 ptr_factory_(this) { |
| 138 DCHECK(stream_factory); | 140 DCHECK(stream_factory); |
| 139 DCHECK(session); | 141 DCHECK(session); |
| 140 if (IsQuicAlternative()) { | 142 if (IsQuicAlternative()) { |
| 141 DCHECK(session_->params().enable_quic); | 143 DCHECK(session_->params().enable_quic); |
| 142 using_quic_ = true; | 144 using_quic_ = true; |
| 143 } | 145 } |
| 144 } | 146 } |
| 145 | 147 |
| 146 HttpStreamFactoryImpl::Job::~Job() { | 148 HttpStreamFactoryImpl::Job::~Job() { |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 158 session_->proxy_service()->CancelPacRequest(pac_request_); | 160 session_->proxy_service()->CancelPacRequest(pac_request_); |
| 159 | 161 |
| 160 // The stream could be in a partial state. It is not reusable. | 162 // The stream could be in a partial state. It is not reusable. |
| 161 if (stream_.get() && next_state_ != STATE_DONE) | 163 if (stream_.get() && next_state_ != STATE_DONE) |
| 162 stream_->Close(true /* not reusable */); | 164 stream_->Close(true /* not reusable */); |
| 163 } | 165 } |
| 164 | 166 |
| 165 void HttpStreamFactoryImpl::Job::Start(Request* request) { | 167 void HttpStreamFactoryImpl::Job::Start(Request* request) { |
| 166 DCHECK(request); | 168 DCHECK(request); |
| 167 request_ = request; | 169 request_ = request; |
| 170 // Saves |for_bidirectional_|, since request is nulled when job is orphaned. | |
| 171 for_bidirectional_ = request_->for_bidirectional(); | |
| 168 StartInternal(); | 172 StartInternal(); |
| 169 } | 173 } |
| 170 | 174 |
| 171 int HttpStreamFactoryImpl::Job::Preconnect(int num_streams) { | 175 int HttpStreamFactoryImpl::Job::Preconnect(int num_streams) { |
| 172 DCHECK_GT(num_streams, 0); | 176 DCHECK_GT(num_streams, 0); |
| 173 base::WeakPtr<HttpServerProperties> http_server_properties = | 177 base::WeakPtr<HttpServerProperties> http_server_properties = |
| 174 session_->http_server_properties(); | 178 session_->http_server_properties(); |
| 175 if (http_server_properties && | 179 if (http_server_properties && |
| 176 http_server_properties->SupportsRequestPriority( | 180 http_server_properties->SupportsRequestPriority( |
| 177 HostPortPair::FromURL(request_info_.url))) { | 181 HostPortPair::FromURL(request_info_.url))) { |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 348 MaybeCopyConnectionAttemptsFromSocketOrHandle(); | 352 MaybeCopyConnectionAttemptsFromSocketOrHandle(); |
| 349 | 353 |
| 350 request_->Complete(was_npn_negotiated(), protocol_negotiated(), using_spdy()); | 354 request_->Complete(was_npn_negotiated(), protocol_negotiated(), using_spdy()); |
| 351 request_->OnWebSocketHandshakeStreamReady(this, | 355 request_->OnWebSocketHandshakeStreamReady(this, |
| 352 server_ssl_config_, | 356 server_ssl_config_, |
| 353 proxy_info_, | 357 proxy_info_, |
| 354 websocket_stream_.release()); | 358 websocket_stream_.release()); |
| 355 // |this| may be deleted after this call. | 359 // |this| may be deleted after this call. |
| 356 } | 360 } |
| 357 | 361 |
| 362 void HttpStreamFactoryImpl::Job::OnBidirectionalStreamReadyCallback() { | |
| 363 DCHECK(bidirectional_stream_); | |
| 364 DCHECK(!IsPreconnecting()); | |
| 365 DCHECK(!stream_factory_->for_websockets_); | |
| 366 | |
| 367 MaybeCopyConnectionAttemptsFromSocketOrHandle(); | |
| 368 | |
| 369 if (IsOrphaned()) { | |
| 370 stream_factory_->OnOrphanedJobComplete(this); | |
| 371 } else { | |
| 372 request_->Complete(was_npn_negotiated(), protocol_negotiated(), | |
| 373 using_spdy()); | |
| 374 request_->OnBidirectionalStreamReady(this, server_ssl_config_, proxy_info_, | |
| 375 bidirectional_stream_.release()); | |
| 376 } | |
| 377 // |this| may be deleted after this call. | |
| 378 } | |
| 379 | |
| 358 void HttpStreamFactoryImpl::Job::OnNewSpdySessionReadyCallback() { | 380 void HttpStreamFactoryImpl::Job::OnNewSpdySessionReadyCallback() { |
| 359 DCHECK(stream_.get()); | 381 DCHECK(stream_.get() || bidirectional_stream_.get()); |
| 360 DCHECK(!IsPreconnecting()); | 382 DCHECK(!IsPreconnecting()); |
| 361 DCHECK(using_spdy()); | 383 DCHECK(using_spdy()); |
| 362 // Note: an event loop iteration has passed, so |new_spdy_session_| may be | 384 // Note: an event loop iteration has passed, so |new_spdy_session_| may be |
| 363 // NULL at this point if the SpdySession closed immediately after creation. | 385 // NULL at this point if the SpdySession closed immediately after creation. |
| 364 base::WeakPtr<SpdySession> spdy_session = new_spdy_session_; | 386 base::WeakPtr<SpdySession> spdy_session = new_spdy_session_; |
| 365 new_spdy_session_.reset(); | 387 new_spdy_session_.reset(); |
| 366 | 388 |
| 367 MaybeCopyConnectionAttemptsFromSocketOrHandle(); | 389 MaybeCopyConnectionAttemptsFromSocketOrHandle(); |
| 368 | 390 |
| 369 // TODO(jgraettinger): Notify the factory, and let that notify |request_|, | 391 // TODO(jgraettinger): Notify the factory, and let that notify |request_|, |
| 370 // rather than notifying |request_| directly. | 392 // rather than notifying |request_| directly. |
| 371 if (IsOrphaned()) { | 393 if (IsOrphaned()) { |
| 372 if (spdy_session) { | 394 if (spdy_session) { |
| 373 stream_factory_->OnNewSpdySessionReady( | 395 stream_factory_->OnNewSpdySessionReady( |
| 374 spdy_session, spdy_session_direct_, server_ssl_config_, proxy_info_, | 396 spdy_session, spdy_session_direct_, server_ssl_config_, proxy_info_, |
| 375 was_npn_negotiated(), protocol_negotiated(), using_spdy(), net_log_); | 397 was_npn_negotiated(), protocol_negotiated(), using_spdy(), net_log_); |
| 376 } | 398 } |
| 377 stream_factory_->OnOrphanedJobComplete(this); | 399 stream_factory_->OnOrphanedJobComplete(this); |
| 378 } else { | 400 } else { |
| 379 request_->OnNewSpdySessionReady( | 401 if (for_bidirectional_) { |
| 380 this, stream_.Pass(), spdy_session, spdy_session_direct_); | 402 request_->OnNewSpdySessionReady(this, nullptr /** spdy_http_stream */, |
|
Bence
2015/10/01 05:29:28
I think the syntax most often used is
/*spdy_http_
xunjieli
2015/10/01 18:41:16
Done.
| |
| 403 bidirectional_stream_.Pass(), | |
| 404 spdy_session, spdy_session_direct_); | |
| 405 | |
| 406 } else { | |
| 407 request_->OnNewSpdySessionReady(this, stream_.Pass(), | |
| 408 nullptr /** bidirectional_stream */, | |
|
Bence
2015/10/01 05:29:28
/*bidirectional_stream=*/ nullptr
xunjieli
2015/10/01 18:41:16
Done.
| |
| 409 spdy_session, spdy_session_direct_); | |
| 410 } | |
| 381 } | 411 } |
| 382 // |this| may be deleted after this call. | 412 // |this| may be deleted after this call. |
| 383 } | 413 } |
| 384 | 414 |
| 385 void HttpStreamFactoryImpl::Job::OnStreamFailedCallback(int result) { | 415 void HttpStreamFactoryImpl::Job::OnStreamFailedCallback(int result) { |
| 386 DCHECK(!IsPreconnecting()); | 416 DCHECK(!IsPreconnecting()); |
| 387 | 417 |
| 388 MaybeCopyConnectionAttemptsFromSocketOrHandle(); | 418 MaybeCopyConnectionAttemptsFromSocketOrHandle(); |
| 389 | 419 |
| 390 if (IsOrphaned()) { | 420 if (IsOrphaned()) { |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 557 next_state_ = STATE_DONE; | 587 next_state_ = STATE_DONE; |
| 558 if (new_spdy_session_.get()) { | 588 if (new_spdy_session_.get()) { |
| 559 base::ThreadTaskRunnerHandle::Get()->PostTask( | 589 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 560 FROM_HERE, base::Bind(&Job::OnNewSpdySessionReadyCallback, | 590 FROM_HERE, base::Bind(&Job::OnNewSpdySessionReadyCallback, |
| 561 ptr_factory_.GetWeakPtr())); | 591 ptr_factory_.GetWeakPtr())); |
| 562 } else if (stream_factory_->for_websockets_) { | 592 } else if (stream_factory_->for_websockets_) { |
| 563 DCHECK(websocket_stream_); | 593 DCHECK(websocket_stream_); |
| 564 base::ThreadTaskRunnerHandle::Get()->PostTask( | 594 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 565 FROM_HERE, base::Bind(&Job::OnWebSocketHandshakeStreamReadyCallback, | 595 FROM_HERE, base::Bind(&Job::OnWebSocketHandshakeStreamReadyCallback, |
| 566 ptr_factory_.GetWeakPtr())); | 596 ptr_factory_.GetWeakPtr())); |
| 597 } else if (for_bidirectional_) { | |
| 598 if (bidirectional_stream_ == nullptr) { | |
| 599 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 600 FROM_HERE, base::Bind(&Job::OnStreamFailedCallback, | |
| 601 ptr_factory_.GetWeakPtr(), ERR_FAILED)); | |
| 602 } else { | |
| 603 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 604 FROM_HERE, base::Bind(&Job::OnBidirectionalStreamReadyCallback, | |
| 605 ptr_factory_.GetWeakPtr())); | |
| 606 } | |
| 567 } else { | 607 } else { |
| 568 DCHECK(stream_.get()); | 608 DCHECK(stream_.get()); |
| 569 base::ThreadTaskRunnerHandle::Get()->PostTask( | 609 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 570 FROM_HERE, | 610 FROM_HERE, |
| 571 base::Bind(&Job::OnStreamReadyCallback, ptr_factory_.GetWeakPtr())); | 611 base::Bind(&Job::OnStreamReadyCallback, ptr_factory_.GetWeakPtr())); |
| 572 } | 612 } |
| 573 return ERR_IO_PENDING; | 613 return ERR_IO_PENDING; |
| 574 | 614 |
| 575 default: | 615 default: |
| 576 DCHECK(result != ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN || | 616 DCHECK(result != ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN || |
| (...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1141 // We're always waiting here for the delegate to call us back. | 1181 // We're always waiting here for the delegate to call us back. |
| 1142 return ERR_IO_PENDING; | 1182 return ERR_IO_PENDING; |
| 1143 } | 1183 } |
| 1144 | 1184 |
| 1145 int HttpStreamFactoryImpl::Job::SetSpdyHttpStream( | 1185 int HttpStreamFactoryImpl::Job::SetSpdyHttpStream( |
| 1146 base::WeakPtr<SpdySession> session, bool direct) { | 1186 base::WeakPtr<SpdySession> session, bool direct) { |
| 1147 // TODO(ricea): Restore the code for WebSockets over SPDY once it's | 1187 // TODO(ricea): Restore the code for WebSockets over SPDY once it's |
| 1148 // implemented. | 1188 // implemented. |
| 1149 if (stream_factory_->for_websockets_) | 1189 if (stream_factory_->for_websockets_) |
| 1150 return ERR_NOT_IMPLEMENTED; | 1190 return ERR_NOT_IMPLEMENTED; |
| 1191 if (for_bidirectional_) { | |
| 1192 bidirectional_stream_.reset(new BidirectionalStream(session)); | |
| 1193 return OK; | |
| 1194 } | |
| 1151 | 1195 |
| 1152 // TODO(willchan): Delete this code, because eventually, the | 1196 // TODO(willchan): Delete this code, because eventually, the |
| 1153 // HttpStreamFactoryImpl will be creating all the SpdyHttpStreams, since it | 1197 // HttpStreamFactoryImpl will be creating all the SpdyHttpStreams, since it |
| 1154 // will know when SpdySessions become available. | 1198 // will know when SpdySessions become available. |
| 1155 | 1199 |
| 1156 bool use_relative_url = direct || request_info_.url.SchemeIs("https"); | 1200 bool use_relative_url = direct || request_info_.url.SchemeIs("https"); |
| 1157 stream_.reset(new SpdyHttpStream(session, use_relative_url)); | 1201 stream_.reset(new SpdyHttpStream(session, use_relative_url)); |
| 1158 return OK; | 1202 return OK; |
| 1159 } | 1203 } |
| 1160 | 1204 |
| (...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1611 if (connection_->socket()) { | 1655 if (connection_->socket()) { |
| 1612 ConnectionAttempts socket_attempts; | 1656 ConnectionAttempts socket_attempts; |
| 1613 connection_->socket()->GetConnectionAttempts(&socket_attempts); | 1657 connection_->socket()->GetConnectionAttempts(&socket_attempts); |
| 1614 request_->AddConnectionAttempts(socket_attempts); | 1658 request_->AddConnectionAttempts(socket_attempts); |
| 1615 } else { | 1659 } else { |
| 1616 request_->AddConnectionAttempts(connection_->connection_attempts()); | 1660 request_->AddConnectionAttempts(connection_->connection_attempts()); |
| 1617 } | 1661 } |
| 1618 } | 1662 } |
| 1619 | 1663 |
| 1620 } // namespace net | 1664 } // namespace net |
| OLD | NEW |