packages feed

req 1.2.1 → 2.0.0

raw patch · 6 files changed

+101/−92 lines, 6 filesdep −data-default-classdep ~connectiondep ~retry

Dependencies removed: data-default-class

Dependency ranges changed: connection, retry

Files

CHANGELOG.md view
@@ -1,3 +1,8 @@+## Req 2.0.0++* Got rid of `data-default-class` dependency, now we export+  `defaultHttpConfig` instead.+ ## Req 1.2.1  * Fixed a typo in the type signature of `parseUrl`.
Network/HTTP/Req.hs view
@@ -1,6 +1,6 @@ -- | -- Module      :  Network.HTTP.Req--- Copyright   :  © 2016–2018 Mark Karpov+-- Copyright   :  © 2016–2019 Mark Karpov -- License     :  BSD 3 clause -- -- Maintainer  :  Mark Karpov <markkarpov92@gmail.com>@@ -24,7 +24,7 @@ -- What does the phrase “easy-to-use” mean? It means that the library is -- designed to be beginner-friendly so it's simple to add to your monad -- stack, intuitive to work with, well-documented, and does not get in your--- way. Doing HTTP requests is a common task and a Haskell library for this+-- way. Doing HTTP requests is a common task and Haskell library for this -- should be very approachable and clear to beginners, thus certain -- compromises were made. For example, one cannot currently modify -- 'L.ManagerSettings' of the default manager because the library always@@ -38,7 +38,7 @@ -- methods like 'GET' or 'OPTIONS', and the amount of implicit assumptions -- is minimized by making the user specify his\/her intentions in an -- explicit form (for example, it's not possible to avoid specifying the--- body or method of a request). Authentication methods that assume HTTPS+-- body or method of request). Authentication methods that assume HTTPS -- force the user to use HTTPS at the type level. The library also carefully -- hides underlying types from the lower-level @http-client@ package because -- those types are not safe enough (for example 'L.Request' is an instance@@ -50,7 +50,7 @@ -- your own HTTP methods, create new ways to construct the body of a -- request, create new authorization options, perform a request in a -- different way, and create your own methods to parse and represent a--- response. As a user extends the library to satisfy his\/her special+-- response. As the user extends the library to satisfy his\/her special -- needs, the new solutions will work just like the built-ins. However, all -- of the common cases are also covered by the library out-of-the-box. --@@ -61,7 +61,7 @@ -- applications. For example, some people prefer throwing exceptions, while -- others are concerned with purity. Just define 'handleHttpException' -- accordingly when making your monad instance of 'MonadHttp' and it will--- play together seamlessly. Finally, the library cuts boilerplate down+-- play together seamlessly. Finally, the library cuts down boilerplate -- considerably, and helps you write concise, easy to read, and maintainable -- code. --@@ -118,10 +118,11 @@   , reqBr   , req'   , withReqManager-    -- * Embedding requests into your monad+    -- * Embedding requests in your monad     -- $embedding-requests   , MonadHttp  (..)   , HttpConfig (..)+  , defaultHttpConfig   , Req   , runReq     -- * Request@@ -224,7 +225,6 @@ import Data.Aeson (ToJSON (..), FromJSON (..)) import Data.ByteString (ByteString) import Data.Data (Data)-import Data.Default.Class import Data.Function (on) import Data.IORef import Data.List (nubBy)@@ -318,7 +318,6 @@ -- > import Control.Monad -- > import Control.Monad.IO.Class -- > import Data.Aeson--- > import Data.Default.Class -- > import Data.Maybe (fromJust) -- > import Data.Monoid ((<>)) -- > import Data.Text (Text)@@ -331,7 +330,7 @@ -- Make a GET request, grab 5 random bytes: -- -- > main :: IO ()--- > main = runReq def $ do+-- > main = runReq defaultHttpConfig $ do -- >   let n :: Int -- >       n = 5 -- >   bs <- req GET (https "httpbin.org" /: "bytes" /~ n) NoReqBody bsResponse mempty@@ -341,7 +340,7 @@ -- seed of the generator: -- -- > main :: IO ()--- > main = runReq def $ do+-- > main = runReq defaultHttpConfig $ do -- >   let n, seed :: Int -- >       n    = 5 -- >       seed = 100@@ -360,7 +359,7 @@ -- > instance FromJSON MyData -- > -- > main :: IO ()--- > main = runReq def $ do+-- > main = runReq defaultHttpConfig $ do -- >   let myData = MyData -- >         { size  = 6 -- >         , color = "Green" }@@ -370,7 +369,7 @@ -- Sending URL-encoded body: -- -- > main :: IO ()--- > main = runReq def $ do+-- > main = runReq defaultHttpConfig $ do -- >   let params = -- >         "foo" =: ("bar" :: Text) <> -- >         queryFlag "baz"@@ -380,7 +379,7 @@ -- Using various optional parameters and URL that is not known in advance: -- -- > main :: IO ()--- > main = runReq def $ do+-- > main = runReq defaultHttpConfig $ do -- >   -- This is an example of what to do when URL is given dynamically. Of -- >   -- course in a real application you may not want to use 'fromJust'. -- >   let (url, options) = fromJust (parseUrlHttps "https://httpbin.org/get?foo=bar")@@ -511,13 +510,16 @@ globalManager :: IORef L.Manager globalManager = unsafePerformIO $ do   context <- NC.initConnectionContext-  let settings = L.mkManagerSettingsContext (Just context) def Nothing+  let settings = L.mkManagerSettingsContext+        (Just context)+        (NC.TLSSettingsSimple False False False)+        Nothing   manager <- L.newManager settings   newIORef manager {-# NOINLINE globalManager #-}  ------------------------------------------------------------------------------- Embedding requests into your monad+-- Embedding requests in your monad  -- $embedding-requests --@@ -526,7 +528,7 @@ -- -- When writing a library, keep your API polymorphic in terms of -- 'MonadHttp', only define instance of 'MonadHttp' in final application.--- Another option is to use @newtype@ wrapped monad stack and define+-- Another option is to use a @newtype@-wrapped monad stack and define -- 'MonadHttp' for it. As of version /0.4.0/, the 'Req' monad that follows -- this strategy is provided out-of-the-box (see below). @@ -552,7 +554,7 @@   -- approach to configuration is desirable.    getHttpConfig :: m HttpConfig-  getHttpConfig = return def+  getHttpConfig = return defaultHttpConfig  -- | 'HttpConfig' contains general and default settings to be used when -- making HTTP requests.@@ -615,29 +617,33 @@     -- @since 0.3.0   } deriving Typeable -instance Default HttpConfig where-  def = HttpConfig-    { httpConfigProxy         = Nothing-    , httpConfigRedirectCount = 10-    , httpConfigAltManager    = Nothing-    , httpConfigCheckResponse = \_ response preview ->-        let scode = statusCode response-        in if 200 <= scode && scode < 300-             then Nothing-             else Just (L.StatusCodeException (void response) preview)-    , httpConfigRetryPolicy  = def-    , httpConfigRetryJudge   = \_ response ->-        statusCode response `elem`-          [ 408 -- Request timeout-          , 504 -- Gateway timeout-          , 524 -- A timeout occurred-          , 598 -- (Informal convention) Network read timeout error-          , 599 -- (Informal convention) Network connect timeout error-          ]-    }-    where-      statusCode = Y.statusCode . L.responseStatus+-- | Default value of 'HttpConfig'.+--+-- @since 2.0.0 +defaultHttpConfig :: HttpConfig+defaultHttpConfig = HttpConfig+  { httpConfigProxy         = Nothing+  , httpConfigRedirectCount = 10+  , httpConfigAltManager    = Nothing+  , httpConfigCheckResponse = \_ response preview ->+      let scode = statusCode response+      in if 200 <= scode && scode < 300+           then Nothing+           else Just (L.StatusCodeException (void response) preview)+  , httpConfigRetryPolicy  = retryPolicyDefault+  , httpConfigRetryJudge   = \_ response ->+      statusCode response `elem`+        [ 408 -- Request timeout+        , 504 -- Gateway timeout+        , 524 -- A timeout occurred+        , 598 -- (Informal convention) Network read timeout error+        , 599 -- (Informal convention) Network connect timeout error+        ]+  }+  where+    statusCode = Y.statusCode . L.responseStatus+ instance RequestComponent HttpConfig where   getRequestMod HttpConfig {..} = Endo $ \x ->     x { L.proxy                   = httpConfigProxy@@ -779,9 +785,9 @@ class HttpMethod a where    -- | Type function 'AllowsBody' returns a type of kind 'CanHaveBody' which-  -- tells the rest of the library whether the method can have a body or-  -- not. We use the special type 'CanHaveBody' lifted to the kind level-  -- instead of 'Bool' to get more user-friendly compiler messages.+  -- tells the rest of the library whether the method can have body or not.+  -- We use the special type 'CanHaveBody' lifted to the kind level instead+  -- of 'Bool' to get more user-friendly compiler messages.    type AllowsBody a :: CanHaveBody @@ -835,13 +841,13 @@   -- NOTE The second value is the path segments in reversed order.   deriving (Eq, Ord, Show, Data, Typeable, Generic) --- | Given host name, produce a 'Url' which have “http” as its scheme and+-- | Given host name, produce a 'Url' which has “http” as its scheme and -- empty path. This also sets port to @80@.  http :: Text -> Url 'Http http = Url Http . pure --- | Given host name, produce a 'Url' which have “https” as its scheme and+-- | Given host name, produce a 'Url' which has “https” as its scheme and -- empty path. This also sets port to @443@.  https :: Text -> Url 'Https@@ -871,6 +877,8 @@ -- This function only parses 'Url' (scheme, host, path) and optional query -- parameters that are returned as 'Option'. It does not parse method name -- or authentication info from given 'ByteString'.+--+-- This function expected scheme to be “http”.  parseUrlHttp :: ByteString -> Maybe (Url 'Http, Option scheme) parseUrlHttp url' = do@@ -878,7 +886,7 @@   (host :| path, option) <- parseUrlHelper url   return (foldl (/:) (http host) path, option) --- | Just like 'parseUrlHttp', but expects “https” scheme.+-- | Just like 'parseUrlHttp', but expects the “https” scheme.  parseUrlHttps :: ByteString -> Maybe (Url 'Https, Option scheme) parseUrlHttps url' = do@@ -933,8 +941,9 @@ -- -- A number of options for request bodies are available. The @Content-Type@ -- header is set for you automatically according to the body option you use--- (it's always specified in documentation for a given body option). To add--- your own way to represent request body, define an instance of 'HttpBody'.+-- (it's always specified in the documentation for a given body option). To+-- add your own way to represent request body, define an instance of+-- 'HttpBody'.  -- | This data type represents empty body of an HTTP request. This is the -- data type to use with 'HttpMethod's that cannot have a body, as it's the@@ -1072,16 +1081,16 @@    getRequestBody :: body -> L.RequestBody -  -- | This method allows to optionally specify value of @Content-Type@-  -- header that should be used with particular body option. By default it-  -- returns 'Nothing' and so @Content-Type@ is not set.+  -- | This method allows us to optionally specify the value of+  -- @Content-Type@ header that should be used with particular body option.+  -- By default it returns 'Nothing' and so @Content-Type@ is not set.    getRequestContentType :: body -> Maybe ByteString   getRequestContentType = const Nothing  -- | The type function recognizes 'NoReqBody' as having 'NoBody', while any--- other body option 'CanHaveBody'. This forces user to use 'NoReqBody' with--- 'GET' method and other methods that should not send a body.+-- other body option 'CanHaveBody'. This forces the user to use 'NoReqBody'+-- with 'GET' method and other methods that should not have body.  type family ProvidesBody body :: CanHaveBody where   ProvidesBody NoReqBody = 'NoBody@@ -1119,7 +1128,7 @@  -- $optional-parameters ----- Optional parameters to a request include things like query parameters,+-- Optional parameters of request include things like query parameters, -- headers, port number, etc. All optional parameters have the type -- 'Option', which is a 'Monoid'. This means that you can use 'mempty' as -- the last argument of 'req' to specify no optional parameters, or combine@@ -1236,8 +1245,7 @@   -> Option scheme header name value = withRequest (attachHeader name value) --- | A non-public helper that attaches a header with given name and content--- to a 'L.Request'.+-- | Attach a header with given name and content to a 'L.Request'. -- -- @since 1.1.0 @@ -1285,7 +1293,7 @@ basicAuth = basicAuthUnsafe  -- | An alternative to 'basicAuth' which works for any scheme. Note that--- using basic access authentication without SSL/TLS is vulnerable to+-- using basic access authentication without SSL\/TLS is vulnerable to -- attacks. Use 'basicAuth' instead unless you know what you are doing. -- -- @since 0.3.1
README.md view
@@ -20,13 +20,12 @@  import Control.Monad.IO.Class import Data.Aeson-import Data.Default.Class import Network.HTTP.Req  main :: IO () -- You can either make your monad an instance of 'MonadHttp', or use -- 'runReq' in any IO-enabled monad without defining new instances.-main = runReq def $ do+main = runReq defaultHttpConfig $ do   let payload = object         [ "foo" .= (10 :: Int)         , "bar" .= (20 :: Int) ]@@ -46,7 +45,7 @@ What does the phrase “easy-to-use” mean? It means that the library is designed to be beginner-friendly so it's simple to add to your monad stack, intuitive to work with, well-documented, and does not get in your way. Doing-HTTP requests is a common task and a Haskell library for this should be very+HTTP requests is a common task and Haskell library for this should be very approachable and clear to beginners, thus certain compromises were made. For example, one cannot currently modify `ManagerSettings` of the default manager because the library always uses the same implicit global manager for@@ -58,7 +57,7 @@ guaranteed that the user does not send the request body when using methods like GET or OPTIONS, and the amount of implicit assumptions is minimized by making the user specify his/her intentions in an explicit form (for example,-it's not possible to avoid specifying the body or method of a request).+it's not possible to avoid specifying the body or method of request). Authentication methods that assume HTTPS force the user to use HTTPS at the type level. The library also carefully hides underlying types from the lower-level `http-client` package because those types are not safe enough@@ -69,7 +68,7 @@ HTTP without having to resort to ugly hacking. For example, it's possible to define your own HTTP methods, create new ways to construct the body of a request, create new authorization options, perform a request in a different-way, and create your own methods to parse and represent a response. As a+way, and create your own methods to parse and represent a response. As the user extends the library to satisfy his/her special needs, the new solutions will work just like the built-ins. However, all of the common cases are also covered by the library out-of-the-box.@@ -81,7 +80,7 @@ example, some people prefer throwing exceptions, while others are concerned with purity. Just define `handleHttpException` accordingly when making your monad instance of `MonadHttp` and it will play together seamlessly. Finally,-the library cuts boilerplate down considerably, and helps you write concise,+the library cuts down boilerplate considerably, and helps you write concise, easy to read, and maintainable code.  The library uses the following mature packages under the hood to guarantee@@ -126,18 +125,18 @@ exactly I don't like about `http-conduit` in words, then it would be “the way requests are constructed”. You set, set, set instead of *being forced* to declare necessary bits and *being allowed* to declare optional bits in a-way that their combination is certainly valid. And you parse request from a-string without the protection of TH that otherwise saves the day as in-Yesod.+way that their combination is certainly valid. Also, with `http-conduit` you+parse request from a string without the protection of TH that otherwise+saves the day as in Yesod.  Then there is Wreq. `wreq` [doesn't see much development lately](https://github.com/bos/wreq/issues/93). `wreq` is by itself a weird library, IMO. You have functions per method—not very good, as there may be-new methods, like PATCH which is not new but still missing (well you have+new methods, like PATCH which is not new but still missing (well, you have `customMethod`, but what is the point of having per-method functions if you have a more general way to use any method? you should be able to just insert methods in the “argument slot” of `customMethod` and end up with a more-general solution). Now every method function has a companion that takes+general solution). Now, every method function has a companion that takes `Options` (like you have `get` and `getWith`). Why the duplication? Where is generality and flexibility? This is not all though, because you cannot really use `get` you see in the main module, because you want to have@@ -148,12 +147,12 @@ set of per-method functions like `get` and `getWith`—these are different ones, to be used with sessions! Now if you have a multi-threaded app, here is a surprise for you: you can't share connections between threads as-connections are shared only inside `withSession` friend and “session will no-longer be valid after that function returns”. There are valid uses for-sessions, but the point is that they are just too inconvenient for common-tasks.+connections are shared only inside of the `withSession` friend and “session+will no longer be valid after that function returns”. There are valid uses+for sessions, but the point is that they are just too inconvenient for+common tasks. -It's funny that one client I worked for had to have his own little wrapper+It's funny that one client I worked for had to invent his own little wrapper around `http-client` just because he could not possibly use `wreq` and `http-client` and friends were too low-level. The previous paragraph is extracted from a talk with a Haskell developer who works for that client. I@@ -202,10 +201,10 @@ Issues, bugs, and questions may be reported in [the GitHub issue tracker for this project](https://github.com/mrkkrp/req/issues). -Pull requests are also welcome and will be reviewed quickly.+Pull requests are also welcome.  ## License -Copyright © 2016–2018 Mark Karpov+Copyright © 2016–2019 Mark Karpov  Distributed under BSD 3 clause license.
httpbin-tests/Network/HTTP/ReqSpec.hs view
@@ -13,7 +13,6 @@ import Control.Monad.Reader import Control.Monad.Trans.Control import Data.Aeson (Value (..), ToJSON (..), object, (.=))-import Data.Default.Class import Data.Monoid ((<>)) import Data.Proxy import Data.Text (Text)@@ -41,7 +40,7 @@    describe "exception throwing on non-2xx status codes (Req monad)" $     it "throws indeed for non-2xx" $-      asIO . runReq def $+      asIO . runReq defaultHttpConfig $         liftBaseWith $ \run ->           run (req GET (httpbin /: "foo") NoReqBody ignoreResponse mempty)             `shouldThrow` selector404@@ -322,14 +321,14 @@ -- response status codes.  prepareForShit :: Req a -> IO a-prepareForShit = runReq def { httpConfigCheckResponse = noNoise }+prepareForShit = runReq defaultHttpConfig { httpConfigCheckResponse = noNoise }   where     noNoise _ _ _ = Nothing  -- | Run request with such settings that it throws on any response.  blindlyThrowing :: Req a -> IO a-blindlyThrowing = runReq def { httpConfigCheckResponse = doit }+blindlyThrowing = runReq defaultHttpConfig { httpConfigCheckResponse = doit }   where     doit _ _ = error "Oops!" 
pure-tests/Network/HTTP/ReqSpec.hs view
@@ -14,9 +14,9 @@ where  import Control.Exception (throwIO)+import Control.Retry import Data.Aeson (ToJSON (..)) import Data.ByteString (ByteString)-import Data.Default.Class import Data.Maybe (isNothing, fromJust) import Data.Monoid ((<>)) import Data.Proxy@@ -266,7 +266,7 @@             (oAuth2Bearer token0 <> oAuth2Bearer token1)           lookup "Authorization" (L.requestHeaders request) `shouldBe`             pure ("Bearer " <> token0)-    describe "ProxyAuthorization" $ do+    describe "ProxyAuthorization" $       it "sets Authorization header to correct value" $         property $ \username password -> do           request <- req_ GET url NoReqBody (basicProxyAuth username password)@@ -326,7 +326,7 @@     httpConfigRedirectCount <- arbitrary     let httpConfigAltManager          = Nothing         httpConfigCheckResponse _ _ _ = Nothing-        httpConfigRetryPolicy         = def+        httpConfigRetryPolicy         = retryPolicyDefault         httpConfigRetryJudge      _ _ = False     return HttpConfig {..} 
req.cabal view
@@ -1,7 +1,7 @@ name:                 req-version:              1.2.1+version:              2.0.0 cabal-version:        1.18-tested-with:          GHC==7.10.3, GHC==8.0.2, GHC==8.2.2, GHC==8.4.3+tested-with:          GHC==7.10.3, GHC==8.0.2, GHC==8.2.2, GHC==8.4.4, GHC==8.6.3 license:              BSD3 license-file:         LICENSE.md author:               Mark Karpov <markkarpov92@gmail.com>@@ -34,14 +34,13 @@                     , bytestring       >= 0.10.8 && < 0.11                     , case-insensitive >= 0.2    && < 1.3                     , connection       >= 0.2.2  && < 0.3-                    , data-default-class-                    , http-api-data    >= 0.2    && < 0.4-                    , http-client      >= 0.5    && < 0.6+                    , http-api-data    >= 0.2    && < 0.5+                    , http-client      >= 0.5    && < 0.7                     , http-client-tls  >= 0.3.2  && < 0.4                     , http-types       >= 0.8    && < 10.0                     , monad-control    >= 1.0    && < 1.1                     , mtl              >= 2.0    && < 3.0-                    , retry            >= 0.7    && < 0.8+                    , retry            >= 0.8    && < 0.9                     , text             >= 0.2    && < 1.3                     , time             >= 1.2    && < 1.9                     , transformers     >= 0.4    && < 0.6@@ -72,13 +71,13 @@                     , blaze-builder    >= 0.3    && < 0.5                     , bytestring       >= 0.10.8 && < 0.11                     , case-insensitive >= 0.2    && < 1.3-                    , data-default-class                     , hspec            >= 2.0    && < 3.0                     , hspec-core       >= 2.0    && < 3.0-                    , http-client      >= 0.5    && < 0.6+                    , http-client      >= 0.5    && < 0.7                     , http-types       >= 0.8    && < 10.0                     , mtl              >= 2.0    && < 3.0                     , req+                    , retry            >= 0.8    && < 0.9                     , text             >= 0.2    && < 1.3                     , time             >= 1.2    && < 1.9   build-tools:        hspec-discover   >= 2.0    && < 3.0@@ -97,15 +96,14 @@                     , aeson            >= 0.9    && < 1.5                     , base             >= 4.8    && < 5.0                     , bytestring       >= 0.10.8 && < 0.11-                    , data-default-class                     , hspec            >= 2.0    && < 3.0-                    , http-client      >= 0.5    && < 0.6+                    , http-client      >= 0.5    && < 0.7                     , http-types       >= 0.8    && < 10.0                     , monad-control    >= 1.0    && < 1.1                     , mtl              >= 2.0    && < 3.0                     , req                     , text             >= 0.2    && < 1.3-                    , unordered-containers >= 0.2.5 && < 0.2.10+                    , unordered-containers >= 0.2.5 && < 0.2.11   build-tools:        hspec-discover   >= 2.0    && < 3.0   if flag(dev)     ghc-options:      -O0 -Wall -Werror