summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/quiche/spdy/core/metadata_extension.h
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/third_party/quiche/src/quiche/spdy/core/metadata_extension.h')
-rw-r--r--chromium/net/third_party/quiche/src/quiche/spdy/core/metadata_extension.h116
1 files changed, 116 insertions, 0 deletions
diff --git a/chromium/net/third_party/quiche/src/quiche/spdy/core/metadata_extension.h b/chromium/net/third_party/quiche/src/quiche/spdy/core/metadata_extension.h
new file mode 100644
index 00000000000..a27ad165caa
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quiche/spdy/core/metadata_extension.h
@@ -0,0 +1,116 @@
+#ifndef QUICHE_SPDY_CORE_METADATA_EXTENSION_H_
+#define QUICHE_SPDY_CORE_METADATA_EXTENSION_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/container/flat_hash_map.h"
+#include "quiche/spdy/core/http2_frame_decoder_adapter.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+#include "quiche/spdy/core/zero_copy_output_buffer.h"
+
+namespace spdy {
+
+// An implementation of the ExtensionVisitorInterface that can parse
+// METADATA frames. METADATA is a non-standard HTTP/2 extension developed and
+// used internally at Google. A peer advertises support for METADATA by sending
+// a setting with a setting ID of kMetadataExtensionId and a value of 1.
+//
+// Metadata is represented as a HPACK header block with literal encoding.
+class MetadataVisitor : public spdy::ExtensionVisitorInterface {
+ public:
+ using MetadataPayload = spdy::SpdyHeaderBlock;
+
+ static_assert(!std::is_copy_constructible<MetadataPayload>::value,
+ "MetadataPayload should be a move-only type!");
+
+ using OnMetadataSupport = std::function<void(bool)>;
+ using OnCompletePayload =
+ std::function<void(spdy::SpdyStreamId, MetadataPayload)>;
+
+ // The HTTP/2 SETTINGS ID that is used to indicate support for METADATA
+ // frames.
+ static const spdy::SpdySettingsId kMetadataExtensionId;
+
+ // The 8-bit frame type code for a METADATA frame.
+ static const uint8_t kMetadataFrameType;
+
+ // The flag that indicates the end of a logical metadata block. Due to frame
+ // size limits, a single metadata block may be emitted as several HTTP/2
+ // frames.
+ static const uint8_t kEndMetadataFlag;
+
+ // |on_payload| is invoked whenever a complete metadata payload is received.
+ // |on_support| is invoked whenever the peer's advertised support for metadata
+ // changes.
+ MetadataVisitor(OnCompletePayload on_payload, OnMetadataSupport on_support);
+ ~MetadataVisitor() override;
+
+ MetadataVisitor(const MetadataVisitor&) = delete;
+ MetadataVisitor& operator=(const MetadataVisitor&) = delete;
+
+ // Interprets the non-standard setting indicating support for METADATA.
+ void OnSetting(spdy::SpdySettingsId id, uint32_t value) override;
+
+ // Returns true iff |type| indicates a METADATA frame.
+ bool OnFrameHeader(spdy::SpdyStreamId stream_id, size_t length, uint8_t type,
+ uint8_t flags) override;
+
+ // Consumes a METADATA frame payload. Invokes the registered callback when a
+ // complete payload has been received.
+ void OnFramePayload(const char* data, size_t len) override;
+
+ // Returns true if the peer has advertised support for METADATA via the
+ // appropriate setting.
+ bool PeerSupportsMetadata() const {
+ return peer_supports_metadata_ == MetadataSupportState::SUPPORTED;
+ }
+
+ private:
+ enum class MetadataSupportState : uint8_t {
+ UNSPECIFIED,
+ SUPPORTED,
+ NOT_SUPPORTED,
+ };
+
+ struct MetadataPayloadState;
+
+ using StreamMetadataMap =
+ absl::flat_hash_map<spdy::SpdyStreamId,
+ std::unique_ptr<MetadataPayloadState>>;
+
+ OnCompletePayload on_payload_;
+ OnMetadataSupport on_support_;
+ StreamMetadataMap metadata_map_;
+ spdy::SpdyStreamId current_stream_;
+ MetadataSupportState peer_supports_metadata_;
+};
+
+// A class that serializes metadata blocks as sequences of frames.
+class MetadataSerializer {
+ public:
+ using MetadataPayload = spdy::SpdyHeaderBlock;
+
+ class FrameSequence {
+ public:
+ virtual ~FrameSequence() {}
+
+ // Returns nullptr once the sequence has been exhausted.
+ virtual std::unique_ptr<spdy::SpdyFrameIR> Next() = 0;
+ };
+
+ MetadataSerializer() {}
+
+ MetadataSerializer(const MetadataSerializer&) = delete;
+ MetadataSerializer& operator=(const MetadataSerializer&) = delete;
+
+ // Returns nullptr on failure.
+ std::unique_ptr<FrameSequence> FrameSequenceForPayload(
+ spdy::SpdyStreamId stream_id, MetadataPayload payload);
+};
+
+} // namespace spdy
+
+#endif // QUICHE_SPDY_CORE_METADATA_EXTENSION_H_