quic_chromium_client_stream.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  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
  3. // found in the LICENSE file.
  4. //
  5. // NOTE: This code is not shared between Google and Chrome.
  6. #ifndef NET_QUIC_QUIC_CHROMIUM_CLIENT_STREAM_H_
  7. #define NET_QUIC_QUIC_CHROMIUM_CLIENT_STREAM_H_
  8. #include <stddef.h>
  9. #include <memory>
  10. #include <vector>
  11. #include "base/callback_forward.h"
  12. #include "base/containers/circular_deque.h"
  13. #include "base/memory/raw_ptr.h"
  14. #include "base/time/time.h"
  15. #include "net/base/completion_once_callback.h"
  16. #include "net/base/idempotency.h"
  17. #include "net/base/ip_endpoint.h"
  18. #include "net/base/net_export.h"
  19. #include "net/base/upload_data_stream.h"
  20. #include "net/http/http_request_info.h"
  21. #include "net/http/http_response_info.h"
  22. #include "net/http/http_stream.h"
  23. #include "net/log/net_log_with_source.h"
  24. #include "net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_stream.h"
  25. #include "net/third_party/quiche/src/quiche/spdy/core/http2_header_block.h"
  26. #include "net/traffic_annotation/network_traffic_annotation.h"
  27. namespace quic {
  28. class QuicSpdyClientSessionBase;
  29. } // namespace quic
  30. namespace net {
  31. // A client-initiated ReliableQuicStream. Instances of this class
  32. // are owned by the QuicClientSession which created them.
  33. class NET_EXPORT_PRIVATE QuicChromiumClientStream
  34. : public quic::QuicSpdyStream {
  35. public:
  36. // Wrapper for interacting with the session in a restricted fashion.
  37. class NET_EXPORT_PRIVATE Handle {
  38. public:
  39. Handle(const Handle&) = delete;
  40. Handle& operator=(const Handle&) = delete;
  41. ~Handle();
  42. // Returns true if the stream is still connected.
  43. bool IsOpen() { return stream_ != nullptr; }
  44. // Reads initial or 103 Early Hints headers into |header_block| and returns
  45. // the length of the HEADERS frame which contained them. If headers are not
  46. // available, returns ERR_IO_PENDING and will invoke |callback|
  47. // asynchronously when the headers arrive.
  48. // TODO(rch): Invoke |callback| when there is a stream or connection error
  49. // instead of calling OnClose() or OnError().
  50. int ReadInitialHeaders(spdy::Http2HeaderBlock* header_block,
  51. CompletionOnceCallback callback);
  52. // Reads at most |buffer_len| bytes of body into |buffer| and returns the
  53. // number of bytes read. If body is not available, returns ERR_IO_PENDING
  54. // and will invoke |callback| asynchronously when data arrive.
  55. // TODO(rch): Invoke |callback| when there is a stream or connection error
  56. // instead of calling OnClose() or OnError().
  57. int ReadBody(IOBuffer* buffer,
  58. int buffer_len,
  59. CompletionOnceCallback callback);
  60. // Reads trailing headers into |header_block| and returns the length of
  61. // the HEADERS frame which contained them. If headers are not available,
  62. // returns ERR_IO_PENDING and will invoke |callback| asynchronously when
  63. // the headers arrive.
  64. // TODO(rch): Invoke |callback| when there is a stream or connection error
  65. // instead of calling OnClose() or OnError().
  66. int ReadTrailingHeaders(spdy::Http2HeaderBlock* header_block,
  67. CompletionOnceCallback callback);
  68. // Writes |header_block| to the peer. Closes the write side if |fin| is
  69. // true. If non-null, |ack_notifier_delegate| will be notified when the
  70. // headers are ACK'd by the peer. Returns a net error code if there is
  71. // an error writing the headers, or the number of bytes written on
  72. // success. Will not return ERR_IO_PENDING.
  73. int WriteHeaders(
  74. spdy::Http2HeaderBlock header_block,
  75. bool fin,
  76. quiche::QuicheReferenceCountedPointer<quic::QuicAckListenerInterface>
  77. ack_notifier_delegate);
  78. // Writes |data| to the peer. Closes the write side if |fin| is true.
  79. // If the data could not be written immediately, returns ERR_IO_PENDING
  80. // and invokes |callback| asynchronously when the write completes.
  81. int WriteStreamData(base::StringPiece data,
  82. bool fin,
  83. CompletionOnceCallback callback);
  84. // Same as WriteStreamData except it writes data from a vector of IOBuffers,
  85. // with the length of each buffer at the corresponding index in |lengths|.
  86. int WritevStreamData(const std::vector<scoped_refptr<IOBuffer>>& buffers,
  87. const std::vector<int>& lengths,
  88. bool fin,
  89. CompletionOnceCallback callback);
  90. // Reads at most |buf_len| bytes into |buf|. Returns the number of bytes
  91. // read.
  92. int Read(IOBuffer* buf, int buf_len);
  93. // Called to notify the stream when the final incoming data is read.
  94. void OnFinRead();
  95. // Prevents the connection from migrating to a cellular network while this
  96. // stream is open.
  97. void DisableConnectionMigrationToCellularNetwork();
  98. // Sets the precedence of the stream to |precedence|.
  99. void SetPriority(const spdy::SpdyStreamPrecedence& precedence);
  100. // Sends a RST_STREAM frame to the peer and closes the streams.
  101. void Reset(quic::QuicRstStreamErrorCode error_code);
  102. quic::QuicStreamId id() const;
  103. quic::QuicErrorCode connection_error() const;
  104. quic::QuicRstStreamErrorCode stream_error() const;
  105. bool fin_sent() const;
  106. bool fin_received() const;
  107. uint64_t stream_bytes_read() const;
  108. uint64_t stream_bytes_written() const;
  109. size_t NumBytesConsumed() const;
  110. bool HasBytesToRead() const;
  111. bool IsDoneReading() const;
  112. bool IsFirstStream() const;
  113. base::TimeTicks first_early_hints_time() const {
  114. return first_early_hints_time_;
  115. }
  116. base::TimeTicks headers_received_start_time() const {
  117. return headers_received_start_time_;
  118. }
  119. // TODO(rch): Move these test-only methods to a peer, or else remove.
  120. void OnPromiseHeaderList(quic::QuicStreamId promised_id,
  121. size_t frame_len,
  122. const quic::QuicHeaderList& header_list);
  123. bool can_migrate_to_cellular_network();
  124. const NetLogWithSource& net_log() const;
  125. // Sets the idempotency of the request.
  126. void SetRequestIdempotency(Idempotency idempotency);
  127. // Returns the idempotency of the request.
  128. Idempotency GetRequestIdempotency() const;
  129. private:
  130. friend class QuicChromiumClientStream;
  131. // Constucts a new Handle for |stream|.
  132. explicit Handle(QuicChromiumClientStream* stream);
  133. // Methods invoked by the stream.
  134. void OnEarlyHintsAvailable();
  135. void OnInitialHeadersAvailable();
  136. void OnTrailingHeadersAvailable();
  137. void OnDataAvailable();
  138. void OnCanWrite();
  139. void OnClose();
  140. void OnError(int error);
  141. // Invokes async IO callbacks because of |error|.
  142. void InvokeCallbacksOnClose(int error);
  143. // Saves various fields from the stream before the stream goes away.
  144. void SaveState();
  145. void SetCallback(CompletionOnceCallback new_callback,
  146. CompletionOnceCallback* callback);
  147. void ResetAndRun(CompletionOnceCallback callback, int rv);
  148. int HandleIOComplete(int rv);
  149. raw_ptr<QuicChromiumClientStream> stream_; // Unowned.
  150. bool may_invoke_callbacks_ = true; // True when callbacks may be invoked.
  151. // Callback to be invoked when ReadInitialHeaders completes asynchronously.
  152. CompletionOnceCallback read_headers_callback_;
  153. // Provided by the owner of this handle when ReadInitialHeaders is called.
  154. raw_ptr<spdy::Http2HeaderBlock> read_headers_buffer_ = nullptr;
  155. // Callback to be invoked when ReadBody completes asynchronously.
  156. CompletionOnceCallback read_body_callback_;
  157. raw_ptr<IOBuffer> read_body_buffer_;
  158. int read_body_buffer_len_ = 0;
  159. // Callback to be invoked when WriteStreamData or WritevStreamData completes
  160. // asynchronously.
  161. CompletionOnceCallback write_callback_;
  162. quic::QuicStreamId id_;
  163. quic::QuicErrorCode connection_error_;
  164. quic::QuicRstStreamErrorCode stream_error_;
  165. bool fin_sent_;
  166. bool fin_received_;
  167. uint64_t stream_bytes_read_;
  168. uint64_t stream_bytes_written_;
  169. bool is_done_reading_;
  170. bool is_first_stream_;
  171. size_t num_bytes_consumed_;
  172. Idempotency idempotency_ = DEFAULT_IDEMPOTENCY;
  173. int net_error_ = ERR_UNEXPECTED;
  174. NetLogWithSource net_log_;
  175. // The time at which the first 103 Early Hints response is received.
  176. base::TimeTicks first_early_hints_time_;
  177. base::TimeTicks headers_received_start_time_;
  178. base::WeakPtrFactory<Handle> weak_factory_{this};
  179. };
  180. QuicChromiumClientStream(
  181. quic::QuicStreamId id,
  182. quic::QuicSpdyClientSessionBase* session,
  183. quic::StreamType type,
  184. const NetLogWithSource& net_log,
  185. const NetworkTrafficAnnotationTag& traffic_annotation);
  186. QuicChromiumClientStream(
  187. quic::PendingStream* pending,
  188. quic::QuicSpdyClientSessionBase* session,
  189. const NetLogWithSource& net_log,
  190. const NetworkTrafficAnnotationTag& traffic_annotation);
  191. QuicChromiumClientStream(const QuicChromiumClientStream&) = delete;
  192. QuicChromiumClientStream& operator=(const QuicChromiumClientStream&) = delete;
  193. ~QuicChromiumClientStream() override;
  194. // quic::QuicSpdyStream
  195. void OnInitialHeadersComplete(
  196. bool fin,
  197. size_t frame_len,
  198. const quic::QuicHeaderList& header_list) override;
  199. void OnTrailingHeadersComplete(
  200. bool fin,
  201. size_t frame_len,
  202. const quic::QuicHeaderList& header_list) override;
  203. void OnPromiseHeaderList(quic::QuicStreamId promised_id,
  204. size_t frame_len,
  205. const quic::QuicHeaderList& header_list) override;
  206. void OnBodyAvailable() override;
  207. void OnClose() override;
  208. void OnCanWrite() override;
  209. size_t WriteHeaders(
  210. spdy::Http2HeaderBlock header_block,
  211. bool fin,
  212. quiche::QuicheReferenceCountedPointer<quic::QuicAckListenerInterface>
  213. ack_listener) override;
  214. // While the server's set_priority shouldn't be called externally, the creator
  215. // of client-side streams should be able to set the priority.
  216. using quic::QuicSpdyStream::SetPriority;
  217. // Writes |data| to the peer and closes the write side if |fin| is true.
  218. // Returns true if the data have been fully written. If the data was not fully
  219. // written, returns false and OnCanWrite() will be invoked later.
  220. bool WriteStreamData(absl::string_view data, bool fin);
  221. // Same as WriteStreamData except it writes data from a vector of IOBuffers,
  222. // with the length of each buffer at the corresponding index in |lengths|.
  223. bool WritevStreamData(const std::vector<scoped_refptr<IOBuffer>>& buffers,
  224. const std::vector<int>& lengths,
  225. bool fin);
  226. // Creates a new Handle for this stream. Must only be called once.
  227. std::unique_ptr<QuicChromiumClientStream::Handle> CreateHandle();
  228. // Clears |handle_| from this stream.
  229. void ClearHandle();
  230. // Notifies the stream handle of error, but doesn't close the stream.
  231. void OnError(int error);
  232. // Reads at most |buf_len| bytes into |buf|. Returns the number of bytes read.
  233. int Read(IOBuffer* buf, int buf_len);
  234. const NetLogWithSource& net_log() const { return net_log_; }
  235. // Prevents this stream from migrating to a cellular network. May be reset
  236. // when connection migrates to a cellular network.
  237. void DisableConnectionMigrationToCellularNetwork();
  238. bool can_migrate_to_cellular_network() {
  239. return can_migrate_to_cellular_network_;
  240. }
  241. // True if this stream is the first data stream created on this session.
  242. bool IsFirstStream();
  243. int DeliverEarlyHints(spdy::Http2HeaderBlock* header_block);
  244. int DeliverInitialHeaders(spdy::Http2HeaderBlock* header_block);
  245. bool DeliverTrailingHeaders(spdy::Http2HeaderBlock* header_block,
  246. int* frame_len);
  247. using quic::QuicSpdyStream::HasBufferedData;
  248. using quic::QuicStream::sequencer;
  249. private:
  250. void NotifyHandleOfInitialHeadersAvailableLater();
  251. void NotifyHandleOfInitialHeadersAvailable();
  252. void NotifyHandleOfTrailingHeadersAvailableLater();
  253. void NotifyHandleOfTrailingHeadersAvailable();
  254. void NotifyHandleOfDataAvailableLater();
  255. void NotifyHandleOfDataAvailable();
  256. NetLogWithSource net_log_;
  257. raw_ptr<Handle> handle_ = nullptr;
  258. // True when initial headers have been sent.
  259. bool initial_headers_sent_ = false;
  260. raw_ptr<quic::QuicSpdyClientSessionBase> session_;
  261. quic::QuicTransportVersion quic_version_;
  262. // Set to false if this stream should not be migrated to a cellular network
  263. // during connection migration.
  264. bool can_migrate_to_cellular_network_ = true;
  265. // True if non-informational (non-1xx) initial headers have arrived.
  266. bool initial_headers_arrived_ = false;
  267. // True if non-informational (non-1xx) initial headers have been delivered to
  268. // the handle.
  269. bool headers_delivered_ = false;
  270. // Stores the initial header until they are delivered to the handle.
  271. spdy::Http2HeaderBlock initial_headers_;
  272. // Length of the HEADERS frame containing initial headers.
  273. size_t initial_headers_frame_len_ = 0;
  274. // Length of the HEADERS frame containing trailing headers.
  275. size_t trailing_headers_frame_len_ = 0;
  276. struct EarlyHints {
  277. EarlyHints(spdy::Http2HeaderBlock headers, size_t frame_len)
  278. : headers(std::move(headers)), frame_len(frame_len) {}
  279. EarlyHints(EarlyHints&& other) = default;
  280. EarlyHints& operator=(EarlyHints&& other) = default;
  281. EarlyHints(const EarlyHints& other) = delete;
  282. EarlyHints& operator=(const EarlyHints& other) = delete;
  283. spdy::Http2HeaderBlock headers;
  284. size_t frame_len = 0;
  285. };
  286. base::circular_deque<EarlyHints> early_hints_;
  287. base::WeakPtrFactory<QuicChromiumClientStream> weak_factory_{this};
  288. };
  289. } // namespace net
  290. #endif // NET_QUIC_QUIC_CHROMIUM_CLIENT_STREAM_H_