The API below is rather low-level. The Network.HTTP.Simple module provides
a higher-level API with built-in support for things like JSON request and
response bodies. For most users, this will be an easier place to start. You
can read the tutorial at:
This module contains everything you need to initiate HTTP connections. If
you want a simple interface based on URLs, you can use simpleHttp. If you
want raw power, http is the underlying workhorse of this package. Some
examples:
-- Just download an HTML document and print it.
import Network.HTTP.Conduit
import qualified Data.ByteString.Lazy as L
main = simpleHttp "http://www.haskell.org/" >>= L.putStr
This example uses interleaved IO to write the response body to a file in
constant memory space.
import Data.Conduit.Binary (sinkFile) -- Exported from the package conduit-extra
import Network.HTTP.Conduit
import Conduit (runConduit, (.|))
import Control.Monad.Trans.Resource (runResourceT)
main :: IO ()
main = do
request <- parseRequest "http://google.com/"
manager <- newManager tlsManagerSettings
runResourceT $ do
response <- http request manager
runConduit $ responseBody response .| sinkFile "google.html"
The following headers are automatically set by this module, and should not
be added to requestHeaders:
Cookie
Content-Length
Transfer-Encoding
Note: In previous versions, the Host header would be set by this module in
all cases. Starting from 1.6.1, if a Host header is present in
requestHeaders, it will be used in place of the header this module would
have generated. This can be useful for calling a server which utilizes
virtual hosting.
Use cookieJar If you want to supply cookies with your request:
{-# LANGUAGE OverloadedStrings #-}
import Network.HTTP.Conduit
import Network
import Data.Time.Clock
import Data.Time.Calendar
import qualified Control.Exception as E
import Network.HTTP.Types.Status (statusCode)
past :: UTCTime
past = UTCTime (ModifiedJulianDay 56200) (secondsToDiffTime 0)
future :: UTCTime
future = UTCTime (ModifiedJulianDay 562000) (secondsToDiffTime 0)
cookie :: Cookie
cookie = Cookie { cookie_name = "password_hash"
, cookie_value = "abf472c35f8297fbcabf2911230001234fd2"
, cookie_expiry_time = future
, cookie_domain = "example.com"
, cookie_path = "/"
, cookie_creation_time = past
, cookie_last_access_time = past
, cookie_persistent = False
, cookie_host_only = False
, cookie_secure_only = False
, cookie_http_only = False
}
main = do
request' <- parseRequest "http://example.com/secret-page"
manager <- newManager tlsManagerSettings
let request = request' { cookieJar = Just $ createCookieJar [cookie] }
fmap Just (httpLbs request manager) `E.catch`
(\ex -> case ex of
HttpExceptionRequest _ (StatusCodeException res _) ->
if statusCode (responseStatus res) == 403
then (putStrLn "login failed" >> return Nothing)
else return Nothing
_ -> E.throw ex)
Cookies are implemented according to RFC 6265.
Note that by default, the functions in this package will throw exceptions
for non-2xx status codes. If you would like to avoid this, you should use
checkStatus, e.g.:
import Data.Conduit.Binary (sinkFile)
import Network.HTTP.Conduit
import qualified Data.Conduit as C
import Network
main :: IO ()
main = do
request' <- parseRequest "http://www.yesodweb.com/does-not-exist"
let request = request' { checkStatus = \_ _ _ -> Nothing }
manager <- newManager tlsManagerSettings
res <- httpLbs request manager
print res
By default, when connecting to websites using HTTPS, functions in this
package will throw an exception if the TLS certificate doesn't validate. To
continue the HTTPS transaction even if the TLS cerficate validation fails,
you should use mkManagerSetttings as follows:
import Network.Connection (TLSSettings (..))
import Network.HTTP.Conduit
main :: IO ()
main = do
request <- parseRequest "https://github.com/"
let settings = mkManagerSettings (TLSSettingsSimple True False False) Nothing
manager <- newManager settings
res <- httpLbs request manager
print res
For more information, please be sure to read the documentation in the
Network.HTTP.Client module.
Download the specified URL, following any redirects, and
return the response body.
This function will throwIO an HttpException for any
response with a non-2xx status code (besides 3xx redirects up
to a limit of 10 redirects). It uses parseUrlThrow to parse the
input. This function essentially wraps httpLbs.
Note: Even though this function returns a lazy bytestring, it
does not utilize lazy I/O, and therefore the entire response
body will live in memory. If you want constant memory usage,
you'll need to use the conduit package and http directly.
Note: This function creates a new Manager. It should be avoided
in production code.
Download the specified Request, returning the results as a Response.
This is a simplified version of http for the common case where you simply
want the response data as a simple datatype. If you want more power, such as
interleaved actions on the response body during download, you'll need to use
http directly. This function is defined as:
Even though the Response contains a lazy bytestring, this
function does not utilize lazy I/O, and therefore the entire
response body will live in memory. If you want constant memory
usage, you'll need to use conduit packages's
C.Source returned by http.
This function will throwIO an HttpException for any
response with a non-2xx status code (besides 3xx redirects up
to a limit of 10 redirects). This behavior can be modified by
changing the checkStatus field of your request.
Note: Unlike previous versions, this function will perform redirects, as
specified by the redirectCount setting.
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.
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 parseRequest.
The constructor for this data type is not exposed. Instead, you should use
either the defaultRequest value, or parseRequest 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:
The Content-Length and Transfer-Encoding headers are set automatically
by this module, and shall not be added to requestHeaders.
If not provided by the user, Host will automatically be set based on
the host and port fields.
Moreover, the Accept-Encoding header is set implicitly to gzip for
convenience by default. This behaviour can be overridden if needed, by
setting the header explicitly to a different value. In order to omit the
Accept-Header altogether, set it to the empty string "". If you need an
empty Accept-Header (i.e. requesting the identity encoding), set it to a
non-empty white-space string, e.g. " ". See RFC 2616 section 14.3 for
details about the semantics of the Accept-Header field. If you request a
content-encoding not supported by this module, you will have to decode
it yourself (see also the decompress field).
Note: Multiple header fields with the same field-name will result in
multiple header fields being sent and therefore it's the responsibility
of the client code to ensure that the rules from RFC 2616 section 4.2
are honoured.
Predicate to specify whether gzipped data should be
decompressed on the fly (see alwaysDecompress and
browserDecompress). Argument is the mime type.
Default: browserDecompress.
Check the response immediately after receiving the status and headers.
This can be useful for throwing exceptions on non-success status codes.
In previous versions of http-client, this went under the name
checkStatus, but was renamed to avoid confusion about the new default
behavior (doing nothing).
Number of microseconds to wait for a response (see ResponseTimeout
for more information). Default: use managerResponseTimeout (which by
default is 30 seconds).
A user-defined cookie jar.
If Nothing, no cookie handling will take place, "Cookie" headers
in requestHeaders will be sent raw, and responseCookieJar will be
empty.
Cookies set on the client after interacting with the server. If
cookies have been disabled by setting cookieJar to Nothing, then
this will always be empty.
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.
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.
Add a Basic Auth header (with the specified user name and password) to the
given Request. Ignore error handling:
applyBasicAuth "user" "pass" $ parseRequest_ url
NOTE: The function applyDigestAuth is provided by the http-client-tls
package instead of this package due to extra dependencies. Please use that
package if you need to use digest authentication.
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 parseRequest.
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 req' (responseHeaders res) (responseCookieJar res) (W.statusCode (responseStatus res))
)
'lift'
req
applyCheckStatus (checkStatus req) res
return redirectRequests
The server responded with too many redirects for a
request.
Contains the list of encountered responses containing
redirects in reverse chronological order; including last
redirect, which triggered the exception and was not
followed.
An exception was raised by an underlying library when
performing the request. Most often, this is caused by a
failing socket action or a TLS exception.
No response data was received from the server at all.
This exception may deserve special handling within the
library, since it may indicate that a pipelining has been
used, and a connection thought to be open was in fact
closed.
Exception thrown when using a Manager which does not
have support for secure connections. Typically, you will
want to use tlsManagerSettings from http-client-tls
to overcome this.