packages feed

http-client 0.4.7.2 → 0.4.8

raw patch · 5 files changed

+51/−4 lines, 5 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Network.HTTP.Client: ResponseLengthAndChunkingBothUsed :: HttpException
+ Network.HTTP.Client.Internal: ResponseLengthAndChunkingBothUsed :: HttpException

Files

ChangeLog.md view
@@ -1,3 +1,7 @@+## 0.4.8++* Add the `ResponseLengthAndChunkingBothUsed` exception constructor [#108](https://github.com/snoyberg/http-client/issues/108)+ ## 0.4.7.2  * Improved `timeout` implementation for high contention cases [#98](https://github.com/snoyberg/http-client/issues/98)
Network/HTTP/Client/Response.hs view
@@ -8,7 +8,7 @@     , lbsResponse     ) where -import Control.Monad ((>=>))+import Control.Monad ((>=>), when)  import Control.Exception (throwIO) @@ -17,6 +17,8 @@  import Data.Default.Class (def) +import Data.Maybe (isJust)+ import qualified Network.HTTP.Types as W import Network.URI (parseURIReference, escapeURIString, isAllowedInURI) @@ -93,11 +95,16 @@                 Just t -> timeout t >=> maybe (throwIO ResponseTimeout) return     StatusHeaders s version hs <- timeout' $ parseStatusHeaders conn     let mcl = lookup "content-length" hs >>= readDec . S8.unpack+        isChunked = ("transfer-encoding", "chunked") `elem` hs          -- should we put this connection back into the connection manager?         toPut = Just "close" /= lookup "connection" hs && version > W.HttpVersion 1 0         cleanup bodyConsumed = connRelease $ if toPut && bodyConsumed then Reuse else DontReuse +    when (isJust mcl && isChunked) $ do+        cleanup False+        throwIO ResponseLengthAndChunkingBothUsed+     body <-         -- RFC 2616 section 4.4_1 defines responses that must not include a body         if hasNoBody method (W.statusCode s) || mcl == Just 0@@ -105,7 +112,6 @@                 cleanup True                 return brEmpty             else do-                let isChunked = ("transfer-encoding", "chunked") `elem` hs                 body1 <-                     if isChunked                         then makeChunkedReader rawBody conn
Network/HTTP/Client/Types.hs view
@@ -114,6 +114,12 @@                    -- ^ Environment name and value                    --                    -- Since 0.4.7++                   | ResponseLengthAndChunkingBothUsed+                   -- ^ Detect a case where both the @content-length@ header+                   -- and @transfer-encoding: chunked@ are used.+                   --+                   -- Since 0.4.8     deriving (Show, T.Typeable) instance Exception HttpException 
http-client.cabal view
@@ -1,5 +1,5 @@ name:                http-client-version:             0.4.7.2+version:             0.4.8 synopsis:            An HTTP client engine, intended as a base layer for more user-friendly packages. description:         Hackage documentation generation is not reliable. For up to date documentation, please see: <http://www.stackage.org/package/http-client>. homepage:            https://github.com/snoyberg/http-client
test-nonet/Network/HTTP/ClientSpec.hs view
@@ -4,7 +4,7 @@ import           Control.Concurrent        (forkIO, threadDelay) import           Control.Concurrent.Async  (withAsync) import           Control.Exception         (bracket)-import           Control.Monad             (forever, replicateM_)+import           Control.Monad             (forever, replicateM_, void) import           Network.HTTP.Client import           Network.HTTP.Types        (status413) import           Network.Socket            (sClose)@@ -69,6 +69,28 @@         readHeaders S.empty         N.appWrite ad "HTTP/1.1 413 Too Large\r\ncontent-length: 7\r\n\r\ngoodbye" +-- Make sure we detect bad situations like+-- https://github.com/yesodweb/wai/issues/346 better than we did previously, so+-- that misreporting like https://github.com/snoyberg/http-client/issues/108+-- doesn't occur.+lengthAndChunked :: (Int -> IO a) -> IO a+lengthAndChunked inner = bracket+    (N.bindRandomPortTCP "*4")+    (sClose . snd)+    $ \(port, lsocket) -> withAsync+        (N.runTCPServer (N.serverSettingsTCPSocket lsocket) app)+        (const $ inner port)+  where+    app ad = do+        let readHeaders front = do+                newBS <- N.appRead ad+                let bs = S.append front newBS+                if "\r\n\r\n" `S.isInfixOf` bs+                    then return ()+                    else readHeaders bs+        readHeaders S.empty+        N.appWrite ad "HTTP/1.1 200 OK\r\ncontent-length: 0\r\ntransfer-encoding: chunked\r\n\r\n0"+ spec :: Spec spec = describe "Client" $ do     describe "fails on empty hostnames #40" $ do@@ -126,3 +148,12 @@                 }             responseBody res `shouldBe` "goodbye"             responseStatus res `shouldBe` status413++    it "length and chunking #108" $ lengthAndChunked $ \port' -> do+        withManager defaultManagerSettings $ \man -> do+            (void $ flip httpLbs man "http://localhost"+                { port = port'+                , checkStatus = \_ _ _ -> Nothing+                , requestBody = RequestBodyStreamChunked+                    ($ return (S.replicate 100000 65))+                }) `shouldThrow` (\e -> case e of { ResponseLengthAndChunkingBothUsed -> True; _ -> False})