APIHttp

Http

What HTTP/1.1 requests and responses share: headers, bodies, versions, and protocol errors.

Http.Server serves requests and Http.Client sends them; Http.Wire frames messages for both. Header names compare without ASCII case, and a header list keeps duplicate fields unless one is replaced.

Body

type Body e    = Empty    | BytesBody Bytes    | StreamBody (Writer e ->{e} ())    | SizedBody Int (Writer e ->{e} ())Source

A message body whose writes perform e. A streaming body runs with the handler’s effects, so it can produce its output while writing it, holding one buffer rather than the whole payload. A body that fails partway leaves the message truncated, never padded or terminated.

Constructors

Empty

Empty : Body eSource

No body.

BytesBody

BytesBody : Bytes -> Body eSource

These bytes, sent with their length.

StreamBody

StreamBody : (Writer e ->{e} ()) -> Body eSource

Bytes pushed into the writer and sent chunked, in chunks of up to 8 KiB; an explicit flush sends whatever is pending.

SizedBody

SizedBody : Int -> (Writer e ->{e} ()) -> Body eSource

Bytes pushed into the writer and sent with this declared length. A write past it, or returning short of it, fails with InvalidMessage.

Error

type Error    = Malformed String    | LineTooLong    | HeadersTooLarge    | BodyTooLarge    | Unsupported String    | InvalidMessage String    | BodyAborted StringSource

A protocol failure. The server answers the status noted with each one.

Constructors

BodyTooLarge

BodyTooLarge : ErrorSource

A body over its limit (413).

BodyAborted

BodyAborted : String -> ErrorSource

A body stopped on purpose through abortBody, after the head was written.

Malformed

Malformed : String -> ErrorSource

Invalid syntax in a start line, header, or chunk, or a fixed-length body that ended early (400).

HeadersTooLarge

HeadersTooLarge : ErrorSource

A header block or trailers over the limit (431).

LineTooLong

LineTooLong : ErrorSource

A request line over its limit (414).

Unsupported

Unsupported : String -> ErrorSource

An unknown transfer coding (501).

InvalidMessage

InvalidMessage : String -> ErrorSource

A response the application built is invalid: a framing header, a body on a status that cannot carry one, or a sized body whose length does not match (500 when nothing has been written yet).

Instances:

Eq Error
Show Error
type Header =    { name : String    , value : String    }Source

One header field. Incoming values are valid UTF-8.

Fields

name

name : StringSource

The field name, compared without ASCII case.

value

value : StringSource

The field value.

Instances:

Eq Header
Show Header

Version

type Version = Http11Source

The protocol version.

Constructors

Http11

Http11 : VersionSource

HTTP/1.1, the only version supported.

Instances:

Eq Version
Show Version

Protocol

effect ProtocolSource

Failing an HTTP exchange with a protocol error. The server and client handle it.

Operations

invalid

abort invalid : Error ->{Protocol} aSource

Fails the exchange with error.

abortBody

abortBody : String ->{Protocol} aSource

Stops a streaming body on purpose. The message is left truncated and the connection is closed, so the peer cannot mistake it for a complete one.

equalAscii

equalAscii : String -> String -> BoolSource

Whether two strings are equal ignoring ASCII case, as header names compare.

import Http

Http.equalAscii "Content-Length" "content-length"
Http.equalAscii "É" "é" == False

fileBody

fileBody : String ->{Fail Error, FileSystem} Body {Fail Error, FileSystem, e}Source

A sized body that streams the file at path. The size is read now and the file is opened only while the body is written; a file that changed size in between fails the length check. The size query performs FileSystem; writing this streaming body also performs FileSystem.

getHeader

getHeader : String -> List Header -> Maybe StringSource

The value of the first header with this name.

import Http exposing (Header(..))

headers : List Http.Header
headers =
    [ { name = "Content-Type", value = "text/plain" }
    , { name = "Set-Cookie", value = "a=1" }
    , { name = "set-cookie", value = "b=2" }
    ]

Http.getHeader "content-type" headers == Just "text/plain"
Http.getHeader "Host" headers == Nothing

getHeaders

getHeaders : String -> List Header -> List StringSource

The values of every header with this name, in order.

import Http exposing (Header(..))

headers : List Http.Header
headers =
    [ { name = "Content-Type", value = "text/plain" }
    , { name = "Set-Cookie", value = "a=1" }
    , { name = "set-cookie", value = "b=2" }
    ]

Http.getHeaders "SET-COOKIE" headers == ["a=1", "b=2"]

hasHeader

hasHeader : String -> List Header -> BoolSource

Whether any header has this name.

removeHeader

removeHeader : String -> List Header -> List HeaderSource

The headers without any of this name.

import Http exposing (Header(..))

headers : List Http.Header
headers =
    [ { name = "Content-Type", value = "text/plain" }
    , { name = "Set-Cookie", value = "a=1" }
    , { name = "set-cookie", value = "b=2" }
    ]

Http.getHeaders "set-cookie" (Http.removeHeader "Set-Cookie" headers) == []

setHeader

setHeader : String -> String -> List Header -> List HeaderSource

The headers with every one of this name replaced by a single new one, placed first.

import Http exposing (Header(..))

headers : List Http.Header
headers =
    [ { name = "Content-Type", value = "text/plain" }
    , { name = "Set-Cookie", value = "a=1" }
    , { name = "set-cookie", value = "b=2" }
    ]

Http.getHeaders "set-cookie" (Http.setHeader "Set-Cookie" "c=3" headers) == ["c=3"]