http2-5.3.10: HTTP/2 library

Safe Haskell | None
Language | Haskell2010

Network.HPACK

Contents

- Encoding and decoding
- Encoding and decoding with token
- DynamicTable
- Strategy for encoding
- Errors
- Token header
- Value table
- Basic types

Description

HPACK(https://tools.ietf.org/html/rfc7541) encoding and decoding a header list.

Synopsis

- encodeHeader :: EncodeStrategy -> Size -> DynamicTable -> [Header] -> IO ByteString
- decodeHeader :: DynamicTable -> ByteString -> IO [Header]
- type Header = (HeaderName, ByteString)
- original :: CI s -> s
- foldedCase :: CI s -> s
- mk :: FoldCase s => s -> CI s
- encodeTokenHeader :: Buffer -> BufferSize -> EncodeStrategy -> Bool -> DynamicTable -> TokenHeaderList -> IO (TokenHeaderList, Int)
- decodeTokenHeader :: DynamicTable -> ByteString -> IO TokenHeaderTable
- data DynamicTable
- defaultDynamicTableSize :: Int
- newDynamicTableForEncoding :: Size -> IO DynamicTable
- newDynamicTableForDecoding :: Size -> Size -> IO DynamicTable
- withDynamicTableForEncoding :: Size -> (DynamicTable -> IO a) -> IO a
- withDynamicTableForDecoding :: Size -> Size -> (DynamicTable -> IO a) -> IO a
- setLimitForEncoding :: Size -> DynamicTable -> IO ()
- data CompressionAlgo
  - = Naive
  - | Static
  - | Linear
- data EncodeStrategy = EncodeStrategy {
  - compressionAlgo :: CompressionAlgo
  - useHuffman :: Bool
  }
- defaultEncodeStrategy :: EncodeStrategy
- data DecodeError
  - = IndexOverrun Index
  - | EosInTheMiddle
  - | IllegalEos
  - | TooLongEos
  - | TooSmallTableSize
  - | TooLargeTableSize
  - | IllegalTableSizeUpdate
  - | HeaderBlockTruncated
  - | IllegalHeaderName
  - | TooLargeHeader
- data BufferOverrun = BufferOverrun
- type FieldValue = ByteString
- type TokenHeader = (Token, FieldValue)
- type TokenHeaderList = [TokenHeader]
- toTokenHeaderTable :: [Header] -> IO TokenHeaderTable
- type ValueTable = Array Int (Maybe FieldValue)
- type TokenHeaderTable = (TokenHeaderList, ValueTable)
- getFieldValue :: Token -> ValueTable -> Maybe FieldValue
- getHeaderValue :: Token -> ValueTable -> Maybe FieldValue
- type Size = Int
- type Index = Int
- type Buffer = Ptr Word8
- type BufferSize = Int

# Encoding and decoding

encodeHeader Source #

Arguments

:: EncodeStrategy |
-> Size | The size of a temporary buffer.
-> DynamicTable |
-> [Header] |
-> IO ByteString | An HPACK format

Converting '[Header]' to the HPACK format. This function has overhead of allocating/freeing a temporary buffer. `BufferOverrun` will be thrown if the temporary buffer is too small.

decodeHeader Source #

Arguments

:: DynamicTable |
-> ByteString | An HPACK format
-> IO [Header] |

Converting the HPACK format to '[Header]'.

- Headers are decoded as is.
- `DecodeError` would be thrown if the HPACK format is broken.
- `BufferOverrun` will be thrown if the temporary buffer for Huffman decoding is too small.

type Header = (HeaderName, ByteString) Source #

A full HTTP header field with the name and value separated.

E.g. `"Content-Length: 28"` parsed into a `Header` would turn into `("Content-Length", "28")`

original :: CI s -> s Source #

Retrieve the original string-like value.

foldedCase :: CI s -> s Source #

Retrieve the case folded string-like value. (Also see `foldCase`).

mk :: FoldCase s => s -> CI s Source #

Make the given string-like value case insensitive.

# Encoding and decoding with token

encodeTokenHeader Source #

Arguments

:: Buffer |
-> BufferSize |
-> EncodeStrategy |
-> Bool | `True` at the first time, `False` when continued.
-> DynamicTable |
-> TokenHeaderList |
-> IO (TokenHeaderList, Int) | Leftover, filled length

Converting `TokenHeaderList` to the HPACK format directly in the buffer.

When calling this function for a new `TokenHeaderList`, 4th argument must be `True`.

The return value is a pair of leftover `TokenHeaderList` and how many bytes are filled in the buffer. If the leftover is empty, the encoding is finished. Otherwise, this function should be called with it again. 4th argument must be `False`.

4th argument is relating to dynamic table size update. If `True` and the limit is set by `setLimitForEncoding`, dynamic table size update is generated at the beginning of the HPACK format.

decodeTokenHeader Source #

Arguments

:: DynamicTable |
-> ByteString | An HPACK format
-> IO TokenHeaderTable |

Converting the HPACK format to `TokenHeaderList` and `ValueTable`.

- Multiple values of Cookie: are concatenated.
- If a pseudo header appears multiple times, `IllegalHeaderName` is thrown.
- If unknown pseudo headers appear, `IllegalHeaderName` is thrown.
- If pseudo headers are found after normal headers, `IllegalHeaderName` is thrown.
- If a header key contains capital letters, `IllegalHeaderName` is thrown.
- `DecodeError` would be thrown if the HPACK format is broken.
- `BufferOverrun` will be thrown if the temporary buffer for Huffman decoding is too small.

# DynamicTable

data DynamicTable Source #

Type for dynamic table.

defaultDynamicTableSize :: Int Source #

Default dynamic table size. The value is 4,096 bytes: an array has 128 entries.

    >>> defaultDynamicTableSize
    4096

newDynamicTableForEncoding Source #

Arguments

:: Size | The dynamic table size
-> IO DynamicTable |

Creating `DynamicTable` for encoding.

newDynamicTableForDecoding Source #

Arguments

:: Size | The dynamic table size
-> Size | The size of temporary buffer for Huffman decoding
-> IO DynamicTable |

Creating `DynamicTable` for decoding.

withDynamicTableForEncoding Source #

Arguments

:: Size | The dynamic table size
-> (DynamicTable -> IO a) |
-> IO a |

Creating `DynamicTable` for encoding, performing the action and clearing the `DynamicTable`.

withDynamicTableForDecoding Source #

Arguments

:: Size | The dynamic table size
-> Size | The size of temporary buffer for Huffman
-> (DynamicTable -> IO a) |
-> IO a |

Creating `DynamicTable` for decoding, performing the action and clearing the `DynamicTable`.

setLimitForEncoding :: Size -> DynamicTable -> IO () Source #

When SETTINGS_HEADER_TABLE_SIZE is received from a peer, its value should be set by this function.

# Strategy for encoding

data CompressionAlgo Source #

Compression algorithms for HPACK encoding.

Constructors

Naive | No compression
Static | Using indices in the static table only
Linear | Using indices

#### Instances

Instances details

Show CompressionAlgo Source # |
Instance details Defined in Network.HPACK.Types Methods showsPrec :: Int -> CompressionAlgo -> ShowS Source # show :: CompressionAlgo -> String Source # showList :: [CompressionAlgo] -> ShowS Source #
Eq CompressionAlgo Source # |
Instance details Defined in Network.HPACK.Types Methods (==) :: CompressionAlgo -> CompressionAlgo -> Bool Source # (/=) :: CompressionAlgo -> CompressionAlgo -> Bool Source #

data EncodeStrategy Source #

Strategy for HPACK encoding.

Constructors

EncodeStrategy |

Fields

- compressionAlgo :: CompressionAlgo

  Which compression algorithm is used.

- useHuffman :: Bool

  Whether or not to use Huffman encoding for strings.

#### Instances

Instances details

Show EncodeStrategy Source # |
Instance details Defined in Network.HPACK.Types Methods showsPrec :: Int -> EncodeStrategy -> ShowS Source # show :: EncodeStrategy -> String Source # showList :: [EncodeStrategy] -> ShowS Source #
Eq EncodeStrategy Source # |
Instance details Defined in Network.HPACK.Types Methods (==) :: EncodeStrategy -> EncodeStrategy -> Bool Source # (/=) :: EncodeStrategy -> EncodeStrategy -> Bool Source #

defaultEncodeStrategy :: EncodeStrategy Source #

Default `EncodeStrategy`.

    >>> defaultEncodeStrategy
    EncodeStrategy {compressionAlgo = Linear, useHuffman = False}

# Errors

data DecodeError Source #

Errors for decoder.

Constructors

IndexOverrun Index | Index is out of range
EosInTheMiddle | Eos appears in the middle of huffman string
IllegalEos | Non-eos appears in the end of huffman string
TooLongEos | Eos of huffman string is more than 7 bits
TooSmallTableSize | A peer set the dynamic table size less than 32
TooLargeTableSize | A peer tried to change the dynamic table size over the limit
IllegalTableSizeUpdate | Table size update at the non-beginning
HeaderBlockTruncated |
IllegalHeaderName |
TooLargeHeader |

#### Instances

Instances details

Exception DecodeError Source # |
Instance details Defined in Network.HPACK.Types Methods toException :: DecodeError -> SomeException Source # fromException :: SomeException -> Maybe DecodeError Source # displayException :: DecodeError -> String Source # backtraceDesired :: DecodeError -> Bool Source #
Show DecodeError Source # |
Instance details Defined in Network.HPACK.Types Methods showsPrec :: Int -> DecodeError -> ShowS Source # show :: DecodeError -> String Source # showList :: [DecodeError] -> ShowS Source #
Eq DecodeError Source # |
Instance details Defined in Network.HPACK.Types Methods (==) :: DecodeError -> DecodeError -> Bool Source # (/=) :: DecodeError -> DecodeError -> Bool Source #

data BufferOverrun Source #

Buffer overrun exception.

Constructors

BufferOverrun | The buffer size is not enough

#### Instances

Instances details

Exception BufferOverrun |
Instance details Defined in Network.ByteOrder Methods toException :: BufferOverrun -> SomeException Source # fromException :: SomeException -> Maybe BufferOverrun Source # displayException :: BufferOverrun -> String Source # backtraceDesired :: BufferOverrun -> Bool Source #
Show BufferOverrun |
Instance details Defined in Network.ByteOrder Methods showsPrec :: Int -> BufferOverrun -> ShowS Source # show :: BufferOverrun -> String Source # showList :: [BufferOverrun] -> ShowS Source #
Eq BufferOverrun |
Instance details Defined in Network.ByteOrder Methods (==) :: BufferOverrun -> BufferOverrun -> Bool Source # (/=) :: BufferOverrun -> BufferOverrun -> Bool Source #

# Token header

type FieldValue = ByteString Source #

Field value.

type TokenHeader = (Token, FieldValue) Source #

TokenBased header.

type TokenHeaderList = [TokenHeader] Source #

TokenBased header list.

toTokenHeaderTable :: [Header] -> IO TokenHeaderTable Source #

Converting a header list of the http-types style to `TokenHeaderList` and `ValueTable`.

# Value table

type ValueTable = Array Int (Maybe FieldValue) Source #

An array to get `FieldValue` quickly. `getHeaderValue` should be used. Internally, the key is `tokenIx`.

type TokenHeaderTable = (TokenHeaderList, ValueTable) Source #

A pair of token list and value table.

getFieldValue :: Token -> ValueTable -> Maybe FieldValue Source #

Accessing `FieldValue` with `Token`.

getHeaderValue :: Token -> ValueTable -> Maybe FieldValue Source #

Accessing `FieldValue` with `Token`.

# Basic types

type Size = Int Source #

Size in bytes.

type Index = Int Source #

Index for table.

type Buffer = Ptr Word8 Source #

A pointer to `Word8`.

type BufferSize = Int Source #

Size of a buffer.