on master help sign in
.github/workflows/ci.yaml+14−13
since splitsnapshots
unifiedsplit
@@ -11,27 +11,25 @@ jobs:
11 ormolu:
11 ormolu:
12 runs-on: ubuntu-latest
12 runs-on: ubuntu-latest
13 steps:
13 steps:
14− - uses: actions/checkout@v3
14+ - uses: actions/checkout@v4
15− - uses: haskell-actions/run-ormolu@v12
15+ - uses: haskell-actions/run-ormolu@v17
16 build:
16 build:
17 runs-on: ubuntu-latest
17 runs-on: ubuntu-latest
18 needs: ormolu
18 needs: ormolu
19 strategy:
19 strategy:
20 matrix:
20 matrix:
21− cabal: ["3.8"]
21+ cabal: ["3.12"]
22− ghc: ["9.0.2", "9.2.5", "9.4.4"]
22+ ghc: ["9.6.3", "9.8.2", "9.10.1"]
23− env:
24− CONFIG: "--enable-tests --enable-benchmarks --flags=dev"
25 steps:
23 steps:
26− - uses: actions/checkout@v3
24+ - uses: actions/checkout@v4
27− - uses: haskell/actions/setup@v2
25+ - uses: haskell-actions/setup@v2
28 id: setup-haskell-cabal
26 id: setup-haskell-cabal
29 with:
27 with:
30 ghc-version: ${{ matrix.ghc }}
28 ghc-version: ${{ matrix.ghc }}
31 cabal-version: ${{ matrix.cabal }}
29 cabal-version: ${{ matrix.cabal }}
32 - run: cabal update
30 - run: cabal update
33− - run: cabal freeze $CONFIG
31+ - run: cabal freeze
34− - uses: actions/cache@v3.3.1
32+ - uses: actions/cache@v4.2.3
35 with:
33 with:
36 path: |
34 path: |
37 ${{ steps.setup-haskell-cabal.outputs.cabal-store }}
35 ${{ steps.setup-haskell-cabal.outputs.cabal-store }}
@@ -40,7 +38,10 @@ jobs:
40 restore-keys: |
38 restore-keys: |
41 ${{ runner.os }}-${{ matrix.ghc }}-
39 ${{ runner.os }}-${{ matrix.ghc }}-
42 - run: cabal format && git diff --exit-code --color=always
40 - run: cabal format && git diff --exit-code --color=always
43− - run: cabal build $CONFIG
41+ - run: cabal build
42+ - run: |
43+ docker pull kennethreitz/httpbin
44+ docker run -p 1234:80 kennethreitz/httpbin &
44− - run: cabal test $CONFIG
45+ cabal test
45− - run: cabal haddock $CONFIG
46+ - run: cabal haddock
46 - run: cabal sdist
47 - run: cabal sdist
.gitignore+1
@@ -25,5 +25,6 @@ cabal.project.local
25cabal.sandbox.config
25cabal.sandbox.config
26dist-*/
26dist-*/
27dist/
27dist/
28+hie.yaml
28stack.yaml
29stack.yaml
29stack.yaml.lock
30stack.yaml.lock
CHANGELOG.md+19−1
@@ -1,4 +1,20 @@
1−## Unreleased
1+## Req 3.13.4
2+
3+* Fixed empty ciphersuite list when compiling against `tls < 2.0.6`
4+ (see [PR 175](https://github.com/mrkkrp/req/pull/175)). As a side effect, now
5+ compatible with older versions of `crypton-connection` (>= 0.3).
6+
7+## Req 3.13.3
8+
9+* Works with `crypton-connection-0.4` and newer.
10+
11+## Req 3.13.2
12+
13+* Disable the problematic `httpbin-tests` test suite by default. Only enable
14+ it when the `dev` flag is enabled. In that case it is expected that an
15+ httpbin server is run locally at `localhost:1234`.
16+
17+## Req 3.13.1
2
18
3* Switched the non-pure test suite to use https://httpbun.org instead of
19* Switched the non-pure test suite to use https://httpbun.org instead of
4 https://httpbin.org since the latter proved to be highly unreliable
20 https://httpbin.org since the latter proved to be highly unreliable
@@ -6,6 +22,8 @@
6
22
7* Switched from `connection` to `crypton-connection`.
23* Switched from `connection` to `crypton-connection`.
8
24
25+* Builds with GHC 9.6.1.
26+
9## Req 3.13.0
27## Req 3.13.0
10
28
11* Add `headerRedacted` function to add header fields, which will be with
29* Add `headerRedacted` function to add header fields, which will be with
Network/HTTP/Req.hs+39−49
@@ -1,19 +1,9 @@
1−{-# LANGUAGE BangPatterns #-}
2{-# LANGUAGE DataKinds #-}
1{-# LANGUAGE DataKinds #-}
3−{-# LANGUAGE DeriveDataTypeable #-}
4−{-# LANGUAGE DeriveGeneric #-}
5−{-# LANGUAGE DeriveLift #-}
6−{-# LANGUAGE FlexibleInstances #-}
7−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
8{-# LANGUAGE LambdaCase #-}
2{-# LANGUAGE LambdaCase #-}
9−{-# LANGUAGE MultiParamTypeClasses #-}
10{-# LANGUAGE OverloadedStrings #-}
3{-# LANGUAGE OverloadedStrings #-}
11{-# LANGUAGE QuasiQuotes #-}
4{-# LANGUAGE QuasiQuotes #-}
12−{-# LANGUAGE RankNTypes #-}
13{-# LANGUAGE RecordWildCards #-}
5{-# LANGUAGE RecordWildCards #-}
14{-# LANGUAGE RoleAnnotations #-}
6{-# LANGUAGE RoleAnnotations #-}
15−{-# LANGUAGE ScopedTypeVariables #-}
16−{-# LANGUAGE StandaloneDeriving #-}
17{-# LANGUAGE TemplateHaskellQuotes #-}
7{-# LANGUAGE TemplateHaskellQuotes #-}
18{-# LANGUAGE TypeFamilies #-}
8{-# LANGUAGE TypeFamilies #-}
19{-# LANGUAGE UndecidableInstances #-}
9{-# LANGUAGE UndecidableInstances #-}
@@ -213,7 +203,7 @@ module Network.HTTP.Req
213 )
203 )
214where
204where
215
205
216−import qualified Blaze.ByteString.Builder as BB
206+import Blaze.ByteString.Builder qualified as BB
217import Control.Applicative
207import Control.Applicative
218import Control.Arrow (first, second)
208import Control.Arrow (first, second)
219import Control.Exception hiding (Handler (..), TypeError)
209import Control.Exception hiding (Handler (..), TypeError)
@@ -229,55 +219,56 @@ import Control.Monad.Trans.Control
229import Control.Monad.Trans.Except (ExceptT)
219import Control.Monad.Trans.Except (ExceptT)
230import Control.Monad.Trans.Identity (IdentityT)
220import Control.Monad.Trans.Identity (IdentityT)
231import Control.Monad.Trans.Maybe (MaybeT)
221import Control.Monad.Trans.Maybe (MaybeT)
232−import qualified Control.Monad.Trans.RWS.CPS as RWS.CPS
222+import Control.Monad.Trans.RWS.CPS qualified as RWS.CPS
233−import qualified Control.Monad.Trans.RWS.Lazy as RWS.Lazy
223+import Control.Monad.Trans.RWS.Lazy qualified as RWS.Lazy
234−import qualified Control.Monad.Trans.RWS.Strict as RWS.Strict
224+import Control.Monad.Trans.RWS.Strict qualified as RWS.Strict
235import Control.Monad.Trans.Select (SelectT)
225import Control.Monad.Trans.Select (SelectT)
236−import qualified Control.Monad.Trans.State.Lazy as State.Lazy
226+import Control.Monad.Trans.State.Lazy qualified as State.Lazy
237−import qualified Control.Monad.Trans.State.Strict as State.Strict
227+import Control.Monad.Trans.State.Strict qualified as State.Strict
238−import qualified Control.Monad.Trans.Writer.CPS as Writer.CPS
228+import Control.Monad.Trans.Writer.CPS qualified as Writer.CPS
239−import qualified Control.Monad.Trans.Writer.Lazy as Writer.Lazy
229+import Control.Monad.Trans.Writer.Lazy qualified as Writer.Lazy
240−import qualified Control.Monad.Trans.Writer.Strict as Writer.Strict
230+import Control.Monad.Trans.Writer.Strict qualified as Writer.Strict
241import Control.Retry
231import Control.Retry
242import Data.Aeson (FromJSON (..), ToJSON (..))
232import Data.Aeson (FromJSON (..), ToJSON (..))
243−import qualified Data.Aeson as A
233+import Data.Aeson qualified as A
244import Data.ByteString (ByteString)
234import Data.ByteString (ByteString)
245−import qualified Data.ByteString as B
235+import Data.ByteString qualified as B
246−import qualified Data.ByteString.Lazy as BL
236+import Data.ByteString.Lazy qualified as BL
247−import qualified Data.CaseInsensitive as CI
237+import Data.CaseInsensitive qualified as CI
248import Data.Data (Data)
238import Data.Data (Data)
239+import Data.Default.Class (def)
249import Data.Function (on)
240import Data.Function (on)
250import Data.IORef
241import Data.IORef
251import Data.Kind (Constraint, Type)
242import Data.Kind (Constraint, Type)
252import Data.List (foldl', nubBy)
243import Data.List (foldl', nubBy)
253import Data.List.NonEmpty (NonEmpty (..))
244import Data.List.NonEmpty (NonEmpty (..))
254−import qualified Data.List.NonEmpty as NE
245+import Data.List.NonEmpty qualified as NE
255import Data.Maybe (fromMaybe)
246import Data.Maybe (fromMaybe)
256import Data.Proxy
247import Data.Proxy
257import Data.Semigroup (Endo (..))
248import Data.Semigroup (Endo (..))
258−import qualified Data.Set as S
249+import Data.Set qualified as S
259import Data.Text (Text)
250import Data.Text (Text)
260−import qualified Data.Text as T
251+import Data.Text qualified as T
261−import qualified Data.Text.Encoding as T
252+import Data.Text.Encoding qualified as T
262import Data.Typeable (Typeable, cast)
253import Data.Typeable (Typeable, cast)
263import GHC.Generics
254import GHC.Generics
264import GHC.TypeLits
255import GHC.TypeLits
265−import qualified Language.Haskell.TH as TH
256+import Language.Haskell.TH qualified as TH
266−import qualified Language.Haskell.TH.Quote as TH
257+import Language.Haskell.TH.Quote qualified as TH
267−import qualified Language.Haskell.TH.Syntax as TH
258+import Language.Haskell.TH.Syntax qualified as TH
268−import qualified Network.Connection as NC
259+import Network.Connection qualified as NC
269−import qualified Network.HTTP.Client as L
260+import Network.HTTP.Client qualified as L
270−import qualified Network.HTTP.Client.Internal as LI
261+import Network.HTTP.Client.Internal qualified as LI
271−import qualified Network.HTTP.Client.MultipartFormData as LM
262+import Network.HTTP.Client.MultipartFormData qualified as LM
272−import qualified Network.HTTP.Client.TLS as L
263+import Network.HTTP.Client.TLS qualified as L
273−import qualified Network.HTTP.Types as Y
264+import Network.HTTP.Types qualified as Y
274import System.IO.Unsafe (unsafePerformIO)
265import System.IO.Unsafe (unsafePerformIO)
275import Text.URI (URI)
266import Text.URI (URI)
276−import qualified Text.URI as URI
267+import Text.URI qualified as URI
277−import qualified Text.URI.QQ as QQ
268+import Text.URI.QQ qualified as QQ
278−import qualified Web.Authenticate.OAuth as OAuth
269+import Web.Authenticate.OAuth qualified as OAuth
279import Web.FormUrlEncoded (FromForm (..), ToForm (..))
270import Web.FormUrlEncoded (FromForm (..), ToForm (..))
280−import qualified Web.FormUrlEncoded as Form
271+import Web.FormUrlEncoded qualified as Form
281import Web.HttpApiData (ToHttpApiData (..))
272import Web.HttpApiData (ToHttpApiData (..))
282
273
283----------------------------------------------------------------------------
274----------------------------------------------------------------------------
@@ -594,10 +585,10 @@ req' method url body options m = do
594 withReqManager (m request)
585 withReqManager (m request)
595
586
596-- | Perform an action using the global implicit 'L.Manager' that the rest
587-- | Perform an action using the global implicit 'L.Manager' that the rest
597−-- of the library uses. This allows to reuse connections that the
588+-- of the library uses. This allows us to reuse connections that the
598-- 'L.Manager' controls.
589-- 'L.Manager' controls.
599withReqManager :: (MonadIO m) => (L.Manager -> m a) -> m a
590withReqManager :: (MonadIO m) => (L.Manager -> m a) -> m a
600−withReqManager m = liftIO (readIORef globalManager) >>= m
591+withReqManager m = m globalManager
601
592
602-- | The global 'L.Manager' that 'req' uses. Here we just go with the
593-- | The global 'L.Manager' that 'req' uses. Here we just go with the
603-- default settings, so users don't need to deal with this manager stuff at
594-- default settings, so users don't need to deal with this manager stuff at
@@ -610,16 +601,16 @@ withReqManager m = liftIO (readIORef globalManager) >>= m
610-- manager. From that moment on the 'IORef' will be just reused—exactly the
601-- manager. From that moment on the 'IORef' will be just reused—exactly the
611-- behavior we want here in order to maximize connection sharing. GHC could
602-- behavior we want here in order to maximize connection sharing. GHC could
612-- spoil the plan by inlining the definition, hence the @NOINLINE@ pragma.
603-- spoil the plan by inlining the definition, hence the @NOINLINE@ pragma.
613−globalManager :: IORef L.Manager
604+globalManager :: L.Manager
614globalManager = unsafePerformIO $ do
605globalManager = unsafePerformIO $ do
615 context <- NC.initConnectionContext
606 context <- NC.initConnectionContext
616 let settings =
607 let settings =
617 L.mkManagerSettingsContext
608 L.mkManagerSettingsContext
618 (Just context)
609 (Just context)
619− (NC.TLSSettingsSimple False False False)
610+ def
620 Nothing
611 Nothing
621 manager <- L.newManager settings
612 manager <- L.newManager settings
622− newIORef manager
613+ return manager
623{-# NOINLINE globalManager #-}
614{-# NOINLINE globalManager #-}
624
615
625----------------------------------------------------------------------------
616----------------------------------------------------------------------------
@@ -725,7 +716,6 @@ data HttpConfig = HttpConfig
725 -- @since 3.6.0
716 -- @since 3.6.0
726 httpConfigBodyPreviewLength :: forall a. (Num a) => a
717 httpConfigBodyPreviewLength :: forall a. (Num a) => a
727 }
718 }
728− deriving (Typeable)
729
719
730-- | The default value of 'HttpConfig'.
720-- | The default value of 'HttpConfig'.
731--
721--
@@ -1034,7 +1024,7 @@ instance (HttpMethod method) => RequestComponent (Tagged "method" method) where
1034-- > -- https://%D1%8E%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4.%D1%80%D1%84
1024-- > -- https://%D1%8E%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4.%D1%80%D1%84
1035data Url (scheme :: Scheme) = Url Scheme (NonEmpty Text)
1025data Url (scheme :: Scheme) = Url Scheme (NonEmpty Text)
1036 -- NOTE The second value is the path segments in reversed order.
1026 -- NOTE The second value is the path segments in reversed order.
1037− deriving (Eq, Ord, Show, Data, Typeable, Generic)
1027+ deriving (Eq, Ord, Show, Data, Generic)
1038
1028
1039type role Url nominal
1029type role Url nominal
1040
1030
@@ -2021,7 +2011,7 @@ data HttpException
2021 | -- | A wrapper with Aeson-produced 'String' describing why decoding
2011 | -- | A wrapper with Aeson-produced 'String' describing why decoding
2022 -- failed
2012 -- failed
2023 JsonHttpException String
2013 JsonHttpException String
2024− deriving (Show, Typeable, Generic)
2014+ deriving (Show, Generic)
2025
2015
2026instance Exception HttpException
2016instance Exception HttpException
2027
2017
@@ -2058,4 +2048,4 @@ data Scheme
2058 Http
2048 Http
2059 | -- | HTTPS
2049 | -- | HTTPS
2060 Https
2050 Https
2061− deriving (Eq, Ord, Show, Data, Typeable, Generic, TH.Lift)
2051+ deriving (Eq, Ord, Show, Data, Generic, TH.Lift)
README.md+1−1
@@ -4,7 +4,7 @@
4[![Hackage](https://img.shields.io/hackage/v/req.svg?style=flat)](https://hackage.haskell.org/package/req)
4[![Hackage](https://img.shields.io/hackage/v/req.svg?style=flat)](https://hackage.haskell.org/package/req)
5[![Stackage Nightly](http://stackage.org/package/req/badge/nightly)](http://stackage.org/nightly/package/req)
5[![Stackage Nightly](http://stackage.org/package/req/badge/nightly)](http://stackage.org/nightly/package/req)
6[![Stackage LTS](http://stackage.org/package/req/badge/lts)](http://stackage.org/lts/package/req)
6[![Stackage LTS](http://stackage.org/package/req/badge/lts)](http://stackage.org/lts/package/req)
7−![CI](https://github.com/mrkkrp/req/workflows/CI/badge.svg?branch=master)
7+[![CI](https://github.com/mrkkrp/req/actions/workflows/ci.yaml/badge.svg)](https://github.com/mrkkrp/req/actions/workflows/ci.yaml)
8
8
9* [Related packages](#related-packages)
9* [Related packages](#related-packages)
10* [Blog posts](#blog-posts)
10* [Blog posts](#blog-posts)
Setup.hsdeleted−6
@@ -1,6 +0,0 @@
1−module Main (main) where
2−
3−import Distribution.Simple
4−
5−main :: IO ()
6−main = defaultMain
cabal.projectnew file+4
@@ -0,0 +1,4 @@
1+packages: .
2+tests: True
3+benchmarks: True
4+constraints: req +dev
httpbun-data/robots.txt → httpbin-data/robots.txtrenamed

The content is the same.

httpbun-data/utf8.html → httpbin-data/utf8.htmlrenamed

The content is the same.

httpbun-tests/Network/HTTP/ReqSpec.hs → httpbin-tests/Network/HTTP/ReqSpec.hsrenamed+156−91
@@ -11,21 +11,22 @@ import Control.Exception
11import Control.Monad (forM_)
11import Control.Monad (forM_)
12import Control.Monad.Trans.Control
12import Control.Monad.Trans.Control
13import Data.Aeson (ToJSON (..), Value (..), object, (.=))
13import Data.Aeson (ToJSON (..), Value (..), object, (.=))
14−import qualified Data.Aeson as A
14+import Data.Aeson qualified as A
15−import qualified Data.Aeson.KeyMap as Aeson.KeyMap
15+import Data.Aeson.KeyMap qualified as Aeson.KeyMap
16−import qualified Data.ByteString as B
16+import Data.ByteString qualified as B
17−import qualified Data.ByteString.Lazy as BL
17+import Data.ByteString.Lazy qualified as BL
18import Data.Functor.Identity (runIdentity)
18import Data.Functor.Identity (runIdentity)
19import Data.Maybe (fromJust)
19import Data.Maybe (fromJust)
20import Data.Proxy
20import Data.Proxy
21import Data.Text (Text)
21import Data.Text (Text)
22−import qualified Data.Text as T
22+import Data.Text qualified as T
23−import qualified Data.Text.Encoding as T
23+import Data.Text.Encoding qualified as T
24−import qualified Data.Text.IO as TIO
24+import Data.Text.IO qualified as TIO
25−import qualified Network.HTTP.Client as L
25+import Network.HTTP.Client qualified as L
26−import qualified Network.HTTP.Client.MultipartFormData as LM
26+import Network.HTTP.Client.MultipartFormData qualified as LM
27−import Network.HTTP.Req
27+import Network.HTTP.Req hiding (req)
28+import Network.HTTP.Req qualified as Req
28−import qualified Network.HTTP.Types as Y
29+import Network.HTTP.Types qualified as Y
29import Test.Hspec
30import Test.Hspec
30import Test.QuickCheck
31import Test.QuickCheck
31
32
@@ -33,25 +34,25 @@ spec :: Spec
33spec = do
34spec = do
34 describe "exception throwing on non-2xx status codes" $
35 describe "exception throwing on non-2xx status codes" $
35 it "throws indeed for non-2xx" $
36 it "throws indeed for non-2xx" $
36− req GET (httpbun /: "foo") NoReqBody ignoreResponse mempty
37+ req GET (httpbin /: "foo") NoReqBody ignoreResponse mempty
37 `shouldThrow` selector404
38 `shouldThrow` selector404
38
39
39 describe "exception throwing on non-2xx status codes (Req monad)" $
40 describe "exception throwing on non-2xx status codes (Req monad)" $
40 it "throws indeed for non-2xx" $
41 it "throws indeed for non-2xx" $
41 asIO . runReq defaultHttpConfig $
42 asIO . runReq defaultHttpConfig $
42 liftBaseWith $ \run ->
43 liftBaseWith $ \run ->
43− run (req GET (httpbun /: "foo") NoReqBody ignoreResponse mempty)
44+ run (req GET (httpbin /: "foo") NoReqBody ignoreResponse mempty)
44 `shouldThrow` selector404
45 `shouldThrow` selector404
45
46
46 describe "response check via httpConfigCheckResponse" $
47 describe "response check via httpConfigCheckResponse" $
47 context "if it's set to always throw" $
48 context "if it's set to always throw" $
48 it "throws indeed" $
49 it "throws indeed" $
49− blindlyThrowing (req GET httpbun NoReqBody ignoreResponse mempty)
50+ blindlyThrowing (req GET httpbin NoReqBody ignoreResponse mempty)
50 `shouldThrow` anyException
51 `shouldThrow` anyException
51
52
52 describe "isStatusCodeException" $
53 describe "isStatusCodeException" $
53 it "extracts non-2xx response" $
54 it "extracts non-2xx response" $
54− req GET (httpbun /: "foo") NoReqBody ignoreResponse mempty
55+ req GET (httpbin /: "foo") NoReqBody ignoreResponse mempty
55 `shouldThrow` selector404ByStatusCodeException
56 `shouldThrow` selector404ByStatusCodeException
56
57
57 describe "receiving user-agent header back" $
58 describe "receiving user-agent header back" $
@@ -59,7 +60,7 @@ spec = do
59 r <-
60 r <-
60 req
61 req
61 GET
62 GET
62− (httpbun /: "user-agent")
63+ (httpbin /: "user-agent")
63 NoReqBody
64 NoReqBody
64 jsonResponse
65 jsonResponse
65 (header "user-agent" "Req")
66 (header "user-agent" "Req")
@@ -74,7 +75,7 @@ spec = do
74 r <-
75 r <-
75 req
76 req
76 GET
77 GET
77− (httpbun /: "headers")
78+ (httpbin /: "headers")
78 NoReqBody
79 NoReqBody
79 jsonResponse
80 jsonResponse
80 (header "Foo" "bar" <> header "Baz" "quux")
81 (header "Foo" "bar" <> header "Baz" "quux")
@@ -92,12 +93,11 @@ spec = do
92
93
93 describe "receiving GET data back" $
94 describe "receiving GET data back" $
94 it "works" $ do
95 it "works" $ do
95− r <- req GET (httpbun /: "get") NoReqBody jsonResponse mempty
96+ r <- req GET (httpbin /: "get") NoReqBody jsonResponse mempty
96 (stripFunnyHeaders . stripOrigin) (responseBody r)
97 (stripFunnyHeaders . stripOrigin) (responseBody r)
97 `shouldBe` object
98 `shouldBe` object
98 [ "args" .= emptyObject,
99 [ "args" .= emptyObject,
99− "url" .= ("https://httpbun.org/get" :: Text),
100+ "url" .= ("http://localhost:1234/get" :: Text),
100− "method" .= ("GET" :: Text),
101 "headers"
101 "headers"
102 .= object
102 .= object
103 [ "Accept-Encoding" .= ("gzip" :: Text)
103 [ "Accept-Encoding" .= ("gzip" :: Text)
@@ -111,14 +111,13 @@ spec = do
111 it "works" $ do
111 it "works" $ do
112 let text = "foo" :: Text
112 let text = "foo" :: Text
113 reflected = reflectJSON text
113 reflected = reflectJSON text
114− r <- req POST (httpbun /: "post") (ReqBodyJson text) jsonResponse mempty
114+ r <- req POST (httpbin /: "post") (ReqBodyJson text) jsonResponse mempty
115 (stripFunnyHeaders . stripOrigin) (responseBody r)
115 (stripFunnyHeaders . stripOrigin) (responseBody r)
116 `shouldBe` object
116 `shouldBe` object
117 [ "args" .= emptyObject,
117 [ "args" .= emptyObject,
118 "json" .= text,
118 "json" .= text,
119 "data" .= reflected,
119 "data" .= reflected,
120− "url" .= ("https://httpbun.org/post" :: Text),
120+ "url" .= ("http://localhost:1234/post" :: Text),
121− "method" .= ("POST" :: Text),
122 "headers"
121 "headers"
123 .= object
122 .= object
124 [ "Content-Type" .= ("application/json; charset=utf-8" :: Text),
123 [ "Content-Type" .= ("application/json; charset=utf-8" :: Text),
@@ -139,15 +138,14 @@ spec = do
139 [ LM.partBS "foo" "foo data!",
138 [ LM.partBS "foo" "foo data!",
140 LM.partBS "bar" "bar data!"
139 LM.partBS "bar" "bar data!"
141 ]
140 ]
142− r <- req POST (httpbun /: "post") body jsonResponse mempty
141+ r <- req POST (httpbin /: "post") body jsonResponse mempty
143 let contentType = fromJust (getRequestContentType body)
142 let contentType = fromJust (getRequestContentType body)
144 (stripFunnyHeaders . stripOrigin) (responseBody r)
143 (stripFunnyHeaders . stripOrigin) (responseBody r)
145 `shouldBe` object
144 `shouldBe` object
146 [ "args" .= emptyObject,
145 [ "args" .= emptyObject,
147 "json" .= Null,
146 "json" .= Null,
148 "data" .= ("" :: Text),
147 "data" .= ("" :: Text),
149− "url" .= ("https://httpbun.org/post" :: Text),
148+ "url" .= ("http://localhost:1234/post" :: Text),
150− "method" .= ("POST" :: Text),
151 "headers"
149 "headers"
152 .= object
150 .= object
153 [ "Content-Type" .= T.decodeUtf8 contentType,
151 [ "Content-Type" .= T.decodeUtf8 contentType,
@@ -168,16 +166,15 @@ spec = do
168 describe "receiving PATCHed file back" $
166 describe "receiving PATCHed file back" $
169 it "works" $ do
167 it "works" $ do
170 let file :: FilePath
168 let file :: FilePath
171− file = "httpbun-data/robots.txt"
169+ file = "httpbin-data/robots.txt"
172 contents <- TIO.readFile file
170 contents <- TIO.readFile file
173− r <- req PATCH (httpbun /: "patch") (ReqBodyFile file) jsonResponse mempty
171+ r <- req PATCH (httpbin /: "patch") (ReqBodyFile file) jsonResponse mempty
174 (stripFunnyHeaders . stripOrigin) (responseBody r)
172 (stripFunnyHeaders . stripOrigin) (responseBody r)
175 `shouldBe` object
173 `shouldBe` object
176 [ "args" .= emptyObject,
174 [ "args" .= emptyObject,
177 "json" .= Null,
175 "json" .= Null,
178 "data" .= contents,
176 "data" .= contents,
179− "url" .= ("https://httpbun.org/patch" :: Text),
177+ "url" .= ("http://localhost:1234/patch" :: Text),
180− "method" .= ("PATCH" :: Text),
181 "headers"
178 "headers"
182 .= object
179 .= object
183 [ "Accept-Encoding" .= ("gzip" :: Text),
180 [ "Accept-Encoding" .= ("gzip" :: Text),
@@ -196,14 +193,13 @@ spec = do
196 "foo" =: ("bar" :: Text)
193 "foo" =: ("bar" :: Text)
197 <> "baz" =: (5 :: Int)
194 <> "baz" =: (5 :: Int)
198 <> queryFlag "quux"
195 <> queryFlag "quux"
199− r <- req PUT (httpbun /: "put") (ReqBodyUrlEnc params) jsonResponse mempty
196+ r <- req PUT (httpbin /: "put") (ReqBodyUrlEnc params) jsonResponse mempty
200 (stripFunnyHeaders . stripOrigin) (responseBody r)
197 (stripFunnyHeaders . stripOrigin) (responseBody r)
201 `shouldBe` object
198 `shouldBe` object
202 [ "args" .= emptyObject,
199 [ "args" .= emptyObject,
203 "json" .= Null,
200 "json" .= Null,
204 "data" .= ("" :: Text),
201 "data" .= ("" :: Text),
205− "url" .= ("https://httpbun.org/put" :: Text),
202+ "url" .= ("http://localhost:1234/put" :: Text),
206− "method" .= ("PUT" :: Text),
207 "headers"
203 "headers"
208 .= object
204 .= object
209 [ "Content-Type" .= ("application/x-www-form-urlencoded" :: Text),
205 [ "Content-Type" .= ("application/x-www-form-urlencoded" :: Text),
@@ -222,19 +218,24 @@ spec = do
222 responseStatusCode r `shouldBe` 200
218 responseStatusCode r `shouldBe` 200
223 responseStatusMessage r `shouldBe` "OK"
219 responseStatusMessage r `shouldBe` "OK"
224
220
221+ -- TODO /delete
222+
225− -- describe "receiving UTF-8 encoded Unicode data" $
223+ describe "receiving UTF-8 encoded Unicode data" $
226− -- it "works" $ do
224+ it "works" $ do
227− -- r <-
225+ r <-
228− -- req
226+ req
229− -- GET
227+ GET
230− -- (httpbun /: "encoding" /: "utf8")
228+ (httpbin /: "encoding" /: "utf8")
231− -- NoReqBody
229+ NoReqBody
232− -- bsResponse
230+ bsResponse
233− -- mempty
231+ mempty
234− -- utf8data <- B.readFile "httpbun-data/utf8.html"
232+ utf8data <- B.readFile "httpbin-data/utf8.html"
235− -- responseBody r `shouldBe` utf8data
233+ responseBody r `shouldBe` utf8data
236− -- responseStatusCode r `shouldBe` 200
234+ responseStatusCode r `shouldBe` 200
237− -- responseStatusMessage r `shouldBe` "OK"
235+ responseStatusMessage r `shouldBe` "OK"
236+
237+ -- TODO /gzip
238+ -- TODO /deflate
238
239
239 describe "retrying" $
240 describe "retrying" $
240 it "retries as many times as specified" $ do
241 it "retries as many times as specified" $ do
@@ -245,7 +246,7 @@ spec = do
245 prepareForShit $
246 prepareForShit $
246 req
247 req
247 GET
248 GET
248− (httpbun /: "status" /~ status)
249+ (httpbin /: "status" /~ status)
249 NoReqBody
250 NoReqBody
250 ignoreResponse
251 ignoreResponse
251 mempty
252 mempty
@@ -257,18 +258,25 @@ spec = do
257 forM_ [400 .. 431] checkStatusCode
258 forM_ [400 .. 431] checkStatusCode
258 forM_ [500 .. 511] checkStatusCode
259 forM_ [500 .. 511] checkStatusCode
259
260
261+ -- TODO /response-headers
262+ -- TODO /redirect
263+
260 describe "redirects" $
264 describe "redirects" $
261 it "follows redirects" $ do
265 it "follows redirects" $ do
262 r <-
266 r <-
263 req
267 req
264 GET
268 GET
265− (httpbun /: "redirect-to")
269+ (httpbin /: "redirect-to")
266 NoReqBody
270 NoReqBody
267 ignoreResponse
271 ignoreResponse
268− ("url" =: ("https://httpbun.org" :: Text))
272+ ("url" =: ("https://httpbin.org" :: Text))
269 responseStatusCode r `shouldBe` 200
273 responseStatusCode r `shouldBe` 200
270 responseStatusMessage r `shouldBe` "OK"
274 responseStatusMessage r `shouldBe` "OK"
271
275
276+ -- TODO /relative-redicet
277+ -- TODO /absolute-redirect
278+ -- TODO /cookies
279+
272 describe "basicAuth" $ do
280 describe "basicAuth" $ do
273 let user, password :: Text
281 let user, password :: Text
274 user = "Scooby"
282 user = "Scooby"
@@ -279,32 +287,43 @@ spec = do
279 prepareForShit $
287 prepareForShit $
280 req
288 req
281 GET
289 GET
282− (httpbun /: "basic-auth" /~ user /~ password)
290+ (httpbin /: "basic-auth" /~ user /~ password)
283 NoReqBody
291 NoReqBody
284 ignoreResponse
292 ignoreResponse
285 mempty
293 mempty
286 responseStatusCode r `shouldBe` 401
294 responseStatusCode r `shouldBe` 401
287− responseStatusMessage r `shouldBe` "Unauthorized"
295+ responseStatusMessage r `shouldBe` "UNAUTHORIZED"
288 context "when we provide appropriate basic auth data" $
296 context "when we provide appropriate basic auth data" $
289 it "succeeds" $ do
297 it "succeeds" $ do
290 r <-
298 r <-
291 req
299 req
292 GET
300 GET
293− (httpbun /: "basic-auth" /~ user /~ password)
301+ (httpbin /: "basic-auth" /~ user /~ password)
294 NoReqBody
302 NoReqBody
295 ignoreResponse
303 ignoreResponse
296− (basicAuth (T.encodeUtf8 user) (T.encodeUtf8 password))
304+ (basicAuthUnsafe (T.encodeUtf8 user) (T.encodeUtf8 password))
297 responseStatusCode r `shouldBe` 200
305 responseStatusCode r `shouldBe` 200
298 responseStatusMessage r `shouldBe` "OK"
306 responseStatusMessage r `shouldBe` "OK"
299
307
308+ -- TODO /hidden-basic-auth
309+ -- TODO /digest-auth
310+ -- TODO /stream
311+ -- TODO /delay
312+ -- TODO /drip
313+ -- TODO /range
314+ -- TODO /html
315+
300 describe "robots.txt" $
316 describe "robots.txt" $
301 it "works" $ do
317 it "works" $ do
302− r <- req GET (httpbun /: "robots.txt") NoReqBody bsResponse mempty
318+ r <- req GET (httpbin /: "robots.txt") NoReqBody bsResponse mempty
303− robots <- B.readFile "httpbun-data/robots.txt"
319+ robots <- B.readFile "httpbin-data/robots.txt"
304 responseBody r `shouldBe` robots
320 responseBody r `shouldBe` robots
305 responseStatusCode r `shouldBe` 200
321 responseStatusCode r `shouldBe` 200
306 responseStatusMessage r `shouldBe` "OK"
322 responseStatusMessage r `shouldBe` "OK"
307
323
324+ -- TODO /deny
325+ -- TODO /cache
326+
308 describe "getting random bytes" $ do
327 describe "getting random bytes" $ do
309 it "works" $
328 it "works" $
310 property $ \n' -> do
329 property $ \n' -> do
@@ -313,7 +332,7 @@ spec = do
313 r <-
332 r <-
314 req
333 req
315 GET
334 GET
316− (httpbun /: "bytes" /~ n)
335+ (httpbin /: "bytes" /~ n)
317 NoReqBody
336 NoReqBody
318 lbsResponse
337 lbsResponse
319 mempty
338 mempty
@@ -329,27 +348,36 @@ spec = do
329 n = 1000
348 n = 1000
330 req
349 req
331 GET
350 GET
332− (httpbun /: "bytes" /~ n)
351+ (httpbin /: "bytes" /~ n)
333 NoReqBody
352 NoReqBody
334 (Proxy :: Proxy (JsonResponse Value))
353 (Proxy :: Proxy (JsonResponse Value))
335 mempty
354 mempty
336 `shouldThrow` selector
355 `shouldThrow` selector
337
356
338−-- describe "streaming random bytes" $
357+ describe "streaming random bytes" $
339−-- it "works" $
358+ it "works" $
340−-- property $ \n' -> do
359+ property $ \n' -> do
341−-- let n :: Word
360+ let n :: Word
342−-- n = getSmall n'
361+ n = getSmall n'
343−-- r <-
362+ r <-
344−-- req
363+ req
345−-- GET
364+ GET
346−-- (httpbun /: "stream-bytes" /~ n)
365+ (httpbin /: "stream-bytes" /~ n)
347−-- NoReqBody
366+ NoReqBody
348−-- bsResponse
367+ bsResponse
349−-- mempty
368+ mempty
350−-- responseBody r `shouldSatisfy` ((== n) . fromIntegral . B.length)
369+ responseBody r `shouldSatisfy` ((== n) . fromIntegral . B.length)
351−-- responseStatusCode r `shouldBe` 200
370+ responseStatusCode r `shouldBe` 200
352−-- responseStatusMessage r `shouldBe` "OK"
371+ responseStatusMessage r `shouldBe` "OK"
372+
373+-- TODO /links
374+-- TODO /image
375+-- TODO /image/png
376+-- TODO /image/jpeg
377+-- TODO /image/webp
378+-- TODO /image/svg
379+-- TODO /forms/post
380+-- TODO /xml
353
381
354----------------------------------------------------------------------------
382----------------------------------------------------------------------------
355-- Instances
383-- Instances
@@ -372,9 +400,29 @@ blindlyThrowing = runReq defaultHttpConfig {httpConfigCheckResponse = doit}
372 where
400 where
373 doit _ _ = error "Oops!"
401 doit _ _ = error "Oops!"
374
402
375−-- | 'Url' representing <https://httpbun.org>.
403+-- | 'Url' representing <https://httpbin.org>.
376−httpbun :: Url 'Https
404+httpbin :: Url 'Http
377−httpbun = https "httpbun.org"
405+httpbin = http "localhost"
406+
407+req ::
408+ ( MonadHttp m,
409+ HttpMethod method,
410+ HttpBody body,
411+ HttpResponse response,
412+ HttpBodyAllowed (AllowsBody method) (ProvidesBody body)
413+ ) =>
414+ method ->
415+ Url scheme ->
416+ body ->
417+ Proxy response ->
418+ Option scheme ->
419+ m response
420+req method url body responseProxy options =
421+ Req.req method url body responseProxy (options <> defaultOptions)
422+
423+-- | Options to apply by default.
424+defaultOptions :: Option scheme
425+defaultOptions = port 1234
378
426
379-- | Remove “origin” field from JSON value. Origin may change, we don't want
427-- | Remove “origin” field from JSON value. Origin may change, we don't want
380-- to depend on that.
428-- to depend on that.
@@ -384,21 +432,38 @@ stripOrigin value = value
384
432
385-- | Remove funny headers that might break the tests.
433-- | Remove funny headers that might break the tests.
386stripFunnyHeaders :: Value -> Value
434stripFunnyHeaders :: Value -> Value
387−stripFunnyHeaders (Object m) =
435+stripFunnyHeaders = \case
436+ Object m ->
437+ Object
438+ ( runIdentity
439+ ( Aeson.KeyMap.alterF
440+ (pure . fmap stripFunnyHeaders')
441+ "headers"
442+ m
443+ )
444+ )
445+ value -> value
446+
447+-- | Similar to 'stripFunnyHeaders', but acts directly on the argument
448+-- without trying to access its "headers" field.
449+stripFunnyHeaders' :: Value -> Value
450+stripFunnyHeaders' = \case
451+ Object p ->
452+ Object $
388− let f (Object p) = Object $ Aeson.KeyMap.filterWithKey (\k _ -> k `elem` hs) p
453+ Aeson.KeyMap.filterWithKey
454+ (\k _ -> k `elem` whitelistedHeaders)
455+ p
389− f value = value
456+ value -> value
390− hs =
457+ where
458+ whitelistedHeaders =
391− [ "Content-Type",
459+ [ "Content-Type",
392− "Accept-Encoding",
460+ "Accept-Encoding",
393− "Host",
394− "Content-Length",
461+ "Content-Length",
395− "Foo",
462+ "Foo",
396− "Baz"
463+ "Baz"
397− ]
464+ ]
398− in Object (runIdentity (Aeson.KeyMap.alterF (pure . fmap f) "headers" m))
465+
399−stripFunnyHeaders value = value
400−
401−-- | This is a complete test case that makes use of <https://httpbun.org> to
466+-- | This is a complete test case that makes use of <https://httpbin.org> to
402-- get various response status codes.
467-- get various response status codes.
403checkStatusCode :: Int -> SpecWith ()
468checkStatusCode :: Int -> SpecWith ()
404checkStatusCode code =
469checkStatusCode code =
@@ -408,7 +473,7 @@ checkStatusCode code =
408 prepareForShit $
473 prepareForShit $
409 req
474 req
410 GET
475 GET
411− (httpbun /: "status" /~ code)
476+ (httpbin /: "status" /~ code)
412 NoReqBody
477 NoReqBody
413 ignoreResponse
478 ignoreResponse
414 mempty
479 mempty
httpbun-tests/Spec.hs → httpbin-tests/Spec.hsrenamed

The content is the same.

pure-tests/Network/HTTP/ReqSpec.hs+17−17
@@ -13,41 +13,41 @@
13
13
14module Network.HTTP.ReqSpec (spec) where
14module Network.HTTP.ReqSpec (spec) where
15
15
16−import qualified Blaze.ByteString.Builder as BB
16+import Blaze.ByteString.Builder qualified as BB
17import Control.Exception (throwIO)
17import Control.Exception (throwIO)
18import Control.Monad
18import Control.Monad
19import Control.Retry
19import Control.Retry
20import Data.Aeson (ToJSON (..))
20import Data.Aeson (ToJSON (..))
21−import qualified Data.Aeson as A
21+import Data.Aeson qualified as A
22import Data.ByteString (ByteString)
22import Data.ByteString (ByteString)
23−import qualified Data.ByteString as B
23+import Data.ByteString qualified as B
24−import qualified Data.ByteString.Char8 as B8
24+import Data.ByteString.Char8 qualified as B8
25−import qualified Data.ByteString.Lazy as BL
25+import Data.ByteString.Lazy qualified as BL
26−import qualified Data.CaseInsensitive as CI
26+import Data.CaseInsensitive qualified as CI
27import Data.Either (isRight)
27import Data.Either (isRight)
28−import qualified Data.List.NonEmpty as NE
28+import Data.List.NonEmpty qualified as NE
29import Data.Maybe (fromJust, fromMaybe, isJust, isNothing)
29import Data.Maybe (fromJust, fromMaybe, isJust, isNothing)
30import Data.Proxy
30import Data.Proxy
31import Data.Text (Text)
31import Data.Text (Text)
32−import qualified Data.Text as T
32+import Data.Text qualified as T
33−import qualified Data.Text.Encoding as T
33+import Data.Text.Encoding qualified as T
34import Data.Time
34import Data.Time
35import Data.Typeable (Typeable, eqT)
35import Data.Typeable (Typeable, eqT)
36import GHC.Exts (IsList (..))
36import GHC.Exts (IsList (..))
37import GHC.Generics
37import GHC.Generics
38−import qualified Language.Haskell.TH as TH
38+import Language.Haskell.TH qualified as TH
39−import qualified Language.Haskell.TH.Quote as TH
39+import Language.Haskell.TH.Quote qualified as TH
40−import qualified Network.HTTP.Client as L
40+import Network.HTTP.Client qualified as L
41import Network.HTTP.Req
41import Network.HTTP.Req
42−import qualified Network.HTTP.Types as Y
42+import Network.HTTP.Types qualified as Y
43−import qualified Network.HTTP.Types.Header as Y
43+import Network.HTTP.Types.Header qualified as Y
44import Test.Hspec
44import Test.Hspec
45import Test.Hspec.Core.Spec (SpecM)
45import Test.Hspec.Core.Spec (SpecM)
46import Test.QuickCheck
46import Test.QuickCheck
47import Text.URI (URI)
47import Text.URI (URI)
48−import qualified Text.URI as URI
48+import Text.URI qualified as URI
49−import qualified Text.URI.QQ as QQ
49+import Text.URI.QQ qualified as QQ
50−import qualified Web.FormUrlEncoded as F
50+import Web.FormUrlEncoded qualified as F
51
51
52spec :: Spec
52spec :: Spec
53spec = do
53spec = do
req.cabal+44−45
@@ -1,11 +1,11 @@
1cabal-version: 2.4
1cabal-version: 2.4
2name: req
2name: req
3−version: 3.13.0
3+version: 3.13.4
4license: BSD-3-Clause
4license: BSD-3-Clause
5license-file: LICENSE.md
5license-file: LICENSE.md
6maintainer: Mark Karpov <markkarpov92@gmail.com>
6maintainer: Mark Karpov <markkarpov92@gmail.com>
7author: Mark Karpov <markkarpov92@gmail.com>
7author: Mark Karpov <markkarpov92@gmail.com>
8−tested-with: ghc ==9.0.2 ghc ==9.2.5 ghc ==9.4.4
8+tested-with: ghc ==9.6.3 ghc ==9.8.2 ghc ==9.10.1
9homepage: https://github.com/mrkkrp/req
9homepage: https://github.com/mrkkrp/req
10bug-reports: https://github.com/mrkkrp/req/issues
10bug-reports: https://github.com/mrkkrp/req/issues
11synopsis: HTTP client library
11synopsis: HTTP client library
@@ -13,8 +13,8 @@ description: HTTP client library.
13category: Network, Web
13category: Network, Web
14build-type: Simple
14build-type: Simple
15data-files:
15data-files:
16− httpbun-data/utf8.html
16+ httpbin-data/utf8.html
17− httpbun-data/robots.txt
17+ httpbin-data/robots.txt
18
18
19extra-doc-files:
19extra-doc-files:
20 CHANGELOG.md
20 CHANGELOG.md
@@ -31,98 +31,97 @@ flag dev
31
31
32library
32library
33 exposed-modules: Network.HTTP.Req
33 exposed-modules: Network.HTTP.Req
34− default-language: Haskell2010
34+ default-language: GHC2021
35 build-depends:
35 build-depends:
36 aeson >=0.9 && <3,
36 aeson >=0.9 && <3,
37 authenticate-oauth >=1.5 && <1.8,
37 authenticate-oauth >=1.5 && <1.8,
38− base >=4.15 && <5.0,
38+ base >=4.15 && <5,
39 blaze-builder >=0.3 && <0.5,
39 blaze-builder >=0.3 && <0.5,
40− bytestring >=0.10.8 && <0.12,
40+ bytestring >=0.10.8 && <0.13,
41 case-insensitive >=0.2 && <1.3,
41 case-insensitive >=0.2 && <1.3,
42− containers >=0.5 && <0.7,
42+ containers >=0.5 && <0.8,
43− crypton-connection >=0.2.2 && <0.4,
43+ crypton-connection >=0.4.2 && <0.5,
44+ data-default-class >=0.2.0.0,
44 exceptions >=0.6 && <0.11,
45 exceptions >=0.6 && <0.11,
45− http-api-data >=0.2 && <0.6,
46+ http-api-data >=0.2 && <0.7,
46 http-client >=0.7.13.1 && <0.8,
47 http-client >=0.7.13.1 && <0.8,
47 http-client-tls >=0.3.2 && <0.4,
48 http-client-tls >=0.3.2 && <0.4,
48− http-types >=0.8 && <10.0,
49+ http-types >=0.8 && <10,
49 modern-uri >=0.3 && <0.4,
50 modern-uri >=0.3 && <0.4,
50 monad-control >=1.0 && <1.1,
51 monad-control >=1.0 && <1.1,
51 mtl >=2.0 && <3.0,
52 mtl >=2.0 && <3.0,
52 retry >=0.8 && <0.10,
53 retry >=0.8 && <0.10,
53− template-haskell >=2.14 && <2.20,
54+ template-haskell >=2.19 && <2.23,
54− text >=0.2 && <2.1,
55+ text >=0.2 && <2.2,
55− time >=1.2 && <1.13,
56 transformers >=0.5.3.0 && <0.7,
56 transformers >=0.5.3.0 && <0.7,
57 transformers-base,
57 transformers-base,
58 unliftio-core >=0.1.1 && <0.3
58 unliftio-core >=0.1.1 && <0.3
59
59
60 if flag(dev)
60 if flag(dev)
61− ghc-options: -O0 -Wall -Werror
61+ ghc-options:
62+ -Wall -Werror -Wpartial-fields -Wunused-packages
63+ -Wno-unused-imports
62
64
63 else
65 else
64 ghc-options: -O2 -Wall
66 ghc-options: -O2 -Wall
65
67
66− if flag(dev)
67− ghc-options:
68− -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns
69− -Wnoncanonical-monad-instances
70−
71test-suite pure-tests
68test-suite pure-tests
72 type: exitcode-stdio-1.0
69 type: exitcode-stdio-1.0
73 main-is: Spec.hs
70 main-is: Spec.hs
74− build-tool-depends: hspec-discover:hspec-discover >=2.0 && <3.0
71+ build-tool-depends: hspec-discover:hspec-discover >=2 && <3
75 hs-source-dirs: pure-tests
72 hs-source-dirs: pure-tests
76 other-modules: Network.HTTP.ReqSpec
73 other-modules: Network.HTTP.ReqSpec
77− default-language: Haskell2010
74+ default-language: GHC2021
78 build-depends:
75 build-depends:
79− QuickCheck >=2.7 && <3.0,
76+ QuickCheck >=2.7 && <3,
80 aeson >=0.9 && <3,
77 aeson >=0.9 && <3,
81 base >=4.15 && <5.0,
78 base >=4.15 && <5.0,
82 blaze-builder >=0.3 && <0.5,
79 blaze-builder >=0.3 && <0.5,
83− bytestring >=0.10.8 && <0.12,
80+ bytestring >=0.10.8 && <0.13,
84 case-insensitive >=0.2 && <1.3,
81 case-insensitive >=0.2 && <1.3,
85− hspec >=2.0 && <3.0,
82+ hspec >=2.0 && <3,
86− hspec-core >=2.0 && <3.0,
83+ hspec-core >=2.0 && <3,
87− http-api-data >=0.2 && <0.6,
84+ http-api-data >=0.2 && <0.7,
88 http-client >=0.7 && <0.8,
85 http-client >=0.7 && <0.8,
89− http-types >=0.8 && <10.0,
86+ http-types >=0.8 && <10,
90 modern-uri >=0.3 && <0.4,
87 modern-uri >=0.3 && <0.4,
91− mtl >=2.0 && <3.0,
92 req,
88 req,
93 retry >=0.8 && <0.10,
89 retry >=0.8 && <0.10,
94− template-haskell >=2.14 && <2.20,
90+ template-haskell >=2.19 && <2.23,
95− text >=0.2 && <2.1,
91+ text >=0.2 && <2.2,
96− time >=1.2 && <1.13
92+ time >=1.2 && <1.15
97
93
98 if flag(dev)
94 if flag(dev)
99− ghc-options: -O0 -Wall -Werror
95+ ghc-options:
96+ -Wall -Werror -Wredundant-constraints -Wpartial-fields
97+ -Wunused-packages
100
98
101 else
99 else
102 ghc-options: -O2 -Wall
100 ghc-options: -O2 -Wall
103
101
104−test-suite httpbun-tests
102+test-suite httpbin-tests
105 type: exitcode-stdio-1.0
103 type: exitcode-stdio-1.0
106 main-is: Spec.hs
104 main-is: Spec.hs
107− build-tool-depends: hspec-discover:hspec-discover >=2.0 && <3.0
105+ build-tool-depends: hspec-discover:hspec-discover >=2 && <3
108− hs-source-dirs: httpbun-tests
106+ hs-source-dirs: httpbin-tests
109 other-modules: Network.HTTP.ReqSpec
107 other-modules: Network.HTTP.ReqSpec
110− default-language: Haskell2010
108+ default-language: GHC2021
111 build-depends:
109 build-depends:
112− QuickCheck >=2.7 && <3.0,
110+ QuickCheck >=2.7 && <3,
113 aeson >=2 && <3,
111 aeson >=2 && <3,
114− base >=4.15 && <5.0,
112+ base >=4.15 && <5,
115− bytestring >=0.10.8 && <0.12,
113+ bytestring >=0.10.8 && <0.13,
116 hspec >=2.0 && <3.0,
114 hspec >=2.0 && <3.0,
117 http-client >=0.7 && <0.8,
115 http-client >=0.7 && <0.8,
118− http-types >=0.8 && <10.0,
116+ http-types >=0.8 && <10,
119 monad-control >=1.0 && <1.1,
117 monad-control >=1.0 && <1.1,
120− mtl >=2.0 && <3.0,
121 req,
118 req,
122− text >=0.2 && <2.1
119+ text >=0.2 && <2.2
123
120
124 if flag(dev)
121 if flag(dev)
125− ghc-options: -O0 -Wall -Werror
122+ ghc-options:
123+ -Wall -Werror -Wredundant-constraints -Wpartial-fields
124+ -Wunused-packages
126
125
127 else
126 else
128− ghc-options: -O2 -Wall
127+ buildable: False