packages feed

ihttp 0.1.0 → 0.2.0

raw patch · 9 files changed

+194/−21 lines, 9 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Network.IHttp.Header: enumHeaders :: Monad m => HeaderMap -> Enumerator ByteString m b
+ Network.IHttp.Request: enumRequest :: Monad m => Request -> Enumerator ByteString m b
+ Network.IHttp.Request: enumRequestLine :: Monad m => HttpMethod -> ByteString -> HttpVersion -> Enumerator ByteString m b
+ Network.IHttp.Response: enumResponse :: Monad m => Response -> Enumerator ByteString m b
+ Network.IHttp.Response: enumResponseLine :: Monad m => HttpVersion -> Int -> ByteString -> Enumerator ByteString m b
+ Network.IHttp.Tools: iterFinally :: Monad m => Iteratee a m b -> Iteratee a m c -> Iteratee a m b
+ Network.IHttp.Tools: iterTry :: MonadIO m => IO b -> Iteratee a m b
+ Network.IHttp.Tools: showMethod :: HttpMethod -> ByteString
+ Network.IHttp.Tools: showVersion :: HttpVersion -> ByteString

Files

Network/IHttp.hs view
@@ -3,7 +3,7 @@ -- Copyright:  (c) 2010 Ertugrul Soeylemez -- License:    BSD3 -- Maintainer: Ertugrul Soeylemez <es@ertes.de>--- Stability:  experimental+-- Stability:  beta -- -- Convenience module for the ihttp library. 
Network/IHttp/Header.hs view
@@ -3,7 +3,7 @@ -- Copyright:  (c) 2010 Ertugrul Soeylemez -- License:    BSD3 -- Maintainer: Ertugrul Soeylemez <es@ertes.de>--- Stability:  experimental+-- Stability:  beta -- -- Iteratees for header parsing. @@ -12,7 +12,10 @@ module Network.IHttp.Header     ( -- * Iteratees       httpHeader,-      httpHeaders+      httpHeaders,++      -- * Enumerators+      enumHeaders     )     where @@ -26,6 +29,22 @@ import Network.IHttp.Parsers import Network.IHttp.Tools import Network.IHttp.Types+++-- | Enumerate a 'HeaderMap' as a protocol string stream.  You can use+-- 'Data.Enumerator.Binary.iterHandle' to send it.  Note that this+-- enumerator never generates continuation lines.  It also does not+-- enumerate the final empty line.++enumHeaders :: forall b m. Monad m => HeaderMap -> Enumerator ByteString m b+enumHeaders headers = enum+    where+    format :: ByteString -> ByteString -> [ByteString] -> [ByteString]+    format header content rest = header : ": " : content : "\r\n" : rest++    enum :: Enumerator ByteString m b+    enum (Continue k) = k (Chunks . M.foldrWithKey format [] $ headers)+    enum step         = returnI step   -- | Get the next header from the 'netLinesEmpty'-splitted stream.  The
Network/IHttp/Parsers.hs view
@@ -3,7 +3,7 @@ -- Copyright:  (c) 2010 Ertugrul Soeylemez -- License:    BSD3 -- Maintainer: Ertugrul Soeylemez <es@ertes.de>--- Stability:  experimental+-- Stability:  beta -- -- HTTP parsers. 
Network/IHttp/Request.hs view
@@ -3,17 +3,24 @@ -- Copyright:  (c) 2010 Ertugrul Soeylemez -- License:    BSD3 -- Maintainer: Ertugrul Soeylemez <es@ertes.de>--- Stability:  experimental+-- Stability:  beta -- -- Iteratees for requests. +{-# LANGUAGE OverloadedStrings, ScopedTypeVariables #-}+ module Network.IHttp.Request     ( -- * Iteratees       request,-      requestLine+      requestLine,++      -- * Enumerators+      enumRequest,+      enumRequestLine     )     where +import qualified Data.ByteString as B import Data.ByteString (ByteString) import Data.Enumerator as E import Data.Enumerator.List as EL@@ -21,6 +28,43 @@ import Network.IHttp.Parsers import Network.IHttp.Tools import Network.IHttp.Types+++-- | Enumerate a complete request as a protocol string stream.  You can+-- use 'Data.Enumerator.Binary.iterHandle' to send it.++enumRequest :: forall b m. Monad m => Request -> Enumerator ByteString m b+enumRequest req =+    E.concatEnums [ enumRequestLine (requestMethod req)+                                    (requestUri req)+                                    (requestVersion req),+                    enumHeaders (requestHeaders req),+                    emptyLine ]++    where+    emptyLine :: Enumerator ByteString m b+    emptyLine (Continue k) = k (Chunks ["\r\n"])+    emptyLine step = returnI step+++-- | Enumerate a request line with the given method, URI and HTTP+-- version as a protocol string stream.  You can use+-- 'Data.Enumerator.Binary.iterHandle' to send it.++enumRequestLine ::+    forall b m. Monad m =>+    HttpMethod -> ByteString -> HttpVersion -> Enumerator ByteString m b+enumRequestLine method uri version = enum+    where+    enum :: Enumerator ByteString m b+    enum (Continue k) = k (Chunks reqChunks)+    enum step         = returnI step++    reqChunks :: [ByteString]+    reqChunks = [ showMethod method, space, uri, space,+                  showVersion version, "\r\n" ]+        where+        space = B.singleton 32   -- | Get the next full request from a 'netLinesEmpty'-splitted byte
Network/IHttp/Response.hs view
@@ -3,17 +3,25 @@ -- Copyright:  (c) 2010 Ertugrul Soeylemez -- License:    BSD3 -- Maintainer: Ertugrul Soeylemez <es@ertes.de>--- Stability:  experimental+-- Stability:  beta -- -- Iteratees for response. +{-# LANGUAGE OverloadedStrings, ScopedTypeVariables #-}+ module Network.IHttp.Response     ( -- * Iteratees       response,-      responseLine+      responseLine,++      -- * Enumerators+      enumResponse,+      enumResponseLine     )     where +import qualified Data.ByteString as B+import qualified Data.ByteString.Char8 as BC import Data.ByteString (ByteString) import Data.Enumerator as E import Data.Enumerator.List as EL@@ -21,6 +29,53 @@ import Network.IHttp.Parsers import Network.IHttp.Tools import Network.IHttp.Types+++-- | Enumerate a complete response as a protocol string stream.  You can+-- use 'Data.Enumerator.Binary.iterHandle' to send it.++enumResponse :: forall b m. Monad m => Response -> Enumerator ByteString m b+enumResponse resp =+    E.concatEnums [ enumResponseLine (responseVersion resp)+                                     (responseCode resp)+                                     (responseMessage resp),+                    enumHeaders (responseHeaders resp),+                    emptyLine ]++    where+    emptyLine :: Enumerator ByteString m b+    emptyLine (Continue k) = k (Chunks ["\r\n"])+    emptyLine step = returnI step+++-- | Enumerate a response line with the given HTTP version, response+-- code and message as a protocol string stream.  You can use+-- 'Data.Enumerator.Binary.iterHandle' to send it.++enumResponseLine ::+    forall b m. Monad m =>+    HttpVersion -> Int -> ByteString -> Enumerator ByteString m b+enumResponseLine version code msg = enum+    where+    enum :: Enumerator ByteString m b+    enum (Continue k) = k (Chunks respChunks)+    enum step         = returnI step++    respChunks :: [ByteString]+    respChunks =+        let space = B.singleton 32 in+        [ showVersion version, space, intStr code, space, msg, "\r\n" ]++    intStr :: Int -> ByteString+    intStr n | n < 0 = BC.cons '-' (intStr (negate n))+    intStr 0 = BC.singleton '0'+    intStr n = intStr' B.empty n+        where+        intStr' :: ByteString -> Int -> ByteString+        intStr' str 0 = str+        intStr' str n =+            let (q,r) = quotRem n 10 in+            intStr' (B.cons (fromIntegral r + 48) str) q   -- | Get the next full response from a 'netLinesEmpty'-splitted byte
Network/IHttp/Simple.hs view
@@ -3,7 +3,7 @@ -- Copyright:  (c) 2010 Ertugrul Soeylemez -- License:    BSD3 -- Maintainer: Ertugrul Soeylemez <es@ertes.de>--- Stability:  experimental+-- Stability:  beta -- -- Simple interface to the HTTP iteratees. 
Network/IHttp/Tools.hs view
@@ -3,28 +3,39 @@ -- Copyright:  (c) 2010 Ertugrul Soeylemez -- License:    BSD3 -- Maintainer: Ertugrul Soeylemez <es@ertes.de>--- Stability:  experimental+-- Stability:  beta -- -- Enumeratees and other tools. -{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE OverloadedStrings, ScopedTypeVariables #-}  module Network.IHttp.Tools-    ( -- * Character tools-      asciiToUpper,--      -- * Parser tools+    ( -- * Parser tools       parseIter,-      parseFull+      parseFull,++      -- * Iteratee tools+      iterFinally,+      iterTry,++      -- * Printing tools+      showMethod,+      showVersion,++      -- * Character tools+      asciiToUpper     )     where +import Control.ContStuff import Control.Exception as Ex import Data.Attoparsec.Char8 as P import Data.ByteString as B+import Data.ByteString.Char8 () import Data.Char import Data.Enumerator as E import Data.List as L+import Network.IHttp.Types import Text.Printf  @@ -36,11 +47,33 @@     | otherwise            = c  +-- | Runs the first computation and then the second, even if the first+-- one throws an exception.  'Iteratee' version of 'Ex.finally'.++iterFinally :: Monad m => Iteratee a m b -> Iteratee a m c -> Iteratee a m b+iterFinally c d = do+    mRes <- catchError (Right <$> c) (return . Left)+    case mRes of+      Left err  -> d >> throwError err+      Right res -> res <$ d+++-- | Try the given 'IO' computation and turn IO exceptions into iteratee+-- exceptions ('Error').++iterTry :: MonadIO m => IO b -> Iteratee a m b+iterTry c = do+    mRes <- liftIO (Ex.try c)+    case mRes of+      Left err  -> throwError (err :: Ex.SomeException)+      Right res -> return res++ -- | Fully parse a string with the given parser.  Throw an iteratee -- error with the given error constructor, if it fails.  parseIter ::-    (Exception ex, Monad m) =>+    (Ex.Exception ex, Monad m) =>     Parser b -> (String -> ex) -> ByteString -> Iteratee a m b parseIter parser ex str =     case parseFull parser str of@@ -55,7 +88,29 @@     loop (parse parser str)      where-    loop :: Result a -> Either String a+    loop :: P.Result a -> Either String a     loop (Fail _ ctxs msg) = Left (printf "%s (%s)" (L.intercalate ": " ctxs) msg)     loop (Partial k)       = loop (k B.empty)     loop (Done _ res)      = Right res+++-- | Turn a method into its corresponding HTTP string.++showMethod :: HttpMethod -> ByteString+showMethod ConnectMethod = "CONNECT"+showMethod DeleteMethod  = "DELETE"+showMethod GetMethod     = "GET"+showMethod HeadMethod    = "HEAD"+showMethod OptionsMethod = "OPTIONS"+showMethod PatchMethod   = "PATCH"+showMethod PostMethod    = "POST"+showMethod PutMethod     = "PUT"+showMethod TraceMethod   = "TRACE"+showMethod (XMethod str) = str+++-- | Turn an HTTP version into its corresponding HTTP string.++showVersion :: HttpVersion -> ByteString+showVersion Http1_0 = "HTTP/1.0"+showVersion Http1_1 = "HTTP/1.1"
Network/IHttp/Types.hs view
@@ -3,7 +3,7 @@ -- Copyright:  (c) 2010 Ertugrul Soeylemez -- License:    BSD3 -- Maintainer: Ertugrul Soeylemez <es@ertes.de>--- Stability:  experimental+-- Stability:  beta -- -- Types for ihttp. 
ihttp.cabal view
@@ -1,5 +1,5 @@ Name:          ihttp-Version:       0.1.0+Version:       0.2.0 Category:      Network Synopsis:      Incremental HTTP iteratee Maintainer:    Ertugrul Söylemez <es@ertes.de>@@ -8,7 +8,7 @@ License:       BSD3 License-file:  LICENSE Build-type:    Simple-Stability:     experimental+Stability:     beta Cabal-version: >= 1.6 Description: