http-conduit 1.9.0 → 1.9.1
raw patch · 5 files changed
+40/−16 lines, 5 files
Files
- Network/HTTP/Conduit.hs +25/−8
- Network/HTTP/Conduit/Parser.hs +7/−0
- Network/HTTP/Conduit/Request.hs +6/−7
- Network/HTTP/Conduit/Types.hs +1/−0
- http-conduit.cabal +1/−1
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>