http-common-0.8.3.4: Common types for HTTP clients and servers

Safe Haskell | None
Language | Haskell2010

Network.Http.Types

Contents

- Requests
- Responses
- Headers
- Exceptions

Description

Basic types used in HTTP communications. This modules is re-exported by both Network.Http.Client and Pipes.Http.Client, so if you're using either of those you don't need to explicitly import this module.

Synopsis

- type Hostname = ByteString
- type Port = Word16
- data Request
- data EntityBody
  - = Empty
  - | Chunking
  - | Static Int64
- data ExpectMode
  - = Normal
  - | Continue
- data RequestBuilder α
- buildRequest :: Monad ν => RequestBuilder α -> ν Request
- buildRequest1 :: RequestBuilder α -> Request
- http :: Method -> ByteString -> RequestBuilder ()
- setHostname :: Hostname -> Port -> RequestBuilder ()
- setAccept :: ByteString -> RequestBuilder ()
- setAccept' :: [(ByteString, Float)] -> RequestBuilder ()
- setAuthorizationBasic :: ByteString -> ByteString -> RequestBuilder ()
- type ContentType = ByteString
- setContentType :: ContentType -> RequestBuilder ()
- setContentLength :: Int64 -> RequestBuilder ()
- setExpectContinue :: RequestBuilder ()
- setTransferEncoding :: RequestBuilder ()
- type FieldName = ByteString
- data Boundary
- unBoundary :: Boundary -> ByteString
- emptyBoundary :: Boundary
- randomBoundary :: IO Boundary
- packBoundary :: String -> Boundary
- setContentMultipart :: Boundary -> RequestBuilder ()
- setHeader :: ByteString -> ByteString -> RequestBuilder ()
- data Response
- type StatusCode = Int
- data TransferEncoding
  - = None
  - | Chunked
- data ContentEncoding
  - = Identity
  - | Gzip
  - | Deflate
- getStatusCode :: Response -> StatusCode
- getStatusMessage :: Response -> ByteString
- getHeader :: Response -> ByteString -> Maybe ByteString
- data Method
  - = GET
  - | HEAD
  - | POST
  - | PUT
  - | DELETE
  - | TRACE
  - | OPTIONS
  - | CONNECT
  - | PATCH
  - | Method ByteString
- data Headers
- emptyHeaders :: Headers
- updateHeader :: Headers -> ByteString -> ByteString -> Headers
- removeHeader :: Headers -> ByteString -> Headers
- buildHeaders :: [(ByteString, ByteString)] -> Headers
- lookupHeader :: Headers -> ByteString -> Maybe ByteString
- retrieveHeaders :: Headers -> [(ByteString, ByteString)]
- class HttpType τ where
  - getHeaders :: τ -> Headers
- data HttpParseException = HttpParseException String

# Requests

type Hostname = ByteString Source #

type Port = Word16 Source #

data Request Source #

A description of the request that will be sent to the server. Note unlike other HTTP libraries, the request body is not a part of this object; that will be streamed out by you when actually sending the request with `sendRequest`.

`Request` has a useful `Show` instance that will output the request line and headers (as it will be sent over the wire but with the `\r` characters stripped) which can be handy for debugging.

Note that the actual `Host:` header is not set until the request is sent, so you will not see it in the Show instance (unless you call `setHostname` to override the value inherited from the `Connection`).

#### Instances

Instances details

Show Request Source # |
Instance details Defined in Network.Http.Internal Methods showsPrec :: Int -> Request -> ShowS Source # show :: Request -> String Source # showList :: [Request] -> ShowS Source #
Eq Request Source # |
Instance details Defined in Network.Http.Internal Methods (==) :: Request -> Request -> Bool Source # (/=) :: Request -> Request -> Bool Source #
HttpType Request Source # |
Instance details Defined in Network.Http.Internal Methods getHeaders :: Request -> Headers Source #
MonadState Request RequestBuilder Source # |
Instance details Defined in Network.Http.RequestBuilder Methods get :: RequestBuilder Request Source # put :: Request -> RequestBuilder () Source # state :: (Request -> (a, Request)) -> RequestBuilder a Source #

data EntityBody Source #

Constructors

Empty |
Chunking |
Static Int64 |

#### Instances

Instances details

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

Instance details

Defined in Network.Http.Internal

Methods

compare :: EntityBody -> EntityBody -> Ordering Source #

(<) :: EntityBody -> EntityBody -> Bool Source #

(<=) :: EntityBody -> EntityBody -> Bool Source #

(>) :: EntityBody -> EntityBody -> Bool Source #

(>=) :: EntityBody -> EntityBody -> Bool Source #

max :: EntityBody -> EntityBody -> EntityBody Source #

min :: EntityBody -> EntityBody -> EntityBody Source #

data ExpectMode Source #

Constructors

Normal |
Continue |

#### Instances

Instances details

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

Instance details

Defined in Network.Http.Internal

Methods

compare :: ExpectMode -> ExpectMode -> Ordering Source #

(<) :: ExpectMode -> ExpectMode -> Bool Source #

(<=) :: ExpectMode -> ExpectMode -> Bool Source #

(>) :: ExpectMode -> ExpectMode -> Bool Source #

(>=) :: ExpectMode -> ExpectMode -> Bool Source #

max :: ExpectMode -> ExpectMode -> ExpectMode Source #

min :: ExpectMode -> ExpectMode -> ExpectMode Source #

data RequestBuilder α Source #

The RequestBuilder monad allows you to abuse do-notation to conveniently setup a `Request` object.

#### Instances

Instances details

Applicative RequestBuilder Source # |

Instance details

Defined in Network.Http.RequestBuilder

Methods

pure :: a -> RequestBuilder a Source #

(<*>) :: RequestBuilder (a -> b) -> RequestBuilder a -> RequestBuilder b Source #

liftA2 :: (a -> b -> c) -> RequestBuilder a -> RequestBuilder b -> RequestBuilder c Source #

(*>) :: RequestBuilder a -> RequestBuilder b -> RequestBuilder b Source #

(<*) :: RequestBuilder a -> RequestBuilder b -> RequestBuilder a Source #

Functor RequestBuilder Source # |
Instance details Defined in Network.Http.RequestBuilder Methods fmap :: (a -> b) -> RequestBuilder a -> RequestBuilder b Source # (<$) :: a -> RequestBuilder b -> RequestBuilder a Source #
Monad RequestBuilder Source # |
Instance details Defined in Network.Http.RequestBuilder Methods (>>=) :: RequestBuilder a -> (a -> RequestBuilder b) -> RequestBuilder b Source # (>>) :: RequestBuilder a -> RequestBuilder b -> RequestBuilder b Source # return :: a -> RequestBuilder a Source #
MonadState Request RequestBuilder Source # |
Instance details Defined in Network.Http.RequestBuilder Methods get :: RequestBuilder Request Source # put :: Request -> RequestBuilder () Source # state :: (Request -> (a, Request)) -> RequestBuilder a Source #

buildRequest :: Monad ν => RequestBuilder α -> ν Request Source #

Run a RequestBuilder from within a monadic action.

Older versions of this library had `buildRequest` in IO; there's no longer a need for that, but this code path will continue to work for existing users.

        q <- buildRequest $ do
                 http GET "/"

buildRequest1 :: RequestBuilder α -> Request Source #

Run a RequestBuilder, yielding a Request object you can use on the given connection.

        let q = buildRequest1 $ do
                    http POST "/api/v1/messages"
                    setContentType "application/json"
                    setHostname "clue.example.com" 80
                    setAccept "text/html"
                    setHeader "X-WhoDoneIt" "The Butler"

Obviously it's up to you to later actually send JSON data.

http :: Method -> ByteString -> RequestBuilder () Source #

Begin constructing a Request, starting with the request line.

setHostname :: Hostname -> Port -> RequestBuilder () Source #

Set the [virtual] hostname for the request. In ordinary conditions you won't need to call this, as the `Host:` header is a required header in HTTP 1.1 and is set directly from the name of the server you connected to when calling `openConnection`.

setAccept :: ByteString -> RequestBuilder () Source #

Indicate the content type you are willing to receive in a reply from the server. For more complex `Accept:` headers, use `setAccept'`.

setAccept' :: [(ByteString, Float)] -> RequestBuilder () Source #

Indicate the content types you are willing to receive in a reply from the server in order of preference. A call of the form:

            setAccept' [("text/html", 1.0),
                        ("application/xml", 0.8),
                        ("*/*", 0)]

will result in an `Accept:` header value of `text/html; q=1.0, application/xml; q=0.8, */*; q=0.0` as you would expect.

setAuthorizationBasic :: ByteString -> ByteString -> RequestBuilder () Source #

Set username and password credentials per the HTTP basic authentication method.

            setAuthorizationBasic "Aladdin" "open sesame"

will result in an `Authorization:` header value of `Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==`.

Basic authentication does not use a message digest function to encipher the password; the above string is only base-64 encoded and is thus plain-text visible to any observer on the wire and all caches and servers at the other end, making basic authentication completely insecure. A number of web services, however, use SSL to encrypt the connection that then use HTTP basic authentication to validate requests. Keep in mind in these cases the secret is still sent to the servers on the other side and passes in clear through all layers after the SSL termination. Do not use basic authentication to protect secure or user-originated privacy-sensitve information.

type ContentType = ByteString Source #

setContentType :: ContentType -> RequestBuilder () Source #

Set the MIME type corresponding to the body of the request you are sending. Defaults to `"text/plain"`, so usually you need to set this if `PUT`ting.

setContentLength :: Int64 -> RequestBuilder () Source #

Specify the length of the request body, in bytes.

RFC 2616 requires that we either send a `Content-Length` header or use `Transfer-Encoding: chunked`. If you know the exact size ahead of time, then call this function; the body content will still be streamed out by `io-streams` in more-or-less constant space.

This function is special: in a PUT or POST request, `http-streams` will assume chunked transfer-encoding unless you specify a content length here, in which case you need to ensure your body function writes precisely that many bytes.

setExpectContinue :: RequestBuilder () Source #

Specify that this request should set the expectation that the server needs to approve the request before you send it.

This function is special: in a PUT or POST request, `http-streams` will wait for the server to reply with an HTTP/1.1 100 Continue status before sending the entity body. This is handled internally; you will get the real response (be it successful 2xx, client error, 4xx, or server error 5xx) in `receiveResponse`. In theory, it should be 417 if the expectation failed.

Only bother with this if you know the service you're talking to requires clients to send an `Expect: 100-continue` header and will handle it properly. Most servers don't do any precondition checking, automatically send an intermediate 100 response, and then just read the body regardless, making this a bit of a no-op in most cases.

setTransferEncoding :: RequestBuilder () Source #

Override the default setting about how the entity body will be sent.

This function is special: this explicitly sets the `Transfer-Encoding:` header to `chunked` and will instruct the library to actually tranfer the body as a stream ("chunked transfer encoding"). See `setContentLength` for forcing the opposite. You really won't need this in normal operation, but some people are control freaks.

type FieldName = ByteString Source #

data Boundary Source #

#### Instances

Instances details

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

unBoundary :: Boundary -> ByteString Source #

emptyBoundary :: Boundary Source #

randomBoundary :: IO Boundary Source #

Generate a random string to be used as an inter-part boundary in RFC 7578 multipart form data. You pass this value to `setContentMultipart` and subsequently to `multipartFormBody`.

packBoundary :: String -> Boundary Source #

If you want to fix the multipart boundary to a known value (for testing purposes) you can use this. The ideal such string, in case you are wondering, is `"bEacHV0113YB@ll"`.

This isn't safe for use in production; you need to use an unpredictable value as the boundary separtor so prefer `randomBoundary`.

setContentMultipart :: Boundary -> RequestBuilder () Source #

If sending multipart form data (RFC 7578), you need to set the MIME type to `"multipart/form-data"` and specify the boundary separator that will be used.

This function is special: you must subsequently use `multipartFormBody` to sequence the individual body parts. When sending the request it will separate the individual parts by the boundary value set by this function.

setHeader :: ByteString -> ByteString -> RequestBuilder () Source #

Set a generic header to be sent in the HTTP request. The other methods in the RequestBuilder API are expressed in terms of this function, but we recommend you use them where offered for their stronger types.

# Responses

data Response Source #

A description of the response received from the server. Note unlike other HTTP libraries, the response body is not a part of this object; that will be streamed in by you when calling `receiveResponse`.

Like `Request`, `Response` has a `Show` instance that will output the status line and response headers as they were received from the server.

#### Instances

Instances details

Show Response Source # |
Instance details Defined in Network.Http.Internal Methods showsPrec :: Int -> Response -> ShowS Source # show :: Response -> String Source # showList :: [Response] -> ShowS Source #
HttpType Response Source # |
Instance details Defined in Network.Http.Internal Methods getHeaders :: Response -> Headers Source #

type StatusCode = Int Source #

data TransferEncoding Source #

Constructors

None |
Chunked |

data ContentEncoding Source #

Constructors

Identity |
Gzip |
Deflate |

#### Instances

Instances details

Show ContentEncoding Source # |
Instance details Defined in Network.Http.Internal Methods showsPrec :: Int -> ContentEncoding -> ShowS Source # show :: ContentEncoding -> String Source # showList :: [ContentEncoding] -> ShowS Source #

getStatusCode :: Response -> StatusCode Source #

Get the HTTP response status code.

getStatusMessage :: Response -> ByteString Source #

Get the HTTP response status message. Keep in mind that this is not normative; whereas `getStatusCode` values are authoritative.

getHeader :: Response -> ByteString -> Maybe ByteString Source #

Lookup a header in the response. HTTP header field names are case-insensitive, so you can specify the name to lookup however you like. If the header is not present `Nothing` will be returned.

        let n = case getHeader p "Content-Length" of
                   Just x' -> read x' :: Int
                   Nothing -> 0

which of course is essentially what goes on inside the client library when it receives a response from the server and has to figure out how many bytes to read.

There is a fair bit of complexity in some of the other HTTP response fields, so there are a number of specialized functions for reading those values where we've found them useful.

data Method Source #

HTTP Methods, as per RFC 2616

Constructors

GET |
HEAD |
POST |
PUT |
DELETE |
TRACE |
OPTIONS |
CONNECT |
PATCH |
Method ByteString |

#### Instances

Instances details

Read Method Source # |
Instance details Defined in Network.Http.Internal Methods readsPrec :: Int -> ReadS Method Source # readList :: ReadS [Method] Source # readPrec :: ReadPrec Method Source # readListPrec :: ReadPrec [Method] Source #
Show Method Source # |
Instance details Defined in Network.Http.Internal Methods showsPrec :: Int -> Method -> ShowS Source # show :: Method -> String Source # showList :: [Method] -> ShowS Source #
Eq Method Source # |
Instance details Defined in Network.Http.Internal Methods (==) :: Method -> Method -> Bool Source # (/=) :: Method -> Method -> Bool Source #
Ord Method Source # |
Instance details Defined in Network.Http.Internal Methods compare :: Method -> Method -> Ordering Source # (<) :: Method -> Method -> Bool Source # (<=) :: Method -> Method -> Bool Source # (>) :: Method -> Method -> Bool Source # (>=) :: Method -> Method -> Bool Source # max :: Method -> Method -> Method Source # min :: Method -> Method -> Method Source #

# Headers

data Headers Source #

The map of headers in a `Request` or `Response`. Note that HTTP header field names are case insensitive, so if you call `setHeader` on a field that's already defined but with a different capitalization you will replace the existing value.

#### Instances

Instances details

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

emptyHeaders :: Headers Source #

updateHeader :: Headers -> ByteString -> ByteString -> Headers Source #

Set a header field to the specified value. This will overwrite any existing value for the field. Remember that HTTP fields names are case insensitive!

removeHeader :: Headers -> ByteString -> Headers Source #

Remove a header from the map. If a field with that name is not present, then this will have no effect.

buildHeaders :: [(ByteString, ByteString)] -> Headers Source #

Given a list of field-name,field-value pairs, construct a Headers map.

lookupHeader :: Headers -> ByteString -> Maybe ByteString Source #

retrieveHeaders :: Headers -> [(ByteString, ByteString)] Source #

Get the headers as a field-name,field-value association list.

class HttpType τ where Source #

Accessors common to both the outbound and return sides of an HTTP connection.

Most people do not need this; for most cases you just need to get a header or two from the response, for which you can use `getHeader`. On the other hand, if you do need to poke around in the raw headers,

    import Network.Http.Types

will give you functions like `lookupHeader` and `updateHeader` to to work with.

Methods

getHeaders :: τ -> Headers Source #

Get the Headers from a Request or Response.y

#### Instances

Instances details

HttpType Request Source # |
Instance details Defined in Network.Http.Internal Methods getHeaders :: Request -> Headers Source #
HttpType Response Source # |
Instance details Defined in Network.Http.Internal Methods getHeaders :: Response -> Headers Source #

# Exceptions

data HttpParseException Source #

Constructors

HttpParseException String |

#### Instances

Instances details

Exception HttpParseException Source # |
Instance details Defined in Network.Http.Internal Methods toException :: HttpParseException -> SomeException Source # fromException :: SomeException -> Maybe HttpParseException Source # displayException :: HttpParseException -> String Source # backtraceDesired :: HttpParseException -> Bool Source #
Show HttpParseException Source # |
Instance details Defined in Network.Http.Internal Methods showsPrec :: Int -> HttpParseException -> ShowS Source # show :: HttpParseException -> String Source # showList :: [HttpParseException] -> ShowS Source #