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 c2caf5cb16e4a683c62e8053978d43601ba37af1..140dbc0af1f2284cfa956dcb514caa5cc1dc5237 100644 |
--- a/net/quic/chromium/quic_http_stream.cc |
+++ b/net/quic/chromium/quic_http_stream.cc |
@@ -64,8 +64,6 @@ QuicHttpStream::QuicHttpStream( |
closed_is_first_stream_(false), |
user_buffer_len_(0), |
session_error_(ERR_UNEXPECTED), |
- quic_connection_error_(QUIC_NO_ERROR), |
- quic_stream_error_(QUIC_STREAM_NO_ERROR), |
found_promise_(false), |
push_handle_(nullptr), |
in_loop_(false), |
@@ -107,8 +105,7 @@ bool QuicHttpStream::CheckVary(const SpdyHeaderBlock& client_request, |
void QuicHttpStream::OnRendezvousResult(QuicSpdyStream* stream) { |
push_handle_ = nullptr; |
if (stream) { |
- stream_ = |
- static_cast<QuicChromiumClientStream*>(stream)->CreateHandle(this); |
+ stream_ = static_cast<QuicChromiumClientStream*>(stream)->CreateHandle(); |
} |
// callback_ should only be non-null in the case of asynchronous |
@@ -193,7 +190,7 @@ int QuicHttpStream::InitializeStream(const HttpRequestInfo* request_info, |
if (rv == ERR_IO_PENDING) |
callback_ = callback; |
- return rv; |
+ return MapStreamError(rv); |
} |
int QuicHttpStream::DoHandlePromise() { |
@@ -305,16 +302,13 @@ int QuicHttpStream::SendRequest(const HttpRequestHeaders& request_headers, |
if (rv == ERR_IO_PENDING) |
callback_ = callback; |
- return rv > 0 ? OK : rv; |
+ return rv > 0 ? OK : MapStreamError(rv); |
} |
int QuicHttpStream::ReadResponseHeaders(const CompletionCallback& callback) { |
CHECK(callback_.is_null()); |
CHECK(!callback.is_null()); |
- if (stream_ == nullptr) |
- return GetResponseStatus(); |
- |
int rv = stream_->ReadInitialHeaders( |
&response_header_block_, |
base::Bind(&QuicHttpStream::OnReadResponseHeadersComplete, |
@@ -328,7 +322,7 @@ int QuicHttpStream::ReadResponseHeaders(const CompletionCallback& callback) { |
} |
if (rv < 0) |
- return rv; |
+ return MapStreamError(rv); |
// Check if we already have the response headers. If so, return synchronously. |
if (response_headers_received_) |
@@ -355,7 +349,7 @@ int QuicHttpStream::ReadResponseBody(IOBuffer* buf, |
request_info_ = nullptr; |
// If the stream is already closed, there is no body to read. |
- if (!stream_) |
+ if (stream_->IsDoneReading()) |
return GetResponseStatus(); |
int rv = stream_->ReadBody(buf, buf_len, |
@@ -369,7 +363,7 @@ int QuicHttpStream::ReadResponseBody(IOBuffer* buf, |
} |
if (rv < 0) |
- return rv; |
+ return MapStreamError(rv); |
return HandleReadComplete(rv); |
} |
@@ -378,15 +372,13 @@ void QuicHttpStream::Close(bool /*not_reusable*/) { |
session_error_ = ERR_ABORTED; |
SaveResponseStatus(); |
// Note: the not_reusable flag has no meaning for QUIC streams. |
- if (stream_) { |
- stream_->ClearDelegate(); |
+ if (stream_) |
stream_->Reset(QUIC_STREAM_CANCELLED); |
- } |
ResetStream(); |
} |
bool QuicHttpStream::IsResponseBodyComplete() const { |
- return next_state_ == STATE_OPEN && !stream_; |
+ return next_state_ == STATE_OPEN && stream_->IsDoneReading(); |
} |
bool QuicHttpStream::IsConnectionReused() const { |
@@ -445,8 +437,8 @@ void QuicHttpStream::PopulateNetErrorDetails(NetErrorDetails* details) { |
details->connection_info = |
ConnectionInfoFromQuicVersion(quic_session()->GetQuicVersion()); |
quic_session()->PopulateNetErrorDetails(details); |
- if (quic_session()->IsCryptoHandshakeConfirmed()) |
- details->quic_connection_error = quic_connection_error_; |
+ if (quic_session()->IsCryptoHandshakeConfirmed() && stream_) |
+ details->quic_connection_error = stream_->connection_error(); |
} |
void QuicHttpStream::SetPriority(RequestPriority priority) { |
@@ -466,9 +458,6 @@ void QuicHttpStream::OnReadResponseHeadersComplete(int rv) { |
} |
void QuicHttpStream::ReadTrailingHeaders() { |
- if (!stream_) |
- return; |
- |
int rv = stream_->ReadTrailingHeaders( |
&trailing_header_block_, |
base::Bind(&QuicHttpStream::OnReadTrailingHeadersComplete, |
@@ -492,33 +481,6 @@ void QuicHttpStream::OnReadTrailingHeadersComplete(int rv) { |
} |
} |
-void QuicHttpStream::OnClose() { |
- quic_connection_error_ = stream_->connection_error(); |
- quic_stream_error_ = stream_->stream_error(); |
- SaveResponseStatus(); |
- |
- ResetStream(); |
- // If already in DoLoop(), |callback_| will be handled when DoLoop() exits. |
- if (in_loop_) |
- return; |
- |
- if (!callback_.is_null()) { |
- DoCallback(GetResponseStatus()); |
- } |
-} |
- |
-void QuicHttpStream::OnError(int error) { |
- ResetStream(); |
- session_error_ = error; |
- SaveResponseStatus(); |
- if (in_loop_) { |
- // If already in DoLoop(), |callback_| will be handled when DoLoop() exits. |
- return; |
- } |
- if (!callback_.is_null()) |
- DoCallback(GetResponseStatus()); |
-} |
- |
void QuicHttpStream::OnIOComplete(int rv) { |
rv = DoLoop(rv); |
@@ -534,7 +496,7 @@ void QuicHttpStream::DoCallback(int rv) { |
// The client callback can do anything, including destroying this class, |
// so any pending callback must be issued after everything else is done. |
- base::ResetAndReturn(&callback_).Run(rv); |
+ base::ResetAndReturn(&callback_).Run(MapStreamError(rv)); |
} |
int QuicHttpStream::DoLoop(int rv) { |
@@ -611,7 +573,7 @@ int QuicHttpStream::DoRequestStreamComplete(int rv) { |
return GetResponseStatus(); |
} |
- stream_ = quic_session()->ReleaseStream(this); |
+ stream_ = quic_session()->ReleaseStream(); |
if (request_info_->load_flags & LOAD_DISABLE_CONNECTION_MIGRATION) { |
stream_->DisableConnectionMigration(); |
} |
@@ -638,9 +600,6 @@ int QuicHttpStream::DoSetRequestPriority() { |
} |
int QuicHttpStream::DoSendHeaders() { |
- if (!stream_) |
- return GetResponseStatus(); |
- |
// Log the actual request with the URL Request's net log. |
stream_net_log_.AddEvent( |
NetLogEventType::HTTP_TRANSACTION_QUIC_SEND_REQUEST_HEADERS, |
@@ -661,10 +620,6 @@ int QuicHttpStream::DoSendHeadersComplete(int rv) { |
if (rv < 0) |
return rv; |
- // If the stream is already closed, don't read the request body. |
- if (!stream_) |
- return GetResponseStatus(); |
- |
next_state_ = request_body_stream_ ? STATE_READ_REQUEST_BODY : STATE_OPEN; |
return OK; |
@@ -678,14 +633,9 @@ int QuicHttpStream::DoReadRequestBody() { |
} |
int QuicHttpStream::DoReadRequestBodyComplete(int rv) { |
- // If the stream is already closed, don't continue. |
- if (!stream_) |
- return GetResponseStatus(); |
- |
// |rv| is the result of read from the request body from the last call to |
// DoSendBody(). |
if (rv < 0) { |
- stream_->ClearDelegate(); |
stream_->Reset(QUIC_ERROR_PROCESSING_STREAM); |
ResetStream(); |
return rv; |
@@ -701,9 +651,6 @@ int QuicHttpStream::DoReadRequestBodyComplete(int rv) { |
} |
int QuicHttpStream::DoSendBody() { |
- if (!stream_) |
- return GetResponseStatus(); |
- |
CHECK(request_body_stream_); |
CHECK(request_body_buf_.get()); |
const bool eof = request_body_stream_->IsEOF(); |
@@ -724,10 +671,6 @@ int QuicHttpStream::DoSendBodyComplete(int rv) { |
if (rv < 0) |
return rv; |
- // If the stream is already closed, don't continue. |
- if (!stream_) |
- return GetResponseStatus(); |
- |
request_body_buf_->DidConsume(request_body_buf_->BytesRemaining()); |
if (!request_body_stream_->IsEOF()) { |
@@ -770,6 +713,12 @@ int QuicHttpStream::ProcessResponseHeaders(const SpdyHeaderBlock& headers) { |
FROM_HERE, base::Bind(&QuicHttpStream::ReadTrailingHeaders, |
weak_factory_.GetWeakPtr())); |
+ if (stream_->IsDoneReading()) { |
+ session_error_ = OK; |
+ SaveResponseStatus(); |
+ stream_->OnFinRead(); |
+ } |
+ |
return OK; |
} |
@@ -783,7 +732,6 @@ void QuicHttpStream::OnReadBodyComplete(int rv) { |
int QuicHttpStream::HandleReadComplete(int rv) { |
if (stream_->IsDoneReading()) { |
- stream_->ClearDelegate(); |
stream_->OnFinRead(); |
SetResponseStatus(OK); |
ResetStream(); |
@@ -804,13 +752,20 @@ void QuicHttpStream::ResetStream() { |
if (!stream_) |
return; |
+ |
DCHECK_LE(stream_->NumBytesConsumed(), stream_->stream_bytes_read()); |
// Only count the uniquely received bytes. |
closed_stream_received_bytes_ = stream_->NumBytesConsumed(); |
closed_stream_sent_bytes_ = stream_->stream_bytes_written(); |
closed_is_first_stream_ = stream_->IsFirstStream(); |
- stream_->ClearDelegate(); |
- stream_ = nullptr; |
+} |
+ |
+int QuicHttpStream::MapStreamError(int rv) { |
+ if (rv == ERR_QUIC_PROTOCOL_ERROR && |
+ !quic_session()->IsCryptoHandshakeConfirmed()) { |
+ return ERR_QUIC_HANDSHAKE_FAILED; |
+ } |
+ return rv; |
} |
int QuicHttpStream::GetResponseStatus() { |
@@ -847,13 +802,11 @@ int QuicHttpStream::ComputeResponseStatus() const { |
return ERR_CONNECTION_CLOSED; |
// Explicit stream error are always fatal. |
- if (quic_stream_error_ != QUIC_STREAM_NO_ERROR && |
- quic_stream_error_ != QUIC_STREAM_CONNECTION_ERROR) { |
+ if (stream_->stream_error() != QUIC_STREAM_NO_ERROR && |
+ stream_->stream_error() != QUIC_STREAM_CONNECTION_ERROR) { |
return ERR_QUIC_PROTOCOL_ERROR; |
} |
- DCHECK_NE(QUIC_HANDSHAKE_TIMEOUT, quic_connection_error_); |
- |
return ERR_QUIC_PROTOCOL_ERROR; |
} |