• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_ENTRY_DECODER_H_
6 #define QUICHE_HTTP2_HPACK_DECODER_HPACK_ENTRY_DECODER_H_
7 
8 // HpackEntryDecoder decodes a single HPACK entry (i.e. one header or one
9 // dynamic table size update), in a resumable fashion. The first call, Start(),
10 // must provide a non-empty decode buffer. Continue with calls to Resume() if
11 // Start, and any subsequent calls to Resume, returns kDecodeInProgress.
12 
13 #include <string>
14 
15 #include "quiche/http2/decoder/decode_buffer.h"
16 #include "quiche/http2/decoder/decode_status.h"
17 #include "quiche/http2/hpack/decoder/hpack_decoding_error.h"
18 #include "quiche/http2/hpack/decoder/hpack_entry_decoder_listener.h"
19 #include "quiche/http2/hpack/decoder/hpack_entry_type_decoder.h"
20 #include "quiche/http2/hpack/decoder/hpack_string_decoder.h"
21 #include "quiche/http2/hpack/http2_hpack_constants.h"
22 #include "quiche/common/platform/api/quiche_export.h"
23 #include "quiche/common/platform/api/quiche_logging.h"
24 
25 namespace http2 {
26 
27 class QUICHE_EXPORT HpackEntryDecoder {
28  public:
29   enum class EntryDecoderState {
30     // Have started decoding the type/varint, but didn't finish on the previous
31     // attempt.  Next state is kResumeDecodingType or kDecodedType.
32     kResumeDecodingType,
33 
34     // Have just finished decoding the type/varint. Final state if the type is
35     // kIndexedHeader or kDynamicTableSizeUpdate. Otherwise, the next state is
36     // kStartDecodingName (if the varint is 0), else kStartDecodingValue.
37     kDecodedType,
38 
39     // Ready to start decoding the literal name of a header entry. Next state
40     // is kResumeDecodingName (if the name is split across decode buffers),
41     // else kStartDecodingValue.
42     kStartDecodingName,
43 
44     // Resume decoding the literal name of a header that is split across decode
45     // buffers.
46     kResumeDecodingName,
47 
48     // Ready to start decoding the literal value of a header entry. Final state
49     // if the value string is entirely in the decode buffer, else the next state
50     // is kResumeDecodingValue.
51     kStartDecodingValue,
52 
53     // Resume decoding the literal value of a header that is split across decode
54     // buffers.
55     kResumeDecodingValue,
56   };
57 
58   // Only call when the decode buffer has data (i.e. HpackBlockDecoder must
59   // not call until there is data).
60   DecodeStatus Start(DecodeBuffer* db, HpackEntryDecoderListener* listener);
61 
62   // Only call Resume if the previous call (Start or Resume) returned
63   // kDecodeInProgress; Resume is also called from Start when it has succeeded
64   // in decoding the entry type and its varint.
65   DecodeStatus Resume(DecodeBuffer* db, HpackEntryDecoderListener* listener);
66 
67   // Return error code after decoding error occurred.
error()68   HpackDecodingError error() const { return error_; }
69 
70   std::string DebugString() const;
71   void OutputDebugString(std::ostream& out) const;
72 
73  private:
74   // Implements handling state kDecodedType.
75   bool DispatchOnType(HpackEntryDecoderListener* listener);
76 
77   HpackEntryTypeDecoder entry_type_decoder_;
78   HpackStringDecoder string_decoder_;
79   EntryDecoderState state_ = EntryDecoderState();
80   HpackDecodingError error_ = HpackDecodingError::kOk;
81 };
82 
83 QUICHE_EXPORT std::ostream& operator<<(std::ostream& out,
84                                        const HpackEntryDecoder& v);
85 QUICHE_EXPORT std::ostream& operator<<(
86     std::ostream& out, HpackEntryDecoder::EntryDecoderState state);
87 
88 }  // namespace http2
89 
90 #endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_ENTRY_DECODER_H_
91