From 88f471e39e08094de760be4cf532ff4bd0a4881a Mon Sep 17 00:00:00 2001 From: Anders Kaseorg Date: Mon, 12 Jul 2010 21:41:15 -0400 Subject: [PATCH] Read byte ranges lazily, and close the file afterwards. Signed-off-by: Anders Kaseorg --- StaticCat.hs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/StaticCat.hs b/StaticCat.hs index 396403b..df4a6e2 100644 --- a/StaticCat.hs +++ b/StaticCat.hs @@ -8,6 +8,7 @@ import Control.Monad.CatchIO import qualified Data.ByteString.Lazy as B import Data.Char import Data.Dynamic +import Data.Int import qualified Data.Map as M import Data.Time.Clock.POSIX import Data.Time.Format @@ -16,6 +17,7 @@ import Numeric import System.FilePath import System.IO import System.IO.Error (isDoesNotExistError, isPermissionError) +import System.IO.Unsafe import System.Locale import System.Posix import System.Posix.Handle @@ -145,6 +147,14 @@ outputAll h size = do setHeader "Content-Length" $ show size outputFPS =<< liftIO (B.hGetContents h) +-- | Lazily read a given number of bytes from the handle into a +-- 'ByteString', then close the handle. +hGetClose :: Handle -> Int64 -> IO B.ByteString +hGetClose h len = do + contents <- B.hGetContents h + end <- unsafeInterleaveIO (hClose h >> return B.empty) + return (B.append (B.take len contents) end) + outputRange :: Handle -> FileOffset -> Maybe (FileOffset, FileOffset) -> CGI CGIResult outputRange h size Nothing = outputAll h size outputRange h size (Just (a, b)) = do @@ -155,7 +165,7 @@ outputRange h size (Just (a, b)) = do "bytes " ++ show a ++ "-" ++ show b ++ "/" ++ show size setHeader "Content-Length" $ show len liftIO $ hSeek h AbsoluteSeek (fromIntegral a) - outputFPS =<< liftIO (B.hGet h (fromIntegral len)) + outputFPS =<< liftIO (hGetClose h (fromIntegral len)) serveFile :: FilePath -> CGI CGIResult serveFile file = (`catch` outputMyError) $ do -- 2.45.0