| Index: net/quic/chromium/quic_http_stream.cc
|
| diff --git a/net/quic/chromium/quic_http_stream.cc b/net/quic/chromium/quic_http_stream.cc
|
| index c72bf9e88ac348001c5f855e9d20c6dfa67cbcf8..16447899be3ce42ac65ddede9bcb790ee07c306e 100644
|
| --- a/net/quic/chromium/quic_http_stream.cc
|
| +++ b/net/quic/chromium/quic_http_stream.cc
|
| @@ -111,26 +111,20 @@ void QuicHttpStream::OnRendezvousResult(QuicSpdyStream* stream) {
|
| stream_ = static_cast<QuicChromiumClientStream*>(stream);
|
| stream_->SetDelegate(this);
|
| }
|
| - // callback_ should be non-null in the case of asynchronous
|
| +
|
| + // callback_ should only be non-null in the case of asynchronous
|
| // rendezvous; i.e. |Try()| returned QUIC_PENDING.
|
| - if (!callback_.is_null()) {
|
| - if (stream) {
|
| - next_state_ = STATE_OPEN;
|
| - stream_net_log_.AddEvent(
|
| - NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
|
| - base::Bind(&NetLogQuicPushStreamCallback, stream_->id(),
|
| - &request_info_->url));
|
| - session_->net_log().AddEvent(
|
| - NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
|
| - base::Bind(&NetLogQuicPushStreamCallback, stream_->id(),
|
| - &request_info_->url));
|
| - DoCallback(OK);
|
| - return;
|
| - }
|
| + if (callback_.is_null())
|
| + return;
|
| +
|
| + if (stream) {
|
| + next_state_ = STATE_HANDLE_PROMISE_COMPLETE;
|
| + } else {
|
| // rendezvous has failed so proceed as with a non-push request.
|
| next_state_ = STATE_REQUEST_STREAM;
|
| - OnIOComplete(OK);
|
| }
|
| +
|
| + OnIOComplete(OK);
|
| }
|
|
|
| int QuicHttpStream::InitializeStream(const HttpRequestInfo* request_info,
|
| @@ -180,40 +174,17 @@ int QuicHttpStream::InitializeStream(const HttpRequestInfo* request_info,
|
| return rv;
|
| }
|
|
|
| -void QuicHttpStream::OnStreamReady(int rv) {
|
| - DCHECK(rv == OK || !stream_);
|
| - if (rv == OK) {
|
| - stream_->SetDelegate(this);
|
| - if (request_info_->load_flags & LOAD_DISABLE_CONNECTION_MIGRATION) {
|
| - stream_->DisableConnectionMigration();
|
| - }
|
| - if (response_info_) {
|
| - // This happens in the case of a asynchronous push rendezvous
|
| - // that ultimately fails (e.g. vary failure). |response_info_|
|
| - // non-null implies that |DoStreamRequest()| was called via
|
| - // |SendRequest()|.
|
| - next_state_ = STATE_SET_REQUEST_PRIORITY;
|
| - rv = DoLoop(OK);
|
| - }
|
| - } else if (!was_handshake_confirmed_) {
|
| - rv = ERR_QUIC_HANDSHAKE_FAILED;
|
| - }
|
| - if (rv != ERR_IO_PENDING) {
|
| - DoCallback(rv);
|
| - }
|
| -}
|
| -
|
| bool QuicHttpStream::CancelPromiseIfHasBody() {
|
| if (!request_body_stream_)
|
| return false;
|
| - // Method type or request with body ineligble for push.
|
| +
|
| + // A request with a body is ineligble for push.
|
| this->push_handle_->Cancel();
|
| this->push_handle_ = nullptr;
|
| - next_state_ = STATE_REQUEST_STREAM;
|
| return true;
|
| }
|
|
|
| -int QuicHttpStream::HandlePromise() {
|
| +int QuicHttpStream::DoHandlePromise() {
|
| QuicAsyncStatus push_status = session_->push_promise_index()->Try(
|
| request_headers_, this, &this->push_handle_);
|
|
|
| @@ -223,32 +194,40 @@ int QuicHttpStream::HandlePromise() {
|
| next_state_ = STATE_REQUEST_STREAM;
|
| break;
|
| case QUIC_SUCCESS:
|
| - next_state_ = STATE_OPEN;
|
| - if (!CancelPromiseIfHasBody()) {
|
| - stream_net_log_.AddEvent(
|
| - NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
|
| - base::Bind(&NetLogQuicPushStreamCallback, stream_->id(),
|
| - &request_info_->url));
|
| - session_->net_log().AddEvent(
|
| - NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
|
| - base::Bind(&NetLogQuicPushStreamCallback, stream_->id(),
|
| - &request_info_->url));
|
| - // Avoid the call to |DoLoop()| below, which would reset
|
| - // next_state_ to STATE_NONE.
|
| - return OK;
|
| - }
|
| -
|
| + next_state_ = STATE_HANDLE_PROMISE_COMPLETE;
|
| break;
|
| case QUIC_PENDING:
|
| if (!CancelPromiseIfHasBody()) {
|
| + next_state_ = STATE_HANDLE_PROMISE_COMPLETE;
|
| // Have a promise but the promised stream doesn't exist yet.
|
| // Still have to do validation before accepting the promised
|
| // stream for sure.
|
| return ERR_IO_PENDING;
|
| }
|
| - break;
|
| + next_state_ = STATE_REQUEST_STREAM;
|
| }
|
| - return DoLoop(OK);
|
| + return OK;
|
| +}
|
| +
|
| +int QuicHttpStream::DoHandlePromiseComplete(int rv) {
|
| + if (rv != OK)
|
| + return rv;
|
| +
|
| + if (CancelPromiseIfHasBody()) {
|
| + next_state_ = STATE_REQUEST_STREAM;
|
| + return OK;
|
| + }
|
| +
|
| + next_state_ = STATE_OPEN;
|
| + stream_net_log_.AddEvent(
|
| + NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
|
| + base::Bind(&NetLogQuicPushStreamCallback, stream_->id(),
|
| + &request_info_->url));
|
| + session_->net_log().AddEvent(
|
| + NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
|
| + base::Bind(&NetLogQuicPushStreamCallback, stream_->id(),
|
| + &request_info_->url));
|
| + return OK;
|
| }
|
|
|
| int QuicHttpStream::SendRequest(const HttpRequestHeaders& request_headers,
|
| @@ -299,11 +278,14 @@ int QuicHttpStream::SendRequest(const HttpRequestHeaders& request_headers,
|
| int rv;
|
|
|
| if (found_promise_) {
|
| - rv = HandlePromise();
|
| + // TODO(rch): If this request has a body, instead of waiting for the pushed
|
| + // headers to arrive before canceling the push we could cancel the pushed
|
| + // stream now and go straight to STATE_REQUEST_STREAM.
|
| + next_state_ = STATE_HANDLE_PROMISE;
|
| } else {
|
| next_state_ = STATE_SET_REQUEST_PRIORITY;
|
| - rv = DoLoop(OK);
|
| }
|
| + rv = DoLoop(OK);
|
|
|
| if (rv == ERR_IO_PENDING)
|
| callback_ = callback;
|
| @@ -592,10 +574,23 @@ int QuicHttpStream::DoLoop(int rv) {
|
| State state = next_state_;
|
| next_state_ = STATE_NONE;
|
| switch (state) {
|
| + case STATE_HANDLE_PROMISE:
|
| + CHECK_EQ(OK, rv);
|
| + rv = DoHandlePromise();
|
| + break;
|
| + case STATE_HANDLE_PROMISE_COMPLETE:
|
| + CHECK_EQ(OK, rv);
|
| + rv = DoHandlePromiseComplete(rv);
|
| + break;
|
| case STATE_REQUEST_STREAM:
|
| - rv = DoStreamRequest();
|
| + CHECK_EQ(OK, rv);
|
| + rv = DoRequestStream();
|
| + break;
|
| + case STATE_REQUEST_STREAM_COMPLETE:
|
| + rv = DoRequestStreamComplete(rv);
|
| break;
|
| case STATE_SET_REQUEST_PRIORITY:
|
| + CHECK_EQ(OK, rv);
|
| rv = DoSetRequestPriority();
|
| break;
|
| case STATE_WAIT_FOR_CONFIRMATION:
|
| @@ -639,22 +634,32 @@ int QuicHttpStream::DoLoop(int rv) {
|
| return rv;
|
| }
|
|
|
| -int QuicHttpStream::DoStreamRequest() {
|
| - int rv = stream_request_.StartRequest(
|
| +int QuicHttpStream::DoRequestStream() {
|
| + next_state_ = STATE_REQUEST_STREAM_COMPLETE;
|
| + return stream_request_.StartRequest(
|
| session_, &stream_,
|
| - base::Bind(&QuicHttpStream::OnStreamReady, weak_factory_.GetWeakPtr()));
|
| - if (rv == OK) {
|
| - stream_->SetDelegate(this);
|
| - if (request_info_->load_flags & LOAD_DISABLE_CONNECTION_MIGRATION) {
|
| - stream_->DisableConnectionMigration();
|
| - }
|
| - if (response_info_) {
|
| - next_state_ = STATE_SET_REQUEST_PRIORITY;
|
| - }
|
| - } else if (rv != ERR_IO_PENDING && !was_handshake_confirmed_) {
|
| - rv = ERR_QUIC_HANDSHAKE_FAILED;
|
| + base::Bind(&QuicHttpStream::OnIOComplete, weak_factory_.GetWeakPtr()));
|
| +}
|
| +
|
| +int QuicHttpStream::DoRequestStreamComplete(int rv) {
|
| + DCHECK(rv == OK || !stream_);
|
| + if (rv != OK)
|
| + return was_handshake_confirmed_ ? rv : ERR_QUIC_HANDSHAKE_FAILED;
|
| +
|
| + stream_->SetDelegate(this);
|
| + if (request_info_->load_flags & LOAD_DISABLE_CONNECTION_MIGRATION) {
|
| + stream_->DisableConnectionMigration();
|
| }
|
| - return rv;
|
| +
|
| + if (response_info_) {
|
| + // This happens in the case of a asynchronous push rendezvous
|
| + // that ultimately fails (e.g. vary failure). |response_info_|
|
| + // non-null implies that |DoRequestStream()| was called via
|
| + // |SendRequest()|.
|
| + next_state_ = STATE_SET_REQUEST_PRIORITY;
|
| + }
|
| +
|
| + return OK;
|
| }
|
|
|
| int QuicHttpStream::DoSetRequestPriority() {
|
|
|