1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #ifndef NET_SPDY_SPDY_STREAM_H_ 6*6777b538SAndroid Build Coastguard Worker #define NET_SPDY_SPDY_STREAM_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker #include <stddef.h> 9*6777b538SAndroid Build Coastguard Worker #include <stdint.h> 10*6777b538SAndroid Build Coastguard Worker 11*6777b538SAndroid Build Coastguard Worker #include <memory> 12*6777b538SAndroid Build Coastguard Worker #include <string> 13*6777b538SAndroid Build Coastguard Worker #include <string_view> 14*6777b538SAndroid Build Coastguard Worker #include <vector> 15*6777b538SAndroid Build Coastguard Worker 16*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h" 17*6777b538SAndroid Build Coastguard Worker #include "base/memory/scoped_refptr.h" 18*6777b538SAndroid Build Coastguard Worker #include "base/memory/weak_ptr.h" 19*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h" 20*6777b538SAndroid Build Coastguard Worker #include "net/base/io_buffer.h" 21*6777b538SAndroid Build Coastguard Worker #include "net/base/net_export.h" 22*6777b538SAndroid Build Coastguard Worker #include "net/base/request_priority.h" 23*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_source.h" 24*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_with_source.h" 25*6777b538SAndroid Build Coastguard Worker #include "net/socket/next_proto.h" 26*6777b538SAndroid Build Coastguard Worker #include "net/socket/ssl_client_socket.h" 27*6777b538SAndroid Build Coastguard Worker #include "net/spdy/spdy_buffer.h" 28*6777b538SAndroid Build Coastguard Worker #include "net/third_party/quiche/src/quiche/spdy/core/http2_header_block.h" 29*6777b538SAndroid Build Coastguard Worker #include "net/third_party/quiche/src/quiche/spdy/core/spdy_framer.h" 30*6777b538SAndroid Build Coastguard Worker #include "net/third_party/quiche/src/quiche/spdy/core/spdy_protocol.h" 31*6777b538SAndroid Build Coastguard Worker #include "net/traffic_annotation/network_traffic_annotation.h" 32*6777b538SAndroid Build Coastguard Worker #include "url/gurl.h" 33*6777b538SAndroid Build Coastguard Worker 34*6777b538SAndroid Build Coastguard Worker namespace net { 35*6777b538SAndroid Build Coastguard Worker 36*6777b538SAndroid Build Coastguard Worker namespace test { 37*6777b538SAndroid Build Coastguard Worker class SpdyStreamTest; 38*6777b538SAndroid Build Coastguard Worker } 39*6777b538SAndroid Build Coastguard Worker 40*6777b538SAndroid Build Coastguard Worker class IPEndPoint; 41*6777b538SAndroid Build Coastguard Worker struct LoadTimingInfo; 42*6777b538SAndroid Build Coastguard Worker class SSLInfo; 43*6777b538SAndroid Build Coastguard Worker class SpdySession; 44*6777b538SAndroid Build Coastguard Worker 45*6777b538SAndroid Build Coastguard Worker enum SpdyStreamType { 46*6777b538SAndroid Build Coastguard Worker // The most general type of stream; there are no restrictions on 47*6777b538SAndroid Build Coastguard Worker // when data can be sent and received. 48*6777b538SAndroid Build Coastguard Worker SPDY_BIDIRECTIONAL_STREAM, 49*6777b538SAndroid Build Coastguard Worker // A stream where the client sends a request with possibly a body, 50*6777b538SAndroid Build Coastguard Worker // and the server then sends a response with a body. 51*6777b538SAndroid Build Coastguard Worker SPDY_REQUEST_RESPONSE_STREAM, 52*6777b538SAndroid Build Coastguard Worker }; 53*6777b538SAndroid Build Coastguard Worker 54*6777b538SAndroid Build Coastguard Worker // Passed to some SpdyStream functions to indicate whether there's 55*6777b538SAndroid Build Coastguard Worker // more data to send. 56*6777b538SAndroid Build Coastguard Worker enum SpdySendStatus { 57*6777b538SAndroid Build Coastguard Worker MORE_DATA_TO_SEND, 58*6777b538SAndroid Build Coastguard Worker NO_MORE_DATA_TO_SEND 59*6777b538SAndroid Build Coastguard Worker }; 60*6777b538SAndroid Build Coastguard Worker 61*6777b538SAndroid Build Coastguard Worker // SpdyStream is owned by SpdySession and is used to represent each stream known 62*6777b538SAndroid Build Coastguard Worker // on the SpdySession. This class provides interfaces for SpdySession to use. 63*6777b538SAndroid Build Coastguard Worker // Streams can be created either by the client or by the server. When they 64*6777b538SAndroid Build Coastguard Worker // are initiated by the client, both the SpdySession and client object (such as 65*6777b538SAndroid Build Coastguard Worker // a SpdyNetworkTransaction) will maintain a reference to the stream. When 66*6777b538SAndroid Build Coastguard Worker // initiated by the server, only the SpdySession will maintain any reference, 67*6777b538SAndroid Build Coastguard Worker // until such a time as a client object requests a stream for the path. 68*6777b538SAndroid Build Coastguard Worker class NET_EXPORT_PRIVATE SpdyStream { 69*6777b538SAndroid Build Coastguard Worker public: 70*6777b538SAndroid Build Coastguard Worker // Delegate handles protocol specific behavior of spdy stream. 71*6777b538SAndroid Build Coastguard Worker class NET_EXPORT_PRIVATE Delegate { 72*6777b538SAndroid Build Coastguard Worker public: 73*6777b538SAndroid Build Coastguard Worker Delegate() = default; 74*6777b538SAndroid Build Coastguard Worker 75*6777b538SAndroid Build Coastguard Worker Delegate(const Delegate&) = delete; 76*6777b538SAndroid Build Coastguard Worker Delegate& operator=(const Delegate&) = delete; 77*6777b538SAndroid Build Coastguard Worker 78*6777b538SAndroid Build Coastguard Worker // Called when the request headers have been sent. Never called 79*6777b538SAndroid Build Coastguard Worker // for push streams. Must not cause the stream to be closed. 80*6777b538SAndroid Build Coastguard Worker virtual void OnHeadersSent() = 0; 81*6777b538SAndroid Build Coastguard Worker 82*6777b538SAndroid Build Coastguard Worker // OnEarlyHintsReceived(), OnHeadersReceived(), OnDataReceived(), 83*6777b538SAndroid Build Coastguard Worker // OnTrailers(), and OnClose() are guaranteed to be called in the following 84*6777b538SAndroid Build Coastguard Worker // order: 85*6777b538SAndroid Build Coastguard Worker // - OnEarlyHintsReceived() zero or more times; 86*6777b538SAndroid Build Coastguard Worker // - OnHeadersReceived() exactly once; 87*6777b538SAndroid Build Coastguard Worker // - OnDataReceived() zero or more times; 88*6777b538SAndroid Build Coastguard Worker // - OnTrailers() zero or one times; 89*6777b538SAndroid Build Coastguard Worker // - OnClose() exactly once. 90*6777b538SAndroid Build Coastguard Worker 91*6777b538SAndroid Build Coastguard Worker // Called when a 103 Early Hints response is received. 92*6777b538SAndroid Build Coastguard Worker virtual void OnEarlyHintsReceived( 93*6777b538SAndroid Build Coastguard Worker const spdy::Http2HeaderBlock& headers) = 0; 94*6777b538SAndroid Build Coastguard Worker 95*6777b538SAndroid Build Coastguard Worker // Called when response headers have been received. 96*6777b538SAndroid Build Coastguard Worker virtual void OnHeadersReceived( 97*6777b538SAndroid Build Coastguard Worker const spdy::Http2HeaderBlock& response_headers) = 0; 98*6777b538SAndroid Build Coastguard Worker 99*6777b538SAndroid Build Coastguard Worker // Called when data is received. |buffer| may be NULL, which signals EOF. 100*6777b538SAndroid Build Coastguard Worker // May cause the stream to be closed. 101*6777b538SAndroid Build Coastguard Worker virtual void OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) = 0; 102*6777b538SAndroid Build Coastguard Worker 103*6777b538SAndroid Build Coastguard Worker // Called when data is sent. Must not cause the stream to be closed. 104*6777b538SAndroid Build Coastguard Worker virtual void OnDataSent() = 0; 105*6777b538SAndroid Build Coastguard Worker 106*6777b538SAndroid Build Coastguard Worker // Called when trailers are received. 107*6777b538SAndroid Build Coastguard Worker virtual void OnTrailers(const spdy::Http2HeaderBlock& trailers) = 0; 108*6777b538SAndroid Build Coastguard Worker 109*6777b538SAndroid Build Coastguard Worker // Called when SpdyStream is closed. No other delegate functions 110*6777b538SAndroid Build Coastguard Worker // will be called after this is called, and the delegate must not 111*6777b538SAndroid Build Coastguard Worker // access the stream after this is called. Must not cause the 112*6777b538SAndroid Build Coastguard Worker // stream to be (re-)closed. 113*6777b538SAndroid Build Coastguard Worker // 114*6777b538SAndroid Build Coastguard Worker // TODO(akalin): Allow this function to re-close the stream and 115*6777b538SAndroid Build Coastguard Worker // handle it gracefully. 116*6777b538SAndroid Build Coastguard Worker virtual void OnClose(int status) = 0; 117*6777b538SAndroid Build Coastguard Worker 118*6777b538SAndroid Build Coastguard Worker // Returns whether it is allowed to send greased (reserved type) frames on 119*6777b538SAndroid Build Coastguard Worker // the HTTP/2 stream. 120*6777b538SAndroid Build Coastguard Worker virtual bool CanGreaseFrameType() const = 0; 121*6777b538SAndroid Build Coastguard Worker 122*6777b538SAndroid Build Coastguard Worker virtual NetLogSource source_dependency() const = 0; 123*6777b538SAndroid Build Coastguard Worker 124*6777b538SAndroid Build Coastguard Worker protected: 125*6777b538SAndroid Build Coastguard Worker virtual ~Delegate() = default; 126*6777b538SAndroid Build Coastguard Worker }; 127*6777b538SAndroid Build Coastguard Worker 128*6777b538SAndroid Build Coastguard Worker // SpdyStream constructor 129*6777b538SAndroid Build Coastguard Worker SpdyStream(SpdyStreamType type, 130*6777b538SAndroid Build Coastguard Worker const base::WeakPtr<SpdySession>& session, 131*6777b538SAndroid Build Coastguard Worker const GURL& url, 132*6777b538SAndroid Build Coastguard Worker RequestPriority priority, 133*6777b538SAndroid Build Coastguard Worker int32_t initial_send_window_size, 134*6777b538SAndroid Build Coastguard Worker int32_t max_recv_window_size, 135*6777b538SAndroid Build Coastguard Worker const NetLogWithSource& net_log, 136*6777b538SAndroid Build Coastguard Worker const NetworkTrafficAnnotationTag& traffic_annotation, 137*6777b538SAndroid Build Coastguard Worker bool detect_broken_connection); 138*6777b538SAndroid Build Coastguard Worker 139*6777b538SAndroid Build Coastguard Worker SpdyStream(const SpdyStream&) = delete; 140*6777b538SAndroid Build Coastguard Worker SpdyStream& operator=(const SpdyStream&) = delete; 141*6777b538SAndroid Build Coastguard Worker 142*6777b538SAndroid Build Coastguard Worker ~SpdyStream(); 143*6777b538SAndroid Build Coastguard Worker 144*6777b538SAndroid Build Coastguard Worker // Set the delegate, which must not be NULL. Must not be called more 145*6777b538SAndroid Build Coastguard Worker // than once. For push streams, calling this may cause buffered data 146*6777b538SAndroid Build Coastguard Worker // to be sent to the delegate (from a posted task). 147*6777b538SAndroid Build Coastguard Worker void SetDelegate(Delegate* delegate); 148*6777b538SAndroid Build Coastguard Worker 149*6777b538SAndroid Build Coastguard Worker // Detach the delegate from the stream, which must not yet be 150*6777b538SAndroid Build Coastguard Worker // closed, and cancel it. 151*6777b538SAndroid Build Coastguard Worker void DetachDelegate(); 152*6777b538SAndroid Build Coastguard Worker 153*6777b538SAndroid Build Coastguard Worker // The time at which the first bytes of the response were received 154*6777b538SAndroid Build Coastguard Worker // from the server, or null if the response hasn't been received 155*6777b538SAndroid Build Coastguard Worker // yet. response_time()156*6777b538SAndroid Build Coastguard Worker base::Time response_time() const { return response_time_; } 157*6777b538SAndroid Build Coastguard Worker type()158*6777b538SAndroid Build Coastguard Worker SpdyStreamType type() const { return type_; } 159*6777b538SAndroid Build Coastguard Worker stream_id()160*6777b538SAndroid Build Coastguard Worker spdy::SpdyStreamId stream_id() const { return stream_id_; } set_stream_id(spdy::SpdyStreamId stream_id)161*6777b538SAndroid Build Coastguard Worker void set_stream_id(spdy::SpdyStreamId stream_id) { stream_id_ = stream_id; } 162*6777b538SAndroid Build Coastguard Worker url()163*6777b538SAndroid Build Coastguard Worker const GURL& url() const { return url_; } 164*6777b538SAndroid Build Coastguard Worker priority()165*6777b538SAndroid Build Coastguard Worker RequestPriority priority() const { return priority_; } 166*6777b538SAndroid Build Coastguard Worker 167*6777b538SAndroid Build Coastguard Worker // Update priority and send PRIORITY frames on the wire if necessary. 168*6777b538SAndroid Build Coastguard Worker void SetPriority(RequestPriority priority); 169*6777b538SAndroid Build Coastguard Worker send_window_size()170*6777b538SAndroid Build Coastguard Worker int32_t send_window_size() const { return send_window_size_; } 171*6777b538SAndroid Build Coastguard Worker recv_window_size()172*6777b538SAndroid Build Coastguard Worker int32_t recv_window_size() const { return recv_window_size_; } 173*6777b538SAndroid Build Coastguard Worker send_stalled_by_flow_control()174*6777b538SAndroid Build Coastguard Worker bool send_stalled_by_flow_control() const { 175*6777b538SAndroid Build Coastguard Worker return send_stalled_by_flow_control_; 176*6777b538SAndroid Build Coastguard Worker } 177*6777b538SAndroid Build Coastguard Worker set_send_stalled_by_flow_control(bool stalled)178*6777b538SAndroid Build Coastguard Worker void set_send_stalled_by_flow_control(bool stalled) { 179*6777b538SAndroid Build Coastguard Worker send_stalled_by_flow_control_ = stalled; 180*6777b538SAndroid Build Coastguard Worker } 181*6777b538SAndroid Build Coastguard Worker 182*6777b538SAndroid Build Coastguard Worker // Called by the session to adjust this stream's send window size by 183*6777b538SAndroid Build Coastguard Worker // |delta_window_size|, which is the difference between the 184*6777b538SAndroid Build Coastguard Worker // spdy::SETTINGS_INITIAL_WINDOW_SIZE in the most recent SETTINGS frame 185*6777b538SAndroid Build Coastguard Worker // and the previous initial send window size, possibly unstalling 186*6777b538SAndroid Build Coastguard Worker // this stream. Although |delta_window_size| may cause this stream's 187*6777b538SAndroid Build Coastguard Worker // send window size to go negative, it must not cause it to wrap 188*6777b538SAndroid Build Coastguard Worker // around in either direction. Does nothing if the stream is already 189*6777b538SAndroid Build Coastguard Worker // closed. 190*6777b538SAndroid Build Coastguard Worker // Returns true if successful. Returns false if |send_window_size_| 191*6777b538SAndroid Build Coastguard Worker // would exceed 2^31-1 after the update, see RFC7540 Section 6.9.2. 192*6777b538SAndroid Build Coastguard Worker // Note that |send_window_size_| should not possibly underflow. 193*6777b538SAndroid Build Coastguard Worker [[nodiscard]] bool AdjustSendWindowSize(int32_t delta_window_size); 194*6777b538SAndroid Build Coastguard Worker 195*6777b538SAndroid Build Coastguard Worker // Called when bytes are consumed from a SpdyBuffer for a DATA frame 196*6777b538SAndroid Build Coastguard Worker // that is to be written or is being written. Increases the send 197*6777b538SAndroid Build Coastguard Worker // window size accordingly if some or all of the SpdyBuffer is being 198*6777b538SAndroid Build Coastguard Worker // discarded. 199*6777b538SAndroid Build Coastguard Worker // 200*6777b538SAndroid Build Coastguard Worker // If stream flow control is turned off, this must not be called. 201*6777b538SAndroid Build Coastguard Worker void OnWriteBufferConsumed(size_t frame_payload_size, 202*6777b538SAndroid Build Coastguard Worker size_t consume_size, 203*6777b538SAndroid Build Coastguard Worker SpdyBuffer::ConsumeSource consume_source); 204*6777b538SAndroid Build Coastguard Worker 205*6777b538SAndroid Build Coastguard Worker // Called by the session to increase this stream's send window size 206*6777b538SAndroid Build Coastguard Worker // by |delta_window_size| (which must be at least 1) from a received 207*6777b538SAndroid Build Coastguard Worker // WINDOW_UPDATE frame or from a dropped DATA frame that was 208*6777b538SAndroid Build Coastguard Worker // intended to be sent, possibly unstalling this stream. If 209*6777b538SAndroid Build Coastguard Worker // |delta_window_size| would cause this stream's send window size to 210*6777b538SAndroid Build Coastguard Worker // overflow, calls into the session to reset this stream. Does 211*6777b538SAndroid Build Coastguard Worker // nothing if the stream is already closed. 212*6777b538SAndroid Build Coastguard Worker // 213*6777b538SAndroid Build Coastguard Worker // If stream flow control is turned off, this must not be called. 214*6777b538SAndroid Build Coastguard Worker void IncreaseSendWindowSize(int32_t delta_window_size); 215*6777b538SAndroid Build Coastguard Worker 216*6777b538SAndroid Build Coastguard Worker // If stream flow control is turned on, called by the session to 217*6777b538SAndroid Build Coastguard Worker // decrease this stream's send window size by |delta_window_size|, 218*6777b538SAndroid Build Coastguard Worker // which must be at least 0 and at most kMaxSpdyFrameChunkSize. 219*6777b538SAndroid Build Coastguard Worker // |delta_window_size| must not cause this stream's send window size 220*6777b538SAndroid Build Coastguard Worker // to go negative. Does nothing if the stream is already closed. 221*6777b538SAndroid Build Coastguard Worker // 222*6777b538SAndroid Build Coastguard Worker // If stream flow control is turned off, this must not be called. 223*6777b538SAndroid Build Coastguard Worker void DecreaseSendWindowSize(int32_t delta_window_size); 224*6777b538SAndroid Build Coastguard Worker 225*6777b538SAndroid Build Coastguard Worker // Called when bytes are consumed by the delegate from a SpdyBuffer 226*6777b538SAndroid Build Coastguard Worker // containing received data. Increases the receive window size 227*6777b538SAndroid Build Coastguard Worker // accordingly. 228*6777b538SAndroid Build Coastguard Worker // 229*6777b538SAndroid Build Coastguard Worker // If stream flow control is turned off, this must not be called. 230*6777b538SAndroid Build Coastguard Worker void OnReadBufferConsumed(size_t consume_size, 231*6777b538SAndroid Build Coastguard Worker SpdyBuffer::ConsumeSource consume_source); 232*6777b538SAndroid Build Coastguard Worker 233*6777b538SAndroid Build Coastguard Worker // Called by OnReadBufferConsume to increase this stream's receive 234*6777b538SAndroid Build Coastguard Worker // window size by |delta_window_size|, which must be at least 1 and 235*6777b538SAndroid Build Coastguard Worker // must not cause this stream's receive window size to overflow, 236*6777b538SAndroid Build Coastguard Worker // possibly also sending a WINDOW_UPDATE frame. Does nothing if the 237*6777b538SAndroid Build Coastguard Worker // stream is not active. 238*6777b538SAndroid Build Coastguard Worker // 239*6777b538SAndroid Build Coastguard Worker // If stream flow control is turned off, this must not be called. 240*6777b538SAndroid Build Coastguard Worker void IncreaseRecvWindowSize(int32_t delta_window_size); 241*6777b538SAndroid Build Coastguard Worker 242*6777b538SAndroid Build Coastguard Worker // Called by OnDataReceived or OnPaddingConsumed (which are in turn called by 243*6777b538SAndroid Build Coastguard Worker // the session) to decrease this stream's receive window size by 244*6777b538SAndroid Build Coastguard Worker // |delta_window_size|, which must be at least 1. May close the stream on 245*6777b538SAndroid Build Coastguard Worker // flow control error. 246*6777b538SAndroid Build Coastguard Worker // 247*6777b538SAndroid Build Coastguard Worker // If stream flow control is turned off or the stream is not active, 248*6777b538SAndroid Build Coastguard Worker // this must not be called. 249*6777b538SAndroid Build Coastguard Worker void DecreaseRecvWindowSize(int32_t delta_window_size); 250*6777b538SAndroid Build Coastguard Worker 251*6777b538SAndroid Build Coastguard Worker int GetPeerAddress(IPEndPoint* address) const; 252*6777b538SAndroid Build Coastguard Worker int GetLocalAddress(IPEndPoint* address) const; 253*6777b538SAndroid Build Coastguard Worker 254*6777b538SAndroid Build Coastguard Worker // Returns true if the underlying transport socket ever had any reads or 255*6777b538SAndroid Build Coastguard Worker // writes. 256*6777b538SAndroid Build Coastguard Worker bool WasEverUsed() const; 257*6777b538SAndroid Build Coastguard Worker net_log()258*6777b538SAndroid Build Coastguard Worker const NetLogWithSource& net_log() const { return net_log_; } 259*6777b538SAndroid Build Coastguard Worker 260*6777b538SAndroid Build Coastguard Worker base::Time GetRequestTime() const; 261*6777b538SAndroid Build Coastguard Worker void SetRequestTime(base::Time t); 262*6777b538SAndroid Build Coastguard Worker 263*6777b538SAndroid Build Coastguard Worker // Called by SpdySession when headers are received for this stream. May close 264*6777b538SAndroid Build Coastguard Worker // the stream. 265*6777b538SAndroid Build Coastguard Worker void OnHeadersReceived(const spdy::Http2HeaderBlock& response_headers, 266*6777b538SAndroid Build Coastguard Worker base::Time response_time, 267*6777b538SAndroid Build Coastguard Worker base::TimeTicks recv_first_byte_time); 268*6777b538SAndroid Build Coastguard Worker 269*6777b538SAndroid Build Coastguard Worker // Called by the SpdySession when response data has been received 270*6777b538SAndroid Build Coastguard Worker // for this stream. This callback may be called multiple times as 271*6777b538SAndroid Build Coastguard Worker // data arrives from the network, and will never be called prior to 272*6777b538SAndroid Build Coastguard Worker // OnResponseHeadersReceived. 273*6777b538SAndroid Build Coastguard Worker // 274*6777b538SAndroid Build Coastguard Worker // |buffer| contains the data received, or NULL if the stream is 275*6777b538SAndroid Build Coastguard Worker // being closed. The stream must copy any data from this 276*6777b538SAndroid Build Coastguard Worker // buffer before returning from this callback. 277*6777b538SAndroid Build Coastguard Worker // 278*6777b538SAndroid Build Coastguard Worker // |length| is the number of bytes received (at most 2^24 - 1) or 0 if 279*6777b538SAndroid Build Coastguard Worker // the stream is being closed. 280*6777b538SAndroid Build Coastguard Worker void OnDataReceived(std::unique_ptr<SpdyBuffer> buffer); 281*6777b538SAndroid Build Coastguard Worker 282*6777b538SAndroid Build Coastguard Worker // Called by the SpdySession when padding is consumed to allow for the stream 283*6777b538SAndroid Build Coastguard Worker // receiving window to be updated. 284*6777b538SAndroid Build Coastguard Worker void OnPaddingConsumed(size_t len); 285*6777b538SAndroid Build Coastguard Worker 286*6777b538SAndroid Build Coastguard Worker // Called by the SpdySession when a frame has been successfully and completely 287*6777b538SAndroid Build Coastguard Worker // written. |frame_size| is the total size of the logical frame in bytes, 288*6777b538SAndroid Build Coastguard Worker // including framing overhead. For fragmented headers, this is the total size 289*6777b538SAndroid Build Coastguard Worker // of the HEADERS or PUSH_PROMISE frame and subsequent CONTINUATION frames. 290*6777b538SAndroid Build Coastguard Worker void OnFrameWriteComplete(spdy::SpdyFrameType frame_type, size_t frame_size); 291*6777b538SAndroid Build Coastguard Worker 292*6777b538SAndroid Build Coastguard Worker // HEADERS-specific write handler invoked by OnFrameWriteComplete(). 293*6777b538SAndroid Build Coastguard Worker int OnHeadersSent(); 294*6777b538SAndroid Build Coastguard Worker 295*6777b538SAndroid Build Coastguard Worker // DATA-specific write handler invoked by OnFrameWriteComplete(). 296*6777b538SAndroid Build Coastguard Worker // If more data is already available to be written, the next write is 297*6777b538SAndroid Build Coastguard Worker // queued and ERR_IO_PENDING is returned. Returns OK otherwise. 298*6777b538SAndroid Build Coastguard Worker int OnDataSent(size_t frame_size); 299*6777b538SAndroid Build Coastguard Worker 300*6777b538SAndroid Build Coastguard Worker // Called by the SpdySession when the request is finished. This callback 301*6777b538SAndroid Build Coastguard Worker // will always be called at the end of the request and signals to the 302*6777b538SAndroid Build Coastguard Worker // stream that the stream has no more network events. No further callbacks 303*6777b538SAndroid Build Coastguard Worker // to the stream will be made after this call. Must be called before 304*6777b538SAndroid Build Coastguard Worker // SpdyStream is destroyed. 305*6777b538SAndroid Build Coastguard Worker // |status| is an error code or OK. 306*6777b538SAndroid Build Coastguard Worker void OnClose(int status); 307*6777b538SAndroid Build Coastguard Worker 308*6777b538SAndroid Build Coastguard Worker // Called by the SpdySession to log stream related errors. 309*6777b538SAndroid Build Coastguard Worker void LogStreamError(int error, std::string_view description); 310*6777b538SAndroid Build Coastguard Worker 311*6777b538SAndroid Build Coastguard Worker // If this stream is active, reset it, and close it otherwise. In 312*6777b538SAndroid Build Coastguard Worker // either case the stream is deleted. 313*6777b538SAndroid Build Coastguard Worker void Cancel(int error); 314*6777b538SAndroid Build Coastguard Worker 315*6777b538SAndroid Build Coastguard Worker // Close this stream without sending a RST_STREAM and delete 316*6777b538SAndroid Build Coastguard Worker // it. 317*6777b538SAndroid Build Coastguard Worker void Close(); 318*6777b538SAndroid Build Coastguard Worker 319*6777b538SAndroid Build Coastguard Worker // Must be used only by |session_|. 320*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> GetWeakPtr(); 321*6777b538SAndroid Build Coastguard Worker 322*6777b538SAndroid Build Coastguard Worker // Interface for the delegate to use. 323*6777b538SAndroid Build Coastguard Worker 324*6777b538SAndroid Build Coastguard Worker // Only one send can be in flight at a time, except for push 325*6777b538SAndroid Build Coastguard Worker // streams, which must not send anything. 326*6777b538SAndroid Build Coastguard Worker 327*6777b538SAndroid Build Coastguard Worker // Sends the request headers. The delegate is called back via OnHeadersSent() 328*6777b538SAndroid Build Coastguard Worker // when the request headers have completed sending. |send_status| must be 329*6777b538SAndroid Build Coastguard Worker // MORE_DATA_TO_SEND for bidirectional streams; for request/response streams, 330*6777b538SAndroid Build Coastguard Worker // it must be MORE_DATA_TO_SEND if the request has data to upload, or 331*6777b538SAndroid Build Coastguard Worker // NO_MORE_DATA_TO_SEND if not. 332*6777b538SAndroid Build Coastguard Worker int SendRequestHeaders(spdy::Http2HeaderBlock request_headers, 333*6777b538SAndroid Build Coastguard Worker SpdySendStatus send_status); 334*6777b538SAndroid Build Coastguard Worker 335*6777b538SAndroid Build Coastguard Worker // Sends a DATA frame. The delegate will be notified via 336*6777b538SAndroid Build Coastguard Worker // OnDataSent() when the send is complete. |send_status| must be 337*6777b538SAndroid Build Coastguard Worker // MORE_DATA_TO_SEND for bidirectional streams; for request/response 338*6777b538SAndroid Build Coastguard Worker // streams, it must be MORE_DATA_TO_SEND if there is more data to 339*6777b538SAndroid Build Coastguard Worker // upload, or NO_MORE_DATA_TO_SEND if not. 340*6777b538SAndroid Build Coastguard Worker // Must not be called until Delegate::OnHeadersSent() is called. 341*6777b538SAndroid Build Coastguard Worker void SendData(IOBuffer* data, int length, SpdySendStatus send_status); 342*6777b538SAndroid Build Coastguard Worker 343*6777b538SAndroid Build Coastguard Worker // Fills SSL info in |ssl_info| and returns true when SSL is in use. 344*6777b538SAndroid Build Coastguard Worker bool GetSSLInfo(SSLInfo* ssl_info) const; 345*6777b538SAndroid Build Coastguard Worker 346*6777b538SAndroid Build Coastguard Worker // Returns the protocol negotiated via ALPN for the underlying socket. 347*6777b538SAndroid Build Coastguard Worker NextProto GetNegotiatedProtocol() const; 348*6777b538SAndroid Build Coastguard Worker 349*6777b538SAndroid Build Coastguard Worker // If the stream is stalled on sending data, but the session is not 350*6777b538SAndroid Build Coastguard Worker // stalled on sending data and |send_window_size_| is positive, then 351*6777b538SAndroid Build Coastguard Worker // set |send_stalled_by_flow_control_| to false and unstall the data 352*6777b538SAndroid Build Coastguard Worker // sending. Called by the session or by the stream itself. Must be 353*6777b538SAndroid Build Coastguard Worker // called only when the stream is still open. 354*6777b538SAndroid Build Coastguard Worker enum ShouldRequeueStream { Requeue, DoNotRequeue }; 355*6777b538SAndroid Build Coastguard Worker ShouldRequeueStream PossiblyResumeIfSendStalled(); 356*6777b538SAndroid Build Coastguard Worker 357*6777b538SAndroid Build Coastguard Worker // Returns whether or not this stream is closed. Note that the only 358*6777b538SAndroid Build Coastguard Worker // time a stream is closed and not deleted is in its delegate's 359*6777b538SAndroid Build Coastguard Worker // OnClose() method. 360*6777b538SAndroid Build Coastguard Worker bool IsClosed() const; 361*6777b538SAndroid Build Coastguard Worker 362*6777b538SAndroid Build Coastguard Worker // Returns whether the streams local endpoint is closed. 363*6777b538SAndroid Build Coastguard Worker // The remote endpoint may still be active. 364*6777b538SAndroid Build Coastguard Worker bool IsLocallyClosed() const; 365*6777b538SAndroid Build Coastguard Worker 366*6777b538SAndroid Build Coastguard Worker // Returns whether this stream is IDLE: request and response headers 367*6777b538SAndroid Build Coastguard Worker // have neither been sent nor receieved. 368*6777b538SAndroid Build Coastguard Worker bool IsIdle() const; 369*6777b538SAndroid Build Coastguard Worker 370*6777b538SAndroid Build Coastguard Worker // Returns whether or not this stream is fully open: that request and 371*6777b538SAndroid Build Coastguard Worker // response headers are complete, and it is not in a half-closed state. 372*6777b538SAndroid Build Coastguard Worker bool IsOpen() const; 373*6777b538SAndroid Build Coastguard Worker 374*6777b538SAndroid Build Coastguard Worker // Returns whether the stream is reserved by remote endpoint: server has sent 375*6777b538SAndroid Build Coastguard Worker // intended request headers for a pushed stream, but haven't started response 376*6777b538SAndroid Build Coastguard Worker // yet. 377*6777b538SAndroid Build Coastguard Worker bool IsReservedRemote() const; 378*6777b538SAndroid Build Coastguard Worker 379*6777b538SAndroid Build Coastguard Worker void AddRawReceivedBytes(size_t received_bytes); 380*6777b538SAndroid Build Coastguard Worker void AddRawSentBytes(size_t sent_bytes); 381*6777b538SAndroid Build Coastguard Worker raw_received_bytes()382*6777b538SAndroid Build Coastguard Worker int64_t raw_received_bytes() const { return raw_received_bytes_; } raw_sent_bytes()383*6777b538SAndroid Build Coastguard Worker int64_t raw_sent_bytes() const { return raw_sent_bytes_; } recv_bytes()384*6777b538SAndroid Build Coastguard Worker int recv_bytes() const { return recv_bytes_; } 385*6777b538SAndroid Build Coastguard Worker 386*6777b538SAndroid Build Coastguard Worker bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const; 387*6777b538SAndroid Build Coastguard Worker request_headers()388*6777b538SAndroid Build Coastguard Worker const spdy::Http2HeaderBlock& request_headers() const { 389*6777b538SAndroid Build Coastguard Worker return request_headers_; 390*6777b538SAndroid Build Coastguard Worker } response_headers()391*6777b538SAndroid Build Coastguard Worker const spdy::Http2HeaderBlock& response_headers() const { 392*6777b538SAndroid Build Coastguard Worker return response_headers_; 393*6777b538SAndroid Build Coastguard Worker } 394*6777b538SAndroid Build Coastguard Worker traffic_annotation()395*6777b538SAndroid Build Coastguard Worker const NetworkTrafficAnnotationTag traffic_annotation() const { 396*6777b538SAndroid Build Coastguard Worker return traffic_annotation_; 397*6777b538SAndroid Build Coastguard Worker } 398*6777b538SAndroid Build Coastguard Worker detect_broken_connection()399*6777b538SAndroid Build Coastguard Worker bool detect_broken_connection() const { return detect_broken_connection_; } 400*6777b538SAndroid Build Coastguard Worker 401*6777b538SAndroid Build Coastguard Worker private: 402*6777b538SAndroid Build Coastguard Worker friend class test::SpdyStreamTest; 403*6777b538SAndroid Build Coastguard Worker 404*6777b538SAndroid Build Coastguard Worker class HeadersBufferProducer; 405*6777b538SAndroid Build Coastguard Worker 406*6777b538SAndroid Build Coastguard Worker // SpdyStream states and transitions are modeled 407*6777b538SAndroid Build Coastguard Worker // on the HTTP/2 stream state machine. All states and transitions 408*6777b538SAndroid Build Coastguard Worker // are modeled, with the exceptions of RESERVED_LOCAL (the client 409*6777b538SAndroid Build Coastguard Worker // cannot initate push streams), and the transition to OPEN due to 410*6777b538SAndroid Build Coastguard Worker // a remote HEADERS (the client can only initate streams). 411*6777b538SAndroid Build Coastguard Worker enum State { 412*6777b538SAndroid Build Coastguard Worker STATE_IDLE, 413*6777b538SAndroid Build Coastguard Worker STATE_OPEN, 414*6777b538SAndroid Build Coastguard Worker STATE_HALF_CLOSED_LOCAL, 415*6777b538SAndroid Build Coastguard Worker STATE_HALF_CLOSED_REMOTE, 416*6777b538SAndroid Build Coastguard Worker STATE_RESERVED_REMOTE, 417*6777b538SAndroid Build Coastguard Worker STATE_CLOSED, 418*6777b538SAndroid Build Coastguard Worker }; 419*6777b538SAndroid Build Coastguard Worker 420*6777b538SAndroid Build Coastguard Worker // Per RFC 7540 Section 8.1, an HTTP response consists of: 421*6777b538SAndroid Build Coastguard Worker // * zero or more header blocks with informational (1xx) HTTP status, 422*6777b538SAndroid Build Coastguard Worker // * one header block, 423*6777b538SAndroid Build Coastguard Worker // * zero or more DATA frames, 424*6777b538SAndroid Build Coastguard Worker // * zero or one header block ("trailers"). 425*6777b538SAndroid Build Coastguard Worker // Each header block must have a ":status" header field. SpdyStream enforces 426*6777b538SAndroid Build Coastguard Worker // these requirements, and resets the stream if they are not met. 427*6777b538SAndroid Build Coastguard Worker enum ResponseState { 428*6777b538SAndroid Build Coastguard Worker READY_FOR_HEADERS, 429*6777b538SAndroid Build Coastguard Worker READY_FOR_DATA_OR_TRAILERS, 430*6777b538SAndroid Build Coastguard Worker TRAILERS_RECEIVED 431*6777b538SAndroid Build Coastguard Worker }; 432*6777b538SAndroid Build Coastguard Worker 433*6777b538SAndroid Build Coastguard Worker // Produces the HEADERS frame for the stream. The stream must 434*6777b538SAndroid Build Coastguard Worker // already be activated. 435*6777b538SAndroid Build Coastguard Worker std::unique_ptr<spdy::SpdySerializedFrame> ProduceHeadersFrame(); 436*6777b538SAndroid Build Coastguard Worker 437*6777b538SAndroid Build Coastguard Worker // Queues the send for next frame of the remaining data in 438*6777b538SAndroid Build Coastguard Worker // |pending_send_data_|. Must be called only when 439*6777b538SAndroid Build Coastguard Worker // |pending_send_data_| is set. 440*6777b538SAndroid Build Coastguard Worker void QueueNextDataFrame(); 441*6777b538SAndroid Build Coastguard Worker 442*6777b538SAndroid Build Coastguard Worker void OnEarlyHintsReceived(const spdy::Http2HeaderBlock& response_headers, 443*6777b538SAndroid Build Coastguard Worker base::TimeTicks recv_first_byte_time); 444*6777b538SAndroid Build Coastguard Worker 445*6777b538SAndroid Build Coastguard Worker // Saves the given headers into |response_headers_| and calls 446*6777b538SAndroid Build Coastguard Worker // OnHeadersReceived() on the delegate if attached. 447*6777b538SAndroid Build Coastguard Worker void SaveResponseHeaders(const spdy::Http2HeaderBlock& response_headers, 448*6777b538SAndroid Build Coastguard Worker int status); 449*6777b538SAndroid Build Coastguard Worker 450*6777b538SAndroid Build Coastguard Worker static std::string DescribeState(State state); 451*6777b538SAndroid Build Coastguard Worker 452*6777b538SAndroid Build Coastguard Worker const SpdyStreamType type_; 453*6777b538SAndroid Build Coastguard Worker 454*6777b538SAndroid Build Coastguard Worker spdy::SpdyStreamId stream_id_ = 0; 455*6777b538SAndroid Build Coastguard Worker const GURL url_; 456*6777b538SAndroid Build Coastguard Worker RequestPriority priority_; 457*6777b538SAndroid Build Coastguard Worker 458*6777b538SAndroid Build Coastguard Worker bool send_stalled_by_flow_control_ = false; 459*6777b538SAndroid Build Coastguard Worker 460*6777b538SAndroid Build Coastguard Worker // Current send window size. 461*6777b538SAndroid Build Coastguard Worker int32_t send_window_size_; 462*6777b538SAndroid Build Coastguard Worker 463*6777b538SAndroid Build Coastguard Worker // Maximum receive window size. Each time a WINDOW_UPDATE is sent, it 464*6777b538SAndroid Build Coastguard Worker // restores the receive window size to this value. 465*6777b538SAndroid Build Coastguard Worker int32_t max_recv_window_size_; 466*6777b538SAndroid Build Coastguard Worker 467*6777b538SAndroid Build Coastguard Worker // Sum of |session_unacked_recv_window_bytes_| and current receive window 468*6777b538SAndroid Build Coastguard Worker // size. 469*6777b538SAndroid Build Coastguard Worker // TODO(bnc): Rename or change semantics so that |window_size_| is actual 470*6777b538SAndroid Build Coastguard Worker // window size. 471*6777b538SAndroid Build Coastguard Worker int32_t recv_window_size_; 472*6777b538SAndroid Build Coastguard Worker 473*6777b538SAndroid Build Coastguard Worker // When bytes are consumed, SpdyIOBuffer destructor calls back to SpdySession, 474*6777b538SAndroid Build Coastguard Worker // and this member keeps count of them until the corresponding WINDOW_UPDATEs 475*6777b538SAndroid Build Coastguard Worker // are sent. 476*6777b538SAndroid Build Coastguard Worker int32_t unacked_recv_window_bytes_ = 0; 477*6777b538SAndroid Build Coastguard Worker 478*6777b538SAndroid Build Coastguard Worker // Time of the last WINDOW_UPDATE for the receive window 479*6777b538SAndroid Build Coastguard Worker base::TimeTicks last_recv_window_update_; 480*6777b538SAndroid Build Coastguard Worker 481*6777b538SAndroid Build Coastguard Worker const base::WeakPtr<SpdySession> session_; 482*6777b538SAndroid Build Coastguard Worker 483*6777b538SAndroid Build Coastguard Worker // The transaction should own the delegate. 484*6777b538SAndroid Build Coastguard Worker raw_ptr<SpdyStream::Delegate> delegate_ = nullptr; 485*6777b538SAndroid Build Coastguard Worker 486*6777b538SAndroid Build Coastguard Worker // The headers for the request to send. 487*6777b538SAndroid Build Coastguard Worker bool request_headers_valid_ = false; 488*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock request_headers_; 489*6777b538SAndroid Build Coastguard Worker 490*6777b538SAndroid Build Coastguard Worker // Data waiting to be sent, and the close state of the local endpoint 491*6777b538SAndroid Build Coastguard Worker // after the data is fully written. 492*6777b538SAndroid Build Coastguard Worker scoped_refptr<DrainableIOBuffer> pending_send_data_; 493*6777b538SAndroid Build Coastguard Worker SpdySendStatus pending_send_status_ = MORE_DATA_TO_SEND; 494*6777b538SAndroid Build Coastguard Worker 495*6777b538SAndroid Build Coastguard Worker // Data waiting to be received, and the close state of the remote endpoint 496*6777b538SAndroid Build Coastguard Worker // after the data is fully read. Specifically, data received before the 497*6777b538SAndroid Build Coastguard Worker // delegate is attached must be buffered and later replayed. A remote FIN 498*6777b538SAndroid Build Coastguard Worker // is represented by a final, zero-length buffer. 499*6777b538SAndroid Build Coastguard Worker std::vector<std::unique_ptr<SpdyBuffer>> pending_recv_data_; 500*6777b538SAndroid Build Coastguard Worker 501*6777b538SAndroid Build Coastguard Worker // The time at which the request was made that resulted in this response. 502*6777b538SAndroid Build Coastguard Worker // For cached responses, this time could be "far" in the past. 503*6777b538SAndroid Build Coastguard Worker base::Time request_time_; 504*6777b538SAndroid Build Coastguard Worker 505*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock response_headers_; 506*6777b538SAndroid Build Coastguard Worker ResponseState response_state_ = READY_FOR_HEADERS; 507*6777b538SAndroid Build Coastguard Worker base::Time response_time_; 508*6777b538SAndroid Build Coastguard Worker 509*6777b538SAndroid Build Coastguard Worker State io_state_ = STATE_IDLE; 510*6777b538SAndroid Build Coastguard Worker 511*6777b538SAndroid Build Coastguard Worker NetLogWithSource net_log_; 512*6777b538SAndroid Build Coastguard Worker 513*6777b538SAndroid Build Coastguard Worker base::TimeTicks send_time_; 514*6777b538SAndroid Build Coastguard Worker 515*6777b538SAndroid Build Coastguard Worker // The time at which the first / last byte of the HTTP headers were received. 516*6777b538SAndroid Build Coastguard Worker // 517*6777b538SAndroid Build Coastguard Worker // These correspond to |LoadTimingInfo::receive_headers_start| and 518*6777b538SAndroid Build Coastguard Worker // |LoadTimingInfo::receive_headers_end|. See also comments there. 519*6777b538SAndroid Build Coastguard Worker base::TimeTicks recv_first_byte_time_; 520*6777b538SAndroid Build Coastguard Worker base::TimeTicks recv_last_byte_time_; 521*6777b538SAndroid Build Coastguard Worker 522*6777b538SAndroid Build Coastguard Worker // The time at which the first byte of the HTTP headers for the 523*6777b538SAndroid Build Coastguard Worker // non-informational response (non-1xx). This corresponds to 524*6777b538SAndroid Build Coastguard Worker // |LoadTimingInfo::receive_non_informational_headers_start|. See also 525*6777b538SAndroid Build Coastguard Worker // comments there. 526*6777b538SAndroid Build Coastguard Worker base::TimeTicks recv_first_byte_time_for_non_informational_response_; 527*6777b538SAndroid Build Coastguard Worker 528*6777b538SAndroid Build Coastguard Worker // The time at which the first 103 Early Hints response is received. 529*6777b538SAndroid Build Coastguard Worker base::TimeTicks first_early_hints_time_; 530*6777b538SAndroid Build Coastguard Worker 531*6777b538SAndroid Build Coastguard Worker // Number of bytes that have been received on this stream, including frame 532*6777b538SAndroid Build Coastguard Worker // overhead and headers. 533*6777b538SAndroid Build Coastguard Worker int64_t raw_received_bytes_ = 0; 534*6777b538SAndroid Build Coastguard Worker // Number of bytes that have been sent on this stream, including frame 535*6777b538SAndroid Build Coastguard Worker // overhead and headers. 536*6777b538SAndroid Build Coastguard Worker int64_t raw_sent_bytes_ = 0; 537*6777b538SAndroid Build Coastguard Worker 538*6777b538SAndroid Build Coastguard Worker // Number of data bytes that have been received on this stream, not including 539*6777b538SAndroid Build Coastguard Worker // frame overhead. Note that this does not count headers. 540*6777b538SAndroid Build Coastguard Worker int recv_bytes_ = 0; 541*6777b538SAndroid Build Coastguard Worker 542*6777b538SAndroid Build Coastguard Worker // Guards calls of delegate write handlers ensuring |this| is not destroyed. 543*6777b538SAndroid Build Coastguard Worker // TODO(jgraettinger): Consider removing after crbug.com/35511 is tracked 544*6777b538SAndroid Build Coastguard Worker // down. 545*6777b538SAndroid Build Coastguard Worker bool write_handler_guard_ = false; 546*6777b538SAndroid Build Coastguard Worker 547*6777b538SAndroid Build Coastguard Worker const NetworkTrafficAnnotationTag traffic_annotation_; 548*6777b538SAndroid Build Coastguard Worker 549*6777b538SAndroid Build Coastguard Worker // Used by SpdySession to remember if this stream requested broken connection 550*6777b538SAndroid Build Coastguard Worker // detection. 551*6777b538SAndroid Build Coastguard Worker bool detect_broken_connection_; 552*6777b538SAndroid Build Coastguard Worker 553*6777b538SAndroid Build Coastguard Worker base::WeakPtrFactory<SpdyStream> weak_ptr_factory_{this}; 554*6777b538SAndroid Build Coastguard Worker }; 555*6777b538SAndroid Build Coastguard Worker 556*6777b538SAndroid Build Coastguard Worker } // namespace net 557*6777b538SAndroid Build Coastguard Worker 558*6777b538SAndroid Build Coastguard Worker #endif // NET_SPDY_SPDY_STREAM_H_ 559