Chromium Code Reviews| Index: net/http/http_stream_factory_impl_job.cc |
| diff --git a/net/http/http_stream_factory_impl_job.cc b/net/http/http_stream_factory_impl_job.cc |
| index 3625e4a4ef9ec69d6ef2fa518835fc3d91c1b243..a075765a23e88f8d7de39f78c35bd98ddd4c11de 100644 |
| --- a/net/http/http_stream_factory_impl_job.cc |
| +++ b/net/http/http_stream_factory_impl_job.cc |
| @@ -42,6 +42,7 @@ |
| #include "net/socket/socks_client_socket_pool.h" |
| #include "net/socket/ssl_client_socket.h" |
| #include "net/socket/ssl_client_socket_pool.h" |
| +#include "net/spdy/bidirectional_spdy_stream.h" |
| #include "net/spdy/spdy_http_stream.h" |
| #include "net/spdy/spdy_protocol.h" |
| #include "net/spdy/spdy_session.h" |
| @@ -137,6 +138,7 @@ HttpStreamFactoryImpl::Job::Job(HttpStreamFactoryImpl* stream_factory, |
| spdy_session_direct_(false), |
| job_status_(STATUS_RUNNING), |
| other_job_status_(STATUS_RUNNING), |
| + for_bidirectional_(false), |
| ptr_factory_(this) { |
| DCHECK(stream_factory); |
| DCHECK(session); |
| @@ -168,6 +170,8 @@ HttpStreamFactoryImpl::Job::~Job() { |
| void HttpStreamFactoryImpl::Job::Start(Request* request) { |
| DCHECK(request); |
| request_ = request; |
| + // Saves |for_bidirectional_|, since request is nulled when job is orphaned. |
| + for_bidirectional_ = request_->for_bidirectional(); |
| StartInternal(); |
| } |
| @@ -358,8 +362,24 @@ void HttpStreamFactoryImpl::Job::OnWebSocketHandshakeStreamReadyCallback() { |
| // |this| may be deleted after this call. |
| } |
| +void HttpStreamFactoryImpl::Job::OnBidirectionalStreamReadyCallback() { |
| + DCHECK(bidirectional_stream_); |
| + |
| + MaybeCopyConnectionAttemptsFromSocketOrHandle(); |
| + |
| + if (IsOrphaned()) { |
| + stream_factory_->OnOrphanedJobComplete(this); |
| + } else { |
| + request_->Complete(was_npn_negotiated(), protocol_negotiated(), |
| + using_spdy()); |
| + request_->OnBidirectionalStreamReady(this, server_ssl_config_, proxy_info_, |
| + bidirectional_stream_.release()); |
| + } |
| + // |this| may be deleted after this call. |
| +} |
| + |
| void HttpStreamFactoryImpl::Job::OnNewSpdySessionReadyCallback() { |
| - DCHECK(stream_.get()); |
| + DCHECK(stream_.get() || bidirectional_stream_.get()); |
| DCHECK(!IsPreconnecting()); |
| DCHECK(using_spdy()); |
| // Note: an event loop iteration has passed, so |new_spdy_session_| may be |
| @@ -379,8 +399,16 @@ void HttpStreamFactoryImpl::Job::OnNewSpdySessionReadyCallback() { |
| } |
| stream_factory_->OnOrphanedJobComplete(this); |
| } else { |
| - request_->OnNewSpdySessionReady( |
| - this, stream_.Pass(), spdy_session, spdy_session_direct_); |
| + if (for_bidirectional_) { |
| + request_->OnNewSpdySessionReady(this, /*spdy_http_stream=*/nullptr, |
| + bidirectional_stream_.Pass(), |
| + spdy_session, spdy_session_direct_); |
| + |
| + } else { |
| + request_->OnNewSpdySessionReady(this, stream_.Pass(), |
| + /** bidirectional_stream=*/nullptr, |
|
mef
2015/10/20 21:56:35
I wonder what would happen if you call Pass() on s
xunjieli
2015/10/21 19:35:36
I am not sure. I guess that will give nulls? I wil
|
| + spdy_session, spdy_session_direct_); |
| + } |
| } |
| // |this| may be deleted after this call. |
| } |
| @@ -567,6 +595,16 @@ int HttpStreamFactoryImpl::Job::RunLoop(int result) { |
| base::ThreadTaskRunnerHandle::Get()->PostTask( |
| FROM_HERE, base::Bind(&Job::OnWebSocketHandshakeStreamReadyCallback, |
| ptr_factory_.GetWeakPtr())); |
| + } else if (for_bidirectional_) { |
| + if (bidirectional_stream_ == nullptr) { |
|
mef
2015/10/20 21:56:35
why do you need this guard? Shouldn't it go to def
xunjieli
2015/10/21 19:35:36
If H2 is not negotiated, we will still enter the O
|
| + base::ThreadTaskRunnerHandle::Get()->PostTask( |
| + FROM_HERE, base::Bind(&Job::OnStreamFailedCallback, |
| + ptr_factory_.GetWeakPtr(), ERR_FAILED)); |
| + } else { |
| + base::ThreadTaskRunnerHandle::Get()->PostTask( |
| + FROM_HERE, base::Bind(&Job::OnBidirectionalStreamReadyCallback, |
| + ptr_factory_.GetWeakPtr())); |
| + } |
| } else { |
| DCHECK(stream_.get()); |
| base::ThreadTaskRunnerHandle::Get()->PostTask( |
| @@ -653,6 +691,7 @@ int HttpStreamFactoryImpl::Job::DoLoop(int result) { |
| int HttpStreamFactoryImpl::Job::StartInternal() { |
| CHECK_EQ(STATE_NONE, next_state_); |
| + |
|
mef
2015/10/20 21:56:35
spurious nl?
xunjieli
2015/10/21 19:35:36
Done.
|
| next_state_ = STATE_START; |
| int rv = RunLoop(OK); |
| DCHECK_EQ(ERR_IO_PENDING, rv); |
| @@ -1145,12 +1184,18 @@ int HttpStreamFactoryImpl::Job::DoWaitingUserAction(int result) { |
| return ERR_IO_PENDING; |
| } |
| -int HttpStreamFactoryImpl::Job::SetSpdyHttpStream( |
| - base::WeakPtr<SpdySession> session, bool direct) { |
| +int HttpStreamFactoryImpl::Job::SetSpdyHttpStreamOrBidirectionalStream( |
| + base::WeakPtr<SpdySession> session, |
| + bool direct) { |
| // TODO(ricea): Restore the code for WebSockets over SPDY once it's |
| // implemented. |
| if (stream_factory_->for_websockets_) |
| return ERR_NOT_IMPLEMENTED; |
| + if (for_bidirectional_) { |
| + // TODO(xunjieli): Enable creation of QUIC's version of BidirectionalStream. |
| + bidirectional_stream_.reset(new BidirectionalSpdyStream(session)); |
| + return OK; |
| + } |
| // TODO(willchan): Delete this code, because eventually, the |
| // HttpStreamFactoryImpl will be creating all the SpdyHttpStreams, since it |
| @@ -1204,7 +1249,8 @@ int HttpStreamFactoryImpl::Job::DoCreateStream() { |
| connection_->socket()->Disconnect(); |
| connection_->Reset(); |
| - int set_result = SetSpdyHttpStream(existing_spdy_session_, direct); |
| + int set_result = |
| + SetSpdyHttpStreamOrBidirectionalStream(existing_spdy_session_, direct); |
| existing_spdy_session_.reset(); |
| return set_result; |
| } |
| @@ -1217,7 +1263,7 @@ int HttpStreamFactoryImpl::Job::DoCreateStream() { |
| return result; |
| } |
| if (spdy_session) { |
| - return SetSpdyHttpStream(spdy_session, direct); |
| + return SetSpdyHttpStreamOrBidirectionalStream(spdy_session, direct); |
| } |
| result = valid_spdy_session_pool_->CreateAvailableSessionFromSocket( |
| @@ -1252,12 +1298,13 @@ int HttpStreamFactoryImpl::Job::DoCreateStream() { |
| if (http_server_properties) |
| http_server_properties->SetSupportsSpdy(host_port_pair, true); |
| - // Create a SpdyHttpStream attached to the session; |
| + // Create a SpdyHttpStream or a BidirectionalStream attached to the session; |
| // OnNewSpdySessionReadyCallback is not called until an event loop |
| // iteration later, so if the SpdySession is closed between then, allow |
| // reuse state from the underlying socket, sampled by SpdyHttpStream, |
| // bubble up to the request. |
| - return SetSpdyHttpStream(new_spdy_session_, spdy_session_direct_); |
| + return SetSpdyHttpStreamOrBidirectionalStream(new_spdy_session_, |
| + spdy_session_direct_); |
| } |
| int HttpStreamFactoryImpl::Job::DoCreateStreamComplete(int result) { |