Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
QPackDecoder.cs
Go to the documentation of this file.
4
6
7internal sealed class QPackDecoder : IDisposable
8{
29
30 private readonly int _maxHeadersLength;
31
32 private State _state;
33
34 private byte[] _stringOctets;
35
36 private byte[] _headerNameOctets;
37
38 private byte[] _headerValueOctets;
39
40 private bool _huffman;
41
42 private int? _index;
43
44 private byte[] _headerName;
45
46 private int _headerNameLength;
47
48 private int _headerValueLength;
49
50 private int _stringLength;
51
52 private int _stringIndex;
53
55
57
58 private static void ReturnAndGetNewPooledArray(ref byte[] buffer, int newSize)
59 {
60 byte[] array = buffer;
61 buffer = null;
62 Pool.Return(array, clearArray: true);
63 buffer = Pool.Rent(newSize);
64 }
65
66 public QPackDecoder(int maxHeadersLength)
67 {
68 _maxHeadersLength = maxHeadersLength;
69 _stringOctets = Pool.Rent(64);
70 _headerNameOctets = Pool.Rent(64);
71 _headerValueOctets = Pool.Rent(64);
72 }
73
74 public void Dispose()
75 {
76 if (_stringOctets != null)
77 {
78 Pool.Return(_stringOctets, clearArray: true);
79 _stringOctets = null;
80 }
81 if (_headerNameOctets != null)
82 {
83 Pool.Return(_headerNameOctets, clearArray: true);
84 _headerNameOctets = null;
85 }
86 if (_headerValueOctets != null)
87 {
88 Pool.Return(_headerValueOctets, clearArray: true);
89 _headerValueOctets = null;
90 }
91 }
92
93 public void Reset()
94 {
95 _state = State.RequiredInsertCount;
96 }
97
98 public void Decode(ReadOnlySpan<byte> headerBlock, IHttpHeadersHandler handler)
99 {
100 ReadOnlySpan<byte> readOnlySpan = headerBlock;
101 for (int i = 0; i < readOnlySpan.Length; i++)
102 {
103 byte b = readOnlySpan[i];
104 OnByte(b, handler);
105 }
106 }
107
108 private void OnByte(byte b, IHttpHeadersHandler handler)
109 {
110 int result;
111 switch (_state)
112 {
113 case State.RequiredInsertCount:
114 if (_integerDecoder.BeginTryDecode(b, 8, out result))
115 {
116 OnRequiredInsertCount(result);
117 }
118 else
119 {
120 _state = State.RequiredInsertCountContinue;
121 }
122 break;
123 case State.RequiredInsertCountContinue:
124 if (_integerDecoder.TryDecode(b, out result))
125 {
126 OnRequiredInsertCount(result);
127 }
128 break;
129 case State.Base:
130 {
131 int num = -129 & b;
132 if (_integerDecoder.BeginTryDecode(b, 7, out result))
133 {
134 OnBase(result);
135 }
136 else
137 {
138 _state = State.BaseContinue;
139 }
140 break;
141 }
142 case State.BaseContinue:
143 if (_integerDecoder.TryDecode(b, out result))
144 {
145 OnBase(result);
146 }
147 break;
148 case State.CompressedHeaders:
150 {
151 case 24:
152 {
153 int num = 0x3F & b;
154 if ((b & 0x40) != 64)
155 {
157 }
158 if (_integerDecoder.BeginTryDecode((byte)num, 6, out result))
159 {
160 OnIndexedHeaderField(result, handler);
161 }
162 else
163 {
164 _state = State.HeaderFieldIndex;
165 }
166 break;
167 }
168 case 25:
169 {
170 if ((0x10 & b) != 16)
171 {
173 }
174 int num = b & 0xF;
175 if (_integerDecoder.BeginTryDecode((byte)num, 4, out result))
176 {
177 OnIndexedHeaderName(result);
178 }
179 else
180 {
181 _state = State.HeaderNameIndex;
182 }
183 break;
184 }
185 case 26:
186 {
187 _huffman = (b & 8) != 0;
188 int num = b & 7;
189 if (_integerDecoder.BeginTryDecode((byte)num, 3, out result))
190 {
191 if (result == 0)
192 {
194 }
195 OnStringLength(result, State.HeaderName);
196 }
197 else
198 {
199 _state = State.HeaderNameLength;
200 }
201 break;
202 }
203 case 27:
204 {
205 int num = -241 & b;
206 if (_integerDecoder.BeginTryDecode((byte)num, 4, out result))
207 {
208 OnPostBaseIndex(result, handler);
209 }
210 else
211 {
212 _state = State.PostBaseIndex;
213 }
214 break;
215 }
216 default:
217 {
218 int num = b & 7;
219 if (_integerDecoder.BeginTryDecode((byte)num, 3, out result))
220 {
222 }
223 else
224 {
225 _state = State.HeaderNameIndexPostBase;
226 }
227 break;
228 }
229 }
230 break;
231 case State.HeaderNameLength:
232 if (_integerDecoder.TryDecode(b, out result))
233 {
234 if (result == 0)
235 {
237 }
238 OnStringLength(result, State.HeaderName);
239 }
240 break;
241 case State.HeaderName:
244 {
245 OnString(State.HeaderValueLength);
246 }
247 break;
248 case State.HeaderNameIndex:
249 if (_integerDecoder.TryDecode(b, out result))
250 {
251 OnIndexedHeaderName(result);
252 }
253 break;
254 case State.HeaderNameIndexPostBase:
255 if (_integerDecoder.TryDecode(b, out result))
256 {
258 }
259 break;
260 case State.HeaderValueLength:
261 _huffman = (b & 0x80) != 0;
262 if (_integerDecoder.BeginTryDecode((byte)(b & 0xFFFFFF7Fu), 7, out result))
263 {
264 OnStringLength(result, State.HeaderValue);
265 if (result == 0)
266 {
267 ProcessHeaderValue(handler);
268 }
269 }
270 else
271 {
272 _state = State.HeaderValueLengthContinue;
273 }
274 break;
275 case State.HeaderValueLengthContinue:
276 if (_integerDecoder.TryDecode(b, out result))
277 {
278 OnStringLength(result, State.HeaderValue);
279 if (result == 0)
280 {
281 ProcessHeaderValue(handler);
282 }
283 }
284 break;
285 case State.HeaderValue:
288 {
289 ProcessHeaderValue(handler);
290 }
291 break;
292 case State.HeaderFieldIndex:
293 if (_integerDecoder.TryDecode(b, out result))
294 {
295 OnIndexedHeaderField(result, handler);
296 }
297 break;
298 case State.PostBaseIndex:
299 if (_integerDecoder.TryDecode(b, out result))
300 {
301 OnPostBaseIndex(result, handler);
302 }
303 break;
304 case State.HeaderNameLengthContinue:
305 case State.DynamicTableSizeUpdate:
306 case State.LiteralHeaderFieldWithNameReference:
307 break;
308 }
309 }
310
311 private void OnStringLength(int length, State nextState)
312 {
313 if (length > _stringOctets.Length)
314 {
316 {
318 }
320 }
322 _stringIndex = 0;
323 _state = nextState;
324 }
325
327 {
328 OnString(State.CompressedHeaders);
330 int? index = _index;
331 if (index.HasValue)
332 {
333 int valueOrDefault = index.GetValueOrDefault();
334 handler.OnStaticIndexedHeader(valueOrDefault, span);
335 _index = null;
336 }
337 else
338 {
340 handler.OnHeader(span2, span);
341 }
342 }
343
344 private void OnString(State nextState)
345 {
346 try
347 {
348 if (_state == State.HeaderName)
349 {
352 }
353 else
354 {
356 }
357 }
358 catch (HuffmanDecodingException innerException)
359 {
361 }
362 _state = nextState;
363 int Decode(ref byte[] dst)
364 {
365 if (_huffman)
366 {
368 }
369 if (dst.Length < _stringLength)
370 {
372 }
374 return _stringLength;
375 }
376 }
377
378 private void OnIndexedHeaderName(int index)
379 {
380 _index = index;
381 _state = State.HeaderValueLength;
382 }
383
388
389 private void OnPostBaseIndex(int intResult, IHttpHeadersHandler handler)
390 {
392 }
393
394 private void OnBase(int deltaBase)
395 {
396 if (deltaBase != 0)
397 {
399 }
400 _state = State.CompressedHeaders;
401 }
402
403 private void OnRequiredInsertCount(int requiredInsertCount)
404 {
405 if (requiredInsertCount != 0)
406 {
408 }
409 _state = State.Base;
410 }
411
413 {
415 _state = State.CompressedHeaders;
416 }
417
422}
static void BlockCopy(Array src, int srcOffset, Array dst, int dstOffset, int count)
Definition Buffer.cs:102
static ArrayPool< T > Shared
Definition ArrayPool.cs:7
static int Decode(ReadOnlySpan< byte > src, ref byte[] dstArray)
Definition Huffman.cs:118
void Decode(ReadOnlySpan< byte > headerBlock, IHttpHeadersHandler handler)
void OnPostBaseIndex(int intResult, IHttpHeadersHandler handler)
void OnIndexedHeaderField(int index, IHttpHeadersHandler handler)
void OnByte(byte b, IHttpHeadersHandler handler)
void ProcessHeaderValue(IHttpHeadersHandler handler)
void OnIndexedHeaderNamePostBase(int index)
QPackDecoder(int maxHeadersLength)
void OnRequiredInsertCount(int requiredInsertCount)
static void ReturnAndGetNewPooledArray(ref byte[] buffer, int newSize)
static ArrayPool< byte > Pool
void OnStringLength(int length, State nextState)
static int LeadingZeroCount(uint value)
static string net_http_invalid_header_name
Definition SR.cs:180
static string net_http_hpack_huffman_decode_failed
Definition SR.cs:160
static string Format(string resourceFormat, object p1)
Definition SR.cs:118
static string net_http_qpack_no_dynamic_table
Definition SR.cs:188
static string net_http_headers_exceeded_length
Definition SR.cs:178
Definition SR.cs:7
void OnHeader(ReadOnlySpan< byte > name, ReadOnlySpan< byte > value)
bool BeginTryDecode(byte b, int prefixLength, out int result)
bool TryDecode(byte b, out int result)