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 <proxygen/lib/http/codec/HQUnidirectionalCodec.h> 12 #include <proxygen/lib/http/codec/HQUtils.h> 13 #include <proxygen/lib/http/codec/compress/QPACKCodec.h> 14 15 namespace proxygen { namespace hq { 16 17 class QPACKDecoderCodec : public HQUnidirectionalCodec { 18 19 public: QPACKDecoderCodec(QPACKCodec & qpackCodec,Callback & cb)20 QPACKDecoderCodec(QPACKCodec& qpackCodec, Callback& cb) 21 : HQUnidirectionalCodec(UnidirectionalStreamType::QPACK_DECODER, 22 StreamDirection::INGRESS), 23 qpackCodec_(qpackCodec), 24 callback_(cb) { 25 } 26 27 // HQUnidirectionalCodec API onUnidirectionalIngress(std::unique_ptr<folly::IOBuf> buf)28 std::unique_ptr<folly::IOBuf> onUnidirectionalIngress( 29 std::unique_ptr<folly::IOBuf> buf) override { 30 auto err = qpackCodec_.decodeDecoderStream(std::move(buf)); 31 if (err != HPACK::DecodeError::NONE) { 32 LOG(ERROR) << "QPACK decoder stream decode error err=" << err; 33 HTTPException ex( 34 HTTPException::Direction::INGRESS_AND_EGRESS, 35 folly::to<std::string>("Compression error on decoder stream err=", 36 uint32_t(err))); 37 ex.setHttp3ErrorCode(HTTP3::ErrorCode::HTTP_QPACK_DECODER_STREAM_ERROR); 38 callback_.onError(kSessionStreamId, ex, false); 39 } 40 return nullptr; 41 } 42 onUnidirectionalIngressEOF()43 void onUnidirectionalIngressEOF() override { 44 LOG(ERROR) << "Unexpected QPACK encoder stream EOF"; 45 HTTPException ex(HTTPException::Direction::INGRESS_AND_EGRESS, 46 "Encoder stream EOF"); 47 ex.setHttp3ErrorCode(HTTP3::ErrorCode::HTTP_CLOSED_CRITICAL_STREAM); 48 callback_.onError(kSessionStreamId, ex, false); 49 } 50 51 private: 52 QPACKCodec& qpackCodec_; 53 Callback& callback_; 54 }; 55 56 }} // namespace proxygen::hq 57