Safe Haskell | None |
---|---|
Language | Haskell2010 |
Note that this is essentially the "kitchen sink" export module, including many functions intended only to be used internally by this package. No API stability is guaranteed for this module. If you see functions here which you believe should be promoted to a stable API, please contact the author.
- makeChunkedReader :: Bool -> Connection -> IO BodyReader
- makeLengthReader :: Int -> Connection -> IO BodyReader
- makeGzipReader :: BodyReader -> IO BodyReader
- makeUnlimitedReader :: Connection -> IO BodyReader
- brConsume :: BodyReader -> IO [ByteString]
- brEmpty :: BodyReader
- brAddCleanup :: IO () -> BodyReader -> BodyReader
- brReadSome :: BodyReader -> Int -> IO ByteString
- brRead :: BodyReader -> IO ByteString
- connectionReadLine :: Connection -> IO ByteString
- connectionReadLineWith :: Connection -> ByteString -> IO ByteString
- connectionDropTillBlankLine :: Connection -> IO ()
- dummyConnection :: [ByteString] -> IO (Connection, IO [ByteString], IO [ByteString])
- openSocketConnection :: (Socket -> IO ()) -> Maybe HostAddress -> String -> Int -> IO Connection
- openSocketConnectionSize :: (Socket -> IO ()) -> Int -> Maybe HostAddress -> String -> Int -> IO Connection
- makeConnection :: IO ByteString -> (ByteString -> IO ()) -> IO () -> IO Connection
- updateCookieJar :: Response a -> Request -> UTCTime -> CookieJar -> (CookieJar, Response a)
- receiveSetCookie :: SetCookie -> Request -> UTCTime -> Bool -> CookieJar -> CookieJar
- generateCookie :: SetCookie -> Request -> UTCTime -> Bool -> Maybe Cookie
- insertCheckedCookie :: Cookie -> CookieJar -> Bool -> CookieJar
- insertCookiesIntoRequest :: Request -> CookieJar -> UTCTime -> (Request, CookieJar)
- computeCookieString :: Request -> CookieJar -> UTCTime -> Bool -> (ByteString, CookieJar)
- evictExpiredCookies :: CookieJar -> UTCTime -> CookieJar
- createCookieJar :: [Cookie] -> CookieJar
- destroyCookieJar :: CookieJar -> [Cookie]
- pathMatches :: ByteString -> ByteString -> Bool
- removeExistingCookieFromCookieJar :: Cookie -> CookieJar -> (Maybe Cookie, CookieJar)
- domainMatches :: ByteString -> ByteString -> Bool
- isIpAddress :: ByteString -> Bool
- defaultPath :: Request -> ByteString
- withResponse :: Request -> Manager -> (Response BodyReader -> IO a) -> IO a
- httpLbs :: Request -> Manager -> IO (Response ByteString)
- httpNoBody :: Request -> Manager -> IO (Response ())
- httpRaw :: Request -> Manager -> IO (Response BodyReader)
- responseOpen :: Request -> Manager -> IO (Response BodyReader)
- responseClose :: Response a -> IO ()
- applyCheckStatus :: Request -> (Status -> ResponseHeaders -> CookieJar -> Maybe SomeException) -> Response BodyReader -> IO (Maybe SomeException)
- httpRedirect :: Int -> (Request -> IO (Response BodyReader, Maybe Request)) -> Request -> IO (Response BodyReader)
- parseStatusHeaders :: Connection -> IO StatusHeaders
- parseUrl :: MonadThrow m => String -> m Request
- setUriRelative :: MonadThrow m => Request -> URI -> m Request
- getUri :: Request -> URI
- setUri :: MonadThrow m => Request -> URI -> m Request
- browserDecompress :: ByteString -> Bool
- alwaysDecompress :: ByteString -> Bool
- addProxy :: ByteString -> Int -> Request -> Request
- applyBasicAuth :: ByteString -> ByteString -> Request -> Request
- applyBasicProxyAuth :: ByteString -> ByteString -> Request -> Request
- urlEncodedBody :: [(ByteString, ByteString)] -> Request -> Request
- needsGunzip :: Request -> [Header] -> Bool
- requestBuilder :: Request -> Connection -> IO ()
- useDefaultTimeout :: Maybe Int
- setQueryString :: [(ByteString, Maybe ByteString)] -> Request -> Request
- getRedirectedRequest :: Request -> ResponseHeaders -> CookieJar -> Int -> Maybe Request
- getResponse :: ConnRelease -> Maybe Int -> Request -> Connection -> IO (Response BodyReader)
- lbsResponse :: Response BodyReader -> IO (Response ByteString)
- data ManagerSettings = ManagerSettings {
- managerConnCount :: Int
- managerRawConnection :: IO (Maybe HostAddress -> String -> Int -> IO Connection)
- managerTlsConnection :: IO (Maybe HostAddress -> String -> Int -> IO Connection)
- managerTlsProxyConnection :: IO (ByteString -> (Connection -> IO ()) -> String -> Maybe HostAddress -> String -> Int -> IO Connection)
- managerResponseTimeout :: Maybe Int
- managerRetryableException :: SomeException -> Bool
- managerWrapIOException :: forall a. IO a -> IO a
- managerIdleConnectionCount :: Int
- managerModifyRequest :: Request -> IO Request
- newManager :: ManagerSettings -> IO Manager
- closeManager :: Manager -> IO ()
- withManager :: ManagerSettings -> (Manager -> IO a) -> IO a
- getConn :: Request -> Manager -> IO (ConnRelease, Connection, ManagedConn)
- failedConnectionException :: Request -> HttpException
- defaultManagerSettings :: ManagerSettings
- rawConnectionModifySocket :: (Socket -> IO ()) -> IO (Maybe HostAddress -> String -> Int -> IO Connection)
- type BodyReader = IO ByteString
- data Connection = Connection {
- connectionRead :: IO ByteString
- connectionUnread :: ByteString -> IO ()
- connectionWrite :: ByteString -> IO ()
- connectionClose :: IO ()
- data StatusHeaders = StatusHeaders Status HttpVersion RequestHeaders
- data HttpException
- = StatusCodeException Status ResponseHeaders CookieJar
- | InvalidUrlException String String
- | TooManyRedirects [Response ByteString]
- | UnparseableRedirect (Response ByteString)
- | TooManyRetries
- | HttpParserException String
- | HandshakeFailed
- | OverlongHeaders
- | ResponseTimeout
- | FailedConnectionException String Int
- | FailedConnectionException2 String Int Bool SomeException
- | ExpectedBlankAfter100Continue
- | InvalidStatusLine ByteString
- | InvalidHeader ByteString
- | InternalIOException IOException
- | ProxyConnectException ByteString Int (Either ByteString HttpException)
- | NoResponseDataReceived
- | TlsException SomeException
- | TlsNotSupported
- | ResponseBodyTooShort Word64 Word64
- | InvalidChunkHeaders
- | IncompleteHeaders
- | InvalidDestinationHost ByteString
- | HttpZlibException ZlibException
- data Cookie = Cookie {}
- newtype CookieJar = CJ {}
- data Proxy = Proxy {
- proxyHost :: ByteString
- proxyPort :: Int
- data RequestBody
- type Popper = IO ByteString
- type NeedsPopper a = Popper -> IO a
- type GivesPopper a = NeedsPopper a -> IO a
- data Request = Request {
- method :: Method
- secure :: Bool
- host :: ByteString
- port :: Int
- path :: ByteString
- queryString :: ByteString
- requestHeaders :: RequestHeaders
- requestBody :: RequestBody
- proxy :: Maybe Proxy
- hostAddress :: Maybe HostAddress
- rawBody :: Bool
- decompress :: ByteString -> Bool
- redirectCount :: Int
- checkStatus :: Status -> ResponseHeaders -> CookieJar -> Maybe SomeException
- responseTimeout :: Maybe Int
- getConnectionWrapper :: Maybe Int -> HttpException -> IO (ConnRelease, Connection, ManagedConn) -> IO (Maybe Int, (ConnRelease, Connection, ManagedConn))
- cookieJar :: Maybe CookieJar
- requestVersion :: HttpVersion
- onRequestBodyException :: SomeException -> IO ()
- data ConnReuse
- type ConnRelease = ConnReuse -> IO ()
- data ManagedConn
- data Response body = Response {
- responseStatus :: Status
- responseVersion :: HttpVersion
- responseHeaders :: ResponseHeaders
- responseBody :: body
- responseCookieJar :: CookieJar
- responseClose' :: ResponseClose
- newtype ResponseClose = ResponseClose {
- runResponseClose :: IO ()
- data Manager = Manager {
- mConns :: IORef ConnsMap
- mConnsBaton :: MVar ()
- mMaxConns :: Int
- mResponseTimeout :: Maybe Int
- mRawConnection :: Maybe HostAddress -> String -> Int -> IO Connection
- mTlsConnection :: Maybe HostAddress -> String -> Int -> IO Connection
- mTlsProxyConnection :: ByteString -> (Connection -> IO ()) -> String -> Maybe HostAddress -> String -> Int -> IO Connection
- mRetryableException :: SomeException -> Bool
- mWrapIOException :: forall a. IO a -> IO a
- mIdleConnectionCount :: Int
- mModifyRequest :: Request -> IO Request
- data ConnsMap
- = ManagerClosed
- | ManagerOpen !Int !(Map ConnKey (NonEmptyList Connection))
- data ManagerSettings = ManagerSettings {
- managerConnCount :: Int
- managerRawConnection :: IO (Maybe HostAddress -> String -> Int -> IO Connection)
- managerTlsConnection :: IO (Maybe HostAddress -> String -> Int -> IO Connection)
- managerTlsProxyConnection :: IO (ByteString -> (Connection -> IO ()) -> String -> Maybe HostAddress -> String -> Int -> IO Connection)
- managerResponseTimeout :: Maybe Int
- managerRetryableException :: SomeException -> Bool
- managerWrapIOException :: forall a. IO a -> IO a
- managerIdleConnectionCount :: Int
- managerModifyRequest :: Request -> IO Request
- data NonEmptyList a
- data ConnHost
- = HostName Text
- | HostAddress HostAddress
- data ConnKey = ConnKey ConnHost Int Bool
- hGetSome :: Handle -> Int -> IO ByteString
- (<>) :: Monoid m => m -> m -> m
- readDec :: Integral i => String -> Maybe i
- hasNoBody :: ByteString -> Int -> Bool
- fromStrict :: ByteString -> ByteString
Low-level response body handling
:: Bool | raw |
-> Connection | |
-> IO BodyReader |
makeLengthReader :: Int -> Connection -> IO BodyReader Source
brConsume :: BodyReader -> IO [ByteString] Source
Strictly consume all remaining chunks of data from the stream.
Since 0.1.0
brAddCleanup :: IO () -> BodyReader -> BodyReader Source
brReadSome :: BodyReader -> Int -> IO ByteString Source
brRead :: BodyReader -> IO ByteString Source
Get a single chunk of data from the response body, or an empty bytestring if no more data is available.
Since 0.1.0
Raw connection handling
connectionDropTillBlankLine :: Connection -> IO () Source
Keep dropping input until a blank line is found.
:: [ByteString] | input |
-> IO (Connection, IO [ByteString], IO [ByteString]) | conn, output, input |
For testing
:: IO ByteString | read |
-> (ByteString -> IO ()) | write |
-> IO () | close |
-> IO Connection |
Cookies
:: Response a | Response received from server |
-> Request | Request which generated the response |
-> UTCTime | Value that should be used as "now" |
-> CookieJar | Current cookie jar |
-> (CookieJar, Response a) | (Updated cookie jar with cookies from the Response, The response stripped of any "Set-Cookie" header) |
This applies receiveSetCookie
to a given Response
:: SetCookie | The |
-> Request | The request that originated the response that yielded the |
-> UTCTime | Value that should be used as "now" |
-> Bool | Whether or not this request is coming from an "http" source (not javascript or anything like that) |
-> CookieJar | Input cookie jar to modify |
-> CookieJar | Updated cookie jar |
This corresponds to the algorithm described in Section 5.3 "Storage Model"
This function consists of calling generateCookie
followed by insertCheckedCookie
.
Use this function if you plan to do both in a row.
generateCookie
and insertCheckedCookie
are only provided for more fine-grained control.
:: SetCookie | The |
-> Request | The request that originated the response that yielded the |
-> UTCTime | Value that should be used as "now" |
-> Bool | Whether or not this request is coming from an "http" source (not javascript or anything like that) |
-> Maybe Cookie | The optional output cookie |
Turn a SetCookie into a Cookie, if it is valid
:: Cookie | The |
-> CookieJar | Input cookie jar to modify |
-> Bool | Whether or not this request is coming from an "http" source (not javascript or anything like that) |
-> CookieJar | Updated (or not) cookie jar |
Insert a cookie created by generateCookie into the cookie jar (or not if it shouldn't be allowed in)
insertCookiesIntoRequest Source
:: Request | The request to insert into |
-> CookieJar | Current cookie jar |
-> UTCTime | Value that should be used as "now" |
-> (Request, CookieJar) | (Ouptut request, Updated cookie jar (last-access-time is updated)) |
This applies the computeCookieString
to a given Request
:: Request | Input request |
-> CookieJar | Current cookie jar |
-> UTCTime | Value that should be used as "now" |
-> Bool | Whether or not this request is coming from an "http" source (not javascript or anything like that) |
-> (ByteString, CookieJar) | (Contents of a "Cookie" header, Updated cookie jar (last-access-time is updated)) |
This corresponds to the algorithm described in Section 5.4 "The Cookie Header"
:: CookieJar | Input cookie jar |
-> UTCTime | Value that should be used as "now" |
-> CookieJar | Filtered cookie jar |
This corresponds to the eviction algorithm described in Section 5.3 "Storage Model"
createCookieJar :: [Cookie] -> CookieJar Source
destroyCookieJar :: CookieJar -> [Cookie] Source
pathMatches :: ByteString -> ByteString -> Bool Source
This corresponds to the subcomponent algorithm entitled "Path-Match" detailed in section 5.1.4
domainMatches :: ByteString -> ByteString -> Bool Source
This corresponds to the subcomponent algorithm entitled "Domain Matching" detailed in section 5.1.3
isIpAddress :: ByteString -> Bool Source
defaultPath :: Request -> ByteString Source
This corresponds to the subcomponent algorithm entitled "Paths" detailed in section 5.1.4
Performing requests
withResponse :: Request -> Manager -> (Response BodyReader -> IO a) -> IO a Source
Perform a Request
using a connection acquired from the given Manager
,
and then provide the Response
to the given function. This function is
fully exception safe, guaranteeing that the response will be closed when the
inner function exits. It is defined as:
withResponse req man f = bracket (responseOpen req man) responseClose f
It is recommended that you use this function in place of explicit calls to
responseOpen
and responseClose
.
You will need to use functions such as brRead
to consume the response
body.
Since 0.1.0
httpLbs :: Request -> Manager -> IO (Response ByteString) Source
A convenience wrapper around withResponse
which reads in the entire
response body and immediately closes the connection. Note that this function
performs fully strict I/O, and only uses a lazy ByteString in its response
for memory efficiency. If you are anticipating a large response body, you
are encouraged to use withResponse
and brRead
instead.
Since 0.1.0
httpNoBody :: Request -> Manager -> IO (Response ()) Source
A convenient wrapper around withResponse
which ignores the response
body. This is useful, for example, when performing a HEAD request.
Since 0.3.2
httpRaw :: Request -> Manager -> IO (Response BodyReader) Source
Get a Response
without any redirect following.
responseOpen :: Request -> Manager -> IO (Response BodyReader) Source
The most low-level function for initiating an HTTP request.
The first argument to this function gives a full specification
on the request: the host to connect to, whether to use SSL,
headers, etc. Please see Request
for full details. The
second argument specifies which Manager
should be used.
This function then returns a Response
with a
BodyReader
. The Response
contains the status code
and headers that were sent back to us, and the
BodyReader
contains the body of the request. Note
that this BodyReader
allows you to have fully
interleaved IO actions during your HTTP download, making it
possible to download very large responses in constant memory.
An important note: the response body returned by this function represents a
live HTTP connection. As such, if you do not use the response body, an open
socket will be retained indefinitely. You must be certain to call
responseClose
on this response to free up resources.
This function automatically performs any necessary redirects, as specified
by the redirectCount
setting.
When implementing a (reverse) proxy using this function or relating functions, it's wise to remove Transfer-Encoding:, Content-Length:, Content-Encoding: and Accept-Encoding: from request and response headers to be relayed.
Since 0.1.0
responseClose :: Response a -> IO () Source
Close any open resources associated with the given Response
. In general,
this will either close an active Connection
or return it to the Manager
to be reused.
Since 0.1.0
applyCheckStatus :: Request -> (Status -> ResponseHeaders -> CookieJar -> Maybe SomeException) -> Response BodyReader -> IO (Maybe SomeException) Source
Apply 'Request'\'s checkStatus
and return resulting exception if any.
:: Int | |
-> (Request -> IO (Response BodyReader, Maybe Request)) | function which performs a request and returns a response, and possibly another request if there's a redirect. |
-> Request | |
-> IO (Response BodyReader) |
Redirect loop
Parse response headers
Request helper functions
setUriRelative :: MonadThrow m => Request -> URI -> m Request Source
Add a URI
to the request. If it is absolute (includes a host name), add
it as per setUri
; if it is relative, merge it with the existing request.
setUri :: MonadThrow m => Request -> URI -> m Request Source
Validate a URI
, then add it to the request.
browserDecompress :: ByteString -> Bool Source
Decompress a compressed stream unless the content-type is 'application/x-tar'.
alwaysDecompress :: ByteString -> Bool Source
Always decompress a compressed stream.
addProxy :: ByteString -> Int -> Request -> Request Source
Add a proxy to the Request so that the Request when executed will use the provided proxy.
Since 0.1.0
applyBasicAuth :: ByteString -> ByteString -> Request -> Request Source
Add a Basic Auth header (with the specified user name and password) to the given Request. Ignore error handling:
applyBasicAuth "user" "pass" $ fromJust $ parseUrl url
Since 0.1.0
applyBasicProxyAuth :: ByteString -> ByteString -> Request -> Request Source
Add a Proxy-Authorization header (with the specified username and
password) to the given Request
. Ignore error handling:
applyBasicProxyAuth "user" "pass" <$> parseUrl "http://example.org"
Since 0.3.4
urlEncodedBody :: [(ByteString, ByteString)] -> Request -> Request Source
Add url-encoded parameters to the Request
.
This sets a new requestBody
, adds a content-type request header and
changes the method
to POST.
Since 0.1.0
requestBuilder :: Request -> Connection -> IO () Source
useDefaultTimeout :: Maybe Int Source
Magic value to be placed in a Request
to indicate that we should use the
timeout value in the Manager
.
Since 1.9.3
setQueryString :: [(ByteString, Maybe ByteString)] -> Request -> Request Source
Set the query string to the given key/value pairs.
Since 0.3.6
Low-level response body handling
getRedirectedRequest :: Request -> ResponseHeaders -> CookieJar -> Int -> Maybe Request Source
If a request is a redirection (status code 3xx) this function will create
a new request from the old request, the server headers returned with the
redirection, and the redirection code itself. This function returns Nothing
if the code is not a 3xx, there is no location
header included, or if the
redirected response couldn't be parsed with parseUrl
.
If a user of this library wants to know the url chain that results from a specific request, that user has to re-implement the redirect-following logic themselves. An example of that might look like this:
myHttp req man = do (res, redirectRequests) <- (`runStateT` []) $ 'httpRedirect' 9000 (\req' -> do res <- http req'{redirectCount=0} man modify (\rqs -> req' : rqs) return (res, getRedirectedRequest req' (responseHeaders res) (responseCookieJar res) (W.statusCode (responseStatus res)) ) 'lift' req applyCheckStatus (checkStatus req) res return redirectRequests
getResponse :: ConnRelease -> Maybe Int -> Request -> Connection -> IO (Response BodyReader) Source
lbsResponse :: Response BodyReader -> IO (Response ByteString) Source
Convert a Response
that has a Source
body to one with a lazy
ByteString
body.
Manager
data ManagerSettings Source
Settings for a Manager
. Please use the defaultManagerSettings
function and then modify
individual settings. For more information, see http://www.yesodweb.com/book/settings-types.
Since 0.1.0
ManagerSettings | |
|
newManager :: ManagerSettings -> IO Manager Source
Create a Manager
. You may manually call closeManager
to shut it down,
or allow the Manager
to be shut down automatically based on garbage
collection.
Creating a new Manager
is a relatively expensive operation, you are
advised to share a single Manager
between requests instead.
The first argument to this function is often defaultManagerSettings
,
though add-on libraries may provide a recommended replacement.
Since 0.1.0
closeManager :: Manager -> IO () Source
Close all connections in a Manager
.
Note that this doesn't affect currently in-flight connections, meaning you can safely use it without hurting any queries you may have concurrently running.
Since 0.1.0
withManager :: ManagerSettings -> (Manager -> IO a) -> IO a Source
Create, use and close a Manager
.
Since 0.2.1
getConn :: Request -> Manager -> IO (ConnRelease, Connection, ManagedConn) Source
failedConnectionException :: Request -> HttpException Source
Create an exception to be thrown if the connection for the given request fails.
defaultManagerSettings :: ManagerSettings Source
Default value for ManagerSettings
.
Note that this value does not have support for SSL/TLS. If you need to
make any https connections, please use the network-client-tls package, which
provides a tlsManagerSettings
value.
Since 0.1.0
rawConnectionModifySocket :: (Socket -> IO ()) -> IO (Maybe HostAddress -> String -> Int -> IO Connection) Source
A value for the managerRawConnection
setting, but also allows you to
modify the underlying Socket
to set additional settings. For a motivating
use case, see: https://github.com/snoyberg/http-client/issues/71.
Since 0.3.8
All types
type BodyReader = IO ByteString Source
An IO
action that represents an incoming response body coming from the
server. Data provided by this action has already been gunzipped and
de-chunked, and respects any content-length headers present.
The action gets a single chunk of data from the response body, or an empty bytestring if no more data is available.
Since 0.4.0
data Connection Source
Connection | |
|
data StatusHeaders Source
StatusHeaders Status HttpVersion RequestHeaders |
data HttpException Source
Define a HTTP proxy, consisting of a hostname and port number.
Proxy | |
|
data RequestBody Source
When using one of the RequestBodyStream
/ RequestBodyStreamChunked
constructors, you must ensure that the GivesPopper
can be called multiple
times. Usually this is not a problem.
The RequestBodyStreamChunked
will send a chunked request body. Note that
not all servers support this. Only use RequestBodyStreamChunked
if you
know the server you're sending to supports chunked request bodies.
Since 0.1.0
type Popper = IO ByteString Source
A function which generates successive chunks of a request body, provider a single empty bytestring when no more data is available.
Since 0.1.0
type NeedsPopper a = Popper -> IO a Source
A function which must be provided with a Popper
.
Since 0.1.0
type GivesPopper a = NeedsPopper a -> IO a Source
A function which will provide a Popper
to a NeedsPopper
. This
seemingly convoluted structure allows for creation of request bodies which
allocate scarce resources in an exception safe manner.
Since 0.1.0
All information on how to connect to a host and what should be sent in the HTTP request.
If you simply wish to download from a URL, see parseUrl
.
The constructor for this data type is not exposed. Instead, you should use
either the def
method to retrieve a default instance, or parseUrl
to
construct from a URL, and then use the records below to make modifications.
This approach allows http-client to add configuration options without
breaking backwards compatibility.
For example, to construct a POST request, you could do something like:
initReq <- parseUrl "http://www.example.com/path" let req = initReq { method = "POST" }
For more information, please see http://www.yesodweb.com/book/settings-types.
Since 0.1.0
Request | |
|
type ConnRelease = ConnReuse -> IO () Source
data ManagedConn Source
A simple representation of the HTTP response.
Since 0.1.0
Response | |
|
newtype ResponseClose Source
ResponseClose | |
|
Keeps track of open connections for keep-alive.
If possible, you should share a single Manager
between multiple threads and requests.
Since 0.1.0
Manager | |
|
data ManagerSettings Source
Settings for a Manager
. Please use the defaultManagerSettings
function and then modify
individual settings. For more information, see http://www.yesodweb.com/book/settings-types.
Since 0.1.0
ManagerSettings | |
|
data NonEmptyList a Source
Typeable (* -> *) NonEmptyList |
Hostname or resolved host address.
HostName Text | |
HostAddress HostAddress |
ConnKey
consists of a hostname, a port and a Bool
specifying whether to use SSL.
Various utilities
hGetSome :: Handle -> Int -> IO ByteString
Like hGet
, except that a shorter ByteString
may be returned
if there are not enough bytes immediately available to satisfy the
whole request. hGetSome
only blocks if there is no data
available, and EOF has not yet been reached.
:: ByteString | request method |
-> Int | status code |
-> Bool |
fromStrict :: ByteString -> ByteString
O(1) Convert a strict ByteString
into a lazy ByteString
.