@@ -1,9 +1,19 @@
1+{-# LANGUAGE BangPatterns #-}
1{-# LANGUAGE DataKinds #-}
3{-# LANGUAGE DataKinds #-}
4+{-# LANGUAGE DeriveDataTypeable #-}
5+{-# LANGUAGE DeriveGeneric #-}
6+{-# LANGUAGE DeriveLift #-}
7+{-# LANGUAGE FlexibleInstances #-}
8+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
2{-# LANGUAGE LambdaCase #-}
9{-# LANGUAGE LambdaCase #-}
10+{-# LANGUAGE MultiParamTypeClasses #-}
3{-# LANGUAGE OverloadedStrings #-}
11{-# LANGUAGE OverloadedStrings #-}
4{-# LANGUAGE QuasiQuotes #-}
12{-# LANGUAGE QuasiQuotes #-}
13+{-# LANGUAGE RankNTypes #-}
5{-# LANGUAGE RecordWildCards #-}
14{-# LANGUAGE RecordWildCards #-}
6{-# LANGUAGE RoleAnnotations #-}
15{-# LANGUAGE RoleAnnotations #-}
16+{-# LANGUAGE ScopedTypeVariables #-}
7{-# LANGUAGE TemplateHaskellQuotes #-}
17{-# LANGUAGE TemplateHaskellQuotes #-}
8{-# LANGUAGE TypeFamilies #-}
18{-# LANGUAGE TypeFamilies #-}
9{-# LANGUAGE UndecidableInstances #-}
19{-# LANGUAGE UndecidableInstances #-}
@@ -19,40 +29,61 @@
20-- The documentation below is structured in such a way that the most
30-- The documentation below is structured in such a way that the most
21-- important information is presented first: you learn how to do HTTP
31-- important information is presented first: you learn how to do HTTP
22−-- requests, how to embed them in the monad you have, and then it gives you
32+-- requests, how to embed them in any monad you have, and then it gives you
23-- details about less-common things you may want to know about. The
33-- details about less-common things you may want to know about. The
24-- documentation is written with sufficient coverage of details and
34-- documentation is written with sufficient coverage of details and
25-- examples, and it's designed to be a complete tutorial on its own.
35-- examples, and it's designed to be a complete tutorial on its own.
37+-- /(A modest intro goes here, click on 'req' to start making requests.)/
27-- === About the library
39-- === About the library
29−-- Req is an HTTP client library that attempts to be easy-to-use, type-safe,
41+-- Req is an easy-to-use, type-safe, expandable, high-level HTTP client
30−-- and expandable.
42+-- library that just works without any fooling around.
32−-- “Easy-to-use” means that the library is designed to be beginner-friendly
44+-- What does the phrase “easy-to-use” mean? It means that the library is
33−-- so it's simple to add to your monad stack, intuitive to work with,
45+-- designed to be beginner-friendly so it's simple to add to your monad
34−-- well-documented, and does not get in your way. Doing HTTP requests is a
46+-- stack, intuitive to work with, well-documented, and does not get in your
35−-- common task and a Haskell library for this should be approachable and
47+-- way. Doing HTTP requests is a common task and Haskell library for this
48+-- should be very approachable and clear to beginners, thus certain
36−-- clear to beginners, thus certain compromises were made. For example, one
49+-- compromises were made. For example, one cannot currently modify
37−-- cannot currently modify 'L.ManagerSettings' of the default manager
50+-- 'L.ManagerSettings' of the default manager because the library always
38−-- because the library always uses the same implicit global manager for
51+-- uses the same implicit global manager for simplicity and maximal
39−-- simplicity and maximal connection sharing. There is a way to use your own
52+-- connection sharing. There is a way to use your own manager with different
40−-- manager with different settings, but it requires more typing.
53+-- settings, but it requires a bit more typing.
42−-- “Type-safe” means that the library tries to eliminate certain classes of
55+-- “Type-safe” means that the library is protective and eliminates certain
43−-- errors. For example, we have correct-by-construction URLs; it is
56+-- classes of errors. For example, we have correct-by-construction 'Url's,
44−-- guaranteed that the user does not send the request body when using
57+-- it's guaranteed that the user does not send the request body when using
45−-- methods like GET or OPTIONS, and the amount of implicit assumptions is
58+-- methods like 'GET' or 'OPTIONS', and the amount of implicit assumptions
46−-- minimized by making the user specify their intentions in an explicit
59+-- is minimized by making the user specify his\/her intentions in an
47−-- form. For example, it's not possible to avoid specifying the body or the
60+-- explicit form (for example, it's not possible to avoid specifying the
48−-- method of a request. Authentication methods that assume HTTPS force the
61+-- body or method of request). Authentication methods that assume HTTPS
49−-- user to use HTTPS at the type level.
62+-- force the user to use HTTPS at the type level. The library also carefully
63+-- hides underlying types from the lower-level @http-client@ package because
64+-- those types are not safe enough (for example 'L.Request' is an instance
65+-- of 'Data.String.IsString' and, if it's malformed, it will blow up at
51−-- “Expandable” refers to the ability to create new components without
68+-- “Expandable” refers to the ability of the library to be expanded without
52−-- having to resort to hacking. For example, it's possible to define your
69+-- having to resort to ugly hacking. For example, it's possible to define
53−-- own HTTP methods, create new ways to construct the body of a request,
70+-- your own HTTP methods, create new ways to construct the body of a
54−-- create new authorization options, perform a request in a different way,
71+-- request, create new authorization options, perform a request in a
55−-- and create your own methods to parse a response.
72+-- different way, and create your own methods to parse and represent a
73+-- response. As the user extends the library to satisfy his\/her special
74+-- needs, the new solutions will work just like the built-ins. However, all
75+-- of the common cases are also covered by the library out-of-the-box.
77+-- “High-level” means that there are less details to worry about. The
78+-- library is a result of my experiences as a Haskell consultant. Working
79+-- for several clients, who had very different projects, showed me that the
80+-- library should adapt easily to any particular style of writing Haskell
81+-- applications. For example, some people prefer throwing exceptions, while
82+-- others are concerned with purity. Just define 'handleHttpException'
83+-- accordingly when making your monad instance of 'MonadHttp' and it will
84+-- play together seamlessly. Finally, the library cuts down boilerplate
85+-- considerably, and helps you write concise, easy to read, and maintainable
57-- === Using with other libraries
88-- === Using with other libraries
@@ -81,7 +112,6 @@ module Network.HTTP.Req
81 -- $making-a-request
112 -- $making-a-request
86 withReqManager,
116 withReqManager,
@@ -119,7 +149,6 @@ module Network.HTTP.Req
119 useHttpsURI,
149 useHttpsURI,
124 -- ** Body
153 -- ** Body
@@ -144,13 +173,11 @@ module Network.HTTP.Req
144 -- $query-parameters
173 -- $query-parameters
146 queryFlag,
175 queryFlag,
148 QueryParam (..),
176 QueryParam (..),
150 -- *** Headers
178 -- *** Headers
152 attachHeader,
180 attachHeader,
155 -- *** Cookies
182 -- *** Cookies
156 -- $cookies
183 -- $cookies
@@ -197,78 +224,56 @@ module Network.HTTP.Req
198 -- * Other
225 -- * Other
199 HttpException (..),
226 HttpException (..),
200− isStatusCodeException,
201 CanHaveBody (..),
227 CanHaveBody (..),
202 Scheme (..),
228 Scheme (..),
206−import Blaze.ByteString.Builder qualified as BB
232+import qualified Blaze.ByteString.Builder as BB
207import Control.Applicative
233import Control.Applicative
208import Control.Arrow (first, second)
234import Control.Arrow (first, second)
209−import Control.Exception hiding (Handler (..), TypeError)
235+import Control.Exception hiding (TypeError)
210−import Control.Monad (guard, void, (>=>))
211import Control.Monad.Base
236import Control.Monad.Base
212−import Control.Monad.Catch (Handler (..), MonadCatch, MonadMask, MonadThrow)
213import Control.Monad.IO.Class
237import Control.Monad.IO.Class
214−import Control.Monad.IO.Unlift
238+import Control.Monad.Reader
215−import Control.Monad.Reader (ReaderT (ReaderT), ask, lift, runReaderT)
216−import Control.Monad.Trans.Accum (AccumT)
217−import Control.Monad.Trans.Cont (ContT)
218import Control.Monad.Trans.Control
239import Control.Monad.Trans.Control
219−import Control.Monad.Trans.Except (ExceptT)
220−import Control.Monad.Trans.Identity (IdentityT)
221−import Control.Monad.Trans.Maybe (MaybeT)
222−import Control.Monad.Trans.RWS.CPS qualified as RWS.CPS
223−import Control.Monad.Trans.RWS.Lazy qualified as RWS.Lazy
224−import Control.Monad.Trans.RWS.Strict qualified as RWS.Strict
225−import Control.Monad.Trans.Select (SelectT)
226−import Control.Monad.Trans.State.Lazy qualified as State.Lazy
227−import Control.Monad.Trans.State.Strict qualified as State.Strict
228−import Control.Monad.Trans.Writer.CPS qualified as Writer.CPS
229−import Control.Monad.Trans.Writer.Lazy qualified as Writer.Lazy
230−import Control.Monad.Trans.Writer.Strict qualified as Writer.Strict
231import Control.Retry
240import Control.Retry
232import Data.Aeson (FromJSON (..), ToJSON (..))
241import Data.Aeson (FromJSON (..), ToJSON (..))
233−import Data.Aeson qualified as A
242+import qualified Data.Aeson as A
234import Data.ByteString (ByteString)
243import Data.ByteString (ByteString)
235−import Data.ByteString qualified as B
244+import qualified Data.ByteString as B
236−import Data.ByteString.Lazy qualified as BL
245+import qualified Data.ByteString.Lazy as BL
237−import Data.CaseInsensitive qualified as CI
246+import qualified Data.CaseInsensitive as CI
238import Data.Data (Data)
247import Data.Data (Data)
239−import Data.Default.Class (def)
240import Data.Function (on)
248import Data.Function (on)
241import Data.IORef
249import Data.IORef
242import Data.Kind (Constraint, Type)
250import Data.Kind (Constraint, Type)
243import Data.List (foldl', nubBy)
251import Data.List (foldl', nubBy)
244import Data.List.NonEmpty (NonEmpty (..))
252import Data.List.NonEmpty (NonEmpty (..))
245−import Data.List.NonEmpty qualified as NE
253+import qualified Data.List.NonEmpty as NE
246import Data.Maybe (fromMaybe)
254import Data.Maybe (fromMaybe)
247import Data.Proxy
255import Data.Proxy
248−import Data.Semigroup (Endo (..))
256+import Data.Semigroup hiding (Option, option)
249−import Data.Set qualified as S
250import Data.Text (Text)
257import Data.Text (Text)
251−import Data.Text qualified as T
258+import qualified Data.Text as T
252−import Data.Text.Encoding qualified as T
259+import qualified Data.Text.Encoding as T
253import Data.Typeable (Typeable, cast)
260import Data.Typeable (Typeable, cast)
254import GHC.Generics
261import GHC.Generics
255import GHC.TypeLits
262import GHC.TypeLits
256−import Language.Haskell.TH qualified as TH
263+import qualified Language.Haskell.TH as TH
257−import Language.Haskell.TH.Quote qualified as TH
264+import qualified Language.Haskell.TH.Quote as TH
258−import Language.Haskell.TH.Syntax qualified as TH
265+import qualified Language.Haskell.TH.Syntax as TH
259−import Network.Connection qualified as NC
266+import qualified Network.Connection as NC
260−import Network.HTTP.Client qualified as L
267+import qualified Network.HTTP.Client as L
261−import Network.HTTP.Client.Internal qualified as LI
268+import qualified Network.HTTP.Client.Internal as LI
262−import Network.HTTP.Client.MultipartFormData qualified as LM
269+import qualified Network.HTTP.Client.MultipartFormData as LM
263−import Network.HTTP.Client.TLS qualified as L
270+import qualified Network.HTTP.Client.TLS as L
264−import Network.HTTP.Types qualified as Y
271+import qualified Network.HTTP.Types as Y
265import System.IO.Unsafe (unsafePerformIO)
272import System.IO.Unsafe (unsafePerformIO)
266import Text.URI (URI)
273import Text.URI (URI)
267−import Text.URI qualified as URI
274+import qualified Text.URI as URI
268−import Text.URI.QQ qualified as QQ
275+import qualified Text.URI.QQ as QQ
269−import Web.Authenticate.OAuth qualified as OAuth
276+import qualified Web.Authenticate.OAuth as OAuth
270−import Web.FormUrlEncoded (FromForm (..), ToForm (..))
271−import Web.FormUrlEncoded qualified as Form
272import Web.HttpApiData (ToHttpApiData (..))
277import Web.HttpApiData (ToHttpApiData (..))
274----------------------------------------------------------------------------
279----------------------------------------------------------------------------
@@ -293,7 +298,7 @@ import Web.HttpApiData (ToHttpApiData (..))
294-- @body@ is a body option such as 'NoReqBody' or 'ReqBodyJson'. The
299-- @body@ is a body option such as 'NoReqBody' or 'ReqBodyJson'. The
295-- tutorial has a section about HTTP bodies, but usage is very
300-- tutorial has a section about HTTP bodies, but usage is very
296−-- straightforward and should be clear from the examples.
301+-- straightforward and should be clear from the examples below.
298-- @response@ is a type hint how to make and interpret response of an HTTP
303-- @response@ is a type hint how to make and interpret response of an HTTP
299-- request. Out-of-the-box it can be the following:
304-- request. Out-of-the-box it can be the following:
@@ -421,7 +426,12 @@ req ::
421 -- | Response
426 -- | Response
422 m response
427 m response
423req method url body responseProxy options =
428req method url body responseProxy options =
424− reqCb method url body responseProxy options pure
429+ reqBr method url body (options <> extraOptions) getHttpResponse
432+ case acceptHeader responseProxy of
434+ Just accept -> header "Accept" accept
426-- | A version of 'req' that does not use one of the predefined instances of
436-- | A version of 'req' that does not use one of the predefined instances of
427-- 'HttpResponse' but instead allows the user to consume @'L.Response'
437-- 'HttpResponse' but instead allows the user to consume @'L.Response'
@@ -446,58 +456,7 @@ reqBr ::
446 (L.Response L.BodyReader -> IO a) ->
456 (L.Response L.BodyReader -> IO a) ->
447 -- | Result
457 -- | Result
449−reqBr method url body options consume =
459+reqBr method url body options consume = req' method url body options $ \request manager -> do
450− req' method url body options (reqHandler consume)
452−-- | A version of 'req' that takes a callback to modify the 'L.Request', but
453−-- otherwise performs the request identically.
460− HttpResponse response,
461− HttpBodyAllowed (AllowsBody method) (ProvidesBody body)
465− -- | 'Url'—location of resource
467− -- | Body of the request
469− -- | A hint how to interpret response
471− -- | Collection of optional parameters
473− -- | Callback to modify the request
474− (L.Request -> m L.Request) ->
477−reqCb method url body responseProxy options adjustRequest =
478− req' method url body (options <> extraOptions) $ \request manager -> do
479− request' <- adjustRequest request
480− reqHandler getHttpResponse request' manager
483− case acceptHeader responseProxy of
485− Just accept -> header "Accept" accept
487−-- | The default handler function that the higher-level request functions
488−-- pass to 'req''. Internal function.
493− -- | How to get final result from a 'L.Response'
494− (L.Response L.BodyReader -> IO b) ->
495− -- | 'L.Request' to perform
497− -- | 'L.Manager' to use
500−reqHandler consume request manager = do
501 HttpConfig {..} <- getHttpConfig
460 HttpConfig {..} <- getHttpConfig
502 let wrapVanilla = handle (throwIO . VanillaHttpException)
461 let wrapVanilla = handle (throwIO . VanillaHttpException)
503 wrapExc = handle (throwIO . LI.toHttpException request)
462 wrapExc = handle (throwIO . LI.toHttpException request)
@@ -513,23 +472,12 @@ reqHandler consume request manager = do
513 r' <- L.responseOpen request manager
472 r' <- L.responseOpen request manager
514 writeIORef rref (Just r')
473 writeIORef rref (Just r')
515 return r'
474 return r'
516− exceptionRetryPolicies =
518− ++ [ \retryStatus -> Handler $ \e ->
519− return $ httpConfigRetryJudgeException retryStatus e
523 httpConfigRetryPolicy
477 httpConfigRetryPolicy
524− (\retryStatus r -> return $ httpConfigRetryJudge retryStatus r)
478+ (\st r -> return $ httpConfigRetryJudge st r)
527− httpConfigRetryPolicy
528− exceptionRetryPolicies
529− (const openResponse)
479+ (const openResponse)
532− (preview, r') <- grabPreview httpConfigBodyPreviewLength r
480+ (preview, r') <- grabPreview bodyPreviewLength r
533 mapM_ LI.throwHttp (httpConfigCheckResponse request r' preview)
481 mapM_ LI.throwHttp (httpConfigCheckResponse request r' preview)
534 consume r'
482 consume r'
@@ -578,22 +526,22 @@ req' method url body options m = do
578 nubHeaders
526 nubHeaders
579 <> getRequestMod options
527 <> getRequestMod options
580 <> getRequestMod config
528 <> getRequestMod config
581− <> getRequestMod (Tagged body :: Tagged "body" body)
529+ <> getRequestMod (Womb body :: Womb "body" body)
582 <> getRequestMod url
530 <> getRequestMod url
583− <> getRequestMod (Tagged method :: Tagged "method" method)
531+ <> getRequestMod (Womb method :: Womb "method" method)
584 request <- finalizeRequest options request'
532 request <- finalizeRequest options request'
585 withReqManager (m request)
533 withReqManager (m request)
587-- | Perform an action using the global implicit 'L.Manager' that the rest
535-- | Perform an action using the global implicit 'L.Manager' that the rest
588−-- of the library uses. This allows us to reuse connections that the
536+-- of the library uses. This allows to reuse connections that the
589-- 'L.Manager' controls.
537-- 'L.Manager' controls.
590−withReqManager :: (MonadIO m) => (L.Manager -> m a) -> m a
538+withReqManager :: MonadIO m => (L.Manager -> m a) -> m a
591−withReqManager m = m globalManager
539+withReqManager m = liftIO (readIORef globalManager) >>= m
593−-- | The global 'L.Manager' that 'req' uses. Here we just go with the
541+-- | Global 'L.Manager' that 'req' uses. Here we just go with the default
594−-- default settings, so users don't need to deal with this manager stuff at
542+-- settings, so users don't need to deal with this manager stuff at all, but
595−-- all, but when we create a request, instance 'HttpConfig' can affect the
543+-- when we create a request, instance 'HttpConfig' can affect the default
596−-- default settings via 'getHttpConfig'.
544+-- settings via 'getHttpConfig'.
598-- A note about safety, in case 'unsafePerformIO' looks suspicious to you.
546-- A note about safety, in case 'unsafePerformIO' looks suspicious to you.
599-- The value of 'globalManager' is named and lives on top level. This means
547-- The value of 'globalManager' is named and lives on top level. This means
@@ -601,16 +549,16 @@ withReqManager m = m globalManager
601-- manager. From that moment on the 'IORef' will be just reused—exactly the
549-- manager. From that moment on the 'IORef' will be just reused—exactly the
602-- behavior we want here in order to maximize connection sharing. GHC could
550-- behavior we want here in order to maximize connection sharing. GHC could
603-- spoil the plan by inlining the definition, hence the @NOINLINE@ pragma.
551-- spoil the plan by inlining the definition, hence the @NOINLINE@ pragma.
604−globalManager :: L.Manager
552+globalManager :: IORef L.Manager
605globalManager = unsafePerformIO $ do
553globalManager = unsafePerformIO $ do
606 context <- NC.initConnectionContext
554 context <- NC.initConnectionContext
607 let settings =
555 let settings =
608 L.mkManagerSettingsContext
556 L.mkManagerSettingsContext
609 (Just context)
557 (Just context)
610− def
558+ (NC.TLSSettingsSimple False False False)
612 manager <- L.newManager settings
560 manager <- L.newManager settings
613− return manager
561+ newIORef manager
614{-# NOINLINE globalManager #-}
562{-# NOINLINE globalManager #-}
616----------------------------------------------------------------------------
564----------------------------------------------------------------------------
@@ -624,13 +572,13 @@ globalManager = unsafePerformIO $ do
624-- When writing a library, keep your API polymorphic in terms of
572-- When writing a library, keep your API polymorphic in terms of
625-- 'MonadHttp', only define instance of 'MonadHttp' in final application.
573-- 'MonadHttp', only define instance of 'MonadHttp' in final application.
626-- Another option is to use a @newtype@-wrapped monad stack and define
574-- Another option is to use a @newtype@-wrapped monad stack and define
627−-- 'MonadHttp' for it. As of the version /0.4.0/, the 'Req' monad that
575+-- 'MonadHttp' for it. As of version /0.4.0/, the 'Req' monad that follows
628−-- follows this strategy is provided out-of-the-box (see below).
576+-- this strategy is provided out-of-the-box (see below).
630-- | A type class for monads that support performing HTTP requests.
578-- | A type class for monads that support performing HTTP requests.
631-- Typically, you only need to define the 'handleHttpException' method
579-- Typically, you only need to define the 'handleHttpException' method
632-- unless you want to tweak 'HttpConfig'.
580-- unless you want to tweak 'HttpConfig'.
633−class (MonadIO m) => MonadHttp m where
581+class MonadIO m => MonadHttp m where
634 -- | This method describes how to deal with 'HttpException' that was
582 -- | This method describes how to deal with 'HttpException' that was
635 -- caught by the library. One option is to re-throw it if you are OK with
583 -- caught by the library. One option is to re-throw it if you are OK with
636 -- exceptions, but if you prefer working with something like
584 -- exceptions, but if you prefer working with something like
@@ -638,16 +586,17 @@ class (MonadIO m) => MonadHttp m where
638 -- 'Control.Monad.Except.throwError'.
586 -- 'Control.Monad.Except.throwError'.
639 handleHttpException :: HttpException -> m a
587 handleHttpException :: HttpException -> m a
641− -- | Return the 'HttpConfig' to be used when performing HTTP requests.
589+ -- | Return 'HttpConfig' to be used when performing HTTP requests. Default
642− -- Default implementation returns its 'def' value, which is described in
590+ -- implementation returns its 'def' value, which is described in the
643− -- the documentation for the type. Common usage pattern with manually
591+ -- documentation for the type. Common usage pattern with manually defined
644− -- defined 'getHttpConfig' is to return some hard-coded value, or a value
592+ -- 'getHttpConfig' is to return some hard-coded value, or a value
645 -- extracted from 'Control.Monad.Reader.MonadReader' if a more flexible
593 -- extracted from 'Control.Monad.Reader.MonadReader' if a more flexible
646 -- approach to configuration is desirable.
594 -- approach to configuration is desirable.
647 getHttpConfig :: m HttpConfig
595 getHttpConfig :: m HttpConfig
648 getHttpConfig = return defaultHttpConfig
596 getHttpConfig = return defaultHttpConfig
650−-- | 'HttpConfig' contains settings to be used when making HTTP requests.
598+-- | 'HttpConfig' contains general and default settings to be used when
599+-- making HTTP requests.
651data HttpConfig = HttpConfig
600data HttpConfig = HttpConfig
652 { -- | Proxy to use. By default values of @HTTP_PROXY@ and @HTTPS_PROXY@
601 { -- | Proxy to use. By default values of @HTTP_PROXY@ and @HTTPS_PROXY@
653 -- environment variables are respected, this setting overwrites them.
602 -- environment variables are respected, this setting overwrites them.
@@ -691,8 +640,8 @@ data HttpConfig = HttpConfig
691 -- | The retry policy to use for request retrying. By default 'def' is
640 -- | The retry policy to use for request retrying. By default 'def' is
692 -- used (see 'RetryPolicyM').
641 -- used (see 'RetryPolicyM').
694− -- __Note__: signature of this function was changed to disallow 'IO' in
643+ -- __Note__: signature of this function was changed in the version
695− -- version /1.0.0/ and then changed back to its current form in /3.1.0/.
644+ -- /1.0.0/.
697 -- @since 0.3.0
646 -- @since 0.3.0
698 httpConfigRetryPolicy :: RetryPolicyM IO,
647 httpConfigRetryPolicy :: RetryPolicyM IO,
@@ -703,21 +652,11 @@ data HttpConfig = HttpConfig
703 -- /1.0.0/.
652 -- /1.0.0/.
705 -- @since 0.3.0
654 -- @since 0.3.0
706− httpConfigRetryJudge :: forall b. RetryStatus -> L.Response b -> Bool,
655+ httpConfigRetryJudge :: forall b. RetryStatus -> L.Response b -> Bool
707− -- | Similar to 'httpConfigRetryJudge', but is used to decide when to
708− -- retry requests that resulted in an exception. By default it retries
709− -- on response timeout and connection timeout (changed in version
713− httpConfigRetryJudgeException :: RetryStatus -> SomeException -> Bool,
714− -- | Max length of preview fragment of response body.
717− httpConfigBodyPreviewLength :: forall a. (Num a) => a
720−-- | The default value of 'HttpConfig'.
659+-- | Default value of 'HttpConfig'.
722-- @since 2.0.0
661-- @since 2.0.0
723defaultHttpConfig :: HttpConfig
662defaultHttpConfig :: HttpConfig
@@ -739,16 +678,7 @@ defaultHttpConfig =
739 524, -- A timeout occurred
678 524, -- A timeout occurred
740 598, -- (Informal convention) Network read timeout error
679 598, -- (Informal convention) Network read timeout error
741 599 -- (Informal convention) Network connect timeout error
680 599 -- (Informal convention) Network connect timeout error
743− httpConfigRetryJudgeException = \_ e ->
744− case fromException e of
745− Just (L.HttpExceptionRequest _ c) ->
747− L.ResponseTimeout -> True
748− L.ConnectionTimeout -> True
751− httpConfigBodyPreviewLength = 1024
754 statusCode = Y.statusCode . L.responseStatus
684 statusCode = Y.statusCode . L.responseStatus
@@ -761,7 +691,7 @@ instance RequestComponent HttpConfig where
761 LI.requestManagerOverride = httpConfigAltManager
691 LI.requestManagerOverride = httpConfigAltManager
764−-- | A monad that allows us to run 'req' in any 'IO'-enabled monad without
694+-- | A monad that allows to run 'req' in any 'IO'-enabled monad without
765-- having to define new instances.
695-- having to define new instances.
767-- @since 0.4.0
697-- @since 0.4.0
@@ -770,19 +700,9 @@ newtype Req a = Req (ReaderT HttpConfig IO a)
770 ( Functor,
700 ( Functor,
771 Applicative,
701 Applicative,
773− MonadIO,
703+ MonadIO
778−deriving instance MonadThrow Req
781−deriving instance MonadCatch Req
784−deriving instance MonadMask Req
786instance MonadBase IO Req where
706instance MonadBase IO Req where
787 liftBase = liftIO
707 liftBase = liftIO
@@ -797,87 +717,12 @@ instance MonadHttp Req where
797 handleHttpException = Req . lift . throwIO
717 handleHttpException = Req . lift . throwIO
798 getHttpConfig = Req ask
718 getHttpConfig = Req ask
801−instance (MonadHttp m, Monoid w) => MonadHttp (AccumT w m) where
802− handleHttpException = lift . handleHttpException
803− getHttpConfig = lift getHttpConfig
806−instance (MonadHttp m) => MonadHttp (ContT r m) where
807− handleHttpException = lift . handleHttpException
808− getHttpConfig = lift getHttpConfig
811−instance (MonadHttp m) => MonadHttp (ExceptT e m) where
812− handleHttpException = lift . handleHttpException
813− getHttpConfig = lift getHttpConfig
816−instance (MonadHttp m) => MonadHttp (IdentityT m) where
817− handleHttpException = lift . handleHttpException
818− getHttpConfig = lift getHttpConfig
821−instance (MonadHttp m) => MonadHttp (MaybeT m) where
822− handleHttpException = lift . handleHttpException
823− getHttpConfig = lift getHttpConfig
826−instance (MonadHttp m) => MonadHttp (ReaderT r m) where
827− handleHttpException = lift . handleHttpException
828− getHttpConfig = lift getHttpConfig
831−instance (MonadHttp m, Monoid w) => MonadHttp (RWS.CPS.RWST r w s m) where
832− handleHttpException = lift . handleHttpException
833− getHttpConfig = lift getHttpConfig
836−instance (MonadHttp m, Monoid w) => MonadHttp (RWS.Lazy.RWST r w s m) where
837− handleHttpException = lift . handleHttpException
838− getHttpConfig = lift getHttpConfig
841−instance (MonadHttp m, Monoid w) => MonadHttp (RWS.Strict.RWST r w s m) where
842− handleHttpException = lift . handleHttpException
843− getHttpConfig = lift getHttpConfig
846−instance (MonadHttp m) => MonadHttp (SelectT r m) where
847− handleHttpException = lift . handleHttpException
848− getHttpConfig = lift getHttpConfig
851−instance (MonadHttp m) => MonadHttp (State.Lazy.StateT s m) where
852− handleHttpException = lift . handleHttpException
853− getHttpConfig = lift getHttpConfig
856−instance (MonadHttp m) => MonadHttp (State.Strict.StateT s m) where
857− handleHttpException = lift . handleHttpException
858− getHttpConfig = lift getHttpConfig
861−instance (MonadHttp m, Monoid w) => MonadHttp (Writer.CPS.WriterT w m) where
862− handleHttpException = lift . handleHttpException
863− getHttpConfig = lift getHttpConfig
866−instance (MonadHttp m, Monoid w) => MonadHttp (Writer.Lazy.WriterT w m) where
867− handleHttpException = lift . handleHttpException
868− getHttpConfig = lift getHttpConfig
871−instance (MonadHttp m, Monoid w) => MonadHttp (Writer.Strict.WriterT w m) where
872− handleHttpException = lift . handleHttpException
873− getHttpConfig = lift getHttpConfig
875-- | Run a computation in the 'Req' monad with the given 'HttpConfig'. In
720-- | Run a computation in the 'Req' monad with the given 'HttpConfig'. In
876−-- the case of an exceptional situation an 'HttpException' will be thrown.
721+-- case of exceptional situation an 'HttpException' will be thrown.
878-- @since 0.4.0
723-- @since 0.4.0
880− (MonadIO m) =>
725+ MonadIO m =>
881 -- | 'HttpConfig' to use
726 -- | 'HttpConfig' to use
882 HttpConfig ->
727 HttpConfig ->
883 -- | Computation to run
728 -- | Computation to run
@@ -982,7 +827,7 @@ class HttpMethod a where
982 -- | Return name of the method as a 'ByteString'.
827 -- | Return name of the method as a 'ByteString'.
983 httpMethodName :: Proxy a -> ByteString
828 httpMethodName :: Proxy a -> ByteString
985−instance (HttpMethod method) => RequestComponent (Tagged "method" method) where
830+instance HttpMethod method => RequestComponent (Womb "method" method) where
986 getRequestMod _ = Endo $ \x ->
831 getRequestMod _ = Endo $ \x ->
987 x {L.method = httpMethodName (Proxy :: Proxy method)}
832 x {L.method = httpMethodName (Proxy :: Proxy method)}
@@ -1024,20 +869,23 @@ instance (HttpMethod method) => RequestComponent (Tagged "method" method) where
1024-- > -- https://%D1%8E%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4.%D1%80%D1%84
869-- > -- https://%D1%8E%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4.%D1%80%D1%84
1025data Url (scheme :: Scheme) = Url Scheme (NonEmpty Text)
870data Url (scheme :: Scheme) = Url Scheme (NonEmpty Text)
1026 -- NOTE The second value is the path segments in reversed order.
871 -- NOTE The second value is the path segments in reversed order.
1027− deriving (Eq, Ord, Show, Data, Generic)
872+ deriving (Eq, Ord, Show, Data, Typeable, Generic)
1029type role Url nominal
874type role Url nominal
1031-- With template-haskell >=2.15 and text >=1.2.4 Lift can be derived, however
876-- With template-haskell >=2.15 and text >=1.2.4 Lift can be derived, however
1032−-- the derived lift forgets the type of the scheme.
877+-- the derived lift forgets the type of scheme.
1033−instance (Typeable scheme) => TH.Lift (Url scheme) where
878+instance Typeable scheme => TH.Lift (Url scheme) where
1034 lift url =
879 lift url =
1035 TH.dataToExpQ (fmap liftText . cast) url `TH.sigE` case url of
880 TH.dataToExpQ (fmap liftText . cast) url `TH.sigE` case url of
1036 Url Http _ -> [t|Url 'Http|]
881 Url Http _ -> [t|Url 'Http|]
1037 Url Https _ -> [t|Url 'Https|]
882 Url Https _ -> [t|Url 'Https|]
1039 liftText t = TH.AppE (TH.VarE 'T.pack) <$> TH.lift (T.unpack t)
884 liftText t = TH.AppE (TH.VarE 'T.pack) <$> TH.lift (T.unpack t)
886+#if MIN_VERSION_template_haskell(2,16,0)
1040− liftTyped = TH.Code . TH.unsafeTExpCoerce . TH.lift
887+ liftTyped url = TH.TExp <$> TH.lift url
1042-- | Given host name, produce a 'Url' which has “http” as its scheme and
890-- | Given host name, produce a 'Url' which has “http” as its scheme and
1043-- empty path. This also sets port to @80@.
891-- empty path. This also sets port to @80@.
@@ -1049,33 +897,20 @@ http = Url Http . pure
1049https :: Text -> Url 'Https
897https :: Text -> Url 'Https
1050https = Url Https . pure
898https = Url Https . pure
1052−-- | Grow a given 'Url' appending a single path segment to it. Note that the
900+-- | Grow given 'Url' appending a single path segment to it. Note that the
1053-- path segment can be of any type that is an instance of 'ToHttpApiData'.
901-- path segment can be of any type that is an instance of 'ToHttpApiData'.
1054infixl 5 /~
902infixl 5 /~
1056−(/~) :: (ToHttpApiData a) => Url scheme -> a -> Url scheme
904+(/~) :: ToHttpApiData a => Url scheme -> a -> Url scheme
1057Url secure path /~ segment = Url secure (NE.cons (toUrlPiece segment) path)
905Url secure path /~ segment = Url secure (NE.cons (toUrlPiece segment) path)
1059−-- | A type-constrained version of @('/~')@ to remove ambiguity in the cases
907+-- | Type-constrained version of @('/~')@ to remove ambiguity in the cases
1060-- when next URL piece is a 'Data.Text.Text' literal.
908-- when next URL piece is a 'Data.Text.Text' literal.
1061infixl 5 /:
909infixl 5 /:
1063(/:) :: Url scheme -> Text -> Url scheme
911(/:) :: Url scheme -> Text -> Url scheme
1064(/:) = (/~)
912(/:) = (/~)
1066−-- | Render a 'Url' as 'Text'.
1069−renderUrl :: Url scheme -> Text
1072− "https://" <> renderParts parts
1074− "http://" <> renderParts parts
1076− renderParts parts =
1077− T.intercalate "/" (reverse $ NE.toList parts)
1079-- | The 'useHttpURI' function provides an alternative method to get 'Url'
914-- | The 'useHttpURI' function provides an alternative method to get 'Url'
1080-- (possibly with some 'Option's) from a 'URI'. This is useful when you are
915-- (possibly with some 'Option's) from a 'URI'. This is useful when you are
1081-- given a URL to query dynamically and don't know it beforehand.
916-- given a URL to query dynamically and don't know it beforehand.
@@ -1089,7 +924,8 @@ useHttpURI uri = do
1089 urlHead <- http <$> uriHost uri
924 urlHead <- http <$> uriHost uri
1090 let url = case URI.uriPath uri of
925 let url = case URI.uriPath uri of
1091 Nothing -> urlHead
926 Nothing -> urlHead
1092− Just uriPath -> uriPathToUrl uriPath urlHead
927+ Just (_, xs) ->
928+ foldl' (/:) urlHead (URI.unRText <$> NE.toList xs)
1093 return (url, uriOptions uri)
929 return (url, uriOptions uri)
1095-- | Just like 'useHttpURI', but expects the “https” scheme.
931-- | Just like 'useHttpURI', but expects the “https” scheme.
@@ -1101,21 +937,10 @@ useHttpsURI uri = do
1101 urlHead <- https <$> uriHost uri
937 urlHead <- https <$> uriHost uri
1102 let url = case URI.uriPath uri of
938 let url = case URI.uriPath uri of
1103 Nothing -> urlHead
939 Nothing -> urlHead
1104− Just uriPath -> uriPathToUrl uriPath urlHead
940+ Just (_, xs) ->
941+ foldl' (/:) urlHead (URI.unRText <$> NE.toList xs)
1105 return (url, uriOptions uri)
942 return (url, uriOptions uri)
1107−-- | Convert URI path to a 'Url'. Internal.
1111− (Bool, NonEmpty (URI.RText 'URI.PathPiece)) ->
1114−uriPathToUrl (trailingSlash, xs) urlHead =
1115− if trailingSlash then path /: T.empty else path
1117− path = foldl' (/:) urlHead (URI.unRText <$> NE.toList xs)
1119-- | A combination of 'useHttpURI' and 'useHttpsURI' for cases when scheme
944-- | A combination of 'useHttpURI' and 'useHttpsURI' for cases when scheme
1120-- is not known in advance.
945-- is not known in advance.
@@ -1232,21 +1057,21 @@ data NoReqBody = NoReqBody
1232instance HttpBody NoReqBody where
1057instance HttpBody NoReqBody where
1233 getRequestBody NoReqBody = L.RequestBodyBS B.empty
1058 getRequestBody NoReqBody = L.RequestBodyBS B.empty
1235−-- | This body option allows us to use a JSON object as the request
1060+-- | This body option allows to use a JSON object as request body—probably
1236−-- body—probably the most popular format right now. Just wrap a data type
1061+-- the most popular format right now. Just wrap a data type that is an
1237−-- that is an instance of 'ToJSON' type class and you are done: it will be
1062+-- instance of 'ToJSON' type class and you are done: it will be converted to
1238−-- converted to JSON and inserted as request body.
1063+-- JSON and inserted as request body.
1240-- This body option sets the @Content-Type@ header to @\"application/json;
1065-- This body option sets the @Content-Type@ header to @\"application/json;
1241-- charset=utf-8\"@ value.
1066-- charset=utf-8\"@ value.
1242newtype ReqBodyJson a = ReqBodyJson a
1067newtype ReqBodyJson a = ReqBodyJson a
1244−instance (ToJSON a) => HttpBody (ReqBodyJson a) where
1069+instance ToJSON a => HttpBody (ReqBodyJson a) where
1245 getRequestBody (ReqBodyJson a) = L.RequestBodyLBS (A.encode a)
1070 getRequestBody (ReqBodyJson a) = L.RequestBodyLBS (A.encode a)
1246 getRequestContentType _ = pure "application/json; charset=utf-8"
1071 getRequestContentType _ = pure "application/json; charset=utf-8"
1248-- | This body option streams request body from a file. It is expected that
1073-- | This body option streams request body from a file. It is expected that
1249−-- the file size does not change during streaming.
1074+-- the file size does not change during the streaming.
1251-- Using of this body option does not set the @Content-Type@ header.
1076-- Using of this body option does not set the @Content-Type@ header.
1252newtype ReqBodyFile = ReqBodyFile FilePath
1077newtype ReqBodyFile = ReqBodyFile FilePath
@@ -1271,11 +1096,12 @@ newtype ReqBodyLbs = ReqBodyLbs BL.ByteString
1271instance HttpBody ReqBodyLbs where
1096instance HttpBody ReqBodyLbs where
1272 getRequestBody (ReqBodyLbs bs) = L.RequestBodyLBS bs
1097 getRequestBody (ReqBodyLbs bs) = L.RequestBodyLBS bs
1274−-- | URL-encoded body. This can hold a collection of parameters which are
1099+-- | Form URL-encoded body. This can hold a collection of parameters which
1275−-- encoded similarly to query parameters at the end of query string, with
1100+-- are encoded similarly to query parameters at the end of query string,
1276−-- the only difference that they are stored in request body. The similarity
1101+-- with the only difference that they are stored in request body. The
1277−-- is reflected in the API as well, as you can use the same combinators you
1102+-- similarity is reflected in the API as well, as you can use the same
1278−-- would use to add query parameters: @('=:')@ and 'queryFlag'.
1103+-- combinators you would use to add query parameters: @('=:')@ and
1280-- This body option sets the @Content-Type@ header to
1106-- This body option sets the @Content-Type@ header to
1281-- @\"application/x-www-form-urlencoded\"@ value.
1107-- @\"application/x-www-form-urlencoded\"@ value.
@@ -1294,13 +1120,6 @@ newtype FormUrlEncodedParam = FormUrlEncodedParam [(Text, Maybe Text)]
1294instance QueryParam FormUrlEncodedParam where
1120instance QueryParam FormUrlEncodedParam where
1295 queryParam name mvalue =
1121 queryParam name mvalue =
1296 FormUrlEncodedParam [(name, toQueryParam <$> mvalue)]
1122 FormUrlEncodedParam [(name, toQueryParam <$> mvalue)]
1297− queryParamToList (FormUrlEncodedParam p) = p
1299−-- | Use 'formToQuery'.
1302−instance FromForm FormUrlEncodedParam where
1303− fromForm = Right . formToQuery
1305-- | Multipart form data. Please consult the
1124-- | Multipart form data. Please consult the
1306-- "Network.HTTP.Client.MultipartFormData" module for how to construct
1125-- "Network.HTTP.Client.MultipartFormData" module for how to construct
@@ -1340,7 +1159,7 @@ instance HttpBody ReqBodyMultipart where
1340-- | Create 'ReqBodyMultipart' request body from a collection of 'LM.Part's.
1159-- | Create 'ReqBodyMultipart' request body from a collection of 'LM.Part's.
1342-- @since 0.2.0
1161-- @since 0.2.0
1343−reqBodyMultipart :: (MonadIO m) => [LM.Part] -> m ReqBodyMultipart
1162+reqBodyMultipart :: MonadIO m => [LM.Part] -> m ReqBodyMultipart
1344reqBodyMultipart parts = liftIO $ do
1163reqBodyMultipart parts = liftIO $ do
1345 boundary <- LM.webkitBoundary
1164 boundary <- LM.webkitBoundary
1346 body <- LM.renderParts boundary parts
1165 body <- LM.renderParts boundary parts
@@ -1368,6 +1187,9 @@ type family ProvidesBody body :: CanHaveBody where
1368-- | This type function allows any HTTP body if method says it
1187-- | This type function allows any HTTP body if method says it
1369-- 'CanHaveBody'. When the method says it should have 'NoBody', the only
1188-- 'CanHaveBody'. When the method says it should have 'NoBody', the only
1370-- body option to use is 'NoReqBody'.
1189-- body option to use is 'NoReqBody'.
1191+-- __Note__: users of GHC 8.0.1 and later will see a slightly more friendly
1192+-- error message when method does not allow a body and body is provided.
1371type family
1193type family
1372 HttpBodyAllowed
1194 HttpBodyAllowed
1373 (allowsBody :: CanHaveBody)
1195 (allowsBody :: CanHaveBody)
@@ -1380,8 +1202,8 @@ type family
1380 TypeError
1202 TypeError
1381 ('Text "This HTTP method does not allow attaching a request body.")
1203 ('Text "This HTTP method does not allow attaching a request body.")
1383−instance (HttpBody body) => RequestComponent (Tagged "body" body) where
1205+instance HttpBody body => RequestComponent (Womb "body" body) where
1384− getRequestMod (Tagged body) = Endo $ \x ->
1206+ getRequestMod (Womb body) = Endo $ \x ->
1386 { L.requestBody = getRequestBody body,
1208 { L.requestBody = getRequestBody body,
1387 L.requestHeaders =
1209 L.requestHeaders =
@@ -1410,8 +1232,8 @@ data Option (scheme :: Scheme)
1410 = Option (Endo (Y.QueryText, L.Request)) (Maybe (L.Request -> IO L.Request))
1232 = Option (Endo (Y.QueryText, L.Request)) (Maybe (L.Request -> IO L.Request))
1412-- NOTE 'QueryText' is just [(Text, Maybe Text)], we keep it along with
1234-- NOTE 'QueryText' is just [(Text, Maybe Text)], we keep it along with
1413−-- Request to avoid appending to an existing query string in request every
1235+-- Request to avoid appending to existing query string in request every
1414−-- time new parameter is added. The additional Maybe (L.Request -> IO
1236+-- time new parameter is added. Additional Maybe (L.Request -> IO
1415-- L.Request) is a finalizer that will be applied after all other
1237-- L.Request) is a finalizer that will be applied after all other
1416-- transformations. This is for authentication methods that sign requests
1238-- transformations. This is for authentication methods that sign requests
1417-- based on data in Request.
1239-- based on data in Request.
@@ -1426,12 +1248,6 @@ instance Monoid (Option scheme) where
1426 mempty = Option mempty Nothing
1248 mempty = Option mempty Nothing
1427 mappend = (<>)
1249 mappend = (<>)
1429−-- | Use 'formToQuery'.
1432−instance FromForm (Option scheme) where
1433− fromForm = Right . formToQuery
1435-- | A helper to create an 'Option' that modifies only collection of query
1251-- | A helper to create an 'Option' that modifies only collection of query
1436-- parameters. This helper is not a part of the public API.
1252-- parameters. This helper is not a part of the public API.
1437withQueryParams :: (Y.QueryText -> Y.QueryText) -> Option scheme
1253withQueryParams :: (Y.QueryText -> Y.QueryText) -> Option scheme
@@ -1450,7 +1266,7 @@ instance RequestComponent (Option scheme) where
1451-- | Finalize given 'L.Request' by applying a finalizer from the given
1267-- | Finalize given 'L.Request' by applying a finalizer from the given
1452-- 'Option' (if it has any).
1268-- 'Option' (if it has any).
1453−finalizeRequest :: (MonadIO m) => Option scheme -> L.Request -> m L.Request
1269+finalizeRequest :: MonadIO m => Option scheme -> L.Request -> m L.Request
1454finalizeRequest (Option _ mfinalizer) = liftIO . fromMaybe pure mfinalizer
1270finalizeRequest (Option _ mfinalizer) = liftIO . fromMaybe pure mfinalizer
1456----------------------------------------------------------------------------
1272----------------------------------------------------------------------------
@@ -1474,7 +1290,7 @@ infix 7 =:
1474(=:) :: (QueryParam param, ToHttpApiData a) => Text -> a -> param
1290(=:) :: (QueryParam param, ToHttpApiData a) => Text -> a -> param
1475name =: value = queryParam name (pure value)
1291name =: value = queryParam name (pure value)
1477−-- | Construct a flag, that is, a valueless query parameter. For example, in
1293+-- | Construct a flag, that is, valueless query parameter. For example, in
1478-- the following URL @\"a\"@ is a flag, while @\"b\"@ is a query parameter
1294-- the following URL @\"a\"@ is a flag, while @\"b\"@ is a query parameter
1479-- with a value:
1295-- with a value:
@@ -1483,27 +1299,9 @@ name =: value = queryParam name (pure value)
1483-- This operator is defined in terms of 'queryParam':
1299-- This operator is defined in terms of 'queryParam':
1485-- > queryFlag name = queryParam name (Nothing :: Maybe ())
1301-- > queryFlag name = queryParam name (Nothing :: Maybe ())
1486−queryFlag :: (QueryParam param) => Text -> param
1302+queryFlag :: QueryParam param => Text -> param
1487queryFlag name = queryParam name (Nothing :: Maybe ())
1303queryFlag name = queryParam name (Nothing :: Maybe ())
1489−-- | Construct query parameters from a 'ToForm' instance. This function
1490−-- produces the same query params as 'Form.urlEncodeAsFormStable'.
1492−-- Note that 'Form.Form' doesn't have the concept of parameters with the
1493−-- empty value (i.e. what you can get by @key =: ""@). If the value is
1494−-- empty, it will be encoded as a valueless parameter (i.e. what you can get
1495−-- by @queryFlag key@).
1498−formToQuery :: (QueryParam param, Monoid param, ToForm f) => f -> param
1499−formToQuery f = mconcat . fmap toParam . Form.toListStable $ toForm f
1501− toParam (key, val) =
1507-- | A type class for query-parameter-like things. The reason to have an
1305-- | A type class for query-parameter-like things. The reason to have an
1508-- overloaded 'queryParam' is to be able to use it as an 'Option' and as a
1306-- overloaded 'queryParam' is to be able to use it as an 'Option' and as a
1509-- 'FormUrlEncodedParam' when constructing form URL encoded request bodies.
1307-- 'FormUrlEncodedParam' when constructing form URL encoded request bodies.
@@ -1513,17 +1311,11 @@ class QueryParam param where
1513 -- 'Nothing', it won't be included at all (i.e. you create a flag this
1311 -- 'Nothing', it won't be included at all (i.e. you create a flag this
1514 -- way). It's recommended to use @('=:')@ and 'queryFlag' instead of this
1312 -- way). It's recommended to use @('=:')@ and 'queryFlag' instead of this
1515 -- method, because they are easier to read.
1313 -- method, because they are easier to read.
1516− queryParam :: (ToHttpApiData a) => Text -> Maybe a -> param
1314+ queryParam :: ToHttpApiData a => Text -> Maybe a -> param
1518− -- | Get the query parameter names and values set by 'queryParam'.
1521− queryParamToList :: param -> [(Text, Maybe Text)]
1523instance QueryParam (Option scheme) where
1316instance QueryParam (Option scheme) where
1524 queryParam name mvalue =
1317 queryParam name mvalue =
1525 withQueryParams ((:) (name, toQueryParam <$> mvalue))
1318 withQueryParams ((:) (name, toQueryParam <$> mvalue))
1526− queryParamToList (Option f _) = fst $ appEndo f ([], L.defaultRequest)
1528----------------------------------------------------------------------------
1320----------------------------------------------------------------------------
1529-- Request—Optional parameters—Headers
1321-- Request—Optional parameters—Headers
@@ -1547,14 +1339,6 @@ attachHeader :: ByteString -> ByteString -> L.Request -> L.Request
1547attachHeader name value x =
1339attachHeader name value x =
1548 x {L.requestHeaders = (CI.mk name, value) : L.requestHeaders x}
1340 x {L.requestHeaders = (CI.mk name, value) : L.requestHeaders x}
1550−-- | Same as 'header', but with redacted values on print.
1553−headerRedacted :: ByteString -> ByteString -> Option scheme
1554−headerRedacted name value = withRequest $ \x ->
1555− let y = attachHeader name value x
1556− in y {L.redactHeaders = CI.mk name `S.insert` L.redactHeaders y}
1558----------------------------------------------------------------------------
1342----------------------------------------------------------------------------
1559-- Request—Optional parameters—Cookies
1343-- Request—Optional parameters—Cookies
@@ -1696,7 +1480,7 @@ customAuth = Option mempty . pure
1697-- | Specify the port to connect to explicitly. Normally, 'Url' you use
1481-- | Specify the port to connect to explicitly. Normally, 'Url' you use
1698-- determines the default port: @80@ for HTTP and @443@ for HTTPS. This
1482-- determines the default port: @80@ for HTTP and @443@ for HTTPS. This
1699−-- 'Option' allows us to choose an arbitrary port overwriting the defaults.
1483+-- 'Option' allows to choose an arbitrary port overwriting the defaults.
1700port :: Int -> Option scheme
1484port :: Int -> Option scheme
1701port n = withRequest $ \x ->
1485port n = withRequest $ \x ->
1702 x {L.port = n}
1486 x {L.port = n}
@@ -1711,8 +1495,8 @@ port n = withRequest $ \x ->
1712-- > decompress (const True)
1496-- > decompress (const True)
1713decompress ::
1497decompress ::
1714− -- | Predicate that is given MIME type, it returns 'True' when content
1498+ -- | Predicate that is given MIME type, it
1715− -- should be decompressed on the fly.
1499+ -- returns 'True' when content should be decompressed on the fly.
1716 (ByteString -> Bool) ->
1500 (ByteString -> Bool) ->
1717 Option scheme
1501 Option scheme
1718decompress f = withRequest $ \x ->
1502decompress f = withRequest $ \x ->
@@ -1762,7 +1546,7 @@ ignoreResponse = Proxy
1762newtype JsonResponse a = JsonResponse (L.Response a)
1546newtype JsonResponse a = JsonResponse (L.Response a)
1763 deriving (Show)
1547 deriving (Show)
1765−instance (FromJSON a) => HttpResponse (JsonResponse a) where
1549+instance FromJSON a => HttpResponse (JsonResponse a) where
1766 type HttpResponseBody (JsonResponse a) = a
1550 type HttpResponseBody (JsonResponse a) = a
1767 toVanillaResponse (JsonResponse r) = r
1551 toVanillaResponse (JsonResponse r) = r
1768 getHttpResponse r = do
1552 getHttpResponse r = do
@@ -1814,7 +1598,7 @@ lbsResponse = Proxy
1814----------------------------------------------------------------------------
1598----------------------------------------------------------------------------
1815-- Helpers for response interpretations
1599-- Helpers for response interpretations
1817−-- | Fetch beginning of the response and return it together with a new
1601+-- | Fetch beginning of response and return it together with new
1818-- @'L.Response' 'L.BodyReader'@ that can be passed to 'getHttpResponse' and
1602-- @'L.Response' 'L.BodyReader'@ that can be passed to 'getHttpResponse' and
1820grabPreview ::
1604grabPreview ::
@@ -1878,14 +1662,14 @@ brReadN br n = go 0 id id
1879-- | Get the response body.
1663-- | Get the response body.
1880responseBody ::
1664responseBody ::
1881− (HttpResponse response) =>
1665+ HttpResponse response =>
1882 response ->
1666 response ->
1883 HttpResponseBody response
1667 HttpResponseBody response
1884responseBody = L.responseBody . toVanillaResponse
1668responseBody = L.responseBody . toVanillaResponse
1886-- | Get the response status code.
1670-- | Get the response status code.
1887responseStatusCode ::
1671responseStatusCode ::
1888− (HttpResponse response) =>
1672+ HttpResponse response =>
1889 response ->
1673 response ->
1891responseStatusCode =
1675responseStatusCode =
@@ -1893,7 +1677,7 @@ responseStatusCode =
1894-- | Get the response status message.
1678-- | Get the response status message.
1895responseStatusMessage ::
1679responseStatusMessage ::
1896− (HttpResponse response) =>
1680+ HttpResponse response =>
1897 response ->
1681 response ->
1898 ByteString
1682 ByteString
1899responseStatusMessage =
1683responseStatusMessage =
@@ -1901,7 +1685,7 @@ responseStatusMessage =
1902-- | Lookup a particular header from a response.
1686-- | Lookup a particular header from a response.
1903responseHeader ::
1687responseHeader ::
1904− (HttpResponse response) =>
1688+ HttpResponse response =>
1905 -- | Response interpretation
1689 -- | Response interpretation
1906 response ->
1690 response ->
1907 -- | Header to lookup
1691 -- | Header to lookup
@@ -1913,7 +1697,7 @@ responseHeader r h =
1914-- | Get the response 'L.CookieJar'.
1698-- | Get the response 'L.CookieJar'.
1915responseCookieJar ::
1699responseCookieJar ::
1916− (HttpResponse response) =>
1700+ HttpResponse response =>
1917 response ->
1701 response ->
1918 L.CookieJar
1702 L.CookieJar
1919responseCookieJar = L.responseCookieJar . toVanillaResponse
1703responseCookieJar = L.responseCookieJar . toVanillaResponse
@@ -1926,9 +1710,9 @@ responseCookieJar = L.responseCookieJar . toVanillaResponse
1926-- To create a new response interpretation you just need to make your data
1710-- To create a new response interpretation you just need to make your data
1927-- type an instance of the 'HttpResponse' type class.
1711-- type an instance of the 'HttpResponse' type class.
1929−-- | A type class for response interpretations. It allows us to describe how
1713+-- | A type class for response interpretations. It allows to describe how to
1930−-- to consume the response from a @'L.Response' 'L.BodyReader'@ and produce
1714+-- consume response from a @'L.Response' 'L.BodyReader'@ and produce the
1931−-- the final result that is to be returned to the user.
1715+-- final result that is to be returned to the user.
1932class HttpResponse response where
1716class HttpResponse response where
1933 -- | The associated type is the type of body that can be extracted from an
1717 -- | The associated type is the type of body that can be extracted from an
1934 -- instance of 'HttpResponse'.
1718 -- instance of 'HttpResponse'.
@@ -1967,16 +1751,6 @@ class HttpResponse response where
1967 acceptHeader :: Proxy response -> Maybe ByteString
1751 acceptHeader :: Proxy response -> Maybe ByteString
1968 acceptHeader Proxy = Nothing
1752 acceptHeader Proxy = Nothing
1970−-- | This instance has been added to make it easier to inspect 'L.Response'
1971−-- using Req's functions like 'responseStatusCode', 'responseStatusMessage',
1975−instance HttpResponse (L.Response ()) where
1976− type HttpResponseBody (L.Response ()) = ()
1977− toVanillaResponse = id
1978− getHttpResponse = return . void
1980----------------------------------------------------------------------------
1754----------------------------------------------------------------------------
@@ -2002,7 +1776,7 @@ class RequestComponent a where
2002-- method@ and @'HttpBody' body => 'RequestComponent' body@ when it decides
1776-- method@ and @'HttpBody' body => 'RequestComponent' body@ when it decides
2003-- which instance to use (i.e. the constraints are taken into account later,
1777-- which instance to use (i.e. the constraints are taken into account later,
2004-- when instance is already chosen).
1778-- when instance is already chosen).
2005−newtype Tagged (tag :: Symbol) a = Tagged a
1779+newtype Womb (tag :: Symbol) a = Womb a
2007-- | Exceptions that this library throws.
1781-- | Exceptions that this library throws.
2008data HttpException
1782data HttpException
@@ -2011,24 +1785,10 @@ data HttpException
2011 | -- | A wrapper with Aeson-produced 'String' describing why decoding
1785 | -- | A wrapper with Aeson-produced 'String' describing why decoding
2012 -- failed
1786 -- failed
2013 JsonHttpException String
1787 JsonHttpException String
2014− deriving (Show, Generic)
1788+ deriving (Show, Typeable, Generic)
2016instance Exception HttpException
1790instance Exception HttpException
2018−-- | Return 'Just' if the given 'HttpException' is wrapping a http-client's
2019−-- 'L.StatusCodeException'. Otherwise, return 'Nothing'.
2022−isStatusCodeException :: HttpException -> Maybe (L.Response ())
2023−isStatusCodeException
2024− ( VanillaHttpException
2025− ( L.HttpExceptionRequest
2027− (L.StatusCodeException r _)
2030−isStatusCodeException _ = Nothing
2032-- | A simple type isomorphic to 'Bool' that we only have for better error
1792-- | A simple type isomorphic to 'Bool' that we only have for better error
2033-- messages. We use it as a kind and its data constructors as type-level
1793-- messages. We use it as a kind and its data constructors as type-level
@@ -2048,4 +1808,11 @@ data Scheme
2049 | -- | HTTPS
1809 | -- | HTTPS
2051− deriving (Eq, Ord, Show, Data, Generic, TH.Lift)
1811+ deriving (Eq, Ord, Show, Data, Typeable, Generic, TH.Lift)
1813+----------------------------------------------------------------------------
1816+-- | Max length of preview fragment of response body.
1817+bodyPreviewLength :: Num a => a
1818+bodyPreviewLength = 1024