1 #ifndef QUICHE_HTTP2_ADAPTER_HTTP2_ADAPTER_H_ 2 #define QUICHE_HTTP2_ADAPTER_HTTP2_ADAPTER_H_ 3 4 #include <cstdint> 5 6 #include "absl/strings/string_view.h" 7 #include "absl/types/span.h" 8 #include "quiche/http2/adapter/data_source.h" 9 #include "quiche/http2/adapter/http2_protocol.h" 10 #include "quiche/http2/adapter/http2_session.h" 11 #include "quiche/http2/adapter/http2_visitor_interface.h" 12 #include "quiche/common/platform/api/quiche_export.h" 13 14 namespace http2 { 15 namespace adapter { 16 17 // Http2Adapter is an HTTP/2-processing class that exposes an interface similar 18 // to the nghttp2 library for processing the HTTP/2 wire format. As nghttp2 19 // parses HTTP/2 frames and invokes callbacks on Http2Adapter, Http2Adapter then 20 // invokes corresponding callbacks on its passed-in Http2VisitorInterface. 21 // Http2Adapter is a base class shared between client-side and server-side 22 // implementations. 23 class QUICHE_EXPORT Http2Adapter { 24 public: 25 Http2Adapter(const Http2Adapter&) = delete; 26 Http2Adapter& operator=(const Http2Adapter&) = delete; 27 ~Http2Adapter()28 virtual ~Http2Adapter() {} 29 30 virtual bool IsServerSession() const = 0; 31 32 virtual bool want_read() const = 0; 33 virtual bool want_write() const = 0; 34 35 // Processes the incoming |bytes| as HTTP/2 and invokes callbacks on the 36 // |visitor_| as appropriate. 37 virtual int64_t ProcessBytes(absl::string_view bytes) = 0; 38 39 // Submits the |settings| to be written to the peer, e.g., as part of the 40 // HTTP/2 connection preface. 41 virtual void SubmitSettings(absl::Span<const Http2Setting> settings) = 0; 42 43 // Submits a PRIORITY frame for the given stream. 44 virtual void SubmitPriorityForStream(Http2StreamId stream_id, 45 Http2StreamId parent_stream_id, 46 int weight, bool exclusive) = 0; 47 48 // Submits a PING on the connection. 49 virtual void SubmitPing(Http2PingId ping_id) = 0; 50 51 // Starts a graceful shutdown. A no-op for clients. 52 virtual void SubmitShutdownNotice() = 0; 53 54 // Submits a GOAWAY on the connection. Note that |last_accepted_stream_id| 55 // refers to stream IDs initiated by the peer. For a server sending this 56 // frame, this last stream ID must be odd (or 0). 57 virtual void SubmitGoAway(Http2StreamId last_accepted_stream_id, 58 Http2ErrorCode error_code, 59 absl::string_view opaque_data) = 0; 60 61 // Submits a WINDOW_UPDATE for the given stream (a |stream_id| of 0 indicates 62 // a connection-level WINDOW_UPDATE). 63 virtual void SubmitWindowUpdate(Http2StreamId stream_id, 64 int window_increment) = 0; 65 66 // Submits a RST_STREAM for the given |stream_id| and |error_code|. 67 virtual void SubmitRst(Http2StreamId stream_id, 68 Http2ErrorCode error_code) = 0; 69 70 // Submits a sequence of METADATA frames for the given stream. A |stream_id| 71 // of 0 indicates connection-level METADATA. 72 virtual void SubmitMetadata(Http2StreamId stream_id, size_t max_frame_size, 73 std::unique_ptr<MetadataSource> source) = 0; 74 75 // Invokes the visitor's OnReadyToSend() method for serialized frame data. 76 // Returns 0 on success. 77 virtual int Send() = 0; 78 79 // Returns the connection-level flow control window advertised by the peer. 80 virtual int GetSendWindowSize() const = 0; 81 82 // Returns the stream-level flow control window advertised by the peer. 83 virtual int GetStreamSendWindowSize(Http2StreamId stream_id) const = 0; 84 85 // Returns the current upper bound on the flow control receive window for this 86 // stream. This value does not account for data received from the peer. 87 virtual int GetStreamReceiveWindowLimit(Http2StreamId stream_id) const = 0; 88 89 // Returns the amount of data a peer could send on a given stream. This is 90 // the outstanding stream receive window. 91 virtual int GetStreamReceiveWindowSize(Http2StreamId stream_id) const = 0; 92 93 // Returns the total amount of data a peer could send on the connection. This 94 // is the outstanding connection receive window. 95 virtual int GetReceiveWindowSize() const = 0; 96 97 // Returns the size of the HPACK encoder's dynamic table, including the 98 // per-entry overhead from the specification. 99 virtual int GetHpackEncoderDynamicTableSize() const = 0; 100 101 // Returns the size of the HPACK decoder's dynamic table, including the 102 // per-entry overhead from the specification. 103 virtual int GetHpackDecoderDynamicTableSize() const = 0; 104 105 // Gets the highest stream ID value seen in a frame received by this endpoint. 106 // This method is only guaranteed to work for server endpoints. 107 virtual Http2StreamId GetHighestReceivedStreamId() const = 0; 108 109 // Marks the given amount of data as consumed for the given stream, which 110 // enables the implementation layer to send WINDOW_UPDATEs as appropriate. 111 virtual void MarkDataConsumedForStream(Http2StreamId stream_id, 112 size_t num_bytes) = 0; 113 114 // Returns the assigned stream ID if the operation succeeds. Otherwise, 115 // returns a negative integer indicating an error code. |data_source| may be 116 // nullptr if the request does not have a body. 117 virtual int32_t SubmitRequest(absl::Span<const Header> headers, 118 std::unique_ptr<DataFrameSource> data_source, 119 void* user_data) = 0; 120 121 // Returns 0 on success. |data_source| may be nullptr if the response does not 122 // have a body. 123 virtual int SubmitResponse(Http2StreamId stream_id, 124 absl::Span<const Header> headers, 125 std::unique_ptr<DataFrameSource> data_source) = 0; 126 127 // Queues trailers to be sent after any outstanding data on the stream with ID 128 // |stream_id|. Returns 0 on success. 129 virtual int SubmitTrailer(Http2StreamId stream_id, 130 absl::Span<const Header> trailers) = 0; 131 132 // Sets a user data pointer for the given stream. Can be called after 133 // SubmitRequest/SubmitResponse, or after receiving any frame for a given 134 // stream. 135 virtual void SetStreamUserData(Http2StreamId stream_id, void* user_data) = 0; 136 137 // Returns nullptr if the stream does not exist, or if stream user data has 138 // not been set. 139 virtual void* GetStreamUserData(Http2StreamId stream_id) = 0; 140 141 // Resumes a stream that was previously blocked (for example, due to 142 // DataFrameSource::SelectPayloadLength() returning kBlocked). Returns true if 143 // the stream was successfully resumed. 144 virtual bool ResumeStream(Http2StreamId stream_id) = 0; 145 146 // Called to communicate that a frame on a stream will not be sent. 147 // TODO(birenroy): remove when removing support for nghttp2. FrameNotSent(Http2StreamId,uint8_t)148 virtual void FrameNotSent(Http2StreamId /*stream_id*/, 149 uint8_t /*frame_type*/) {} 150 151 protected: 152 // Subclasses should expose a public factory method for constructing and 153 // initializing (via Initialize()) adapter instances. Http2Adapter(Http2VisitorInterface & visitor)154 explicit Http2Adapter(Http2VisitorInterface& visitor) : visitor_(visitor) {} 155 156 // Accessors. Do not transfer ownership. visitor()157 Http2VisitorInterface& visitor() { return visitor_; } 158 159 private: 160 // Http2Adapter will invoke callbacks upon the |visitor_| while processing. 161 Http2VisitorInterface& visitor_; 162 }; 163 164 } // namespace adapter 165 } // namespace http2 166 167 #endif // QUICHE_HTTP2_ADAPTER_HTTP2_ADAPTER_H_ 168