packages feed

req 1.0.0 → 1.1.0

raw patch · 7 files changed

+99/−50 lines, 7 filesdep ~aeson

Dependency ranges changed: aeson

Files

CHANGELOG.md view
@@ -1,3 +1,10 @@+## Req 1.1.0++* Added `customAuth` and `attachHeader` to facilitate creation of custom+  authentication options.++* Added `basicProxyAuth` authentication option.+ ## Req 1.0.0  * Added the `reqBr` function allowing to consume `Response BodyReader`
LICENSE.md view
@@ -1,4 +1,4 @@-Copyright © 2016–2017 Mark Karpov+Copyright © 2016–2018 Mark Karpov  All rights reserved. 
Network/HTTP/Req.hs view
@@ -1,6 +1,6 @@ -- | -- Module      :  Network.HTTP.Req--- Copyright   :  © 2016–2017 Mark Karpov+-- Copyright   :  © 2016–2018 Mark Karpov -- License     :  BSD 3 clause -- -- Maintainer  :  Mark Karpov <markkarpov92@gmail.com>@@ -18,8 +18,8 @@ -- -- === About the library ----- Req is an easy-to-use, type-safe, expandable, high-level HTTP library--- that just works without any fooling around.+-- Req is an easy-to-use, type-safe, expandable, high-level HTTP client+-- library that just works without any fooling around. -- -- 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@@ -170,6 +170,7 @@   , QueryParam (..)     -- *** Headers   , header+  , attachHeader     -- *** Cookies     -- $cookies   , cookieJar@@ -177,9 +178,11 @@     -- $authentication   , basicAuth   , basicAuthUnsafe+  , basicProxyAuth   , oAuth1   , oAuth2Bearer   , oAuth2Token+  , customAuth     -- *** Other   , port   , decompress@@ -311,41 +314,39 @@ -- > -- > module Main (main) where -- >--- > import Control.Exception (throwIO) -- > 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) -- > import GHC.Generics -- > import Network.HTTP.Req -- > import qualified Data.ByteString.Char8 as B--- >--- > instance MonadHttp IO where--- >   handleHttpException = throwIO -- -- We will be making requests against the <https://httpbin.org> service. -- -- Make a GET request, grab 5 random bytes: -- -- > main :: IO ()--- > main = do+-- > main = runReq def $ do -- >   let n :: Int -- >       n = 5 -- >   bs <- req GET (https "httpbin.org" /: "bytes" /~ n) NoReqBody bsResponse mempty--- >   B.putStrLn (responseBody bs)+-- >   liftIO $ B.putStrLn (responseBody bs) -- -- The same, but now we use a query parameter named @\"seed\"@ to control -- seed of the generator: -- -- > main :: IO ()--- > main = do+-- > main = runReq def $ do -- >   let n, seed :: Int -- >       n    = 5 -- >       seed = 100 -- >   bs <- req GET (https "httpbin.org" /: "bytes" /~ n) NoReqBody bsResponse $ -- >     "seed" =: seed--- >   B.putStrLn (responseBody bs)+-- >   liftIO $ B.putStrLn (responseBody bs) -- -- POST JSON data and get some info about the POST request: --@@ -358,27 +359,27 @@ -- > instance FromJSON MyData -- > -- > main :: IO ()--- > main = do+-- > main = runReq def $ do -- >   let myData = MyData -- >         { size  = 6 -- >         , color = "Green" } -- >   v <- req POST (https "httpbin.org" /: "post") (ReqBodyJson myData) jsonResponse mempty--- >   print (responseBody v :: Value)+-- >   liftIO $ print (responseBody v :: Value) -- -- Sending URL-encoded body: -- -- > main :: IO ()--- > main = do+-- > main = runReq def $ do -- >   let params = -- >         "foo" =: ("bar" :: Text) <> -- >         queryFlag "baz" -- >   response <- req POST (https "httpbin.org" /: "post") (ReqBodyUrlEnc params) jsonResponse mempty--- >   print (responseBody response :: Value)+-- >   liftIO $ print (responseBody response :: Value) -- -- Using various optional parameters and URL that is not known in advance: -- -- > main :: IO ()--- > main = do+-- > main = runReq def $ 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")@@ -388,7 +389,7 @@ -- >     basicAuth "username" "password" <> -- >     options                         <> -- contains the ?foo=bar part -- >     port 443 -- here you can put any port of course--- >   print (responseBody response :: Value)+-- >   liftIO $ print (responseBody response :: Value)  req   :: ( MonadHttp    m@@ -1012,17 +1013,15 @@ -- -- @since 0.2.0 ----- ==== __Example__+-- ==== __Examples__ ----- > import Control.Exception (throwIO)--- > import qualified Network.HTTP.Client.MultipartFormData as LM+-- > import Control.Monad.IO.Class+-- > import Data.Default.Class -- > import Network.HTTP.Req--- >--- > instance MonadHttp IO where--- >   handleHttpException = throwIO+-- > import qualified Network.HTTP.Client.MultipartFormData as LM -- > -- > main :: IO ()--- > main = do+-- > main = runReq def $ do -- >   body <- -- >     reqBodyMultipart -- >       [ LM.partBS "title" "My Image"@@ -1033,7 +1032,7 @@ -- >       body -- >       bsResponse -- >       mempty--- >   print $ responseBody response+-- >   liftIO $ print (responseBody response)  data ReqBodyMultipart = ReqBodyMultipart ByteString LI.RequestBody @@ -1147,12 +1146,6 @@ withRequest :: (L.Request -> L.Request) -> Option scheme withRequest f = Option (Endo (second f)) Nothing --- | A helper to create an 'Option' that adds a finalizer (an IO-enabled--- request transformation that is applied after all other modifications).--asFinalizer :: (L.Request -> IO L.Request) -> Option scheme-asFinalizer = Option mempty . pure- instance RequestComponent (Option scheme) where   getRequestMod (Option f _) = Endo $ \x ->     let (qparams, x') = appEndo f ([], x)@@ -1233,6 +1226,8 @@  -- | A non-public helper that attaches a header with given name and content -- to a 'L.Request'.+--+-- @since 1.1.0  attachHeader :: ByteString -> ByteString -> L.Request -> L.Request attachHeader name value x =@@ -1287,9 +1282,20 @@   :: ByteString        -- ^ Username   -> ByteString        -- ^ Password   -> Option scheme     -- ^ Auth 'Option'-basicAuthUnsafe username password = asFinalizer+basicAuthUnsafe username password = customAuth   (pure . L.applyBasicAuth username password) +-- | The 'Option' set basic proxy authentication header.+--+-- @since 1.1.0++basicProxyAuth+  :: ByteString       -- ^ Username+  -> ByteString       -- ^ Password+  -> Option scheme    -- ^ Auth 'Option'+basicProxyAuth username password =+  withRequest (L.applyBasicProxyAuth username password)+ -- | The 'Option' adds OAuth1 authentication. -- -- @since 0.2.0@@ -1301,7 +1307,7 @@   -> ByteString        -- ^ OAuth token secret   -> Option scheme     -- ^ Auth 'Option' oAuth1 consumerToken consumerSecret token tokenSecret =-  asFinalizer (OAuth.signOAuth app creds)+  customAuth (OAuth.signOAuth app creds)   where     app = OAuth.newOAuth       { OAuth.oauthConsumerKey    = consumerToken@@ -1320,7 +1326,7 @@ oAuth2Bearer   :: ByteString        -- ^ Token   -> Option 'Https     -- ^ Auth 'Option'-oAuth2Bearer token = asFinalizer+oAuth2Bearer token = customAuth   (pure . attachHeader "Authorization" ("Bearer " <> token))  -- | The 'Option' adds a not-quite-standard OAuth2 bearer token (that seems@@ -1336,8 +1342,17 @@ oAuth2Token   :: ByteString        -- ^ Token   -> Option 'Https     -- ^ Auth 'Option'-oAuth2Token token = asFinalizer+oAuth2Token token = customAuth   (pure . attachHeader "Authorization" ("token " <> token))++-- | A helper to create custom authentication 'Option's. The given+-- 'IO'-enabled request transformation is applied after all other+-- modifications when constructing a request. Use wisely.+--+-- @since 1.1.0++customAuth :: (L.Request -> IO L.Request) -> Option scheme+customAuth = Option mempty . pure  ---------------------------------------------------------------------------- -- Request—Optional parameters—Other
README.md view
@@ -5,11 +5,11 @@ [![Stackage Nightly](http://stackage.org/package/req/badge/nightly)](http://stackage.org/nightly/package/req) [![Stackage LTS](http://stackage.org/package/req/badge/lts)](http://stackage.org/lts/package/req) [![Build Status](https://travis-ci.org/mrkkrp/req.svg?branch=master)](https://travis-ci.org/mrkkrp/req)-[![Coverage Status](https://coveralls.io/repos/mrkkrp/req/badge.svg?branch=master&service=github)](https://coveralls.io/github/mrkkrp/req?branch=master)  * [Motivation and Req vs other libraries](#motivation-and-req-vs-other-libraries) * [Unsolved problems](#unsolved-problems) * [Related packages](#related-packages)+* [Blog posts](#blog-posts) * [Contribution](#contribution) * [License](#license) @@ -40,8 +40,8 @@   liftIO $ print (responseBody r :: Value) ``` -Req is an easy-to-use, type-safe, expandable, high-level HTTP library that-just works without any fooling around.+Req is an easy-to-use, type-safe, expandable, high-level HTTP client library+that just works without any fooling around.  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,@@ -193,6 +193,10 @@ If you happen to have written a package that adds new features to Req, please submit a PR to include it in this list. +## Blog posts++* [Req 1.0.0, HTTP client, and streaming](https://markkarpov.com/post/req-1.0.0-http-client-and-streaming.html)+ ## Contribution  Issues, bugs, and questions may be reported in [the GitHub issue tracker for@@ -202,6 +206,6 @@  ## License -Copyright © 2016–2017 Mark Karpov+Copyright © 2016–2018 Mark Karpov  Distributed under BSD 3 clause license.
httpbin-tests/Network/HTTP/ReqSpec.hs view
@@ -210,7 +210,7 @@         NoReqBody ignoreResponse mempty       responseStatusCode r `shouldBe` status -  forM_ [101..102] checkStatusCode+  -- forM_ [101..102] checkStatusCode   forM_ [200..208] checkStatusCode   -- forM_ [300..308] checkStatusCode   forM_ [400..431] checkStatusCode
pure-tests/Network/HTTP/ReqSpec.hs view
@@ -37,6 +37,7 @@ import qualified Data.Text.Encoding       as T import qualified Network.HTTP.Client      as L import qualified Network.HTTP.Types       as Y+import qualified Network.HTTP.Types.Header as Y  spec :: Spec spec = do@@ -238,6 +239,12 @@             (oAuth2Bearer token0 <> oAuth2Bearer token1)           lookup "Authorization" (L.requestHeaders request) `shouldBe`             pure ("Bearer " <> token0)+    describe "ProxyAuthorization" $ do+      it "sets Authorization header to correct value" $+        property $ \username password -> do+          request <- req_ GET url NoReqBody (basicProxyAuth username password)+          lookup "Proxy-Authorization" (L.requestHeaders request) `shouldBe`+            pure (basicProxyAuthHeader username password)     describe "oAuth2Token" $ do       it "sets Authorization header to correct value" $         property $ \token -> do@@ -447,3 +454,11 @@ basicAuthHeader username password =   fromJust . lookup Y.hAuthorization . L.requestHeaders $     L.applyBasicAuth username password L.defaultRequest++-- | Get "Proxy-Authorization" basic proxy auth header given username and+-- password.++basicProxyAuthHeader :: ByteString -> ByteString -> ByteString+basicProxyAuthHeader username password =+  fromJust . lookup Y.hProxyAuthorization . L.requestHeaders $+    L.applyBasicProxyAuth username password L.defaultRequest
req.cabal view
@@ -1,7 +1,7 @@ name:                 req-version:              1.0.0-cabal-version:        >= 1.18-tested-with:          GHC==7.10.3, GHC==8.0.2, GHC==8.2.2+version:              1.1.0+cabal-version:        1.18+tested-with:          GHC==7.10.3, GHC==8.0.2, GHC==8.2.2, GHC==8.4.2 license:              BSD3 license-file:         LICENSE.md author:               Mark Karpov <markkarpov92@gmail.com>@@ -9,9 +9,9 @@ homepage:             https://github.com/mrkkrp/req bug-reports:          https://github.com/mrkkrp/req/issues category:             Network, Web-synopsis:             Easy-to-use, type-safe, expandable, high-level HTTP library+synopsis:             Easy-to-use, type-safe, expandable, high-level HTTP client library build-type:           Simple-description:          Easy-to-use, type-safe, expandable, high-level HTTP library.+description:          Easy-to-use, type-safe, expandable, high-level HTTP client library. extra-doc-files:      CHANGELOG.md                     , README.md data-files:           httpbin-data/utf8.html@@ -27,7 +27,7 @@   default:            False  library-  build-depends:      aeson            >= 0.9    && < 1.3+  build-depends:      aeson            >= 0.9    && < 1.4                     , authenticate-oauth >= 1.5  && < 1.7                     , base             >= 4.8    && < 5.0                     , blaze-builder    >= 0.3    && < 0.5@@ -53,6 +53,12 @@     ghc-options:      -O0 -Wall -Werror   else     ghc-options:      -O2 -Wall+  if flag(dev) && impl(ghc >= 8.0)+    ghc-options:      -Wcompat+                      -Wincomplete-record-updates+                      -Wincomplete-uni-patterns+                      -Wnoncanonical-monad-instances+                      -Wnoncanonical-monadfail-instances   default-language:   Haskell2010  test-suite pure-tests@@ -61,7 +67,7 @@   hs-source-dirs:     pure-tests   type:               exitcode-stdio-1.0   build-depends:      QuickCheck       >= 2.7    && < 3.0-                    , aeson            >= 0.9    && < 1.3+                    , aeson            >= 0.9    && < 1.4                     , base             >= 4.8    && < 5.0                     , blaze-builder    >= 0.3    && < 0.5                     , bytestring       >= 0.10.8 && < 0.11@@ -75,6 +81,7 @@                     , req                     , text             >= 0.2    && < 1.3                     , time             >= 1.2    && < 1.9+  build-tools:        hspec-discover   >= 2.0    && < 3.0   if flag(dev)     ghc-options:      -O0 -Wall -Werror   else@@ -87,7 +94,7 @@   hs-source-dirs:     httpbin-tests   type:               exitcode-stdio-1.0   build-depends:      QuickCheck       >= 2.7    && < 3.0-                    , aeson            >= 0.9    && < 1.3+                    , aeson            >= 0.9    && < 1.4                     , base             >= 4.8    && < 5.0                     , bytestring       >= 0.10.8 && < 0.11                     , data-default-class@@ -98,7 +105,8 @@                     , mtl              >= 2.0    && < 3.0                     , req                     , text             >= 0.2    && < 1.3-                    , unordered-containers >= 0.2.5 && < 0.2.9+                    , unordered-containers >= 0.2.5 && < 0.2.10+  build-tools:        hspec-discover   >= 2.0    && < 3.0   if flag(dev)     ghc-options:      -O0 -Wall -Werror   else