Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1226)

Unified Diff: net/quic/chromium/quic_http_stream.cc

Issue 2777333002: Simplify the the logic for setting the final response status for a (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 e6200fbcb85942fa187e96ad5dbe5f004e078b34..594d67bc6ea46ff6803ab43960c64112d4dba2d8 100644
--- a/net/quic/chromium/quic_http_stream.cc
+++ b/net/quic/chromium/quic_http_stream.cc
@@ -50,14 +50,15 @@ QuicHttpStream::QuicHttpStream(
next_state_(STATE_NONE),
session_(session),
quic_version_(session->GetQuicVersion()),
- session_error_(OK),
+ session_error_(ERR_UNEXPECTED),
was_handshake_confirmed_(session->IsCryptoHandshakeConfirmed()),
stream_(nullptr),
request_info_(nullptr),
request_body_stream_(nullptr),
priority_(MINIMUM_PRIORITY),
response_info_(nullptr),
- response_status_(OK),
+ has_response_status_(false),
+ response_status_(ERR_UNEXPECTED),
response_headers_received_(false),
headers_bytes_received_(0),
headers_bytes_sent_(0),
@@ -66,6 +67,7 @@ QuicHttpStream::QuicHttpStream(
closed_is_first_stream_(false),
user_buffer_len_(0),
quic_connection_error_(QUIC_NO_ERROR),
+ quic_stream_error_(QUIC_STREAM_NO_ERROR),
port_migration_detected_(false),
found_promise_(false),
push_handle_(nullptr),
@@ -158,8 +160,7 @@ int QuicHttpStream::InitializeStream(const HttpRequestInfo* request_info,
CHECK(callback_.is_null());
DCHECK(!stream_);
if (!session_)
- return was_handshake_confirmed_ ? ERR_CONNECTION_CLOSED
- : ERR_QUIC_HANDSHAKE_FAILED;
+ return GetResponseStatus();
stream_net_log.AddEvent(
NetLogEventType::HTTP_STREAM_REQUEST_BOUND_TO_QUIC_SESSION,
@@ -250,10 +251,9 @@ int QuicHttpStream::SendRequest(const HttpRequestHeaders& request_headers,
UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.CookieSentToAccountsOverChannelId",
ssl_info.channel_id_sent);
}
- if ((!found_promise_ && !stream_) || !session_) {
- return was_handshake_confirmed_ ? ERR_CONNECTION_CLOSED
- : ERR_QUIC_HANDSHAKE_FAILED;
- }
+
+ if ((!found_promise_ && !stream_) || !session_)
+ return GetResponseStatus();
// Store the serialized request headers.
CreateSpdyHeadersFromHttpRequest(*request_info_, request_headers,
@@ -310,7 +310,7 @@ int QuicHttpStream::ReadResponseHeaders(const CompletionCallback& callback) {
CHECK(!callback.is_null());
if (stream_ == nullptr)
- return response_status_;
+ return GetResponseStatus();
// Check if we already have the response headers. If so, return synchronously.
if (response_headers_received_)
@@ -338,10 +338,9 @@ int QuicHttpStream::ReadResponseBody(IOBuffer* buf,
// anymore.
request_info_ = nullptr;
- if (!stream_) {
- // If the stream is already closed, there is no body to read.
- return response_status_;
- }
+ // If the stream is already closed, there is no body to read.
+ if (!stream_)
+ return GetResponseStatus();
int rv = ReadAvailableData(buf, buf_len);
if (rv != ERR_IO_PENDING)
@@ -353,13 +352,12 @@ int QuicHttpStream::ReadResponseBody(IOBuffer* buf,
return ERR_IO_PENDING;
}
-void QuicHttpStream::Close(bool not_reusable) {
- // Note: the not_reusable flag has no meaning for SPDY streams.
+void QuicHttpStream::Close(bool /*not_reusable*/) {
+ GetResponseStatus(); // Sets response_status_ if not already set.
+ // Note: the not_reusable flag has no meaning for QUIC streams.
if (stream_) {
stream_->SetDelegate(nullptr);
stream_->Reset(QUIC_STREAM_CANCELLED);
- response_status_ = was_handshake_confirmed_ ? ERR_CONNECTION_CLOSED
- : ERR_QUIC_HANDSHAKE_FAILED;
}
ResetStream();
}
@@ -438,6 +436,7 @@ void QuicHttpStream::OnHeadersAvailable(const SpdyHeaderBlock& headers,
// Close the read side. If the write side has been closed, this will
// invoke QuicHttpStream::OnClose to reset the stream.
stream_->OnFinRead();
+ SetResponseStatus(OK);
}
return;
}
@@ -469,35 +468,30 @@ void QuicHttpStream::OnDataAvailable() {
}
void QuicHttpStream::OnClose() {
- if (stream_->connection_error() != QUIC_NO_ERROR ||
- stream_->stream_error() != QUIC_STREAM_NO_ERROR) {
- response_status_ = was_handshake_confirmed_ ? ERR_QUIC_PROTOCOL_ERROR
- : ERR_QUIC_HANDSHAKE_FAILED;
- } else if (!response_headers_received_) {
- response_status_ = ERR_ABORTED;
- }
-
quic_connection_error_ = stream_->connection_error();
+ quic_stream_error_ = stream_->stream_error();
+ GetResponseStatus(); // Sets response_status_ if not already set.
+
ResetStream();
- if (in_loop_) {
- // If already in DoLoop(), |callback_| will be handled when DoLoop() exits.
+ // If already in DoLoop(), |callback_| will be handled when DoLoop() exits.
+ if (in_loop_)
return;
- }
+
if (!callback_.is_null()) {
- DoCallback(response_status_);
+ DoCallback(GetResponseStatus());
Buck 2017/03/28 21:19:57 Why not use a cached result from the call above?
Ryan Hamilton 2017/03/28 21:54:03 Done. Good idea! (Well, and then it changed as a
}
}
void QuicHttpStream::OnError(int error) {
ResetStream();
- response_status_ =
- was_handshake_confirmed_ ? error : ERR_QUIC_HANDSHAKE_FAILED;
+ session_error_ = error;
+ GetResponseStatus(); // Sets response_status_ if not already set.
if (in_loop_) {
// If already in DoLoop(), |callback_| will be handled when DoLoop() exits.
return;
}
if (!callback_.is_null())
- DoCallback(response_status_);
+ DoCallback(GetResponseStatus());
}
bool QuicHttpStream::HasSendHeadersComplete() {
@@ -520,9 +514,11 @@ void QuicHttpStream::OnSuccessfulVersionNegotiation(
}
void QuicHttpStream::OnSessionClosed(int error, bool port_migration_detected) {
- Close(false);
session_error_ = error;
port_migration_detected_ = port_migration_detected;
+ GetResponseStatus(); // Sets response_status_ if not already set.
+
+ Close(false);
session_.reset();
}
@@ -620,8 +616,10 @@ int QuicHttpStream::DoRequestStream() {
int QuicHttpStream::DoRequestStreamComplete(int rv) {
DCHECK(rv == OK || !stream_);
- if (rv != OK)
- return was_handshake_confirmed_ ? rv : ERR_QUIC_HANDSHAKE_FAILED;
+ if (rv != OK) {
+ session_error_ = rv;
+ return GetResponseStatus();
+ }
stream_->SetDelegate(this);
if (request_info_->load_flags & LOAD_DISABLE_CONNECTION_MIGRATION) {
@@ -668,7 +666,7 @@ int QuicHttpStream::DoWaitForConfirmationComplete(int rv) {
int QuicHttpStream::DoSendHeaders() {
if (!stream_)
- return ERR_UNEXPECTED;
+ return GetResponseStatus();
// Log the actual request with the URL Request's net log.
stream_net_log_.AddEvent(
@@ -692,7 +690,7 @@ int QuicHttpStream::DoSendHeadersComplete(int rv) {
// If the stream is already closed, don't read the request body.
if (!stream_)
- return response_status_;
+ return GetResponseStatus();
next_state_ = request_body_stream_ ? STATE_READ_REQUEST_BODY : STATE_OPEN;
@@ -709,7 +707,7 @@ int QuicHttpStream::DoReadRequestBody() {
int QuicHttpStream::DoReadRequestBodyComplete(int rv) {
// If the stream is already closed, don't continue.
if (!stream_)
- return response_status_;
+ return GetResponseStatus();
// |rv| is the result of read from the request body from the last call to
// DoSendBody().
@@ -731,7 +729,7 @@ int QuicHttpStream::DoReadRequestBodyComplete(int rv) {
int QuicHttpStream::DoSendBody() {
if (!stream_)
- return ERR_UNEXPECTED;
+ return GetResponseStatus();
CHECK(request_body_stream_);
CHECK(request_body_buf_.get());
@@ -755,7 +753,7 @@ int QuicHttpStream::DoSendBodyComplete(int rv) {
// If the stream is already closed, don't continue.
if (!stream_)
- return response_status_;
+ return GetResponseStatus();
request_body_buf_->DidConsume(request_body_buf_->BytesRemaining());
@@ -805,6 +803,7 @@ int QuicHttpStream::ReadAvailableData(IOBuffer* buf, int buf_len) {
if (stream_->IsDoneReading()) {
stream_->SetDelegate(nullptr);
stream_->OnFinRead();
+ SetResponseStatus(OK);
ResetStream();
}
return rv;
@@ -831,4 +830,42 @@ void QuicHttpStream::ResetStream() {
request_body_stream_->Reset();
}
+int QuicHttpStream::GetResponseStatus() {
+ if (!has_response_status_) {
+ SetResponseStatus(ComputeResponseStatus());
+ }
+
+ return response_status_;
+}
+
+void QuicHttpStream::SetResponseStatus(int response_status) {
+ has_response_status_ = true;
+ response_status_ = response_status;
+}
+
+int QuicHttpStream::ComputeResponseStatus() const {
+ DCHECK(!has_response_status_);
+
+ // If the handshake has failed this will be handled by the
+ // QuicStreamFactory and HttpStreamFactory to mark QUIC as broken.
+ if (!was_handshake_confirmed_)
+ return ERR_QUIC_HANDSHAKE_FAILED;
+
+ // If the session was aborted by a higher layer, simply use that error code.
+ if (session_error_ != ERR_UNEXPECTED)
+ return session_error_;
+
+ // For bening errors, return ERR_CONNECTION_CLOSED to permit
Buck 2017/03/28 21:19:57 s/bening/benign/
Ryan Hamilton 2017/03/28 21:54:03 Done.
+ // HttpNetworkTransaction to retry the request (assuming that
+ // headers have not been received, and this is not the firs stream).
Buck 2017/03/28 21:19:57 s/firs/first/
Ryan Hamilton 2017/03/28 21:54:03 Done.
+ if ((quic_connection_error_ == QUIC_CONNECTION_IP_POOLED ||
+ quic_connection_error_ == QUIC_NETWORK_IDLE_TIMEOUT ||
+ quic_connection_error_ == QUIC_NO_ERROR) &&
+ quic_stream_error_ == QUIC_STREAM_NO_ERROR) {
+ return ERR_CONNECTION_CLOSED;
+ }
+
+ return ERR_QUIC_PROTOCOL_ERROR;
+}
+
} // namespace net

Powered by Google App Engine
This is Rietveld 408576698