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