Safe Haskell | None |
---|---|
Language | Haskell2010 |
Utilities for working with headers.
- lowercaseHeaders :: Headers -> Headers
- headersAreLowercase :: Headers -> Bool
- headersAreLowercaseAtHeaderEditor :: HeaderEditor -> Bool
- fetchHeader :: Headers -> HeaderName -> Maybe HeaderValue
- data HeaderEditor
- type Headers = [Header]
- fromList :: Headers -> HeaderEditor
- toList :: HeaderEditor -> Headers
- headerLens :: ByteString -> Lens' HeaderEditor (Maybe ByteString)
- replaceHeaderValue :: HeaderEditor -> HeaderName -> Maybe HeaderValue -> HeaderEditor
- replaceHostByAuthority :: HeaderEditor -> HeaderEditor
- introduceDateHeader :: HeaderEditor -> IO HeaderEditor
- headerIsPseudo :: HeaderName -> Bool
- combineAuthorityAndHost :: HeaderEditor -> HeaderEditor
- removeConnectionHeaders :: Headers -> Headers
- fusionHeaders :: HeaderName -> ByteString -> Headers -> Headers
- data PrettyPrintHeadersConfig = PrettyPrintHeadersConfig {}
- indentSpace_PPHC :: Iso' PrettyPrintHeadersConfig Int
- prettyPrintHeaders :: PrettyPrintHeadersConfig -> Headers -> ByteString
- defaultPrettyPrintHeadersConfig :: PrettyPrintHeadersConfig
Simple manipulation
These transformations are simple enough that don't require
going away from the list representation (see type Headers
)
lowercaseHeaders :: Headers -> Headers
HTTP headers are case-insensitive, so we can use lowercase versions everywhere
headersAreLowercase :: Headers -> Bool
Checks that headers are lowercase
fetchHeader :: Headers -> HeaderName -> Maybe HeaderValue
Looks for a given header
Transformations based on maps
Many operations benefit from transforming the list to a map with custom sorting and doing a set of operations on that representation.
data HeaderEditor
List of headers. The first part of each tuple is the header name (be sure to conform to the HTTP/2 convention of using lowercase) and the second part is the headers contents. This list needs to include the special :method, :scheme, :authority and :path pseudo-headers for requests; and :status (with a plain numeric value represented in ascii digits) for responses.
Introducing and removing the HeaderEditor
fromList :: Headers -> HeaderEditor
O(n*log n) Builds the editor from a list.
toList :: HeaderEditor -> Headers
O(n) Takes the HeaderEditor back to Headers. Notice that these headers are good for both HTTP1.1 and HTTP2, as combined headers won't be merged. It will even work for Cookie headers.
Access to a particular header
headerLens :: ByteString -> Lens' HeaderEditor (Maybe ByteString)
headerLens header_name represents a lens into the headers,
and you can use it then to add, alter and() remove headers.
It uses the same semantics than replaceHeaderValue
replaceHeaderValue :: HeaderEditor -> HeaderName -> Maybe HeaderValue -> HeaderEditor
replaceHeaderValue headers header_name maybe_header_value looks for header_name. If header_name is found and maybe_header_value is nothing, it returns a new headers list with the header deleted. If header_name is found and header_value is Just new_value, it returns a new list with the header containing the new value. If header_name is not in headers and maybe_header_value is Nothing, it returns the original headers list. If header_name is not in headers and maybe_header_value is Just new_value, it returns a new list where the last element is (header_name, new_value)
HTTP utilities
replaceHostByAuthority :: HeaderEditor -> HeaderEditor
Replaces a "host" HTTP/1.1 header by an ":authority" HTTP/2 header. The list is expected to be already in lowercase, so nothing will happen if there the header name portion is "Host" instead of "host".
Notice that having a Host header in an HTTP/2 message is perfectly valid in certain circumstances, check Section 8.1.2.3 of the spec for details.
introduceDateHeader :: HeaderEditor -> IO HeaderEditor
Given a header editor, introduces a Date header. This function has a side-effect: to get the current time
headerIsPseudo :: HeaderName -> Bool
combineAuthorityAndHost :: HeaderEditor -> HeaderEditor
Combines ":authority" and "host", giving priority to the first. This is used when proxying HTTP2 to HTTP1.1. It leaves whichever header of highest priority is present
removeConnectionHeaders :: Headers -> Headers
Remove connection-specific headers as required by HTTP/2
fusionHeaders :: HeaderName -> ByteString -> Headers -> Headers
Fusion values for a specific header, using a provided separator.