{-# LANGUAGE OverloadedStrings #-} module Network.HTTP.Client.RequestBodySpec where import Control.Monad import Test.Hspec import Control.Exception import System.IO import Data.IORef import qualified Data.ByteString as BS import Network.HTTP.Client (streamFile, parseUrlThrow, requestBody) import Network.HTTP.Client.Internal (dummyConnection, connectionWrite, requestBuilder) import System.Directory (getTemporaryDirectory) spec :: Spec spec = describe "streamFile" $ it "works" $ withTmpFile $ \(path, h) -> do replicateM_ 5000 $ BS.hPut h "Hello, world!\r\n" hClose h withBinaryFile path ReadMode $ \h' -> do conn <- verifyFileConnection h' req0 <- parseUrlThrow "http://example.com" body <- streamFile path let req = req0 { requestBody = body } _ <- requestBuilder req conn hIsEOF h' `shouldReturn` True where withTmpFile = bracket getTmpFile closeTmpFile getTmpFile = do tmp <- getTemporaryDirectory openBinaryTempFile tmp "request-body-stream-file" closeTmpFile (_, h) = hClose h firstReadBS = "GET / HTTP/1.1\r\nHost: example.com\r\nAccept-Encoding: gzip\r\nContent-Length: 75000\r\n\r\n" verifyFileConnection h = do (conn, _, _) <- dummyConnection [] isFirstReadRef <- newIORef True return conn { connectionWrite = \bs -> do isFirstRead <- readIORef isFirstReadRef if isFirstRead then do bs `shouldBe` firstReadBS writeIORef isFirstReadRef False else do bs' <- BS.hGet h (BS.length bs) bs `shouldBe` bs' }