packages feed

http-kit 0.3.0 → 0.4.0

raw patch · 5 files changed

+58/−35 lines, 5 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Network.HTTP.Toolkit: UnexpectedEndOfInput :: ToolkitError
+ Network.HTTP.Toolkit.Error: UnexpectedEndOfInput :: ToolkitError
+ Network.HTTP.Toolkit.Error: catchOnly :: (Eq e, Exception e) => IO a -> e -> IO a -> IO a

Files

http-kit.cabal view
@@ -1,5 +1,5 @@ name:             http-kit-version:          0.3.0+version:          0.4.0 synopsis:         A low-level HTTP library description:      A low-level HTTP library that can be used to build more                   sophisticated applications on top of it.
src/Network/HTTP/Toolkit.hs view
@@ -1,6 +1,15 @@ module Network.HTTP.Toolkit (+-- * Exceptions+-- |+-- * All functions that consume input fail with `UnexpectedEndOfInput` if the+--   input ends before the function can completely successfully.+--+-- * All cases where a function may fail with an exception other than+--   @UnexpectedEndOfInput@ are documented thoroughly on a per function level.+--+  ToolkitError(..) -- * Connection-  Connection+, Connection , makeConnection , connectionFromHandle @@ -22,9 +31,6 @@ , BodyReader , sendBody , consumeBody---- * Error type-, ToolkitError(..) ) where  import           Network.HTTP.Toolkit.Body
src/Network/HTTP/Toolkit/Body.hs view
@@ -124,8 +124,9 @@     if done       then return ""       else do-        xs <- connectionRead c-        when (B.null xs) $ writeIORef ref True+        xs <- connectionRead c `catchOnly` UnexpectedEndOfInput $ do+          writeIORef ref True+          return ""         return xs  -- | Create a reader for bodies with a specified length.@@ -158,32 +159,36 @@ makeChunkedReader :: Connection -> IO BodyReader makeChunkedReader conn = do   ref <- newIORef (More 0 Data)-  return $ do-    c <- readIORef ref-    case c of-      More 0 Data -> do-        (n, xs) <- readChunkSize conn-        writeIORef ref (More n Extension)-        return xs-      More n Extension -> do-        bs <- connectionRead conn-        case breakOnNewline bs of-          ("", _) ->-            if n > 0-              then do-                handleChunkData ref (n + 3) bs-              else do-                writeIORef ref Trailer-                connectionUnread conn bs-                readTrailer ref-          (xs, ys) -> do-            connectionUnread conn ys-            return xs-      More n Data -> do-        connectionRead conn >>= handleChunkData ref n-      Trailer -> readTrailer ref-      Done -> return ""+  return $ go ref `catchOnly` UnexpectedEndOfInput $ do+    writeIORef ref Done+    return ""   where+    go ref = do+      c <- readIORef ref+      case c of+        More 0 Data -> do+          (n, xs) <- readChunkSize conn+          writeIORef ref (More n Extension)+          return xs+        More n Extension -> do+          bs <- connectionRead conn+          case breakOnNewline bs of+            ("", _) ->+              if n > 0+                then do+                  handleChunkData ref (n + 3) bs+                else do+                  writeIORef ref Trailer+                  connectionUnread conn bs+                  readTrailer ref+            (xs, ys) -> do+              connectionUnread conn ys+              return xs+        More n Data -> do+          connectionRead conn >>= handleChunkData ref n+        Trailer -> readTrailer ref+        Done -> return ""+     handleChunkData :: IORef State -> Int -> ByteString -> IO ByteString     handleChunkData ref n bs = do       let (xs, ys) = B.splitAt n bs
src/Network/HTTP/Toolkit/Connection.hs view
@@ -8,12 +8,15 @@ ) where  import           Prelude hiding (read)-import           Control.Monad (join, unless)+import           Control.Monad (join, when, unless)+import           Control.Exception import           System.IO (Handle) import           Data.IORef import           Data.ByteString (ByteString) import qualified Data.ByteString as B +import           Network.HTTP.Toolkit.Error+ -- | An abstract connection type that allows to read and unread input. data Connection = Connection {   _read :: IO ByteString@@ -37,7 +40,10 @@  -- | Read some input. connectionRead :: Connection -> IO ByteString-connectionRead = _read+connectionRead c = do+  bs <- _read c+  when (B.null bs) $ throwIO UnexpectedEndOfInput+  return bs  -- | Push back some input.  The pushed back input will be returned by a later -- call to `connectionRead`.
src/Network/HTTP/Toolkit/Error.hs view
@@ -2,12 +2,15 @@ module Network.HTTP.Toolkit.Error where  import           Data.Typeable+import           Control.Monad (guard) import           Control.Exception import           Data.ByteString (ByteString)  data ToolkitError =+    -- | The input ended unpexpectedly while reading a message.+    UnexpectedEndOfInput     -- | The request-line of the message is malformed.-    InvalidRequestLine ByteString+  | InvalidRequestLine ByteString     -- | The status-line of the message is malformed.   | InvalidStatusLine ByteString     -- | A header field is malformed.@@ -23,3 +26,6 @@   deriving (Eq, Show, Typeable)  instance Exception ToolkitError++catchOnly :: (Eq e, Exception e) => IO a -> e -> IO a -> IO a+(action `catchOnly` e) handler = catchJust (guard . (== e)) action $ \() -> handler