Signed-off-by: Anders Kaseorg <andersk@mit.edu>
import qualified Data.ByteString.Lazy as B
import Data.Char
import Data.Dynamic
import qualified Data.ByteString.Lazy as B
import Data.Char
import Data.Dynamic
import qualified Data.Map as M
import Data.Time.Clock.POSIX
import Data.Time.Format
import qualified Data.Map as M
import Data.Time.Clock.POSIX
import Data.Time.Format
import System.FilePath
import System.IO
import System.IO.Error (isDoesNotExistError, isPermissionError)
import System.FilePath
import System.IO
import System.IO.Error (isDoesNotExistError, isPermissionError)
import System.Locale
import System.Posix
import System.Posix.Handle
import System.Locale
import System.Posix
import System.Posix.Handle
setHeader "Content-Length" $ show size
outputFPS =<< liftIO (B.hGetContents h)
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
outputRange :: Handle -> FileOffset -> Maybe (FileOffset, FileOffset) -> CGI CGIResult
outputRange h size Nothing = outputAll h size
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)
"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
serveFile :: FilePath -> CGI CGIResult
serveFile file = (`catch` outputMyError) $ do