1
#pragma once
2

            
3
#include <cstdint>
4
#include <string>
5

            
6
#include "envoy/http/codec.h"
7

            
8
#include "source/common/buffer/buffer_impl.h"
9
#include "source/common/common/logger.h"
10

            
11
namespace Envoy {
12
namespace Http {
13
namespace Http2 {
14

            
15
class MetadataEncoderDecoderTest_VerifyEncoderDecoderOnMultipleMetadataMaps_Test;
16

            
17
// A class that decodes METADATA payload in the format of HTTP/2 header block into MetadataMap, a
18
// map of string key value pairs.
19
class MetadataDecoder : Logger::Loggable<Logger::Id::http2> {
20
public:
21
  /**
22
   * @param cb is the decoder's callback function. The callback function is called when the decoder
23
   * finishes decoding metadata.
24
   */
25
  MetadataDecoder(MetadataCallback cb, uint64_t max_payload_size_bound);
26
  ~MetadataDecoder();
27

            
28
  /**
29
   * Calls this function when METADATA frame payload is received. The payload doesn't need to be
30
   * complete.
31
   * @param data is the pointer to the start of the payload.
32
   * @param len is the size of the received payload.
33
   * @return whether Metadata is received successfully.
34
   */
35
  bool receiveMetadata(const uint8_t* data, size_t len);
36

            
37
  /**
38
   * Calls when a complete METADATA frame is received. The function will decode METADATA received.
39
   * If the frame is the last one in the group, the function triggers the registered callback
40
   * function callback_.
41
   * @param end_metadata indicates if all the METADATA has been received.
42
   * @return whether the operation succeeds.
43
   */
44
  bool onMetadataFrameComplete(bool end_metadata);
45

            
46
  /**
47
   * Returns the total size of METADATA frame payloads received.
48
   */
49
3
  uint64_t totalPayloadSize() const { return total_payload_size_; }
50

            
51
private:
52
  friend class MetadataEncoderDecoderTest_VerifyEncoderDecoderOnMultipleMetadataMaps_Test;
53
  friend class MetadataEncoderDecoderTest_VerifyEncoderDecoderMultipleMetadataReachSizeLimit_Test;
54
  friend class MetadataEncoderTest_VerifyEncoderDecoderOnMultipleMetadataMaps_Test;
55
  friend class MetadataEncoderTest_VerifyEncoderDecoderMultipleMetadataReachSizeLimit_Test;
56
  friend class MetadataEncoderTest_VerifyAdjustingMetadataSizeLimit_Test;
57

            
58
  struct HpackDecoderContext;
59

            
60
  /**
61
   * Decodes METADATA payload using QUICHE.
62
   * @param end_metadata indicates is END_METADATA is true.
63
   * @return if decoding succeeds.
64
   */
65
  bool decodeMetadataPayload(bool end_metadata);
66

            
67
  void resetDecoderContext();
68

            
69
  // Metadata that is currently being decoded.
70
  MetadataMapPtr metadata_map_;
71

            
72
  // Metadata event callback function.
73
  MetadataCallback callback_;
74

            
75
  // Payload received.
76
  Buffer::OwnedImpl payload_;
77

            
78
  // Payload size limit. If the total payload received exceeds the limit, fails the connection.
79
  const uint64_t max_payload_size_bound_;
80

            
81
  uint64_t total_payload_size_ = 0;
82

            
83
  std::unique_ptr<HpackDecoderContext> decoder_context_;
84
};
85

            
86
} // namespace Http2
87
} // namespace Http
88
} // namespace Envoy