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" |
(...skipping 23 matching lines...) Expand all Loading... | |
34 #include "net/http/http_stream_factory.h" | 34 #include "net/http/http_stream_factory.h" |
35 #include "net/http/http_stream_factory_impl_request.h" | 35 #include "net/http/http_stream_factory_impl_request.h" |
36 #include "net/log/net_log.h" | 36 #include "net/log/net_log.h" |
37 #include "net/quic/quic_http_stream.h" | 37 #include "net/quic/quic_http_stream.h" |
38 #include "net/socket/client_socket_handle.h" | 38 #include "net/socket/client_socket_handle.h" |
39 #include "net/socket/client_socket_pool.h" | 39 #include "net/socket/client_socket_pool.h" |
40 #include "net/socket/client_socket_pool_manager.h" | 40 #include "net/socket/client_socket_pool_manager.h" |
41 #include "net/socket/socks_client_socket_pool.h" | 41 #include "net/socket/socks_client_socket_pool.h" |
42 #include "net/socket/ssl_client_socket.h" | 42 #include "net/socket/ssl_client_socket.h" |
43 #include "net/socket/ssl_client_socket_pool.h" | 43 #include "net/socket/ssl_client_socket_pool.h" |
44 #include "net/spdy/bidirectional_spdy_stream.h" | |
44 #include "net/spdy/spdy_http_stream.h" | 45 #include "net/spdy/spdy_http_stream.h" |
45 #include "net/spdy/spdy_session.h" | 46 #include "net/spdy/spdy_session.h" |
46 #include "net/spdy/spdy_session_pool.h" | 47 #include "net/spdy/spdy_session_pool.h" |
47 #include "net/ssl/ssl_cert_request_info.h" | 48 #include "net/ssl/ssl_cert_request_info.h" |
48 #include "net/ssl/ssl_failure_state.h" | 49 #include "net/ssl/ssl_failure_state.h" |
49 | 50 |
50 namespace net { | 51 namespace net { |
51 | 52 |
52 // Returns parameters associated with the start of a HTTP stream job. | 53 // Returns parameters associated with the start of a HTTP stream job. |
53 scoped_ptr<base::Value> NetLogHttpStreamJobCallback( | 54 scoped_ptr<base::Value> NetLogHttpStreamJobCallback( |
(...skipping 73 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_); | |
mmenke
2015/10/08 19:31:53
Think the latter two of these make more sense as D
xunjieli
2015/10/19 21:07:46
Hmm.. A few unit tests fail those two DCHECKs if I
| |
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, /*spdy_http_stream=*/nullptr, |
403 bidirectional_stream_.Pass(), | |
404 spdy_session, spdy_session_direct_); | |
405 | |
406 } else { | |
407 request_->OnNewSpdySessionReady(this, stream_.Pass(), | |
408 /** bidirectional_stream=*/nullptr, | |
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_) { | |
mmenke
2015/10/08 19:31:53
Hrm...Should we fail earlier for non-HTTPS/HTTP2 r
xunjieli
2015/10/19 21:07:46
I added a check in the wrapper to fail early for n
| |
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 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1135 | 1175 |
1136 int HttpStreamFactoryImpl::Job::DoWaitingUserAction(int result) { | 1176 int HttpStreamFactoryImpl::Job::DoWaitingUserAction(int result) { |
1137 // This state indicates that the stream request is in a partially | 1177 // This state indicates that the stream request is in a partially |
1138 // completed state, and we've called back to the delegate for more | 1178 // completed state, and we've called back to the delegate for more |
1139 // information. | 1179 // information. |
1140 | 1180 |
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( |
mmenke
2015/10/08 19:31:53
This method needs to be renamed.
xunjieli
2015/10/19 21:07:46
Done.
| |
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 // TODO(xunjieli): Enable creation of QUIC's version of BidirectionalStream. | |
1193 bidirectional_stream_.reset(new BidirectionalSpdyStream(session)); | |
1194 return OK; | |
1195 } | |
1151 | 1196 |
1152 // TODO(willchan): Delete this code, because eventually, the | 1197 // TODO(willchan): Delete this code, because eventually, the |
1153 // HttpStreamFactoryImpl will be creating all the SpdyHttpStreams, since it | 1198 // HttpStreamFactoryImpl will be creating all the SpdyHttpStreams, since it |
1154 // will know when SpdySessions become available. | 1199 // will know when SpdySessions become available. |
1155 | 1200 |
1156 bool use_relative_url = direct || request_info_.url.SchemeIs("https"); | 1201 bool use_relative_url = direct || request_info_.url.SchemeIs("https"); |
1157 stream_.reset(new SpdyHttpStream(session, use_relative_url)); | 1202 stream_.reset(new SpdyHttpStream(session, use_relative_url)); |
1158 return OK; | 1203 return OK; |
1159 } | 1204 } |
1160 | 1205 |
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1602 if (connection_->socket()) { | 1647 if (connection_->socket()) { |
1603 ConnectionAttempts socket_attempts; | 1648 ConnectionAttempts socket_attempts; |
1604 connection_->socket()->GetConnectionAttempts(&socket_attempts); | 1649 connection_->socket()->GetConnectionAttempts(&socket_attempts); |
1605 request_->AddConnectionAttempts(socket_attempts); | 1650 request_->AddConnectionAttempts(socket_attempts); |
1606 } else { | 1651 } else { |
1607 request_->AddConnectionAttempts(connection_->connection_attempts()); | 1652 request_->AddConnectionAttempts(connection_->connection_attempts()); |
1608 } | 1653 } |
1609 } | 1654 } |
1610 | 1655 |
1611 } // namespace net | 1656 } // namespace net |
OLD | NEW |