OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/quic/chromium/quic_http_stream.h" | 5 #include "net/quic/chromium/quic_http_stream.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
(...skipping 28 matching lines...) Expand all Loading... | |
39 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 39 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
40 dict->SetInteger("stream_id", stream_id); | 40 dict->SetInteger("stream_id", stream_id); |
41 dict->SetString("url", url->spec()); | 41 dict->SetString("url", url->spec()); |
42 return std::move(dict); | 42 return std::move(dict); |
43 } | 43 } |
44 | 44 |
45 } // namespace | 45 } // namespace |
46 | 46 |
47 QuicHttpStream::QuicHttpStream( | 47 QuicHttpStream::QuicHttpStream( |
48 const base::WeakPtr<QuicChromiumClientSession>& session, | 48 const base::WeakPtr<QuicChromiumClientSession>& session, |
49 HttpServerProperties* http_server_properties) | 49 HttpServerProperties* http_server_properties, |
50 bool mark_quic_broken_when_network_suspected) | |
50 : MultiplexedHttpStream(MultiplexedSessionHandle(session)), | 51 : MultiplexedHttpStream(MultiplexedSessionHandle(session)), |
51 next_state_(STATE_NONE), | 52 next_state_(STATE_NONE), |
52 session_(session), | 53 session_(session), |
54 server_id_(session->server_id()), | |
53 http_server_properties_(http_server_properties), | 55 http_server_properties_(http_server_properties), |
56 mark_quic_broken_when_network_suspected_( | |
57 mark_quic_broken_when_network_suspected), | |
54 quic_version_(session->GetQuicVersion()), | 58 quic_version_(session->GetQuicVersion()), |
55 session_error_(ERR_UNEXPECTED), | 59 session_error_(ERR_UNEXPECTED), |
56 was_handshake_confirmed_(session->IsCryptoHandshakeConfirmed()), | 60 was_handshake_confirmed_(session->IsCryptoHandshakeConfirmed()), |
57 stream_(nullptr), | 61 stream_(nullptr), |
58 request_info_(nullptr), | 62 request_info_(nullptr), |
59 request_body_stream_(nullptr), | 63 request_body_stream_(nullptr), |
60 priority_(MINIMUM_PRIORITY), | 64 priority_(MINIMUM_PRIORITY), |
61 response_info_(nullptr), | 65 response_info_(nullptr), |
62 has_response_status_(false), | 66 has_response_status_(false), |
63 response_status_(ERR_UNEXPECTED), | 67 response_status_(ERR_UNEXPECTED), |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
313 | 317 |
314 return rv > 0 ? OK : rv; | 318 return rv > 0 ? OK : rv; |
315 } | 319 } |
316 | 320 |
317 int QuicHttpStream::ReadResponseHeaders(const CompletionCallback& callback) { | 321 int QuicHttpStream::ReadResponseHeaders(const CompletionCallback& callback) { |
318 CHECK(callback_.is_null()); | 322 CHECK(callback_.is_null()); |
319 CHECK(!callback.is_null()); | 323 CHECK(!callback.is_null()); |
320 | 324 |
321 if (stream_ == nullptr) | 325 if (stream_ == nullptr) |
322 return GetResponseStatus(); | 326 return GetResponseStatus(); |
323 | |
324 // Check if we already have the response headers. If so, return synchronously. | 327 // Check if we already have the response headers. If so, return synchronously. |
325 if (response_headers_received_) | 328 if (response_headers_received_) |
326 return OK; | 329 return OK; |
327 | 330 |
328 // Still waiting for the response, return IO_PENDING. | 331 // Still waiting for the response, return IO_PENDING. |
329 CHECK(callback_.is_null()); | 332 CHECK(callback_.is_null()); |
330 callback_ = callback; | 333 callback_ = callback; |
331 return ERR_IO_PENDING; | 334 return ERR_IO_PENDING; |
332 } | 335 } |
333 | 336 |
(...skipping 21 matching lines...) Expand all Loading... | |
355 if (rv != ERR_IO_PENDING) | 358 if (rv != ERR_IO_PENDING) |
356 return rv; | 359 return rv; |
357 | 360 |
358 callback_ = callback; | 361 callback_ = callback; |
359 user_buffer_ = buf; | 362 user_buffer_ = buf; |
360 user_buffer_len_ = buf_len; | 363 user_buffer_len_ = buf_len; |
361 return ERR_IO_PENDING; | 364 return ERR_IO_PENDING; |
362 } | 365 } |
363 | 366 |
364 void QuicHttpStream::Close(bool /*not_reusable*/) { | 367 void QuicHttpStream::Close(bool /*not_reusable*/) { |
368 session_error_ = ERR_ABORTED; | |
Jana
2017/04/06 02:29:18
Why this change?
| |
365 SaveResponseStatus(); | 369 SaveResponseStatus(); |
366 // Note: the not_reusable flag has no meaning for QUIC streams. | 370 // Note: the not_reusable flag has no meaning for QUIC streams. |
367 if (stream_) { | 371 if (stream_) { |
368 stream_->SetDelegate(nullptr); | 372 stream_->SetDelegate(nullptr); |
369 stream_->Reset(QUIC_STREAM_CANCELLED); | 373 stream_->Reset(QUIC_STREAM_CANCELLED); |
370 } | 374 } |
371 ResetStream(); | 375 ResetStream(); |
372 } | 376 } |
373 | 377 |
374 bool QuicHttpStream::IsResponseBodyComplete() const { | 378 bool QuicHttpStream::IsResponseBodyComplete() const { |
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
847 void QuicHttpStream::SaveResponseStatus() { | 851 void QuicHttpStream::SaveResponseStatus() { |
848 if (!has_response_status_) | 852 if (!has_response_status_) |
849 SetResponseStatus(ComputeResponseStatus()); | 853 SetResponseStatus(ComputeResponseStatus()); |
850 } | 854 } |
851 | 855 |
852 void QuicHttpStream::SetResponseStatus(int response_status) { | 856 void QuicHttpStream::SetResponseStatus(int response_status) { |
853 has_response_status_ = true; | 857 has_response_status_ = true; |
854 response_status_ = response_status; | 858 response_status_ = response_status; |
855 } | 859 } |
856 | 860 |
861 // Returns true if |error| is possibly caused by the network | |
862 bool IsPossiblyNetworkError(QuicErrorCode error) { | |
863 return error == QUIC_NETWORK_IDLE_TIMEOUT || | |
864 error == QUIC_TIMEOUTS_WITH_OPEN_STREAMS || | |
865 error == QUIC_TOO_MANY_RTOS; | |
Jana
2017/04/06 02:29:18
I'm surprised to see NETWORK_IDLE_TIMEOUT treated
Ryan Hamilton
2017/04/06 03:43:38
The objective is to mark QUIC as broken when the n
Jana
2017/04/06 23:55:25
Thanks for the explanation -- if you could add a c
| |
866 } | |
867 | |
857 int QuicHttpStream::ComputeResponseStatus() const { | 868 int QuicHttpStream::ComputeResponseStatus() const { |
858 DCHECK(!has_response_status_); | 869 DCHECK(!has_response_status_); |
859 | 870 |
860 // If the handshake has failed this will be handled by the | 871 // If the handshake has failed this will be handled by the QuicStreamFactory |
861 // QuicStreamFactory and HttpStreamFactory to mark QUIC as broken. | 872 // and HttpStreamFactory to mark QUIC as broken if TCP is actually working. |
862 if (!was_handshake_confirmed_) | 873 if (!was_handshake_confirmed_) |
863 return ERR_QUIC_HANDSHAKE_FAILED; | 874 return ERR_QUIC_HANDSHAKE_FAILED; |
864 | 875 |
865 // If the session was aborted by a higher layer, simply use that error code. | 876 // If the session was aborted by a higher layer, simply use that error code. |
866 if (session_error_ != ERR_UNEXPECTED) | 877 if (session_error_ != ERR_UNEXPECTED) |
867 return session_error_; | 878 return session_error_; |
868 | 879 |
869 // If |response_info_| is null then the request has not been sent, so | 880 // If |response_info_| is null then the request has not been sent, so |
870 // return ERR_CONNECTION_CLOSED to permit HttpNetworkTransaction to | 881 // return ERR_CONNECTION_CLOSED to permit HttpNetworkTransaction to |
871 // retry the request. | 882 // retry the request. |
872 if (!response_info_) | 883 if (!response_info_) |
873 return ERR_CONNECTION_CLOSED; | 884 return ERR_CONNECTION_CLOSED; |
874 | 885 |
886 // Explicit stream error are always fatal. | |
Jana
2017/04/06 02:29:18
nit: error -> errors
I also don't understand this
Ryan Hamilton
2017/04/06 03:43:38
So it's a bit more complicated than that :/
There
| |
887 if (quic_stream_error_ != QUIC_STREAM_NO_ERROR && | |
888 quic_stream_error_ != QUIC_STREAM_CONNECTION_ERROR) { | |
889 return ERR_QUIC_PROTOCOL_ERROR; | |
890 } | |
891 | |
892 DCHECK_NE(QUIC_HANDSHAKE_TIMEOUT, quic_connection_error_); | |
Jana
2017/04/06 02:29:18
What's the point of this DCHECK? The branch on lin
Ryan Hamilton
2017/04/06 03:43:38
That's why it's a DCHECK :)
QUIC_HANDSHAKE_TIMEOU
Jana
2017/04/06 23:55:25
Acknowledged.
| |
893 | |
894 if (!mark_quic_broken_when_network_suspected_) | |
895 return ERR_QUIC_PROTOCOL_ERROR; | |
896 | |
897 // Error codes which could not have been caused by the network are fatal. | |
Jana
2017/04/06 02:29:18
the use of "fatal" is confusing... perhaps you mea
Ryan Hamilton
2017/04/06 03:43:38
By "fatal" I mean fatal to the request. Happy to h
| |
898 if (!IsPossiblyNetworkError(quic_connection_error_)) | |
899 return ERR_QUIC_PROTOCOL_ERROR; | |
900 | |
901 // For error codes which could have been generated by "the network", mark | |
Jana
2017/04/06 02:29:18
odd to say that error codes could have been genera
Ryan Hamilton
2017/04/06 03:43:38
Done.
| |
902 // QUIC as broken. | |
903 HistogramBrokenAlternateProtocolLocation( | |
904 BROKEN_ALTERNATE_PROTOCOL_LOCATION_QUIC_HTTP_STREAM); | |
905 http_server_properties_->MarkAlternativeServiceBroken( | |
906 AlternativeService(kProtoQUIC, server_id_.host(), server_id_.port())); | |
907 // If the headesr have not been received, return ERR_QUIC_BROKEN_ERROR to | |
Jana
2017/04/06 02:29:18
nit: "headers"
Ryan Hamilton
2017/04/06 03:43:38
Done.
Ryan Hamilton
2017/04/06 03:43:38
Done.
| |
908 // permit HttpNetworkTransaction to retry the request over TCP. | |
909 if (!response_headers_received_) | |
910 return ERR_QUIC_BROKEN_ERROR; | |
911 | |
875 return ERR_QUIC_PROTOCOL_ERROR; | 912 return ERR_QUIC_PROTOCOL_ERROR; |
876 } | 913 } |
877 | 914 |
878 } // namespace net | 915 } // namespace net |
OLD | NEW |