request 0.2.2.0 → 0.2.3.0
raw patch · 4 files changed
+94/−41 lines, 4 filesdep +hspecdep +requestdep ~basedep ~bytestring
Dependencies added: hspec, request
Dependency ranges changed: base, bytestring
Files
- LICENSE +1/−1
- request.cabal +12/−3
- src/Network/HTTP/Request.hs +52/−37
- test/Spec.hs +29/−0
LICENSE view
@@ -1,4 +1,4 @@-Copyright An Long (c) 2021+Copyright AN Long (c) 2021 All rights reserved.
request.cabal view
@@ -1,5 +1,5 @@ name: request-version: 0.2.2.0+version: 0.2.3.0 -- synopsis: description: "HTTP client for haskell, inpired by requests and http-dispatch." homepage: https://github.com/aisk/request#readme@@ -7,7 +7,7 @@ license-file: LICENSE author: An Long maintainer: aisk1988@gmail.com-copyright: 2020 An Long+copyright: 2020 AN Long category: Web build-type: Simple extra-source-files: README.md@@ -17,7 +17,7 @@ hs-source-dirs: src exposed-modules: Network.HTTP.Request build-depends: base >= 4.7 && < 5- , bytestring >= 0.10.12 && < 0.12+ , bytestring >= 0.10.12 && < 0.13 , case-insensitive >= 1.2.1 && < 1.3 , http-client >= 0.6.4 && < 0.8 , http-types >= 0.12.3 && < 0.13@@ -27,3 +27,12 @@ source-repository head type: git location: https://github.com/aisk/request++test-suite spec+ type: exitcode-stdio-1.0+ hs-source-dirs: test+ main-is: Spec.hs+ build-depends: base+ , request+ , hspec+ default-language: Haskell2010
src/Network/HTTP/Request.hs view
@@ -1,26 +1,27 @@-{-# LANGUAGE DatatypeContexts #-} {-# LANGUAGE OverloadedStrings #-} module Network.HTTP.Request- ( Header- , Headers- , Method (..)- , Request (..)- , Response (..)- , get- , post- , put- , send- ) where+ ( Header,+ Headers,+ Method (..),+ Request (..),+ Response (..),+ get,+ patch,+ post,+ put,+ send,+ )+where -import qualified Data.String as S-import qualified Data.ByteString as BS-import qualified Data.ByteString.Char8 as C-import qualified Data.ByteString.Lazy as LBS-import qualified Data.CaseInsensitive as CI-import qualified Data.List as List-import qualified Network.HTTP.Client as LowLevelClient-import qualified Network.HTTP.Client.TLS as LowLevelTLSClient+import qualified Data.ByteString as BS+import qualified Data.ByteString.Char8 as C+import qualified Data.ByteString.Lazy as LBS+import qualified Data.CaseInsensitive as CI+import qualified Data.List as List+import qualified Data.String as S+import qualified Network.HTTP.Client as LowLevelClient+import qualified Network.HTTP.Client.TLS as LowLevelTLSClient import qualified Network.HTTP.Types.Status as LowLevelStatus type Header = (BS.ByteString, BS.ByteString)@@ -39,6 +40,7 @@ | Method String instance Show Method where+ show DELETE = "DELETE" show GET = "GET" show HEAD = "HEAD" show OPTIONS = "OPTIONS"@@ -48,36 +50,45 @@ show TRACE = "TRACE" show (Method method) = method -data (S.IsString a) => Request a = Request- { requestMethod :: Method- , requestUrl :: String- , requestHeaders :: Headers- , requestBody :: Maybe a- } deriving (Show)+data Request a = Request+ { requestMethod :: Method,+ requestUrl :: String,+ requestHeaders :: Headers,+ requestBody :: Maybe a+ }+ deriving (Show) toLowlevelRequest :: (S.IsString a) => Request a -> IO LowLevelClient.Request toLowlevelRequest req = do initReq <- LowLevelClient.parseRequest $ requestUrl req- return $ initReq { LowLevelClient.method = C.pack . show $ requestMethod req- , LowLevelClient.requestHeaders = map (\(k, v) -> (CI.mk k, v)) $ requestHeaders req- }+ return $+ initReq+ { LowLevelClient.method = C.pack . show $ requestMethod req,+ LowLevelClient.requestHeaders = map (\(k, v) -> (CI.mk k, v)) $ requestHeaders req+ } data Response = Response- { responseStatus :: Int- , responseHeaders :: Headers- , responseBody :: BS.ByteString- } deriving (Show)+ { responseStatus :: Int,+ responseHeaders :: Headers,+ responseBody :: BS.ByteString+ }+ deriving (Show) fromLowLevelRequest :: LowLevelClient.Response LBS.ByteString -> Response fromLowLevelRequest res = let status = LowLevelStatus.statusCode . LowLevelClient.responseStatus $ res body = LBS.toStrict $ LowLevelClient.responseBody res headers = LowLevelClient.responseHeaders res- in- Response status (map (\(k,v) ->- let hk = CI.original k- in- (hk, v)) headers) body+ in Response+ status+ ( map+ ( \(k, v) ->+ let hk = CI.original k+ in (hk, v)+ )+ headers+ )+ body send :: (S.IsString a) => Request a -> IO Response send req = do@@ -101,3 +112,7 @@ put :: (String, Maybe BS.ByteString) -> IO Response put (url, body) = send $ Request PUT url [] body++patch :: (String, Maybe BS.ByteString) -> IO Response+patch (url, body) =+ send $ Request PATCH url [] body
+ test/Spec.hs view
@@ -0,0 +1,29 @@+{-# LANGUAGE OverloadedStrings #-}++module Main where++import Network.HTTP.Request+import Test.Hspec++main :: IO ()+main = hspec $ do+ describe "Network.HTTP.Request" $ do+ it "should fetch example.com and return 200 OK" $ do+ response <- get "http://example.com"+ responseStatus response `shouldBe` 200++ it "should send a request to example.com and return 200 OK" $ do+ response <- send (Request GET "http://example.com" [] Nothing)+ responseStatus response `shouldBe` 200++ it "should post to httpbin.org/post and return 200 OK" $ do+ response <- post ("https://postman-echo.com/post", Just "Hello!")+ responseStatus response `shouldBe` 200++ it "should put to httpbin.org/put and return 200 OK" $ do+ response <- put ("https://postman-echo.com/put", Just "Hello!")+ responseStatus response `shouldBe` 200++ it "should patch to httpbin.org/patch and return 200 OK" $ do+ response <- patch ("https://postman-echo.com/patch", Just "Hello!")+ responseStatus response `shouldBe` 200