• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef NET_SPDY_SPDY_HTTP_STREAM_H_
6 #define NET_SPDY_SPDY_HTTP_STREAM_H_
7 
8 #include <stdint.h>
9 
10 #include <memory>
11 #include <set>
12 
13 #include "base/memory/raw_ptr.h"
14 #include "base/memory/raw_ptr_exclusion.h"
15 #include "base/memory/scoped_refptr.h"
16 #include "base/memory/weak_ptr.h"
17 #include "base/strings/string_piece.h"
18 #include "base/timer/timer.h"
19 #include "net/base/completion_once_callback.h"
20 #include "net/base/load_timing_info.h"
21 #include "net/base/net_export.h"
22 #include "net/log/net_log_source.h"
23 #include "net/spdy/multiplexed_http_stream.h"
24 #include "net/spdy/spdy_read_queue.h"
25 #include "net/spdy/spdy_session.h"
26 #include "net/spdy/spdy_stream.h"
27 
28 namespace net {
29 
30 struct HttpRequestInfo;
31 class HttpResponseInfo;
32 class IOBuffer;
33 class SpdySession;
34 class UploadDataStream;
35 
36 // The SpdyHttpStream is a HTTP-specific type of stream known to a SpdySession.
37 class NET_EXPORT_PRIVATE SpdyHttpStream : public SpdyStream::Delegate,
38                                           public MultiplexedHttpStream {
39  public:
40   static const size_t kRequestBodyBufferSize;
41   // |spdy_session| must not be NULL.
42   SpdyHttpStream(const base::WeakPtr<SpdySession>& spdy_session,
43                  spdy::SpdyStreamId pushed_stream_id,
44                  NetLogSource source_dependency,
45                  std::set<std::string> dns_aliases);
46 
47   SpdyHttpStream(const SpdyHttpStream&) = delete;
48   SpdyHttpStream& operator=(const SpdyHttpStream&) = delete;
49 
50   ~SpdyHttpStream() override;
51 
stream()52   SpdyStream* stream() { return stream_; }
53 
54   // Cancels any callbacks from being invoked and deletes the stream.
55   void Cancel();
56 
57   // HttpStream implementation.
58   void RegisterRequest(const HttpRequestInfo* request_info) override;
59   int InitializeStream(bool can_send_early,
60                        RequestPriority priority,
61                        const NetLogWithSource& net_log,
62                        CompletionOnceCallback callback) override;
63 
64   int SendRequest(const HttpRequestHeaders& headers,
65                   HttpResponseInfo* response,
66                   CompletionOnceCallback callback) override;
67   int ReadResponseHeaders(CompletionOnceCallback callback) override;
68   int ReadResponseBody(IOBuffer* buf,
69                        int buf_len,
70                        CompletionOnceCallback callback) override;
71   void Close(bool not_reusable) override;
72   bool IsResponseBodyComplete() const override;
73 
74   // Must not be called if a NULL SpdySession was pssed into the
75   // constructor.
76   bool IsConnectionReused() const override;
77 
78   // Total number of bytes received over the network of SPDY data, headers, and
79   // push_promise frames associated with this stream, including the size of
80   // frame headers, after SSL decryption and not including proxy overhead.
81   int64_t GetTotalReceivedBytes() const override;
82   // Total number of bytes sent over the network of SPDY frames associated with
83   // this stream, including the size of frame headers, before SSL encryption and
84   // not including proxy overhead. Note that some SPDY frames such as pings are
85   // not associated with any stream, and are not included in this value.
86   int64_t GetTotalSentBytes() const override;
87   bool GetAlternativeService(
88       AlternativeService* alternative_service) const override;
89   bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
90   int GetRemoteEndpoint(IPEndPoint* endpoint) override;
91   void PopulateNetErrorDetails(NetErrorDetails* details) override;
92   void SetPriority(RequestPriority priority) override;
93   const std::set<std::string>& GetDnsAliases() const override;
94   base::StringPiece GetAcceptChViaAlps() const override;
95 
96   // SpdyStream::Delegate implementation.
97   void OnHeadersSent() override;
98   void OnEarlyHintsReceived(const spdy::Http2HeaderBlock& headers) override;
99   void OnHeadersReceived(
100       const spdy::Http2HeaderBlock& response_headers,
101       const spdy::Http2HeaderBlock* pushed_request_headers) override;
102   void OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) override;
103   void OnDataSent() override;
104   void OnTrailers(const spdy::Http2HeaderBlock& trailers) override;
105   void OnClose(int status) override;
106   bool CanGreaseFrameType() const override;
107   NetLogSource source_dependency() const override;
108 
109  private:
110   // Helper function used to initialize private members and to set delegate on
111   // stream when stream is created.
112   void InitializeStreamHelper();
113 
114   // Helper function used for resetting stream from inside the stream.
115   void ResetStream(int error);
116 
117   // Must be called only when |request_info_| is non-NULL.
118   bool HasUploadData() const;
119 
120   void OnStreamCreated(CompletionOnceCallback callback, int rv);
121 
122   // Reads the remaining data (whether chunked or not) from the
123   // request body stream and sends it if there's any. The read and
124   // subsequent sending may happen asynchronously. Must be called only
125   // when HasUploadData() is true.
126   void ReadAndSendRequestBodyData();
127 
128   // Send an empty body.  Must only be called if there is no upload data and
129   // sending greased HTTP/2 frames is enabled.  This allows SpdyStream to
130   // prepend a greased HTTP/2 frame to the empty DATA frame that closes the
131   // stream.
132   void SendEmptyBody();
133 
134   // Called when data has just been read from the request body stream;
135   // does the actual sending of data.
136   void OnRequestBodyReadCompleted(int status);
137 
138   // Call the user callback associated with sending the request.
139   void DoRequestCallback(int rv);
140 
141   // Method to PostTask for calling request callback asynchronously.
142   void MaybeDoRequestCallback(int rv);
143 
144   // Post the request callback if not null.
145   // This is necessary because the request callback might destroy |stream_|,
146   // which does not support that.
147   void MaybePostRequestCallback(int rv);
148 
149   // Call the user callback associated with reading the response.
150   void DoResponseCallback(int rv);
151 
152   void MaybeScheduleBufferedReadCallback();
153   void DoBufferedReadCallback();
154 
155   const base::WeakPtr<SpdySession> spdy_session_;
156 
157   // The ID of the pushed stream if one is claimed by this request.
158   // In this case, the request fails if it cannot use that pushed stream.
159   // Otherwise set to kNoPushedStreamFound.
160   const spdy::SpdyStreamId pushed_stream_id_;
161 
162   bool is_reused_;
163   SpdyStreamRequest stream_request_;
164   const NetLogSource source_dependency_;
165 
166   // |stream_| is owned by SpdySession.
167   // Before InitializeStream() is called, stream_ == nullptr.
168   // After InitializeStream() is called but before OnClose() is called,
169   //   |*stream_| is guaranteed to be valid.
170   // After OnClose() is called, stream_ == nullptr.
171   raw_ptr<SpdyStream> stream_ = nullptr;
172 
173   // False before OnClose() is called, true after.
174   bool stream_closed_ = false;
175 
176   // Set only when |stream_closed_| is true.
177   int closed_stream_status_ = ERR_FAILED;
178   spdy::SpdyStreamId closed_stream_id_ = 0;
179   bool closed_stream_has_load_timing_info_;
180   LoadTimingInfo closed_stream_load_timing_info_;
181   // After |stream_| has been closed, this keeps track of the total number of
182   // bytes received over the network for |stream_| while it was open.
183   int64_t closed_stream_received_bytes_ = 0;
184   // After |stream_| has been closed, this keeps track of the total number of
185   // bytes sent over the network for |stream_| while it was open.
186   int64_t closed_stream_sent_bytes_ = 0;
187 
188   // The request to send.
189   // Set to null before response body is starting to be read. This is to allow
190   // |this| to be shared for reading and to possibly outlive request_info_'s
191   // owner. Setting to null happens after headers are completely read or upload
192   // data stream is uploaded, whichever is later.
193   raw_ptr<const HttpRequestInfo> request_info_ = nullptr;
194 
195   // |response_info_| is the HTTP response data object which is filled in
196   // when a response HEADERS comes in for the stream.
197   // It is not owned by this stream object, or point to |push_response_info_|.
198   raw_ptr<HttpResponseInfo> response_info_ = nullptr;
199 
200   std::unique_ptr<HttpResponseInfo> push_response_info_;
201 
202   bool response_headers_complete_ = false;
203 
204   bool upload_stream_in_progress_ = false;
205 
206   // We buffer the response body as it arrives asynchronously from the stream.
207   SpdyReadQueue response_body_queue_;
208 
209   CompletionOnceCallback request_callback_;
210   CompletionOnceCallback response_callback_;
211 
212   // User provided buffer for the ReadResponseBody() response.
213   scoped_refptr<IOBuffer> user_buffer_;
214   int user_buffer_len_ = 0;
215 
216   // Temporary buffer used to read the request body from UploadDataStream.
217   scoped_refptr<IOBufferWithSize> request_body_buf_;
218   int request_body_buf_size_ = 0;
219 
220   // Timer to execute DoBufferedReadCallback() with a delay.
221   base::OneShotTimer buffered_read_timer_;
222 
223   bool was_alpn_negotiated_ = false;
224 
225   // Stores any DNS aliases for the remote endpoint. Includes all known aliases,
226   // e.g. from A, AAAA, or HTTPS, not just from the address used for the
227   // connection, in no particular order. These are stored in the stream instead
228   // of the session due to complications related to IP-pooling.
229   std::set<std::string> dns_aliases_;
230 
231   base::WeakPtrFactory<SpdyHttpStream> weak_factory_{this};
232 };
233 
234 }  // namespace net
235 
236 #endif  // NET_SPDY_SPDY_HTTP_STREAM_H_
237