packages feed

http-client 0.6.2 → 0.6.3

raw patch · 5 files changed

+45/−30 lines, 5 files

Files

ChangeLog.md view
@@ -1,5 +1,12 @@ # Changelog for http-client +## 0.6.3++* Detect response body termination before reading an extra null chunk+  when possible. This allows connections to be reused in some corner+  cases. See+  [#395](https://github.com/snoyberg/http-client/issues/395)+ ## 0.6.2  * Add `shouldStripHeaderOnRedirect` option to `Request` [#300](https://github.com/snoyberg/http-client/issues/300)
Network/HTTP/Client/Body.hs view
@@ -8,7 +8,6 @@     , brConsume     , brEmpty     , constBodyReader-    , brAddCleanup     , brReadSome     , brRead     ) where@@ -61,12 +60,6 @@             [] -> ([], S.empty)             x:xs -> (xs, x) -brAddCleanup :: IO () -> BodyReader -> BodyReader-brAddCleanup cleanup brRead' = do-    bs <- brRead'-    when (S.null bs) cleanup-    return bs- -- | Strictly consume all remaining chunks of data from the stream. -- -- Since 0.1.0@@ -111,16 +104,25 @@             Nothing -> start             Just popper -> goPopper popper -makeUnlimitedReader :: Connection -> IO BodyReader-makeUnlimitedReader Connection {..} = do+makeUnlimitedReader+  :: IO () -- ^ cleanup+  -> Connection+  -> IO BodyReader+makeUnlimitedReader cleanup Connection {..} = do     icomplete <- newIORef False     return $ do         bs <- connectionRead-        when (S.null bs) $ writeIORef icomplete True+        when (S.null bs) $ do+          writeIORef icomplete True+          cleanup         return bs -makeLengthReader :: Int -> Connection -> IO BodyReader-makeLengthReader count0 Connection {..} = do+makeLengthReader+  :: IO () -- ^ cleanup+  -> Int+  -> Connection+  -> IO BodyReader+makeLengthReader cleanup count0 Connection {..} = do     icount <- newIORef count0     return $ do         count <- readIORef icount@@ -134,20 +136,27 @@                         let (x, y) = S.splitAt count bs                         connectionUnread y                         writeIORef icount (-1)+                        cleanup                         return x                     EQ -> do                         writeIORef icount (-1)+                        cleanup                         return bs                     GT -> do                         writeIORef icount (count - S.length bs)                         return bs -makeChunkedReader :: Bool -- ^ raw-                  -> Connection-                  -> IO BodyReader-makeChunkedReader raw conn@Connection {..} = do+makeChunkedReader+  :: IO () -- ^ cleanup+  -> Bool -- ^ raw+  -> Connection+  -> IO BodyReader+makeChunkedReader cleanup raw conn@Connection {..} = do     icount <- newIORef 0-    return $ go icount+    return $ do+      bs <- go icount+      when (S.null bs) cleanup+      pure bs   where     go icount = do         count0 <- readIORef icount
Network/HTTP/Client/Response.hs view
@@ -107,15 +107,14 @@             else do                 body1 <-                     if isChunked-                        then makeChunkedReader rawBody conn+                        then makeChunkedReader (cleanup True) rawBody conn                         else                             case mcl of-                                Just len -> makeLengthReader len conn-                                Nothing -> makeUnlimitedReader conn-                body2 <- if needsGunzip req hs+                                Just len -> makeLengthReader (cleanup True) len conn+                                Nothing -> makeUnlimitedReader (cleanup True) conn+                if needsGunzip req hs                     then makeGzipReader body1                     else return body1-                return $ brAddCleanup (cleanup True) body2      return Response         { responseStatus = s
http-client.cabal view
@@ -1,5 +1,5 @@ name:                http-client-version:             0.6.2+version:             0.6.3 synopsis:            An HTTP client engine 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/Client/BodySpec.hs view
@@ -22,7 +22,7 @@         (conn, _, input) <- dummyConnection             [ "5\r\nhello\r\n6\r\n world\r\n0\r\nnot consumed"             ]-        reader <- makeChunkedReader False conn+        reader <- makeChunkedReader (return ()) False conn         body <- brConsume reader         S.concat body `shouldBe` "hello world"         input' <- input@@ -32,7 +32,7 @@     it "chunked, pieces" $ do         (conn, _, input) <- dummyConnection $ map S.singleton $ S.unpack             "5\r\nhello\r\n6\r\n world\r\n0\r\nnot consumed"-        reader <- makeChunkedReader False conn+        reader <- makeChunkedReader (return ()) False conn         body <- brConsume reader         S.concat body `shouldBe` "hello world"         input' <- input@@ -43,7 +43,7 @@         (conn, _, input) <- dummyConnection             [ "5\r\nhello\r\n6\r\n world\r\n0\r\nnot consumed"             ]-        reader <- makeChunkedReader True conn+        reader <- makeChunkedReader (return ()) True conn         body <- brConsume reader         S.concat body `shouldBe` "5\r\nhello\r\n6\r\n world\r\n0\r\n"         input' <- input@@ -53,7 +53,7 @@     it "chunked, pieces, raw" $ do         (conn, _, input) <- dummyConnection $ map S.singleton $ S.unpack             "5\r\nhello\r\n6\r\n world\r\n0\r\nnot consumed"-        reader <- makeChunkedReader True conn+        reader <- makeChunkedReader (return ()) True conn         body <- brConsume reader         S.concat body `shouldBe` "5\r\nhello\r\n6\r\n world\r\n0\r\n"         input' <- input@@ -64,7 +64,7 @@         (conn, _, input) <- dummyConnection             [ "hello world done"             ]-        reader <- makeLengthReader 11 conn+        reader <- makeLengthReader (return ()) 11 conn         body <- brConsume reader         S.concat body `shouldBe` "hello world"         input' <- input@@ -74,7 +74,7 @@     it "length, pieces" $ do         (conn, _, input) <- dummyConnection $ map S.singleton $ S.unpack             "hello world done"-        reader <- makeLengthReader 11 conn+        reader <- makeLengthReader (return ()) 11 conn         body <- brConsume reader         S.concat body `shouldBe` "hello world"         input' <- input@@ -85,7 +85,7 @@         let orig = L.fromChunks $ replicate 5000 "Hello world!"             origZ = compress orig         (conn, _, input) <- dummyConnection $ L.toChunks origZ ++ ["ignored"]-        reader' <- makeLengthReader (fromIntegral $ L.length origZ) conn+        reader' <- makeLengthReader (return ()) (fromIntegral $ L.length origZ) conn         reader <- makeGzipReader reader'         body <- brConsume reader         L.fromChunks body `shouldBe` orig