# HPACK (RFC 7541)
\- Header Compression for HTTP/2

---

# http/1.1

## Request

```
GET /path HTTP/1.1
Host: www.example.com
Accept-Encoding: gzip, deflate,br
```

---

# http/1.1

## Response

```
HTTP/1.1 200 OK
Accept-Ranges: bytes
Content-Length: 438
Content-Type: text/html; charset=UTF-8
Content-Encoding: gzip
```

---

# PROS

- Easy to support, works both ways

---

# CONS
- Different algorithms have different implementations
- Does not support header compression
- Multiple security issues, via chosen-plaintext attacks.

---

Unrelated: There's also TLS compression (don't use it)

---

# hpack

---

# core ideas

1. most web requests will have fairly similar headers.
2. should be fast.
3. reduce complexity or implementation issues.
4. ignore encoding, focus on a correct decoding.
5. "streaming"

---

# important-to-note

1. Headers can be repeated
2. Headers are an Ordered List

---

# Static Table

Generated by frequency of header fields on popular websites.

```
+-------+-----------------------------+---------------+
| Index | Header Name                 | Header Value  |
+-------+-----------------------------+---------------+
| 1     | :authority                  |               |
| 2     | :method                     | GET           |
| 3     | :method                     | POST          |
| 4     | :path                       | /             |
| 5     | :path                       | /index.html   |
| 6     | :scheme                     | http          |
| 7     | :scheme                     | https         |
| 8     | :status                     | 200           |
| 9     | :status                     | 204           |
| 10    | :status                     | 206           |
| 11    | :status                     | 304           |
```

---

# Index Address Space

```
   <----------  Index Address Space ---------->
   <-- Static  Table -->  <-- Dynamic Table -->
   +---+-----------+---+  +---+-----------+---+
   | 1 |    ...    | s |  |s+1|    ...    |s+k|
   +---+-----------+---+  +---+-----------+---+
                          ^                   |
                          |                   V
                   Insertion Point      Dropping Point
```

# Representation

A header field(=`name+value`) can be represented as:

## an index
is a reference to either:

- the static table
- the dynamic table

---

## or a literal (1)

the header field name can be represented

- literally
- a reference to either tables

---

# or a literal (2)

the header value is represented literally and

1. **ADD** it to the dynamic table
2. **DON'T ADD** it to the dynamic table
3. **NEVER ADD** it to the dynamic table

---

# a literal

can be presented in two forms:

1. directly
2. using a Huffman code

---

# decisions while parsing

- do a table lookup
  - static table
  - dynamic table
- read it literally
  - directly
  - using the huffman code

Almost is encoded as a integer or as a string

---

# literal representation


```
   0   1   2   3   4   5   6   7
 +---+---+---+---+---+---+---+---+
 | H |    String Length (7+)     |
 +---+---------------------------+
 |  String Data (Length octets)  |
 +-------------------------------+
```
H=1 -> Huffman Encoded
H=0 -> Encoded as a "string"

# index representation

This is simple table lookup

```
   0   1   2   3   4   5   6   7
 +---+---+---+---+---+---+---+---+
 | 1 |        Index (7+)         |
 +---+---------------------------+
```

---

# Static Huffman Code

```
                                                code
                  code as bits                 as hex   len
sym              aligned to MSB                aligned   in
                                               to LSB   bits
(  0)  |11111111|11000                             1ff8  [13]
(  1)  |11111111|11111111|1011000                7fffd8  [23]
(  2)  |11111111|11111111|11111110|0010         fffffe2  [28]
(  3)  |11111111|11111111|11111110|0011         fffffe3  [28]
```

---

# dynamic table updates

- You can add entries to the table
- You can set the table size dynamically

>This mechanism can be used to completely clear entries from the
   dynamic table by setting a maximum size of 0, which can subsequently
   be restored.