http2-1.6.3: HTTP/2 library including frames, priority queues and HPACK

Safe HaskellNone
LanguageHaskell2010

Network.HTTP2

Contents

Description

Synopsis

Frame

data Frame #

The data type for HTTP/2 frames.

Constructors

Frame 

type HeaderBlockFragment = ByteString #

The type for fragments of a header encoded with HPACK.

type Padding = ByteString #

The type for padding in payloads.

isPaddingDefined :: FramePayload -> Bool #

Checking if padding is defined in this frame type.

>>> isPaddingDefined $ DataFrame ""
True
>>> isPaddingDefined $ PingFrame ""
False

Encoding

encodeFrame :: EncodeInfo -> FramePayload -> ByteString #

Encoding an HTTP/2 frame to ByteString. This function is not efficient enough for high performace program because of the concatenation of ByteString.

>>> encodeFrame (encodeInfo id 1) (DataFrame "body")
"\NUL\NUL\EOT\NUL\NUL\NUL\NUL\NUL\SOHbody"

encodeFrameChunks :: EncodeInfo -> FramePayload -> [ByteString] #

Encoding an HTTP/2 frame to [ByteString]. This is suitable for sendMany.

encodeFrameHeader :: FrameTypeId -> FrameHeader -> ByteString #

Encoding an HTTP/2 frame header. The frame header must be completed.

encodeFrameHeaderBuf :: FrameTypeId -> FrameHeader -> Ptr Word8 -> IO () #

Writing an encoded HTTP/2 frame header to the buffer. The length of the buffer must be larger than or equal to 9 bytes.

encodeFramePayload :: EncodeInfo -> FramePayload -> (FrameHeader, [ByteString]) #

Encoding an HTTP/2 frame payload. This returns a complete frame header and chunks of payload.

data EncodeInfo #

Auxiliary information for frame encoding.

Constructors

EncodeInfo 

Fields

  • encodeFlags :: !FrameFlags

    Flags to be set in a frame header

  • encodeStreamId :: !StreamId

    Stream id to be set in a frame header

  • encodePadding :: !(Maybe Padding)

    Padding if any. In the case where this value is set but the priority flag is not set, this value gets preference over the priority flag. So, if this value is set, the priority flag is also set.

encodeInfo #

Arguments

:: (FrameFlags -> FrameFlags) 
-> Int

stream identifier

-> EncodeInfo 

A smart builder of EncodeInfo.

>>> encodeInfo setAck 0
EncodeInfo {encodeFlags = 1, encodeStreamId = 0, encodePadding = Nothing}

Decoding

decodeFrame #

Arguments

:: Settings

HTTP/2 settings

-> ByteString

Input byte-stream

-> Either HTTP2Error Frame

Decoded frame

Decoding an HTTP/2 frame to ByteString. The second argument must be include the entire of frame. So, this function is not useful for real applications but useful for testing.

decodeFrameHeader :: ByteString -> (FrameTypeId, FrameHeader) #

Decoding an HTTP/2 frame header. Must supply 9 bytes.

checkFrameHeader :: Settings -> (FrameTypeId, FrameHeader) -> Either HTTP2Error (FrameTypeId, FrameHeader) #

Checking a frame header and reporting an error if any.

>>> checkFrameHeader defaultSettings (FrameData,(FrameHeader 100 0 0))
Left (ConnectionError ProtocolError "cannot used in control stream")

Decoding payload

decodeFramePayload :: FrameTypeId -> FramePayloadDecoder #

Decoding an HTTP/2 frame payload. This function is considered to return a frame payload decoder according to a frame type.

type FramePayloadDecoder = FrameHeader -> ByteString -> Either HTTP2Error FramePayload #

The type for frame payload decoder.

decodeDataFrame :: FramePayloadDecoder #

Frame payload decoder for DATA frame.

decodeHeadersFrame :: FramePayloadDecoder #

Frame payload decoder for HEADERS frame.

decodePriorityFrame :: FramePayloadDecoder #

Frame payload decoder for PRIORITY frame.

decoderstStreamFrame :: FramePayloadDecoder #

Frame payload decoder for RST_STREAM frame.

decodeSettingsFrame :: FramePayloadDecoder #

Frame payload decoder for SETTINGS frame.

decodePushPromiseFrame :: FramePayloadDecoder #

Frame payload decoder for PUSH_PROMISE frame.

decodePingFrame :: FramePayloadDecoder #

Frame payload decoder for PING frame.

decodeGoAwayFrame :: FramePayloadDecoder #

Frame payload decoder for GOAWAY frame.

decodeWindowUpdateFrame :: FramePayloadDecoder #

Frame payload decoder for WINDOW_UPDATE frame.

decodeContinuationFrame :: FramePayloadDecoder #

Frame payload decoder for CONTINUATION frame.

Frame type ID

framePayloadToFrameTypeId :: FramePayload -> FrameTypeId #

Getting FrameType from FramePayload.

>>> framePayloadToFrameTypeId (DataFrame "body")
FrameData

Frame type

type FrameType = Word8 #

The type for raw frame type.

fromFrameTypeId :: FrameTypeId -> FrameType #

Converting FrameTypeId to FrameType.

>>> fromFrameTypeId FrameData
0
>>> fromFrameTypeId FrameContinuation
9
>>> fromFrameTypeId (FrameUnknown 10)
10

toFrameTypeId :: FrameType -> FrameTypeId #

Converting FrameType to FrameTypeId.

>>> toFrameTypeId 0
FrameData
>>> toFrameTypeId 9
FrameContinuation
>>> toFrameTypeId 10
FrameUnknown 10

Priority

type Weight = Int #

The type for weight in priority. Its values are from 1 to 256.

defaultPriority :: Priority #

Default priority which depends on stream 0.

>>> defaultPriority
Priority {exclusive = False, streamDependency = 0, weight = 16}

highestPriority :: Priority #

Highest priority which depends on stream 0.

>>> highestPriority
Priority {exclusive = False, streamDependency = 0, weight = 256}

Stream identifier

type StreamId = Int #

The type for stream identifier

isControl :: StreamId -> Bool #

Checking if the stream identifier for control.

>>> isControl 0
True
>>> isControl 1
False

isRequest :: StreamId -> Bool #

Checking if the stream identifier for request.

>>> isRequest 0
False
>>> isRequest 1
True

isResponse :: StreamId -> Bool #

Checking if the stream identifier for response.

>>> isResponse 0
False
>>> isResponse 2
True

Stream identifier related

testExclusive :: StreamId -> Bool #

Checking if the exclusive flag is set.

setExclusive :: StreamId -> StreamId #

Setting the exclusive flag.

clearExclusive :: StreamId -> StreamId #

Clearing the exclusive flag.

Flags

type FrameFlags = Word8 #

The type for flags.

defaultFlags :: FrameFlags #

The initial value of flags. No flags are set.

>>> defaultFlags
0

testEndStream :: FrameFlags -> Bool #

Checking if the END_STREAM flag is set. >>> testEndStream 0x1 True

testAck :: FrameFlags -> Bool #

Checking if the ACK flag is set. >>> testAck 0x1 True

testEndHeader :: FrameFlags -> Bool #

Checking if the END_HEADERS flag is set.

>>> testEndHeader 0x4
True

testPadded :: FrameFlags -> Bool #

Checking if the PADDED flag is set.

>>> testPadded 0x8
True

testPriority :: FrameFlags -> Bool #

Checking if the PRIORITY flag is set.

>>> testPriority 0x20
True

setEndStream :: FrameFlags -> FrameFlags #

Setting the END_STREAM flag.

>>> setEndStream 0
1

setAck :: FrameFlags -> FrameFlags #

Setting the ACK flag.

>>> setAck 0
1

setEndHeader :: FrameFlags -> FrameFlags #

Setting the END_HEADERS flag.

>>> setEndHeader 0
4

setPadded :: FrameFlags -> FrameFlags #

Setting the PADDED flag.

>>> setPadded 0
8

setPriority :: FrameFlags -> FrameFlags #

Setting the PRIORITY flag.

>>> setPriority 0
32

SettingsList

type SettingsList = [(SettingsKeyId, SettingsValue)] #

Association list of SETTINGS.

data SettingsKeyId #

The type for SETTINGS key.

type SettingsValue = Int #

The type for raw SETTINGS value.

fromSettingsKeyId :: SettingsKeyId -> Word16 #

Converting SettingsKeyId to raw value.

>>> fromSettingsKeyId SettingsHeaderTableSize
1
>>> fromSettingsKeyId SettingsMaxHeaderBlockSize
6

toSettingsKeyId :: Word16 -> Maybe SettingsKeyId #

Converting raw value to SettingsKeyId.

>>> toSettingsKeyId 0
Nothing
>>> toSettingsKeyId 1
Just SettingsHeaderTableSize
>>> toSettingsKeyId 6
Just SettingsMaxHeaderBlockSize
>>> toSettingsKeyId 7
Nothing

checkSettingsList :: SettingsList -> Maybe HTTP2Error #

Checking SettingsList and reporting an error if any.

>>> checkSettingsList [(SettingsEnablePush,2)]
Just (ConnectionError ProtocolError "enable push must be 0 or 1")

Settings

data Settings #

Cooked version of settings. This is suitable to be stored in a HTTP/2 context.

Instances

defaultSettings :: Settings #

The default settings.

>>> defaultSettings
Settings {headerTableSize = 4096, enablePush = True, maxConcurrentStreams = Nothing, initialWindowSize = 65535, maxFrameSize = 16384, maxHeaderBlockSize = Nothing}

updateSettings :: Settings -> SettingsList -> Settings #

Updating settings.

>>> updateSettings defaultSettings [(SettingsEnablePush,0),(SettingsMaxHeaderBlockSize,200)]
Settings {headerTableSize = 4096, enablePush = False, maxConcurrentStreams = Nothing, initialWindowSize = 65535, maxFrameSize = 16384, maxHeaderBlockSize = Just 200}

Window

type WindowSize = Int #

The type for window size.

defaultInitialWindowSize :: WindowSize #

The default initial window size.

>>> defaultInitialWindowSize
65535

maxWindowSize :: WindowSize #

The maximum window size.

>>> maxWindowSize
2147483647

isWindowOverflow :: WindowSize -> Bool #

Checking if a window size exceeds the maximum window size.

>>> isWindowOverflow 10
False
>>> isWindowOverflow maxWindowSize
False
>>> isWindowOverflow (maxWindowSize + 1)
True

Error code

type ErrorCode = Word32 #

The type for raw error code.

fromErrorCodeId :: ErrorCodeId -> ErrorCode #

Converting ErrorCodeId to ErrorCode.

>>> fromErrorCodeId NoError
0
>>> fromErrorCodeId InadequateSecurity
12

toErrorCodeId :: ErrorCode -> ErrorCodeId #

Converting ErrorCode to ErrorCodeId.

>>> toErrorCodeId 0
NoError
>>> toErrorCodeId 0xc
InadequateSecurity
>>> toErrorCodeId 0xe
UnknownErrorCode 14

Error

Predefined values

connectionPreface :: ByteString #

The preface of HTTP/2.

>>> connectionPreface
"PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"

connectionPrefaceLength :: Int #

Length of the preface.

>>> connectionPrefaceLength
24

frameHeaderLength :: Int #

The length of HTTP/2 frame header.

>>> frameHeaderLength
9

maxPayloadLength :: Int #

The maximum length of HTTP/2 payload.

>>> maxPayloadLength
16384

recommendedConcurrency :: Int #

Default concurrency.

>>> recommendedConcurrency
100