View Javadoc
1   /*
2    * Copyright 2020 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty.handler.codec.http3;
17  
18  import io.netty.buffer.ByteBuf;
19  import io.netty.util.AsciiString;
20  import io.netty.util.internal.ConstantTimeUtils;
21  import io.netty.util.internal.PlatformDependent;
22  
23  import static io.netty.util.internal.ObjectUtil.checkInRange;
24  import static java.lang.Math.floorDiv;
25  
26  final class QpackUtil {
27      private static final QpackException PREFIXED_INTEGER_TOO_LONG =
28              QpackException.newStatic(QpackDecoder.class, "toIntOrThrow(...)",
29                      "QPACK - invalid prefixed integer");
30  
31      /**
32       * Encode integer according to
33       * <a href="https://tools.ietf.org/html/rfc7541#section-5.1">Section 5.1</a>.
34       */
35      static void encodePrefixedInteger(ByteBuf out, byte mask, int prefixLength, long toEncode) {
36          checkInRange(toEncode, 0, MAX_UNSIGNED_INT, "toEncode");
37          int nbits = (1 << prefixLength) - 1;
38          if (toEncode < nbits) {
39              out.writeByte((byte) (mask | toEncode));
40          } else {
41              out.writeByte((byte) (mask | nbits));
42              long remainder = toEncode - nbits;
43              while (remainder > 128) {
44                  byte next = (byte) ((remainder % 128) | 0x80);
45                  out.writeByte(next);
46                  remainder = remainder / 128;
47              }
48              out.writeByte((byte) remainder);
49          }
50      }
51  
52      /**
53       * Decode the integer or return {@code -1} if not enough bytes are readable.
54       * This method increases the readerIndex when the integer could be decoded.
55       *
56       * @param in the input {@link ByteBuf}
57       * @param prefixLength the prefix length
58       * @return the integer or {@code -1} if not enough readable bytes are in the {@link ByteBuf).
59       */
60      static int decodePrefixedIntegerAsInt(ByteBuf in, int prefixLength) throws QpackException {
61          return toIntOrThrow(decodePrefixedInteger(in, prefixLength));
62      }
63  
64      /**
65       * Converts the passed {@code aLong} to an {@code int} if the value can fit an {@code int}, otherwise throws a
66       * {@link QpackException}.
67       *
68       * @param aLong to convert.
69       * @throws QpackException If the value does not fit an {@code int}.
70       */
71      static int toIntOrThrow(long aLong) throws QpackException {
72          if ((int) aLong != aLong) {
73              throw PREFIXED_INTEGER_TOO_LONG;
74          }
75          return (int) aLong;
76      }
77  
78      /**
79       * Decode the integer or return {@code -1} if not enough bytes are readable.
80       * This method increases the readerIndex when the integer could be decoded.
81       *
82       * @param in the input {@link ByteBuf}
83       * @param prefixLength the prefix length
84       * @return the integer or {@code -1} if not enough readable bytes are in the {@link ByteBuf).
85       */
86      static long decodePrefixedInteger(ByteBuf in, int prefixLength) {
87          int readerIndex = in.readerIndex();
88          int writerIndex = in.writerIndex();
89          if (readerIndex == writerIndex) {
90              return -1;
91          }
92  
93          int nbits = (1 << prefixLength) - 1;
94          int first = in.readByte() & nbits;
95          if (first < nbits) {
96              return first;
97          }
98  
99          int idx = readerIndex + 1;
100         long i = first;
101         int factor = 0;
102         byte next;
103         do {
104             if (idx == writerIndex) {
105                 in.readerIndex(readerIndex);
106                 return -1;
107             }
108             next = in.getByte(idx++);
109             i += (next & 0x7fL) << factor;
110             factor += 7;
111         } while ((next & 0x80) == 0x80);
112         in.readerIndex(idx);
113         return i;
114     }
115 
116     static boolean firstByteEquals(ByteBuf in, byte mask) {
117         return (in.getByte(in.readerIndex()) & mask) == mask;
118     }
119 
120     /**
121      * Compare two {@link CharSequence} objects without leaking timing information.
122      * <p>
123      * The {@code int} return type is intentional and is designed to allow cascading of constant time operations:
124      * <pre>
125      *     String s1 = "foo";
126      *     String s2 = "foo";
127      *     String s3 = "foo";
128      *     String s4 = "goo";
129      *     boolean equals = (equalsConstantTime(s1, s2) & equalsConstantTime(s3, s4)) != 0;
130      * </pre>
131      * @param s1 the first value.
132      * @param s2 the second value.
133      * @return {@code 0} if not equal. {@code 1} if equal.
134      */
135     static int equalsConstantTime(CharSequence s1, CharSequence s2) {
136         if (s1 instanceof AsciiString && s2 instanceof AsciiString) {
137             if (s1.length() != s2.length()) {
138                 return 0;
139             }
140             AsciiString s1Ascii = (AsciiString) s1;
141             AsciiString s2Ascii = (AsciiString) s2;
142             return PlatformDependent.equalsConstantTime(s1Ascii.array(), s1Ascii.arrayOffset(),
143                                                         s2Ascii.array(), s2Ascii.arrayOffset(), s1.length());
144         }
145 
146         return ConstantTimeUtils.equalsConstantTime(s1, s2);
147     }
148 
149     /**
150      * Compare two {@link CharSequence}s.
151      * @param s1 the first value.
152      * @param s2 the second value.
153      * @return {@code false} if not equal. {@code true} if equal.
154      */
155     static boolean equalsVariableTime(CharSequence s1, CharSequence s2) {
156         return AsciiString.contentEquals(s1, s2);
157     }
158 
159     /**
160      * Calculate the MaxEntries based on
161      * <a href="https://www.rfc-editor.org/rfc/rfc9204.html#section-4.5.1.1">RFC9204 Section 4.5.1.1</a>.
162      *
163      * @param maxTableCapacity the maximum table capacity.
164      * @return maxEntries.
165      */
166     static long maxEntries(long maxTableCapacity) {
167         // MaxEntries = floor( MaxTableCapacity / 32 )
168         return floorDiv(maxTableCapacity, 32);
169     }
170 
171     // Section 6.2. Literal Header Field Representation
172     enum IndexType {
173         INCREMENTAL, // Section 6.2.1. Literal Header Field with Incremental Indexing
174         NONE,        // Section 6.2.2. Literal Header Field without Indexing
175         NEVER        // Section 6.2.3. Literal Header Field never Indexed
176     }
177 
178     // Appendix B: Huffman Codes
179     // https://tools.ietf.org/html/rfc7541#appendix-B
180     static final int[] HUFFMAN_CODES = {
181         0x1ff8,
182         0x7fffd8,
183         0xfffffe2,
184         0xfffffe3,
185         0xfffffe4,
186         0xfffffe5,
187         0xfffffe6,
188         0xfffffe7,
189         0xfffffe8,
190         0xffffea,
191         0x3ffffffc,
192         0xfffffe9,
193         0xfffffea,
194         0x3ffffffd,
195         0xfffffeb,
196         0xfffffec,
197         0xfffffed,
198         0xfffffee,
199         0xfffffef,
200         0xffffff0,
201         0xffffff1,
202         0xffffff2,
203         0x3ffffffe,
204         0xffffff3,
205         0xffffff4,
206         0xffffff5,
207         0xffffff6,
208         0xffffff7,
209         0xffffff8,
210         0xffffff9,
211         0xffffffa,
212         0xffffffb,
213         0x14,
214         0x3f8,
215         0x3f9,
216         0xffa,
217         0x1ff9,
218         0x15,
219         0xf8,
220         0x7fa,
221         0x3fa,
222         0x3fb,
223         0xf9,
224         0x7fb,
225         0xfa,
226         0x16,
227         0x17,
228         0x18,
229         0x0,
230         0x1,
231         0x2,
232         0x19,
233         0x1a,
234         0x1b,
235         0x1c,
236         0x1d,
237         0x1e,
238         0x1f,
239         0x5c,
240         0xfb,
241         0x7ffc,
242         0x20,
243         0xffb,
244         0x3fc,
245         0x1ffa,
246         0x21,
247         0x5d,
248         0x5e,
249         0x5f,
250         0x60,
251         0x61,
252         0x62,
253         0x63,
254         0x64,
255         0x65,
256         0x66,
257         0x67,
258         0x68,
259         0x69,
260         0x6a,
261         0x6b,
262         0x6c,
263         0x6d,
264         0x6e,
265         0x6f,
266         0x70,
267         0x71,
268         0x72,
269         0xfc,
270         0x73,
271         0xfd,
272         0x1ffb,
273         0x7fff0,
274         0x1ffc,
275         0x3ffc,
276         0x22,
277         0x7ffd,
278         0x3,
279         0x23,
280         0x4,
281         0x24,
282         0x5,
283         0x25,
284         0x26,
285         0x27,
286         0x6,
287         0x74,
288         0x75,
289         0x28,
290         0x29,
291         0x2a,
292         0x7,
293         0x2b,
294         0x76,
295         0x2c,
296         0x8,
297         0x9,
298         0x2d,
299         0x77,
300         0x78,
301         0x79,
302         0x7a,
303         0x7b,
304         0x7ffe,
305         0x7fc,
306         0x3ffd,
307         0x1ffd,
308         0xffffffc,
309         0xfffe6,
310         0x3fffd2,
311         0xfffe7,
312         0xfffe8,
313         0x3fffd3,
314         0x3fffd4,
315         0x3fffd5,
316         0x7fffd9,
317         0x3fffd6,
318         0x7fffda,
319         0x7fffdb,
320         0x7fffdc,
321         0x7fffdd,
322         0x7fffde,
323         0xffffeb,
324         0x7fffdf,
325         0xffffec,
326         0xffffed,
327         0x3fffd7,
328         0x7fffe0,
329         0xffffee,
330         0x7fffe1,
331         0x7fffe2,
332         0x7fffe3,
333         0x7fffe4,
334         0x1fffdc,
335         0x3fffd8,
336         0x7fffe5,
337         0x3fffd9,
338         0x7fffe6,
339         0x7fffe7,
340         0xffffef,
341         0x3fffda,
342         0x1fffdd,
343         0xfffe9,
344         0x3fffdb,
345         0x3fffdc,
346         0x7fffe8,
347         0x7fffe9,
348         0x1fffde,
349         0x7fffea,
350         0x3fffdd,
351         0x3fffde,
352         0xfffff0,
353         0x1fffdf,
354         0x3fffdf,
355         0x7fffeb,
356         0x7fffec,
357         0x1fffe0,
358         0x1fffe1,
359         0x3fffe0,
360         0x1fffe2,
361         0x7fffed,
362         0x3fffe1,
363         0x7fffee,
364         0x7fffef,
365         0xfffea,
366         0x3fffe2,
367         0x3fffe3,
368         0x3fffe4,
369         0x7ffff0,
370         0x3fffe5,
371         0x3fffe6,
372         0x7ffff1,
373         0x3ffffe0,
374         0x3ffffe1,
375         0xfffeb,
376         0x7fff1,
377         0x3fffe7,
378         0x7ffff2,
379         0x3fffe8,
380         0x1ffffec,
381         0x3ffffe2,
382         0x3ffffe3,
383         0x3ffffe4,
384         0x7ffffde,
385         0x7ffffdf,
386         0x3ffffe5,
387         0xfffff1,
388         0x1ffffed,
389         0x7fff2,
390         0x1fffe3,
391         0x3ffffe6,
392         0x7ffffe0,
393         0x7ffffe1,
394         0x3ffffe7,
395         0x7ffffe2,
396         0xfffff2,
397         0x1fffe4,
398         0x1fffe5,
399         0x3ffffe8,
400         0x3ffffe9,
401         0xffffffd,
402         0x7ffffe3,
403         0x7ffffe4,
404         0x7ffffe5,
405         0xfffec,
406         0xfffff3,
407         0xfffed,
408         0x1fffe6,
409         0x3fffe9,
410         0x1fffe7,
411         0x1fffe8,
412         0x7ffff3,
413         0x3fffea,
414         0x3fffeb,
415         0x1ffffee,
416         0x1ffffef,
417         0xfffff4,
418         0xfffff5,
419         0x3ffffea,
420         0x7ffff4,
421         0x3ffffeb,
422         0x7ffffe6,
423         0x3ffffec,
424         0x3ffffed,
425         0x7ffffe7,
426         0x7ffffe8,
427         0x7ffffe9,
428         0x7ffffea,
429         0x7ffffeb,
430         0xffffffe,
431         0x7ffffec,
432         0x7ffffed,
433         0x7ffffee,
434         0x7ffffef,
435         0x7fffff0,
436         0x3ffffee,
437         0x3fffffff // EOS
438     };
439 
440     static final byte[] HUFFMAN_CODE_LENGTHS = {
441         13, 23, 28, 28, 28, 28, 28, 28, 28, 24, 30, 28, 28, 30, 28, 28,
442         28, 28, 28, 28, 28, 28, 30, 28, 28, 28, 28, 28, 28, 28, 28, 28,
443         6, 10, 10, 12, 13, 6, 8, 11, 10, 10, 8, 11, 8, 6, 6, 6,
444         5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 8, 15, 6, 12, 10,
445         13, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
446         7, 7, 7, 7, 7, 7, 7, 7, 8, 7, 8, 13, 19, 13, 14, 6,
447         15, 5, 6, 5, 6, 5, 6, 6, 6, 5, 7, 7, 6, 6, 6, 5,
448         6, 7, 6, 5, 5, 6, 7, 7, 7, 7, 7, 15, 11, 14, 13, 28,
449         20, 22, 20, 20, 22, 22, 22, 23, 22, 23, 23, 23, 23, 23, 24, 23,
450         24, 24, 22, 23, 24, 23, 23, 23, 23, 21, 22, 23, 22, 23, 23, 24,
451         22, 21, 20, 22, 22, 23, 23, 21, 23, 22, 22, 24, 21, 22, 23, 23,
452         21, 21, 22, 21, 23, 22, 23, 23, 20, 22, 22, 22, 23, 22, 22, 23,
453         26, 26, 20, 19, 22, 23, 22, 25, 26, 26, 26, 27, 27, 26, 24, 25,
454         19, 21, 26, 27, 27, 26, 27, 24, 21, 21, 26, 26, 28, 27, 27, 27,
455         20, 24, 20, 21, 22, 21, 21, 23, 22, 22, 25, 25, 24, 24, 26, 23,
456         26, 27, 26, 26, 27, 27, 27, 27, 27, 28, 27, 27, 27, 27, 27, 26,
457         30 // EOS
458     };
459 
460     static final int HUFFMAN_EOS = 256;
461 
462     static final long MIN_HEADER_TABLE_SIZE = 0;
463     static final long MAX_UNSIGNED_INT = 0xffffffffL;
464     static final long MAX_HEADER_TABLE_SIZE = MAX_UNSIGNED_INT;
465 
466     private QpackUtil() {
467     }
468 }