• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 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_TEST_EMBEDDED_TEST_SERVER_HTTP2_CONNECTION_H_
6 #define NET_TEST_EMBEDDED_TEST_SERVER_HTTP2_CONNECTION_H_
7 
8 #include <memory>
9 #include <queue>
10 #include <string>
11 
12 #include "base/containers/flat_map.h"
13 #include "base/containers/flat_set.h"
14 #include "base/memory/raw_ptr.h"
15 #include "base/memory/scoped_refptr.h"
16 #include "base/memory/weak_ptr.h"
17 #include "net/base/io_buffer.h"
18 #include "net/test/embedded_test_server/embedded_test_server_connection_listener.h"
19 #include "net/test/embedded_test_server/http_connection.h"
20 #include "net/test/embedded_test_server/http_request.h"
21 #include "net/third_party/quiche/src/quiche/http2/adapter/http2_visitor_interface.h"
22 #include "net/third_party/quiche/src/quiche/http2/adapter/oghttp2_adapter.h"
23 
24 namespace net::test_server {
25 
26 using StreamId = http2::adapter::Http2StreamId;
27 template <class T>
28 using StreamMap = base::flat_map<StreamId, T>;
29 
30 class EmbeddedTestServer;
31 
32 // Outside of the text/binary (which is just a drop-in parser/decoder
33 // replacement) the main difference from Http1Connection is that multiple
34 // request/response "streams" can exist on the same connection, which means
35 // connections don't open on first request and don't close on first response
36 class Http2Connection : public HttpConnection,
37                         public http2::adapter::Http2VisitorInterface {
38  public:
39   Http2Connection(std::unique_ptr<StreamSocket> socket,
40                   EmbeddedTestServerConnectionListener* connection_listener,
41                   EmbeddedTestServer* server_delegate);
42   ~Http2Connection() override;
43   Http2Connection(const HttpConnection&) = delete;
44   Http2Connection& operator=(const Http2Connection&) = delete;
45 
46   // HttpConnection
47   void OnSocketReady() override;
48   StreamSocket* Socket() override;
49   std::unique_ptr<StreamSocket> TakeSocket() override;
50   base::WeakPtr<HttpConnection> GetWeakPtr() override;
51 
52   // http2::adapter::Http2VisitorInterface
53   int64_t OnReadyToSend(std::string_view serialized) override;
54   OnHeaderResult OnHeaderForStream(StreamId stream_id,
55                                    std::string_view key,
56                                    std::string_view value) override;
57   bool OnEndHeadersForStream(StreamId stream_id) override;
58   bool OnEndStream(StreamId stream_id) override;
59   bool OnCloseStream(StreamId stream_id,
60                      http2::adapter::Http2ErrorCode error_code) override;
61   DataFrameHeaderInfo OnReadyToSendDataForStream(StreamId stream_id,
62                                                  size_t max_length) override;
63   bool SendDataFrame(StreamId stream_id,
64                      absl::string_view frame_header,
65                      size_t payload_bytes) override;
66   // Unused functions
OnConnectionError(ConnectionError)67   void OnConnectionError(ConnectionError /*error*/) override {}
68   bool OnFrameHeader(StreamId /*stream_id*/,
69                      size_t /*length*/,
70                      uint8_t /*type*/,
71                      uint8_t /*flags*/) override;
OnSettingsStart()72   void OnSettingsStart() override {}
OnSetting(http2::adapter::Http2Setting setting)73   void OnSetting(http2::adapter::Http2Setting setting) override {}
OnSettingsEnd()74   void OnSettingsEnd() override {}
OnSettingsAck()75   void OnSettingsAck() override {}
76   bool OnBeginHeadersForStream(StreamId stream_id) override;
77   bool OnBeginDataForStream(StreamId stream_id, size_t payload_length) override;
78   bool OnDataForStream(StreamId stream_id, std::string_view data) override;
79   bool OnDataPaddingLength(StreamId stream_id, size_t padding_length) override;
OnRstStream(StreamId stream_id,http2::adapter::Http2ErrorCode error_code)80   void OnRstStream(StreamId stream_id,
81                    http2::adapter::Http2ErrorCode error_code) override {}
OnPriorityForStream(StreamId stream_id,StreamId parent_stream_id,int weight,bool exclusive)82   void OnPriorityForStream(StreamId stream_id,
83                            StreamId parent_stream_id,
84                            int weight,
85                            bool exclusive) override {}
OnPing(http2::adapter::Http2PingId ping_id,bool is_ack)86   void OnPing(http2::adapter::Http2PingId ping_id, bool is_ack) override {}
OnPushPromiseForStream(StreamId stream_id,StreamId promised_stream_id)87   void OnPushPromiseForStream(StreamId stream_id,
88                               StreamId promised_stream_id) override {}
89   bool OnGoAway(StreamId last_accepted_stream_id,
90                 http2::adapter::Http2ErrorCode error_code,
91                 std::string_view opaque_data) override;
OnWindowUpdate(StreamId stream_id,int window_increment)92   void OnWindowUpdate(StreamId stream_id, int window_increment) override {}
93   int OnBeforeFrameSent(uint8_t frame_type,
94                         StreamId stream_id,
95                         size_t length,
96                         uint8_t flags) override;
97   int OnFrameSent(uint8_t frame_type,
98                   StreamId stream_id,
99                   size_t length,
100                   uint8_t flags,
101                   uint32_t error_code) override;
102   bool OnInvalidFrame(StreamId stream_id, InvalidFrameError error) override;
OnBeginMetadataForStream(StreamId stream_id,size_t payload_length)103   void OnBeginMetadataForStream(StreamId stream_id,
104                                 size_t payload_length) override {}
105   bool OnMetadataForStream(StreamId stream_id,
106                            std::string_view metadata) override;
107   bool OnMetadataEndForStream(StreamId stream_id) override;
OnErrorDebug(std::string_view message)108   void OnErrorDebug(std::string_view message) override {}
109 
adapter()110   http2::adapter::OgHttp2Adapter* adapter() { return adapter_.get(); }
111 
112  private:
113   // Corresponds to one HTTP/2 stream in a connection
114   class ResponseDelegate;
115   class DataFrameSource;
116 
117   void ReadData();
118   void OnDataRead(int rv);
119   bool HandleData(int rv);
120   void SendInternal();
121   void OnSendInternalDone(int rv);
122 
123   void SendIfNotProcessing();
124 
125   StreamMap<std::unique_ptr<HttpRequest>> request_map_;
126   StreamMap<std::unique_ptr<ResponseDelegate>> response_map_;
127   StreamMap<HttpRequest::HeaderMap> header_map_;
128   std::queue<StreamId> ready_streams_;
129   std::unique_ptr<http2::adapter::OgHttp2Adapter> adapter_;
130   std::unique_ptr<StreamSocket> socket_;
131   const raw_ptr<EmbeddedTestServerConnectionListener> connection_listener_;
132   const raw_ptr<EmbeddedTestServer> embedded_test_server_;
133   scoped_refptr<IOBufferWithSize> read_buf_;
134   // Frames can be submitted asynchronusly, so frames will be pulled one at a
135   // time by the data frame through ReadyToSend. If the buffer is not null, it
136   // is being processed and new frames should be blocked.
137   scoped_refptr<DrainableIOBuffer> write_buf_{nullptr};
138   // Streams from a DataFrameSource that were blocked.
139   base::flat_set<StreamId> blocked_streams_;
140   // Whether the connection is in the midst of processing requests, and will
141   // send queued frames and data sources. Stops early on an I/O block or
142   // depleted flow-control window.
143   bool processing_responses_ = false;
144 
145   base::WeakPtrFactory<Http2Connection> weak_factory_{this};
146 };
147 
148 }  // namespace net::test_server
149 
150 #endif  // NET_TEST_EMBEDDED_TEST_SERVER_HTTP2_CONNECTION_H_
151