Just (a, b) | a <= b -> return $ Just (a, b)
_ -> throwExceptionCGI BadRange
+outputAll :: Handle -> FileOffset -> CGI CGIResult
+outputAll h size = do
+ setHeader "Content-Length" $ show size
+ outputFPS =<< liftIO (B.hGetContents h)
+
+outputRange :: Handle -> FileOffset -> Maybe (FileOffset, FileOffset) -> CGI CGIResult
+outputRange h size Nothing = outputAll h size
+outputRange h size (Just (a, b)) = do
+ let len = b - a + 1
+
+ setStatus 206 "Partial Content"
+ setHeader "Content-Range" $
+ "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))
+
serveFile :: FilePath -> CGI CGIResult
serveFile file = (`catchExceptionCGI` outputMyError) $ do
checkExtension file
size = fileSize status
checkModified mTime
- checkRange mTime size >>= maybe
- (do
- setHeader "Content-Length" $ show size
- outputFPS =<< (liftIO $ B.hGetContents h))
- (\(a, b) -> do
- let len = b - a + 1
-
- setStatus 206 "Partial Content"
- setHeader "Content-Range" $
- "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)))
+ range <- checkRange mTime size
+ outputRange h size range
main :: IO ()
main = runCGI $ handleErrors $ serveFile =<< pathTranslated