packages feed

http-enumerator 0.7.1.2 → 0.7.1.3

raw patch · 2 files changed

+74/−32 lines, 2 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

Network/HTTP/Enumerator.hs view
@@ -110,6 +110,7 @@     ( Iteratee (..), Stream (..), catchError, throwError     , yield, Step (..), Enumeratee, ($$), joinI, Enumerator, run_     , returnI, (>==>), (>>==), continue, checkDone, enumEOF+    , (=$)     ) import qualified Data.Enumerator.List as EL import Network.HTTP.Enumerator.HttpParser@@ -140,6 +141,7 @@ import Blaze.ByteString.Builder (toByteString) import Data.Maybe (fromMaybe) import Data.Default (Default (def))+import Numeric (showHex) #if !MIN_VERSION_base(4,3,0) import GHC.IO.Handle.Types import System.IO                (hWaitForInput, hIsEOF)@@ -400,8 +402,8 @@      -> (W.Status -> W.ResponseHeaders -> Iteratee S.ByteString m a)      -> Manager      -> Iteratee S.ByteString m a-http Request {..} bodyStep m = do-    withConn m connhost connport requestEnum $$ go+http req@(Request {..}) bodyStep m =+    withConn m connhost connport requestEnum $$ getResponse req bodyStep   where     (useProxy, connhost, connport) =         case proxy of@@ -455,36 +457,54 @@                 `mappend` Blaze.fromByteString "\r\n")             `mappend` Blaze.fromByteString "\r\n"     requestEnum = enumSingle requestHeaders' >==> bodyEnum-    go = do-        ((_, sc, sm), hs) <- iterHeaders-        let s = W.Status sc sm-        let hs' = map (first CI.mk) hs-        let mcl = lookup "content-length" hs'-        let body' x =-                if not rawBody && ("transfer-encoding", "chunked") `elem` hs'-                    then joinI $ chunkedEnumeratee $$ x-                    else case mcl >>= readMay . S8.unpack of-                        Just len -> joinI $ takeLBS len $$ x-                        Nothing -> x-        let decompresser x =-                if not rawBody-                        && ("content-encoding", "gzip") `elem` hs'-                        && decompress (fromMaybe "" $ lookup "content-type" hs')-                    then joinI $ Z.ungzip x-                    else returnI x-        -- RFC 2616 section 4.4_1 defines responses that must not include a body-        res <--            if method == "HEAD" || sc == 204 -- No Content-                                || sc == 304 -- Not Modified-                                || (sc < 200 && sc >= 100)-                then enumEOF $$ bodyStep s hs'-                else body' $ decompresser $$ do-                        x <- bodyStep s hs'-                        flushStream-                        return x-        let toPut = Just "close" /= lookup "connection" hs'-        return (toPut, res) +getResponse :: MonadIO m+            => Request m+            -> (W.Status -> [W.Header] -> Iteratee S8.ByteString m a)+            -> Iteratee S8.ByteString m (Bool, a)+getResponse Request {..} bodyStep = do+    ((_, sc, sm), hs) <- iterHeaders+    let s = W.Status sc sm+    let hs' = map (first CI.mk) hs+    let mcl = lookup "content-length" hs'+    let body' =+            case (rawBody, ("transfer-encoding", "chunked") `elem` hs') of+                (False, True) -> (chunkedEnumeratee =$)+                (True , True) -> (chunkedTerminator =$)+                (_    , False) -> case mcl >>= readMay . S8.unpack of+                                      Just len -> (takeLBS len =$)+                                      Nothing  -> id+    let decompresser =+            if needsGunzip hs'+                then (Z.ungzip =$)+                else id+    -- RFC 2616 section 4.4_1 defines responses that must not include a body+    res <-+        if hasNoBody method sc+            then enumEOF $$ bodyStep s hs'+            else body' $ decompresser $ do+                    x <- bodyStep s hs'+                    flushStream+                    return x++    -- should we put this connection back into the connection manager?+    let toPut = Just "close" /= lookup "connection" hs'+    return (toPut, res)+  where+    hasNoBody :: S8.ByteString -- ^ request method+              -> Int -- ^ status code+              -> Bool+    hasNoBody "HEAD" _ = True+    hasNoBody _ 204 = True+    hasNoBody _ 304 = True+    hasNoBody _ i = 100 <= i && i < 200++    needsGunzip :: [W.Header] -> Bool+    needsGunzip hs' =+            not rawBody+         && ("content-encoding", "gzip") `elem` hs'+         && decompress (fromMaybe "" $ lookup "content-type" hs')+ flushStream :: Monad m => Iteratee a m () flushStream = do     x <- EL.head@@ -502,6 +522,28 @@             catchParser "End of chunk newline" iterNewline             chunkedEnumeratee k' chunkedEnumeratee step = return step++chunkedTerminator :: MonadIO m => Enumeratee S.ByteString S.ByteString m a+chunkedTerminator (Continue k) = do+    len <- catchParser "Chunk header" iterChunkHeader+    k' <- sendCont k $ S8.pack $ showHex len "\r\n"+    if len == 0+        then return k'+        else do+            step <- takeLBS len k'+            catchParser "End of chunk newline" iterNewline+            case step of+                Continue k'' -> do+                    k''' <- sendCont k'' "\r\n"+                    chunkedTerminator k'''+                _ -> return step+chunkedTerminator step = return step++sendCont :: Monad m+         => (Stream S8.ByteString -> Iteratee S8.ByteString m a)+         -> S8.ByteString+         -> Iteratee S8.ByteString m (Step S8.ByteString m a)+sendCont k bs = lift $ runIteratee $ k $ Chunks [bs]  chunkIt :: Monad m => Enumeratee Blaze.Builder Blaze.Builder m a chunkIt = checkDone $ continue . step
http-enumerator.cabal view
@@ -1,5 +1,5 @@ name:            http-enumerator-version:         0.7.1.2+version:         0.7.1.3 license:         BSD3 license-file:    LICENSE author:          Michael Snoyman <michael@snoyman.com>