http-types-0.12.4: Generic HTTP types for Haskell (for both client and server code).

Safe Haskell | Safe-Inferred
Language | Haskell2010

Network.HTTP.Types.URI

Contents

- Query strings
  - Query
    - Query (Text)
  - SimpleQuery
  - PartialEscapeQuery
- Path
  - Segments + Query String
  - Path Segments
- URL encoding / decoding

Description

Query strings generally have the following form: `"key1=value1&key2=value2"`

    >>> renderQuery False [("key1", Just "value1"), ("key2", Just "value2")]
    "key1=value1&key2=value2"

But if the value of `key1` is `Nothing`, it becomes: `key1&key2=value2`

    >>> renderQuery False [("key1", Nothing), ("key2", Just "value2")]
    "key1&key2=value2"

This module also provides type synonyms and functions to handle queries that do not allow/expect keys without values (`SimpleQuery`), handle queries which have partially escaped characters

Synopsis

- type Query = [QueryItem]
- type QueryItem = (ByteString, Maybe ByteString)
- renderQuery :: Bool -> Query -> ByteString
- renderQueryBuilder :: Bool -> Query -> Builder
- parseQuery :: ByteString -> Query
- parseQueryReplacePlus :: Bool -> ByteString -> Query
- type QueryText = [(Text, Maybe Text)]
- queryTextToQuery :: QueryText -> Query
- queryToQueryText :: Query -> QueryText
- renderQueryText :: Bool -> QueryText -> Builder
- parseQueryText :: ByteString -> QueryText
- type SimpleQuery = [SimpleQueryItem]
- type SimpleQueryItem = (ByteString, ByteString)
- simpleQueryToQuery :: SimpleQuery -> Query
- renderSimpleQuery :: Bool -> SimpleQuery -> ByteString
- parseSimpleQuery :: ByteString -> SimpleQuery
- type PartialEscapeQuery = [PartialEscapeQueryItem]
- type PartialEscapeQueryItem = (ByteString, [EscapeItem])
- data EscapeItem
  - = QE ByteString
  - | QN ByteString
- renderQueryPartialEscape :: Bool -> PartialEscapeQuery -> ByteString
- renderQueryBuilderPartialEscape :: Bool -> PartialEscapeQuery -> Builder
- extractPath :: ByteString -> ByteString
- encodePath :: [Text] -> Query -> Builder
- decodePath :: ByteString -> ([Text], Query)
- encodePathSegments :: [Text] -> Builder
- encodePathSegmentsRelative :: [Text] -> Builder
- decodePathSegments :: ByteString -> [Text]
- urlEncode :: Bool -> ByteString -> ByteString
- urlEncodeBuilder :: Bool -> ByteString -> Builder
- urlDecode :: Bool -> ByteString -> ByteString

# Query strings

## Query

type Query = [QueryItem] #

A sequence of `QueryItem`s.

type QueryItem = (ByteString, Maybe ByteString) #

An item from the query string, split up into two parts.

The second part should be `Nothing` if there was no key-value separator after the query item name.

Since: 0.2.0

renderQuery :: Bool -> Query -> ByteString #

Renders the given `Query` into a `ByteString`.

If you want a question mark (`?`) added to the front of the result, use `True`.

Since: 0.2.0

renderQueryBuilder :: Bool -> Query -> Builder #

Renders the given `Query` into a `Builder`.

If you want a question mark (`?`) added to the front of the result, use `True`.

Since: 0.5

parseQuery :: ByteString -> Query #

Split out the query string into a list of keys and values. A few importants points:

- The result returned is still bytestrings, since we perform no character decoding here. Most likely, you will want to use UTF-8 decoding, but this is left to the user of the library.
- Percent decoding errors are ignored. In particular, `"%Q"` will be output as `"%Q"`.
- It decodes `'+'` characters to `' '`

Since: 0.2.0

parseQueryReplacePlus :: Bool -> ByteString -> Query #

Same functionality as `parseQuery`, but with the option to decode `'+'` characters to `' '` or to preserve any `'+'` encountered.

If you want to replace any `'+'` with a space, use `True`.

Since: 0.12.2

### Query (Text)

type QueryText = [(Text, Maybe Text)] #

Like Query, but with `Text` instead of `ByteString` (UTF8-encoded).

Since: 0.5.2

queryTextToQuery :: QueryText -> Query #

Convert `QueryText` to `Query`.

Since: 0.5.2

queryToQueryText :: Query -> QueryText #

Convert `Query` to `QueryText` (leniently decoding the UTF-8).

Since: 0.5.2

renderQueryText :: Bool -> QueryText -> Builder #

Convert `QueryText` to a `Builder`.

If you want a question mark (`?`) added to the front of the result, use `True`.

Since: 0.5.2

parseQueryText :: ByteString -> QueryText #

Parse a `QueryText` from a `ByteString`. See `parseQuery` for details.

    queryToQueryText . parseQuery

Since: 0.5.2

## SimpleQuery

If values are guaranteed, it might be easier working with `SimpleQuery`.

This way, you don't have to worry about any `Maybe`s, though when parsing a query string and there's no `'='` after the key in the query item, the value will just be an empty `ByteString`.

type SimpleQuery = [SimpleQueryItem] #

A sequence of `SimpleQueryItem`s.

type SimpleQueryItem = (ByteString, ByteString) #

Simplified query item type without support for parameter-less items.

Since: 0.2.0

simpleQueryToQuery :: SimpleQuery -> Query #

Convert `SimpleQuery` to `Query`.

Since: 0.5

renderSimpleQuery :: Bool -> SimpleQuery -> ByteString #

Render the given `SimpleQuery` into a `ByteString`.

If you want a question mark (`?`) added to the front of the result, use `True`.

Since: 0.2.0

parseSimpleQuery :: ByteString -> SimpleQuery #

Parse `SimpleQuery` from a `ByteString`.

This uses `parseQuery` under the hood, and will transform any `Nothing` values into an empty `ByteString`.

Since: 0.2.0

## PartialEscapeQuery

For some values in query items, certain characters must not be percent-encoded, for example `'+'` or `':'` in

    q=a+language:haskell+created:2009-01-01..2009-02-01&sort=stars

Using specific `EscapeItem`s provides a way to decide which parts of a query string value will be URL encoded and which won't.

This is mandatory when searching for `'+'` (`%2B` being a percent-encoded `'+'`):

    q=%2B+language:haskell

type PartialEscapeQuery = [PartialEscapeQueryItem] #

Query with some characters that should not be escaped.

General form: `a=b&c=d:e+f&g=h`

Since: 0.12.1

type PartialEscapeQueryItem = (ByteString, [EscapeItem]) #

Partially escaped query item.

The key will always be encoded using `'urlEncode True'`, but the value will be encoded depending on which `EscapeItem`s are used.

Since: 0.12.1

data EscapeItem #

Section of a query item value that decides whether to use regular URL encoding (using `'urlEncode True'`) with `QE`, or to not encode anything with `QN`.

Since: 0.12.1

Constructors

QE ByteString | will be URL encoded
QN ByteString | will NOT at all be URL encoded

#### Instances

Instances details

Show EscapeItem # |
Instance details Defined in Network.HTTP.Types.URI Methods showsPrec :: Int -> EscapeItem -> ShowS # show :: EscapeItem -> String # showList :: [EscapeItem] -> ShowS #
Eq EscapeItem # |
Instance details Defined in Network.HTTP.Types.URI Methods (==) :: EscapeItem -> EscapeItem -> Bool # (/=) :: EscapeItem -> EscapeItem -> Bool #
Ord EscapeItem # |
Instance details Defined in Network.HTTP.Types.URI Methods compare :: EscapeItem -> EscapeItem -> Ordering # (<) :: EscapeItem -> EscapeItem -> Bool # (<=) :: EscapeItem -> EscapeItem -> Bool # (>) :: EscapeItem -> EscapeItem -> Bool # (>=) :: EscapeItem -> EscapeItem -> Bool # max :: EscapeItem -> EscapeItem -> EscapeItem # min :: EscapeItem -> EscapeItem -> EscapeItem #

renderQueryPartialEscape :: Bool -> PartialEscapeQuery -> ByteString #

Convert `PartialEscapeQuery` to `ByteString`.

If you want a question mark (`?`) added to the front of the result, use `True`.

    >>> renderQueryPartialEscape True [("a", [QN "x:z + ", QE (encodeUtf8 "They said: \"שלום\"")])]
    "?a=x:z + They%20said%3A%20%22%D7%A9%D7%9C%D7%95%D7%9D%22"

Since: 0.12.1

renderQueryBuilderPartialEscape :: Bool -> PartialEscapeQuery -> Builder #

Convert a `PartialEscapeQuery` to a `Builder`.

If you want a question mark (`?`) added to the front of the result, use `True`.

Since: 0.12.1

# Path

## Segments + Query String

extractPath :: ByteString -> ByteString #

Extract whole path (path segments + query) from a RFC 2616 Request-URI.

Though a more accurate description of this function's behaviour is that it removes the domain/origin if the string starts with an HTTP protocol. (i.e. `http://` or `https://`)

This function will not change anything when given any other `ByteString`. (except return a root path `"/"` if given an empty string)

    >>> extractPath "/path"
    "/path"

    >>> extractPath "http://example.com:8080/path"
    "/path"

    >>> extractPath "http://example.com"
    "/"

    >>> extractPath ""
    "/"

    >>> extractPath "www.google.com/some/path"
    "www.google.com/some/path"

Since: 0.8.5

encodePath :: [Text] -> Query -> Builder #

Encode a whole path (path segments + query).

Since: 0.5

decodePath :: ByteString -> ([Text], Query) #

Decode a whole path (path segments + query).

Since: 0.5

## Path Segments

encodePathSegments :: [Text] -> Builder #

Encodes a list of path segments into a valid URL fragment.

This function takes the following three steps:

- UTF-8 encodes the characters.
- Prepends each segment with a slash.

- Performs percent-encoding on all characters that are not:

  - alphanumeric (i.e. `A-Z` and `a-z`)
  - digits (i.e. `0-9`)
  - a dash `'-'`, an underscore `'_'`, a dot `'.'`, or a tilde `'~'`

For example:

    >>> encodePathSegments ["foo", "bar1", "~baz"]
    "/foo/bar1/~baz"

    >>> encodePathSegments ["foo bar", "baz/bin"]
    "/foo%20bar/baz%2Fbin"

    >>> encodePathSegments ["שלום"]
    "/%D7%A9%D7%9C%D7%95%D7%9D"

Huge thanks to Jeremy Shaw who created the original implementation of this function in web-routes and did such thorough research to determine all correct escaping procedures.

Since: 0.5

encodePathSegmentsRelative :: [Text] -> Builder #

Like `encodePathSegments`, but without the initial slash.

Since: 0.6.10

decodePathSegments :: ByteString -> [Text] #

Parse a list of path segments from a valid URL fragment.

Will also decode any percent-encoded characters.

Since: 0.5

# URL encoding / decoding

urlEncode :: Bool -> ByteString -> ByteString #

Percent-encoding for URLs.

In short:

- if you're encoding (parts of) a path element, use `False`.
- if you're encoding (parts of) a query string, use `True`.

### In-depth explanation

Expand

This will substitute every byte with its percent-encoded equivalent unless:

- The byte is alphanumeric. (i.e. `A-Z`, `a-z`, or `0-9`)
- The byte is either a dash `'-'`, an underscore `'_'`, a dot `'.'`, or a tilde `'~'`

- If `False` is used, the following will also not be percent-encoded:

  - colon `':'`, at sign `'@'`, ampersand `'&'`, equals sign `'='`, plus sign `'+'`, dollar sign `'$'` or a comma `','`

Since: 0.2.0

urlEncodeBuilder :: Bool -> ByteString -> Builder #

Percent-encoding for URLs.

Like `urlEncode`, but only makes the `Builder`.

Since: 0.5

urlDecode :: Bool -> ByteString -> ByteString #

Percent-decoding.

If you want to replace any `'+'` with a space, use `True`.

Since: 0.2.0