1 /* 2 * Copyright (c) Facebook, Inc. and its affiliates. 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. 7 */ 8 9 #pragma once 10 11 #include <memory> 12 #include <proxygen/lib/http/codec/TransportDirection.h> 13 #include <proxygen/lib/http/codec/compress/HPACKCodec.h> // table info 14 #include <proxygen/lib/http/codec/compress/HeaderCodec.h> 15 #include <proxygen/lib/http/codec/compress/HeaderIndexingStrategy.h> 16 #include <proxygen/lib/http/codec/compress/QPACKDecoder.h> 17 #include <proxygen/lib/http/codec/compress/QPACKEncoder.h> 18 #include <string> 19 #include <vector> 20 21 namespace folly { namespace io { 22 class Cursor; 23 }} // namespace folly::io 24 25 namespace proxygen { 26 27 class HPACKHeader; 28 29 /* 30 * Current version of the wire protocol. When we're making changes to the wire 31 * protocol we need to change this version and the ALPN string so that old 32 * clients will not be able to negotiate it anymore. 33 */ 34 35 class QPACKCodec : public HeaderCodec { 36 public: 37 QPACKCodec(); ~QPACKCodec()38 ~QPACKCodec() override { 39 } 40 41 // QPACK encode: id is used for internal tracking of references 42 QPACKEncoder::EncodeResult encode( 43 std::vector<compress::Header>& headers, 44 uint64_t id, 45 uint32_t maxEncoderStreamBytes = 46 std::numeric_limits<uint32_t>::max()) noexcept; 47 48 std::unique_ptr<folly::IOBuf> encodeHTTP( 49 folly::IOBufQueue& controlQueue, 50 const HTTPMessage& msg, 51 bool includeDate, 52 uint64_t id, 53 uint32_t maxEncoderStreamBytes = std::numeric_limits<uint32_t>::max(), 54 const folly::Optional<HTTPHeaders>& extraHeaders = folly::none) noexcept; 55 decodeEncoderStream(std::unique_ptr<folly::IOBuf> buf)56 HPACK::DecodeError decodeEncoderStream(std::unique_ptr<folly::IOBuf> buf) { 57 // stats? 58 return decoder_.decodeEncoderStream(std::move(buf)); 59 } 60 encoderStreamEnd()61 HPACK::DecodeError encoderStreamEnd() { 62 return decoder_.encoderStreamEnd(); 63 } 64 65 // QPACK blocking decode. The decoder may queue the block if there are 66 // unsatisfied dependencies 67 void decodeStreaming(uint64_t streamId, 68 std::unique_ptr<folly::IOBuf> block, 69 uint32_t length, 70 HPACK::StreamingCallback* streamingCb) noexcept; 71 72 // This function sets both the decoder's advertised max and the size the 73 // encoder will use. The encoder has a limit of 64k. This function can 74 // only be called once with a unique non-zero value. 75 // 76 // Returns false if it was previously called with a different non-zero value. 77 bool setEncoderHeaderTableSize(uint32_t size, bool updateMax = true) { 78 VLOG(4) << __func__ << " size=" << size; 79 return encoder_.setHeaderTableSize(size, updateMax); 80 } 81 setDecoderHeaderTableMaxSize(uint32_t size)82 void setDecoderHeaderTableMaxSize(uint32_t size) { 83 decoder_.setHeaderTableMaxSize(size); 84 } 85 86 // Process bytes on the decoder stream decodeDecoderStream(std::unique_ptr<folly::IOBuf> buf)87 HPACK::DecodeError decodeDecoderStream(std::unique_ptr<folly::IOBuf> buf) { 88 return encoder_.decodeDecoderStream(std::move(buf)); 89 } 90 decoderStreamEnd()91 HPACK::DecodeError decoderStreamEnd() { 92 return encoder_.decoderStreamEnd(); 93 } 94 95 // QPACK when a stream is reset. Clears all reference counts for outstanding 96 // blocks onStreamReset(uint64_t streamId)97 void onStreamReset(uint64_t streamId) { 98 encoder_.onHeaderAck(streamId, true); 99 } 100 encodeInsertCountInc()101 std::unique_ptr<folly::IOBuf> encodeInsertCountInc() { 102 return decoder_.encodeInsertCountInc(); 103 } 104 encodeHeaderAck(uint64_t streamId)105 std::unique_ptr<folly::IOBuf> encodeHeaderAck(uint64_t streamId) { 106 return decoder_.encodeHeaderAck(streamId); 107 } 108 encodeCancelStream(uint64_t streamId)109 std::unique_ptr<folly::IOBuf> encodeCancelStream(uint64_t streamId) { 110 return decoder_.encodeCancelStream(streamId); 111 } 112 113 void describe(std::ostream& os) const; 114 setMaxUncompressed(uint64_t maxUncompressed)115 void setMaxUncompressed(uint64_t maxUncompressed) override { 116 HeaderCodec::setMaxUncompressed(maxUncompressed); 117 decoder_.setMaxUncompressed(maxUncompressed); 118 } 119 getCompressionInfo()120 CompressionInfo getCompressionInfo() const { 121 return CompressionInfo(encoder_.getTableSize(), 122 encoder_.getBytesStored(), 123 encoder_.getHeadersStored(), 124 encoder_.getInsertCount(), 125 encoder_.getBlockedInserts(), 126 encoder_.getDuplications(), 127 encoder_.getStaticRefs(), 128 decoder_.getTableSize(), 129 decoder_.getBytesStored(), 130 decoder_.getHeadersStored(), 131 decoder_.getInsertCount(), 132 0, // decoder can't track blocked inserts 133 decoder_.getDuplications(), 134 decoder_.getStaticRefs()); 135 } 136 setHeaderIndexingStrategy(const HeaderIndexingStrategy * indexingStrat)137 void setHeaderIndexingStrategy(const HeaderIndexingStrategy* indexingStrat) { 138 encoder_.setHeaderIndexingStrategy(indexingStrat); 139 } getHeaderIndexingStrategy()140 const HeaderIndexingStrategy* getHeaderIndexingStrategy() const { 141 return encoder_.getHeaderIndexingStrategy(); 142 } 143 getHolBlockCount()144 uint64_t getHolBlockCount() const { 145 return decoder_.getHolBlockCount(); 146 } 147 getQueuedBytes()148 uint64_t getQueuedBytes() const { 149 return decoder_.getQueuedBytes(); 150 } 151 setMaxVulnerable(uint32_t maxVulnerable)152 void setMaxVulnerable(uint32_t maxVulnerable) { 153 encoder_.setMaxVulnerable(maxVulnerable); 154 } 155 setMaxBlocking(uint32_t maxBlocking)156 void setMaxBlocking(uint32_t maxBlocking) { 157 decoder_.setMaxBlocking(maxBlocking); 158 } 159 setMaxNumOutstandingBlocks(uint32_t value)160 void setMaxNumOutstandingBlocks(uint32_t value) { 161 encoder_.setMaxNumOutstandingBlocks(value); 162 } 163 164 protected: 165 QPACKEncoder encoder_; 166 QPACKDecoder decoder_; 167 168 private: 169 void recordCompressedSize(const folly::IOBuf* stream, size_t controlSize); 170 171 std::vector<HPACKHeader> decodedHeaders_; 172 }; 173 174 std::ostream& operator<<(std::ostream& os, const QPACKCodec& codec); 175 } // namespace proxygen 176