| 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 4debbec04ae9181168f55064813d1167476bc7ee..f52e00ed74ad83caa73f86082a29b1f6b99f86ce 100644
|
| --- a/net/quic/chromium/quic_http_stream.cc
|
| +++ b/net/quic/chromium/quic_http_stream.cc
|
| @@ -50,6 +50,7 @@ QuicHttpStream::QuicHttpStream(
|
| : MultiplexedHttpStream(MultiplexedSessionHandle(session)),
|
| next_state_(STATE_NONE),
|
| session_(session),
|
| + server_id_(session->server_id()),
|
| http_server_properties_(http_server_properties),
|
| quic_version_(session->GetQuicVersion()),
|
| session_error_(ERR_UNEXPECTED),
|
| @@ -322,7 +323,6 @@ int QuicHttpStream::ReadResponseHeaders(const CompletionCallback& callback) {
|
|
|
| if (stream_ == nullptr)
|
| return GetResponseStatus();
|
| -
|
| // Check if we already have the response headers. If so, return synchronously.
|
| if (response_headers_received_)
|
| return OK;
|
| @@ -364,6 +364,7 @@ int QuicHttpStream::ReadResponseBody(IOBuffer* buf,
|
| }
|
|
|
| void QuicHttpStream::Close(bool /*not_reusable*/) {
|
| + session_error_ = ERR_ABORTED;
|
| SaveResponseStatus();
|
| // Note: the not_reusable flag has no meaning for QUIC streams.
|
| if (stream_) {
|
| @@ -859,8 +860,8 @@ void QuicHttpStream::SetResponseStatus(int 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 the handshake has failed this will be handled by the QuicStreamFactory
|
| + // and HttpStreamFactory to mark QUIC as broken if TCP is actually working.
|
| if (!was_handshake_confirmed_)
|
| return ERR_QUIC_HANDSHAKE_FAILED;
|
|
|
| @@ -874,6 +875,23 @@ int QuicHttpStream::ComputeResponseStatus() const {
|
| if (!response_info_)
|
| 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) {
|
| + return ERR_QUIC_PROTOCOL_ERROR;
|
| + }
|
| +
|
| + DCHECK_NE(QUIC_HANDSHAKE_TIMEOUT, quic_connection_error_);
|
| +
|
| + // If the headers have not been received and QUIC is now broken, return
|
| + // ERR_QUIC_BROKEN_ERROR to permit HttpNetworkTransaction to retry the request
|
| + // over TCP.
|
| + if (!response_headers_received_ &&
|
| + http_server_properties_->IsAlternativeServiceBroken(AlternativeService(
|
| + kProtoQUIC, server_id_.host(), server_id_.port()))) {
|
| + return ERR_QUIC_BROKEN_ERROR;
|
| + }
|
| +
|
| return ERR_QUIC_PROTOCOL_ERROR;
|
| }
|
|
|
|
|