packages feed

http-conduit 1.9.0 → 1.9.1

raw patch · 5 files changed

+40/−16 lines, 5 files

Files

Network/HTTP/Conduit.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE CPP #-}+{-# LANGUAGE ScopedTypeVariables #-} -- | This module contains everything you need to initiate HTTP connections.  If -- you want a simple interface based on URLs, you can use 'simpleHttp'. If you -- want raw power, 'http' is the underlying workhorse of this package. Some@@ -189,7 +190,7 @@ import qualified Network.HTTP.Types as W import Data.Default (def) -import Control.Exception.Lifted (throwIO, try, IOException, handle)+import Control.Exception.Lifted (throwIO, try, IOException, handle, fromException) import Control.Monad ((<=<)) import Control.Monad.IO.Class (MonadIO (liftIO)) import Control.Monad.Trans.Resource@@ -297,17 +298,18 @@     -- not on calling @getResponse@. However, some servers seem to close     -- connections after accepting the request headers, so we need to check for     -- exceptions in both.-    ex <- try' $ do+    ex <- try $ do         requestBuilder req C.$$ builderToByteString C.=$ connSink ci+         getResponse connRelease timeout' req src      case (ex, isManaged) of-        -- Connection was reused, and might be been closed. Try again-        (Left _, Reused) -> do+        -- Connection was reused, and might have been closed. Try again+        (Left e, Reused) | isRetryableException e -> do             connRelease DontReuse             http req m-        -- Not reused, so this is a real exception-        (Left e, Fresh) -> liftIO $ throwIO e+        -- Not reused, or a non-retry, so this is a real exception+        (Left e, _) -> liftIO $ throwIO e         -- Everything went ok, so the connection is good. If any exceptions get         -- thrown in the response body, just throw them as normal.         (Right res, _) -> case cookieJar req' of@@ -317,8 +319,23 @@                 return $ res {responseCookieJar = cookie_jar}             Nothing -> return res   where-    try' :: MonadBaseControl IO m => m a -> m (Either IOException a)-    try' = try++    -- Exceptions for which we should retry our request if we were reusing an+    -- already open connection. In the case of IOExceptions, for example, we+    -- assume that the connection was closed on the server and therefore open a+    -- new one.+    isRetryableException e =+        case fromException e of+            Just (_ :: IOException) -> True+            _ ->+                case fromException e of+                    -- Note: Some servers will timeout connections by accepting+                    -- the incoming packets for the new request, but closing+                    -- the connection as soon as we try to read. To make sure+                    -- we open a new connection under these circumstances, we+                    -- check for the NoResponseDataReceived exception.+                    Just NoResponseDataReceived -> True+                    _ -> False  -- | Download the specified 'Request', returning the results as a 'Response'. --
Network/HTTP/Conduit/Parser.hs view
@@ -31,6 +31,13 @@     return (status, headers)   where     getStatusLine = do+        -- Ensure that there is some data coming in. If not, we want to signal+        -- this as a connection problem and not a protocol problem.+        mx <- CL.peek+        case mx of+            Nothing -> monadThrow NoResponseDataReceived+            Just _ -> return ()+         status@(_, code, _) <- sinkLine >>= parseStatus         if code == 100             then newline ExpectedBlankAfter100Continue >> getStatusLine
Network/HTTP/Conduit/Request.hs view
@@ -32,7 +32,6 @@ import Blaze.ByteString.Builder.Char8 (fromChar)  import qualified Data.Conduit as C-import qualified Data.Conduit.List as CL  import qualified Data.ByteString as S import qualified Data.ByteString.Char8 as S8@@ -256,15 +255,15 @@     => Request m     -> C.Source m Builder requestBuilder req =-    CL.sourceList [builder] `mappend` bodySource+    bodySource   where     (contentLength, bodySource) =         case requestBody req of-            RequestBodyLBS lbs -> (Just $ L.length lbs, C.yield $ fromLazyByteString lbs)-            RequestBodyBS bs -> (Just $ fromIntegral $ S.length bs, C.yield $ fromByteString bs)-            RequestBodyBuilder i b -> (Just $ i, C.yield b)-            RequestBodySource i source -> (Just i, source)-            RequestBodySourceChunked source -> (Nothing, source C.$= chunkIt)+            RequestBodyLBS lbs -> (Just $ L.length lbs, C.yield $ builder `mappend` fromLazyByteString lbs)+            RequestBodyBS bs -> (Just $ fromIntegral $ S.length bs, C.yield $ builder `mappend` fromByteString bs)+            RequestBodyBuilder i b -> (Just $ i, C.yield $ builder `mappend` b)+            RequestBodySource i source -> (Just i, C.yield builder >> source)+            RequestBodySourceChunked source -> (Nothing, C.yield builder >> (source C.$= chunkIt))      hh         | port req == 80 && not (secure req) = host req
Network/HTTP/Conduit/Types.hs view
@@ -191,6 +191,7 @@                    | InvalidHeader S.ByteString                    | InternalIOException IOException                    | ProxyConnectException S.ByteString Int (Either S.ByteString HttpException) -- ^ host/port+                   | NoResponseDataReceived     deriving (Show, Typeable) instance Exception HttpException 
http-conduit.cabal view
@@ -1,5 +1,5 @@ name:            http-conduit-version:         1.9.0+version:         1.9.1 license:         BSD3 license-file:    LICENSE author:          Michael Snoyman <michael@snoyman.com>