@@ -33,7 +33,7 @@ import qualified Data.ByteString.Char8 as B (pack)
3333import qualified Data.CaseInsensitive as CI
3434import Data.Function (on)
3535import Data.List (deleteBy)
36−import Data.Maybe (isJust, listToMaybe)
36+import Data.Maybe (isJust, fromMaybe)
3737#if MIN_VERSION_base(4,5,0)
3838# if __GLASGOW_HASKELL__ < 709
3939import Data.Monoid (mempty)
@@ -51,14 +51,11 @@ import qualified Network.Wai.Handler.Warp.Date as D
5151import qualified Network.Wai.Handler.Warp.FdCache as F
5252import Network.Wai.Handler.Warp.Header
5353import Network.Wai.Handler.Warp.IO (toBufIOWith)
54−import Network.Wai.Handler.Warp.RequestHeader (parseByteRanges)
5554import Network.Wai.Handler.Warp.ResponseHeader
5655import qualified Network.Wai.Handler.Warp.Timeout as T
5756import Network.Wai.Handler.Warp.Types
5857import Network.Wai.Internal
59−import Numeric (showInt)
6058import qualified Paths_warp
61−import qualified System.PosixCompat.Files as P
6259
6360#if !MIN_VERSION_base(4,5,0)
6461(<>) :: Monoid m => m -> m -> m
@@ -68,11 +65,6 @@ import qualified System.PosixCompat.Files as P
6865-- $setup
6966-- >>> :set -XOverloadedStrings
7067
71−mapRight :: (b -> c) -> Either a b -> Either a c
72−mapRight f eith = case eith of
73− Right x -> Right (f x)
74− Left l -> Left l
75−
7668----------------------------------------------------------------
7769
7870fileRange :: H.Status -> H.ResponseHeaders -> FilePath
@@ -80,8 +72,7 @@ fileRange :: H.Status -> H.ResponseHeaders -> FilePath
8072 -> IO (Either IOException
8173 (H.Status, H.ResponseHeaders, Integer, Integer))
8274fileRange s0 hs0 path Nothing mRange =
83− mapRight (fileRangeSized s0 hs0 Nothing mRange . fromIntegral . P.fileSize) <$>
84− try (P.getFileStatus path)
75+ fmap (fileRangeSized s0 hs0 Nothing mRange) <$> tryGetFileSize path
8576fileRange s0 hs0 _ mPart@(Just part) mRange =
8677 return . Right $ fileRangeSized s0 hs0 mPart mRange size
8778 where
@@ -92,40 +83,18 @@ fileRangeSized :: H.Status -> H.ResponseHeaders
9283 -> (H.Status, H.ResponseHeaders, Integer, Integer)
9384fileRangeSized s0 hs0 mPart mRange fileSize = (s, hs, beg, len)
9485 where
95− (beg, end, len, isEntire) = checkPartRange fileSize mPart mRange
96− hs1 = addContentLength len hs0
97− hs | isEntire = hs1
98− | otherwise = addContentRange beg end fileSize hs1
99− s | isEntire = s0
100− | otherwise = H.status206
86+ (beg, _end, len, _entire) = checkPartRange fileSize mPart mRange
87+ (s, hs) = adjustForFilePart s0 hs0 $ FilePart beg len fileSize
10188
10289checkPartRange :: Integer -> Maybe FilePart -> Maybe HeaderValue
10390 -> (Integer, Integer, Integer, Bool)
104−checkPartRange fileSize = checkPart
91+checkPartRange fileSize mpart mrange = (beg, end, len, isEntire)
10592 where
106− checkPart Nothing Nothing = (0, fileSize - 1, fileSize, True)
107− checkPart Nothing (Just range) = case parseByteRanges range >>= listToMaybe of
108− -- Range is broken
109− Nothing -> (0, fileSize - 1, fileSize, True)
110− Just hrange -> checkRange hrange
111− -- Ignore Range if FilePart is specified.
112− -- We assume that an application handled Range and specified
113− -- FilePart.
114− checkPart (Just part) _ = (beg, end, len, isEntire)
115− where
116− beg = filePartOffset part
117− len = filePartByteCount part
118− end = beg + len - 1
119− isEntire = beg == 0 && len == fileSize
120−
121− checkRange (H.ByteRangeFrom beg) = fromRange beg (fileSize - 1)
122− checkRange (H.ByteRangeFromTo beg end) = fromRange beg (min (fileSize - 1) end)
123− checkRange (H.ByteRangeSuffix count) = fromRange (max 0 (fileSize - count)) (fileSize - 1)
124−
125− fromRange beg end = (beg, end, len, isEntire)
126− where
127− len = end - beg + 1
128− isEntire = beg == 0 && len == fileSize
93+ part = fromMaybe (chooseFilePart fileSize mrange) mpart
94+ beg = filePartOffset part
95+ len = filePartByteCount part
96+ end = beg + len - 1
97+ isEntire = beg == 0 && len == fileSize
12998
13099----------------------------------------------------------------
131100
@@ -396,25 +365,6 @@ addAcceptRanges hdrs = (hAcceptRanges, "bytes") : hdrs
396365addTransferEncoding :: H.ResponseHeaders -> H.ResponseHeaders
397366addTransferEncoding hdrs = (hTransferEncoding, "chunked") : hdrs
398367
399−addContentLength :: Integer -> H.ResponseHeaders -> H.ResponseHeaders
400−addContentLength cl hdrs = (H.hContentLength, len) : hdrs
401− where
402− len = B.pack $ show cl
403−
404−addContentRange :: Integer -> Integer -> Integer
405− -> H.ResponseHeaders -> H.ResponseHeaders
406−addContentRange beg end total hdrs = (hContentRange, range) : hdrs
407− where
408− range = B.pack
409− -- building with ShowS
410− $ 'b' : 'y': 't' : 'e' : 's' : ' '
411− : (if beg > end then ('*':) else
412− showInt beg
413− . ('-' :)
414− . showInt end)
415− ( '/'
416− : showInt total "")
417−
418368addDate :: D.DateCache -> IndexedHeader -> H.ResponseHeaders -> IO H.ResponseHeaders
419369addDate dc rspidxhdr hdrs = case rspidxhdr ! idxDate of
420370 Nothing -> do