on master help sign in
adding a new member filePartFileSize to FilePart.
commit6794e43f0380dbff899f8b355cc9c33479fde4cc authorKazu Yamamoto <kazu@iij.ad.jp> dateThu 31 Oct 2013, 10:02 (13 years ago) parentd792c31
4 files changed+32−23
wai/Network/Wai.hs+1−1 wai/Network/Wai/Internal.hs+1 warp/Network/Wai/Handler/Warp/Response.hs+23−16 warp/test/PartialFileSpec.hs+7−6
wai/Network/Wai.hs+1−1
@@ -110,7 +110,7 @@ responseToSource (ResponseBuilder s h b) =
110110 (s, h, ($ CL.sourceList [C.Chunk b]))
111111
112112sourceFilePart :: IO.Handle -> FilePart -> C.Source IO B.ByteString
113−sourceFilePart handle (FilePart offset count) =
113+sourceFilePart handle (FilePart offset count _) =
114114 CB.sourceHandleRange handle (Just offset) (Just count)
115115
116116responseLBS :: H.Status -> H.ResponseHeaders -> L.ByteString -> Response
wai/Network/Wai/Internal.hs+1
@@ -101,4 +101,5 @@ data RequestBodyLength = ChunkedBody | KnownLength Word64
101101data FilePart = FilePart
102102 { filePartOffset :: Integer
103103 , filePartByteCount :: Integer
104+ , filePartFileSize :: Integer
104105 } deriving Show
warp/Network/Wai/Handler/Warp/Response.hs+23−16
@@ -43,15 +43,15 @@ fileRange :: IndexedHeader -> IndexedHeader
4343 -> FilePath -> Maybe FilePart
4444 -> IO (Either SomeException
4545 (H.Status, H.ResponseHeaders, Integer, Integer))
46−fileRange reqidxhdr rspidxhdr s0 hs0 path mpart = liftIO . try $
47− tryContentLength s0 hs0
46+fileRange reqidxhdr rspidxhdr s0 hs0 path mpart =
47+ liftIO . try $ checkContentLength s0 hs0
4848 where
4949 mRange = reqidxhdr ! idxRange
5050 mContentLength = rspidxhdr ! idxContentLength
5151 mContentRange = rspidxhdr ! idxContentRange
5252
53− tryContentLength s' hdr' = do
54− quad@(s, hdr, beg, len) <- tryMpart s' hdr' mpart
53+ checkContentLength s' hdr' = do
54+ quad@(s, hdr, beg, len) <- checkMpart s' hdr' mpart
5555 -- We respect Content-Length if exists.
5656 -- The validity of Content-Length's value is Applications's
5757 -- responsibility.
@@ -59,25 +59,25 @@ fileRange reqidxhdr rspidxhdr s0 hs0 path mpart = liftIO . try $
5959 Nothing -> return (s, addContentLength len hdr, beg, len)
6060 _ -> return quad
6161
62− tryMpart s hdr Nothing = do
62+ checkMpart s hdr Nothing = do
6363 -- We don't know the size of the file.
6464 -- Content-Length cannot help.
6565 -- Let's obtain it first.
6666 fileSize <- fromIntegral . P.fileSize <$> P.getFileStatus path
6767 -- Then, let's manipulate Range in HTTP request.
68− return $ tryRange s hdr mRange fileSize
68+ return $ checkRange s hdr mRange fileSize
6969 -- We respect Status.
7070 -- The validity of Status's value is Applications's responsibility.
71− tryMpart s hdr (Just part) = return (s, hdr', beg, len)
71+ checkMpart s hdr (Just part) = return (s, hdr', beg, len)
7272 where
7373 beg = filePartOffset part
7474 len = filePartByteCount part
75− hdr' = addRange mContentRange
76− addRange Nothing = addContentRange len beg (beg + len - 1) hdr
77− addRange _ = hdr
75+ end = beg + len - 1
76+ fileSize = filePartFileSize part
77+ hdr' = addRange hdr fileSize beg end mContentRange
7878
79− tryRange s hdr Nothing fileSize = (s, hdr, 0, fileSize)
80− tryRange s hdr (Just range) fileSize = case mhrange of
79+ checkRange s hdr Nothing fileSize = (s, hdr, 0, fileSize)
80+ checkRange s hdr (Just range) fileSize = case mhrange of
8181 Nothing -> (s, hdr, 0, fileSize)
8282 -- FIXME: original code checks if s is 200.
8383 Just hrange -> case hrange of
@@ -87,10 +87,17 @@ fileRange reqidxhdr rspidxhdr s0 hs0 path mpart = liftIO . try $
8787 where
8888 mhrange = parseByteRanges range >>= listToMaybe
8989
90− fromRange hdr total from to = (H.status206
91− ,addContentRange total from to hdr
92− ,from
93− ,to - from + 1)
90+ fromRange hdr fileSize from to = (status, hdr', beg, len)
91+ where
92+ status = H.status206
93+ hdr' = addRange hdr fileSize from to mContentRange
94+ beg = from
95+ len = to - from + 1
96+
97+ -- We respect Content-Range.
98+ -- The validity of Content-Range's value is Applications's responsibility.
99+ addRange hdr fileSize from to Nothing = addContentRange fileSize from to hdr
100+ addRange hdr _ _ _ _ = hdr
94101
95102----------------------------------------------------------------
96103
warp/test/PartialFileSpec.hs+7−6
@@ -42,11 +42,12 @@ testRange range out crange = it title $ withApp defaultSettings app $ \port -> d
4242 (x, ':':y) -> Just (x, dropWhile (== ' ') y)
4343 _ -> Nothing
4444
45−testPartial :: Integer -- ^ offset
45+testPartial :: Integer -- ^ file size
46+ -> Integer -- ^ offset
4647 -> Integer -- ^ byte count
4748 -> String -- ^ expected output
4849 -> Spec
49−testPartial offset count out = it title $ withApp defaultSettings app $ \port -> do
50+testPartial size offset count out = it title $ withApp defaultSettings app $ \port -> do
5051 handle <- connectTo "127.0.0.1" $ PortNumber $ fromIntegral port
5152 S.hPutStr handle "GET / HTTP/1.0\r\n\r\n"
5253 hFlush handle
@@ -57,7 +58,7 @@ testPartial offset count out = it title $ withApp defaultSettings app $ \port ->
5758 let hs = mapMaybe toHeader bss
5859 lookup "Content-Length" hs `shouldBe` Just (show $ length $ last bss)
5960 where
60− app _ = return $ responseFile status200 [] "attic/hex" $ Just $ FilePart offset count
61+ app _ = return $ responseFile status200 [] "attic/hex" $ Just $ FilePart offset count size
6162 title = show (offset, count, out)
6263 toHeader s =
6364 case break (== ':') s of
@@ -72,6 +73,6 @@ spec = do
7273 testRange "5-8" "5678" "5-8/16"
7374 testRange "-3" "def" "13-15/16"
7475 describe "partial files" $ do
75− testPartial 2 2 "23"
76− testPartial 0 2 "01"
77− testPartial 3 8 "3456789a"
76+ testPartial 16 2 2 "23"
77+ testPartial 16 0 2 "01"
78+ testPartial 16 3 8 "3456789a"