pipes-http (empty) → 1.0.0
raw patch · 4 files changed
+183/−0 lines, 4 filesdep +basedep +bytestringdep +http-clientsetup-changed
Dependencies added: base, bytestring, http-client, http-client-tls, pipes
Files
- LICENSE +24/−0
- Setup.hs +2/−0
- pipes-http.cabal +27/−0
- src/Pipes/HTTP.hs +130/−0
+ LICENSE view
@@ -0,0 +1,24 @@+Copyright (c) 2014 Gabriel Gonzalez+All rights reserved.++Redistribution and use in source and binary forms, with or without modification,+are permitted provided that the following conditions are met:+ * Redistributions of source code must retain the above copyright notice,+ this list of conditions and the following disclaimer.+ * Redistributions in binary form must reproduce the above copyright notice,+ this list of conditions and the following disclaimer in the documentation+ and/or other materials provided with the distribution.+ * Neither the name of Gabriel Gonzalez nor the names of other contributors+ may be used to endorse or promote products derived from this software+ without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ pipes-http.cabal view
@@ -0,0 +1,27 @@+Name: pipes-http+Version: 1.0.0+Cabal-Version: >=1.8.0.2+Build-Type: Simple+License: BSD3+License-File: LICENSE+Copyright: 2014 Gabriel Gonzalez+Author: Gabriel Gonzalez+Maintainer: Gabriel439@gmail.com+Bug-Reports: https://github.com/Gabriel439/Haskell-Pipes-HTTP-Client-Library/issues+Synopsis: HTTP client with pipes interface+Description: @pipes-http@ is a @pipes@ wrapper around the @http-client@ library+Category: Pipes, Web+Source-Repository head+ Type: git+ Location: https://github.com/Gabriel439/Haskell-Pipes-HTTP-Library++Library+ HS-Source-Dirs: src+ Build-Depends:+ base >= 4 && < 5 ,+ bytestring >= 0.9.2.1 && < 0.11,+ pipes >= 4.0 && < 4.2 ,+ http-client >= 0.2 && < 0.3 ,+ http-client-tls < 0.3+ Exposed-Modules: Pipes.HTTP+ GHC-Options: -O2 -Wall
+ src/Pipes/HTTP.hs view
@@ -0,0 +1,130 @@+-- | Here is an example GET request that streams the response body to standard+-- output:+--+-- > import Pipes+-- > import Pipes.HTTP+-- > import qualified Pipes.ByteString as PB -- from `pipes-bytestring`+-- >+-- > main = do+-- > req <- parseUrl "https://www.example.com"+-- > withManager tlsManagerSettings $ \m ->+-- > withHTTP req m $ \resp ->+-- > runEffect $ responseBody resp >-> PB.stdout+--+-- Here is an example POST request that also streams the request body from+-- standard input:+--+-- > {-# LANGUAGE OverloadedStrings #-}+-- >+-- > import Pipes+-- > import Pipes.HTTP+-- > import qualified Pipes.ByteString as PB+-- >+-- > main = do+-- > req <- parseUrl "https://www.example.com"+-- > let req' = req+-- > { method = "POST"+-- > , requestBody = stream PB.stdin+-- > }+-- > withManager tlsManagerSettings $ \m ->+-- > withHTTP req' m $ \resp ->+-- > runEffect $ responseBody resp >-> PB.stdout+--+-- For non-streaming request bodies, study the 'RequestBody' type, which also+-- accepts strict \/ lazy bytestrings or builders.+++module Pipes.HTTP (+ -- * http-client+ -- $httpclient+ module Network.HTTP.Client+ , module Network.HTTP.Client.TLS++ -- * Pipes Interface+ , withHTTP+ , streamN+ , stream++ ) where++import Control.Monad (unless)+import Data.ByteString (ByteString)+import qualified Data.ByteString as B+import Data.Int (Int64)+import Data.IORef (newIORef, readIORef, writeIORef)+import Network.HTTP.Client+import Network.HTTP.Client.TLS+import Pipes++{- $httpclient+ This module is a thin @pipes@ wrapper around the @http-client@ and+ @http-client-tls@ libraries.++ Read the documentation in the "Network.HTTP.Client" module of the+ @http-client@ library to learn about how to:++ * manage connections using connection pooling,++ * use more advanced request\/response features,++ * handle exceptions, and:++ * manage cookies.++ @http-client-tls@ provides support for TLS connections (i.e. HTTPS).+-}++-- | Send an HTTP 'Request' and wait for an HTTP 'Response'+withHTTP+ :: Request+ -- ^+ -> Manager+ -- ^+ -> (Response (Producer ByteString IO ()) -> IO a)+ -- ^ Handler for response+ -> IO a+withHTTP r m k = withResponse r m k'+ where+ k' resp = do+ let p = (from . brRead . responseBody) resp+ k (resp { responseBody = p})+{-# INLINABLE withHTTP #-}++-- | Create a 'RequestBody' from a content length and 'Producer'+streamN :: Int64 -> Producer ByteString IO () -> RequestBody+streamN n p = RequestBodyStream n (to p)+{-# INLINABLE streamN #-}++{-| Create a 'RequestBody' from a 'Producer'++ 'stream' is more flexible than 'streamN', but requires the server to support+ chunked transfer encoding.+-}+stream :: Producer ByteString IO () -> RequestBody+stream p = RequestBodyStreamChunked (to p)+{-# INLINABLE stream #-}++to :: Producer ByteString IO () -> (IO ByteString -> IO ()) -> IO ()+to p0 k = do+ ioref <- newIORef p0+ let readAction :: IO ByteString+ readAction = do+ p <- readIORef ioref+ x <- next p+ case x of+ Left () -> do+ writeIORef ioref (return ())+ return B.empty+ Right (bs, p') -> do+ writeIORef ioref p'+ return bs+ k readAction ++from :: IO ByteString -> Producer ByteString IO ()+from io = go+ where+ go = do+ bs <- lift io+ unless (B.null bs) $ do+ yield bs+ go