OLD | NEW |
| (Empty) |
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 NET_HTTP2_HPACK_DECODER_HPACK_ENTRY_DECODER_H_ | |
6 #define NET_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 "base/logging.h" | |
16 #include "net/base/net_export.h" | |
17 #include "net/http2/decoder/decode_buffer.h" | |
18 #include "net/http2/decoder/decode_status.h" | |
19 #include "net/http2/hpack/decoder/hpack_entry_decoder_listener.h" | |
20 #include "net/http2/hpack/decoder/hpack_entry_type_decoder.h" | |
21 #include "net/http2/hpack/decoder/hpack_string_decoder.h" | |
22 #include "net/http2/hpack/http2_hpack_constants.h" | |
23 | |
24 namespace net { | |
25 | |
26 class NET_EXPORT_PRIVATE HpackEntryDecoder { | |
27 public: | |
28 enum class EntryDecoderState { | |
29 // Have started decoding the type/varint, but didn't finish on the previous | |
30 // attempt. Next state is kResumeDecodingType or kDecodedType. | |
31 kResumeDecodingType, | |
32 | |
33 // Have just finished decoding the type/varint. Final state if the type is | |
34 // kIndexedHeader or kDynamicTableSizeUpdate. Otherwise, the next state is | |
35 // kStartDecodingName (if the varint is 0), else kStartDecodingValue. | |
36 kDecodedType, | |
37 | |
38 // Ready to start decoding the literal name of a header entry. Next state | |
39 // is kResumeDecodingName (if the name is split across decode buffers), | |
40 // else kStartDecodingValue. | |
41 kStartDecodingName, | |
42 | |
43 // Resume decoding the literal name of a header that is split across decode | |
44 // buffers. | |
45 kResumeDecodingName, | |
46 | |
47 // Ready to start decoding the literal value of a header entry. Final state | |
48 // if the value string is entirely in the decode buffer, else the next state | |
49 // is kResumeDecodingValue. | |
50 kStartDecodingValue, | |
51 | |
52 // Resume decoding the literal value of a header that is split across decode | |
53 // buffers. | |
54 kResumeDecodingValue, | |
55 }; | |
56 | |
57 // Only call when the decode buffer has data (i.e. HpackBlockDecoder must | |
58 // not call until there is data). | |
59 DecodeStatus Start(DecodeBuffer* db, HpackEntryDecoderListener* listener) { | |
60 DCHECK(db != nullptr); | |
61 DCHECK(listener != nullptr); | |
62 DCHECK(db->HasData()); | |
63 DecodeStatus status = entry_type_decoder_.Start(db); | |
64 switch (status) { | |
65 case DecodeStatus::kDecodeDone: | |
66 // The type of the entry and its varint fit into the current decode | |
67 // buffer. | |
68 if (entry_type_decoder_.entry_type() == | |
69 HpackEntryType::kIndexedHeader) { | |
70 // The entry consists solely of the entry type and varint. This | |
71 // is by far the most common case in practice. | |
72 listener->OnIndexedHeader(entry_type_decoder_.varint()); | |
73 return DecodeStatus::kDecodeDone; | |
74 } | |
75 state_ = EntryDecoderState::kDecodedType; | |
76 return Resume(db, listener); | |
77 case DecodeStatus::kDecodeInProgress: | |
78 // Hit the end of the decode buffer before fully decoding the entry | |
79 // type and varint. | |
80 DCHECK_EQ(0u, db->Remaining()); | |
81 state_ = EntryDecoderState::kResumeDecodingType; | |
82 return status; | |
83 case DecodeStatus::kDecodeError: | |
84 // The varint must have been invalid (too long). | |
85 return status; | |
86 } | |
87 | |
88 NOTREACHED(); | |
89 return DecodeStatus::kDecodeError; | |
90 } | |
91 | |
92 // Only call Resume if the previous call (Start or Resume) returned | |
93 // kDecodeInProgress; Resume is also called from Start when it has succeeded | |
94 // in decoding the entry type and its varint. | |
95 DecodeStatus Resume(DecodeBuffer* db, HpackEntryDecoderListener* listener); | |
96 | |
97 std::string DebugString() const; | |
98 void OutputDebugString(std::ostream& out) const; | |
99 | |
100 private: | |
101 // Implements handling state kDecodedType. | |
102 bool DispatchOnType(HpackEntryDecoderListener* listener); | |
103 | |
104 HpackEntryTypeDecoder entry_type_decoder_; | |
105 HpackStringDecoder string_decoder_; | |
106 EntryDecoderState state_ = EntryDecoderState(); | |
107 }; | |
108 | |
109 NET_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out, | |
110 const HpackEntryDecoder& v); | |
111 NET_EXPORT_PRIVATE std::ostream& operator<<( | |
112 std::ostream& out, | |
113 HpackEntryDecoder::EntryDecoderState state); | |
114 | |
115 } // namespace net | |
116 | |
117 #endif // NET_HTTP2_HPACK_DECODER_HPACK_ENTRY_DECODER_H_ | |
OLD | NEW |