proxygen
HTTP2Codec.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-present, Facebook, Inc.
3  * All rights reserved.
4  *
5  * This source code is licensed under the BSD-style license found in the
6  * LICENSE file in the root directory of this source tree. An additional grant
7  * of patent rights can be found in the PATENTS file in the same directory.
8  *
9  */
10 #pragma once
11 
19 
20 #include <bitset>
21 #include <set>
22 
23 namespace proxygen {
24 
30 public:
31  void onHeader(const folly::fbstring& name,
32  const folly::fbstring& value) override;
33  void onHeadersComplete(HTTPHeaderSize decodedSize) override;
34  void onDecodeError(HPACK::DecodeError decodeError) override;
35 
36  explicit HTTP2Codec(TransportDirection direction);
37  ~HTTP2Codec() override;
38 
39  // HTTPCodec API
40  CodecProtocol getProtocol() const override {
41  return CodecProtocol::HTTP_2;
42  }
43 
44  const std::string& getUserAgent() const override {
45  return userAgent_;
46  }
47 
48  size_t onIngress(const folly::IOBuf& buf) override;
49  bool onIngressUpgradeMessage(const HTTPMessage& msg) override;
51  void generateHeader(folly::IOBufQueue& writeBuf,
53  const HTTPMessage& msg,
54  bool eom = false,
55  HTTPHeaderSize* size = nullptr) override;
57  folly::IOBufQueue& queue,
58  StreamID stream,
59  size_t maxFrameSize);
61  StreamID stream,
62  const HTTPMessage& msg,
63  StreamID assocStream,
64  bool eom = false,
65  HTTPHeaderSize* size = nullptr) override;
66  void generateExHeader(folly::IOBufQueue& writeBuf,
67  StreamID stream,
68  const HTTPMessage& msg,
69  const HTTPCodec::ExAttributes& exAttributes,
70  bool eom = false,
71  HTTPHeaderSize* size = nullptr) override;
72  size_t generateBody(folly::IOBufQueue& writeBuf,
73  StreamID stream,
74  std::unique_ptr<folly::IOBuf> chain,
76  bool eom) override;
77  size_t generateChunkHeader(folly::IOBufQueue& writeBuf,
78  StreamID stream,
79  size_t length) override;
81  StreamID stream) override;
82  size_t generateTrailers(folly::IOBufQueue& writeBuf,
83  StreamID stream,
84  const HTTPHeaders& trailers) override;
85  size_t generateEOM(folly::IOBufQueue& writeBuf,
86  StreamID stream) override;
87  size_t generateRstStream(folly::IOBufQueue& writeBuf,
88  StreamID stream,
89  ErrorCode statusCode) override;
90  size_t generateGoaway(
91  folly::IOBufQueue& writeBuf,
92  StreamID lastStream,
93  ErrorCode statusCode,
94  std::unique_ptr<folly::IOBuf> debugData = nullptr) override;
95  size_t generatePingRequest(folly::IOBufQueue& writeBuf) override;
96  size_t generatePingReply(folly::IOBufQueue& writeBuf,
97  uint64_t uniqueID) override;
98  size_t generateSettings(folly::IOBufQueue& writeBuf) override;
99  size_t generateSettingsAck(folly::IOBufQueue& writeBuf) override;
100  size_t generateWindowUpdate(folly::IOBufQueue& writeBuf,
101  StreamID stream,
102  uint32_t delta) override;
103  size_t generatePriority(folly::IOBufQueue& writeBuf,
104  StreamID stream,
105  const HTTPMessage::HTTPPriority& pri) override;
107  folly::IOBufQueue& writeBuf,
108  uint16_t requestId,
109  std::unique_ptr<folly::IOBuf> certificateRequestData) override;
110  size_t generateCertificate(folly::IOBufQueue& writeBuf,
111  uint16_t certId,
112  std::unique_ptr<folly::IOBuf> certData) override;
113  const HTTPSettings* getIngressSettings() const override {
114  return &ingressSettings_;
115  }
117  uint32_t getDefaultWindowSize() const override {
118  return http2::kInitialWindow;
119  }
120  bool supportsPushTransactions() const override {
121  return
126  }
127  bool peerHasWebsockets() const {
129  }
130  bool supportsExTransactions() const override {
133  }
134  void setHeaderCodecStats(HeaderCodec::Stats* hcStats) override {
135  headerCodec_.setStats(hcStats);
136  }
137 
138  bool isRequest(StreamID id) const {
140  (id & 0x1) == 1) ||
142  (id & 0x1) == 0));
143  }
144 
145  size_t addPriorityNodes(
146  PriorityQueue& queue,
147  folly::IOBufQueue& writeBuf,
148  uint8_t maxLevel) override;
149  HTTPCodec::StreamID mapPriorityToDependency(uint8_t priority) const override;
150 
153  }
154 
155  //HTTP2Codec specific API
156 
157  static void requestUpgrade(HTTPMessage& request);
158 
159 #ifndef NDEBUG
161  return receivedFrameCount_;
162  }
163 #endif
164 
165  // Whether turn on the optimization to reuse IOBuf headroom when write DATA
166  // frame. For other frames, it's always ON.
167  void setReuseIOBufHeadroomForData(bool enabled) {
168  reuseIOBufHeadroomForData_ = enabled;
169  }
170 
173  }
176  }
177 
178  private:
179  void generateHeaderImpl(folly::IOBufQueue& writeBuf,
180  StreamID stream,
181  const HTTPMessage& msg,
182  const folly::Optional<StreamID>& assocStream,
183  const folly::Optional<ExAttributes>& exAttributes,
184  bool eom,
186  std::unique_ptr<folly::IOBuf> encodeHeaders(
187  const HTTPHeaders& headers,
188  std::vector<compress::Header>& allHeaders,
189  HTTPHeaderSize* size);
190 
191  size_t generateHeaderCallbackWrapper(StreamID stream, http2::FrameType type, size_t length);
192 
196  folly::io::Cursor& cursor,
197  size_t bufLen,
198  size_t& parsed);
212  folly::io::Cursor& cursor,
213  std::unique_ptr<folly::IOBuf> headerBuf,
215  const folly::Optional<uint32_t>& promisedStream,
216  const folly::Optional<ExAttributes>& exAttributes);
219  const folly::Optional<uint32_t>& promisedStream,
220  const folly::Optional<ExAttributes>& exAttributes,
221  std::unique_ptr<HTTPMessage>& msg);
224 
226  ErrorCode checkNewStream(uint32_t stream, bool trailersAllowed);
227  bool checkConnectionError(ErrorCode, const folly::IOBuf* buf);
228  ErrorCode handleSettings(const std::deque<SettingPair>& settings);
229  size_t maxSendFrameSize() const {
232  }
236  }
237  void streamError(const std::string& msg, ErrorCode error, bool newTxn=false);
238  bool parsingTrailers() const;
239 
241 
242  // Current frame state
247 
248  std::unordered_set<StreamID> upgradedStreams_;
249 
253 
258  { SettingsId::MAX_FRAME_SIZE, 16384 },
259  };
263  { SettingsId::MAX_FRAME_SIZE, 16384 },
264  { SettingsId::MAX_HEADER_LIST_SIZE, 1 << 17 }, // same as SPDYCodec
265  };
266 #ifndef NDEBUG
268 #endif
269  enum FrameState {
275  };
278 
281 
283  std::vector<StreamID> virtualPriorityNodes_;
285 
286  // True if last parsed HEADERS frame was trailers.
287  // Reset only when HEADERS frame is parsed, thus
288  // remains unchanged and used during CONTINUATION frame
289  // parsing as well.
290  // Applies only to DOWNSTREAM, for UPSTREAM we use
291  // diffrent heuristic - lack of status code.
293 
294  // CONTINUATION frame can follow either HEADERS or PUSH_PROMISE frames.
295  // Keeps frame type of iniating frame of header block.
297 };
298 
299 } // proxygen
size_t addPriorityNodes(PriorityQueue &queue, folly::IOBufQueue &writeBuf, uint8_t maxLevel) override
Definition: HTTP2Codec.cpp:670
void generateContinuation(folly::IOBufQueue &writeBuf, folly::IOBufQueue &queue, StreamID stream, size_t maxFrameSize)
ErrorCode parseFrame(folly::io::Cursor &cursor)
Definition: HTTP2Codec.cpp:163
ErrorCode parseDataFrameData(folly::io::Cursor &cursor, size_t bufLen, size_t &parsed)
Definition: HTTP2Codec.cpp:299
ErrorCode parsePushPromise(folly::io::Cursor &cursor)
Definition: HTTP2Codec.cpp:817
const uint32_t kInitialWindow
spdy::GoawayStatusCode statusCode
Definition: SPDYCodec.cpp:110
folly::IOBufQueue curHeaderBlock_
Definition: HTTP2Codec.h:254
FrameState frameState_
Definition: HTTP2Codec.h:276
http2::FrameType headerBlockFrameType_
Definition: HTTP2Codec.h:296
ErrorCode parseWindowUpdate(folly::io::Cursor &cursor)
Definition: HTTP2Codec.cpp:898
HTTP2Codec(TransportDirection direction)
Definition: HTTP2Codec.cpp:42
HTTPSettings ingressSettings_
Definition: HTTP2Codec.h:255
ErrorCode parseContinuation(folly::io::Cursor &cursor)
Definition: HTTP2Codec.cpp:413
ErrorCode parseCertificateRequest(folly::io::Cursor &cursor)
Definition: HTTP2Codec.cpp:931
ErrorCode parseCertificate(folly::io::Cursor &cursor)
Definition: HTTP2Codec.cpp:945
void setHeaderCodecStats(HeaderCodec::Stats *hcStats) override
Definition: HTTP2Codec.h:134
ErrorCode parseHeadersImpl(folly::io::Cursor &cursor, std::unique_ptr< folly::IOBuf > headerBuf, const folly::Optional< http2::PriorityUpdate > &priority, const folly::Optional< uint32_t > &promisedStream, const folly::Optional< ExAttributes > &exAttributes)
Definition: HTTP2Codec.cpp:424
HTTPSettings egressSettings_
Definition: HTTP2Codec.h:260
size_t generatePingReply(folly::IOBufQueue &writeBuf, uint64_t uniqueID) override
void generatePushPromise(folly::IOBufQueue &writeBuf, StreamID stream, const HTTPMessage &msg, StreamID assocStream, bool eom=false, HTTPHeaderSize *size=nullptr) override
size_t generatePingRequest(folly::IOBufQueue &writeBuf) override
void onHeader(const folly::fbstring &name, const folly::fbstring &value) override
Definition: HTTP2Codec.cpp:606
ErrorCode parseGoaway(folly::io::Cursor &cursor)
Definition: HTTP2Codec.cpp:869
PskType type
void generateExHeader(folly::IOBufQueue &writeBuf, StreamID stream, const HTTPMessage &msg, const HTTPCodec::ExAttributes &exAttributes, bool eom=false, HTTPHeaderSize *size=nullptr) override
size_t onIngress(const folly::IOBuf &buf) override
Definition: HTTP2Codec.cpp:70
void generateHeaderImpl(folly::IOBufQueue &writeBuf, StreamID stream, const HTTPMessage &msg, const folly::Optional< StreamID > &assocStream, const folly::Optional< ExAttributes > &exAttributes, bool eom, HTTPHeaderSize *size)
folly::Optional< ErrorCode > parseHeadersDecodeFrames(const folly::Optional< http2::PriorityUpdate > &priority, const folly::Optional< uint32_t > &promisedStream, const folly::Optional< ExAttributes > &exAttributes, std::unique_ptr< HTTPMessage > &msg)
Definition: HTTP2Codec.cpp:507
std::unordered_set< StreamID > upgradedStreams_
Definition: HTTP2Codec.h:248
bool supportsExTransactions() const override
Definition: HTTP2Codec.h:130
void generateHeader(folly::IOBufQueue &writeBuf, StreamID stream, const HTTPMessage &msg, bool eom=false, HTTPHeaderSize *size=nullptr) override
size_t generateRstStream(folly::IOBufQueue &writeBuf, StreamID stream, ErrorCode statusCode) override
static http_parser_settings settings
Definition: test.c:1529
ErrorCode checkNewStream(uint32_t stream, bool trailersAllowed)
Definition: HTTP2Codec.cpp:973
ErrorCode parseAllData(folly::io::Cursor &cursor)
Definition: HTTP2Codec.cpp:281
const HeaderIndexingStrategy * getHeaderIndexingStrategy() const
Definition: HPACKCodec.h:81
size_t generateCertificate(folly::IOBufQueue &writeBuf, uint16_t certId, std::unique_ptr< folly::IOBuf > certData) override
HPACKTableInfo getHPACKTableInfo() const override
Definition: HTTP2Codec.h:151
requires And< SemiMovable< VN >... > &&SemiMovable< E > auto error(E e)
Definition: error.h:48
size_t generateEOM(folly::IOBufQueue &writeBuf, StreamID stream) override
const HeaderIndexingStrategy * getHeaderIndexingStrategy() const
Definition: HTTP2Codec.h:174
const HTTPSettings * getIngressSettings() const override
Definition: HTTP2Codec.h:113
bool peerHasWebsockets() const
Definition: HTTP2Codec.h:127
size_t generateBody(folly::IOBufQueue &writeBuf, StreamID stream, std::unique_ptr< folly::IOBuf > chain, folly::Optional< uint8_t > padding, bool eom) override
HPACKCodec headerCodec_
Definition: HTTP2Codec.h:240
size_t generatePriority(folly::IOBufQueue &writeBuf, StreamID stream, const HTTPMessage::HTTPPriority &pri) override
size_t pendingDataFrameBytes_
Definition: HTTP2Codec.h:279
size_t maxSendFrameSize() const
Definition: HTTP2Codec.h:229
static void requestUpgrade(HTTPMessage &request)
HTTPCodec::StreamID mapPriorityToDependency(uint8_t priority) const override
const char * name
Definition: http_parser.c:437
bool pendingEndStreamHandling_
Definition: HTTP2Codec.h:245
bool onIngressUpgradeMessage(const HTTPMessage &msg) override
const uint32_t kMaxFramePayloadLengthMin
size_t generateSettingsAck(folly::IOBufQueue &writeBuf) override
uint32_t maxRecvFrameSize() const
Definition: HTTP2Codec.h:233
folly::Optional< ErrorCode > parseHeadersCheckConcurrentStreams(const folly::Optional< http2::PriorityUpdate > &priority)
Definition: HTTP2Codec.cpp:585
ErrorCode handleSettings(const std::deque< SettingPair > &settings)
Definition: HTTP2Codec.cpp:721
constexpr auto size(C const &c) -> decltype(c.size())
Definition: Access.h:45
void setHeaderIndexingStrategy(const HeaderIndexingStrategy *indexingStrat)
Definition: HTTP2Codec.h:171
void writeBuf(const Buf &buf, folly::io::Appender &out)
static Options cacheChainLength()
Definition: IOBufQueue.h:83
size_t generateConnectionPreface(folly::IOBufQueue &writeBuf) override
void onDecodeError(HPACK::DecodeError decodeError) override
Definition: HTTP2Codec.cpp:646
size_t generateGoaway(folly::IOBufQueue &writeBuf, StreamID lastStream, ErrorCode statusCode, std::unique_ptr< folly::IOBuf > debugData=nullptr) override
HeaderDecodeInfo decodeInfo_
Definition: HTTP2Codec.h:282
std::vector< StreamID > virtualPriorityNodes_
Definition: HTTP2Codec.h:283
static const char *const value
Definition: Conv.cpp:50
StreamID expectedContinuationStream_
Definition: HTTP2Codec.h:244
folly::IOBufQueue curAuthenticatorBlock_
Definition: HTTP2Codec.h:251
http2::FrameHeader curHeader_
Definition: HTTP2Codec.h:243
ErrorCode parseExHeaders(folly::io::Cursor &cursor)
Definition: HTTP2Codec.cpp:395
size_t generateHeaderCallbackWrapper(StreamID stream, http2::FrameType type, size_t length)
void setStats(Stats *stats)
Definition: HeaderCodec.h:84
std::tuple< uint32_t, bool, uint8_t > HTTPPriority
Definition: HTTPMessage.h:592
size_t generateTrailers(folly::IOBufQueue &writeBuf, StreamID stream, const HTTPHeaders &trailers) override
uint64_t receivedFrameCount_
Definition: HTTP2Codec.h:267
bool reuseIOBufHeadroomForData_
Definition: HTTP2Codec.h:284
~HTTP2Codec() override
Definition: HTTP2Codec.cpp:66
void streamError(const std::string &msg, ErrorCode error, bool newTxn=false)
bool parsingDownstreamTrailers_
Definition: HTTP2Codec.h:292
std::unique_ptr< folly::IOBuf > encodeHeaders(const HTTPHeaders &headers, std::vector< compress::Header > &allHeaders, HTTPHeaderSize *size)
HTTPSettings * getEgressSettings() override
Definition: HTTP2Codec.h:116
size_t pendingDataFramePaddingBytes_
Definition: HTTP2Codec.h:280
bool checkConnectionError(ErrorCode, const folly::IOBuf *buf)
ErrorCode parseSettings(folly::io::Cursor &cursor)
Definition: HTTP2Codec.cpp:705
const char * string
Definition: Conv.cpp:212
size_t generateChunkHeader(folly::IOBufQueue &writeBuf, StreamID stream, size_t length) override
const std::string & getUserAgent() const override
Definition: HTTP2Codec.h:44
ErrorCode parseRstStream(folly::io::Cursor &cursor)
Definition: HTTP2Codec.cpp:686
size_t generateWindowUpdate(folly::IOBufQueue &writeBuf, StreamID stream, uint32_t delta) override
CodecProtocol getProtocol() const override
Definition: HTTP2Codec.h:40
ErrorCode parsePriority(folly::io::Cursor &cursor)
Definition: HTTP2Codec.cpp:650
uint64_t StreamID
Definition: HTTPCodec.h:49
void onHeadersComplete(HTTPHeaderSize decodedSize) override
Definition: HTTP2Codec.cpp:618
uint64_t getReceivedFrameCount() const
Definition: HTTP2Codec.h:160
TransportDirection transportDirection_
ErrorCode handleEndStream()
Definition: HTTP2Codec.cpp:252
ErrorCode parsePing(folly::io::Cursor &cursor)
Definition: HTTP2Codec.cpp:854
void setHeaderIndexingStrategy(const HeaderIndexingStrategy *indexingStrat)
Definition: HPACKCodec.h:78
std::string userAgent_
Definition: HTTP2Codec.h:277
HPACKTableInfo getHPACKTableInfo() const
Definition: HPACKCodec.h:69
void setReuseIOBufHeadroomForData(bool enabled)
Definition: HTTP2Codec.h:167
bool supportsPushTransactions() const override
Definition: HTTP2Codec.h:120
bool parsingTrailers() const
size_t generateChunkTerminator(folly::IOBufQueue &writeBuf, StreamID stream) override
size_t generateSettings(folly::IOBufQueue &writeBuf) override
const HTTPSetting * getSetting(SettingsId id) const
size_t generateCertificateRequest(folly::IOBufQueue &writeBuf, uint16_t requestId, std::unique_ptr< folly::IOBuf > certificateRequestData) override
ErrorCode parseHeaders(folly::io::Cursor &cursor)
Definition: HTTP2Codec.cpp:378
bool isRequest(StreamID id) const
Definition: HTTP2Codec.h:138
uint32_t getDefaultWindowSize() const override
Definition: HTTP2Codec.h:117