@@ -33,7 +33,7 @@ import qualified Data.ByteString.Char8 as B (pack)
33import qualified Data.CaseInsensitive as CI
33import qualified Data.CaseInsensitive as CI
34import Data.Function (on)
34import Data.Function (on)
35import Data.List (deleteBy)
35import Data.List (deleteBy)
36−import Data.Maybe (isJust, listToMaybe)
36+import Data.Maybe (isJust, fromMaybe)
37#if MIN_VERSION_base(4,5,0)
37#if MIN_VERSION_base(4,5,0)
38# if __GLASGOW_HASKELL__ < 709
38# if __GLASGOW_HASKELL__ < 709
39import Data.Monoid (mempty)
39import Data.Monoid (mempty)
@@ -51,14 +51,11 @@ import qualified Network.Wai.Handler.Warp.Date as D
51import qualified Network.Wai.Handler.Warp.FdCache as F
51import qualified Network.Wai.Handler.Warp.FdCache as F
52import Network.Wai.Handler.Warp.Header
52import Network.Wai.Handler.Warp.Header
53import Network.Wai.Handler.Warp.IO (toBufIOWith)
53import Network.Wai.Handler.Warp.IO (toBufIOWith)
54−import Network.Wai.Handler.Warp.RequestHeader (parseByteRanges)
55import Network.Wai.Handler.Warp.ResponseHeader
54import Network.Wai.Handler.Warp.ResponseHeader
56import qualified Network.Wai.Handler.Warp.Timeout as T
55import qualified Network.Wai.Handler.Warp.Timeout as T
57import Network.Wai.Handler.Warp.Types
56import Network.Wai.Handler.Warp.Types
58import Network.Wai.Internal
57import Network.Wai.Internal
59−import Numeric (showInt)
60import qualified Paths_warp
58import qualified Paths_warp
61−import qualified System.PosixCompat.Files as P
63#if !MIN_VERSION_base(4,5,0)
60#if !MIN_VERSION_base(4,5,0)
64(<>) :: Monoid m => m -> m -> m
61(<>) :: Monoid m => m -> m -> m
@@ -68,11 +65,6 @@ import qualified System.PosixCompat.Files as P
69-- >>> :set -XOverloadedStrings
66-- >>> :set -XOverloadedStrings
71−mapRight :: (b -> c) -> Either a b -> Either a c
72−mapRight f eith = case eith of
73− Right x -> Right (f x)
76----------------------------------------------------------------
68----------------------------------------------------------------
78fileRange :: H.Status -> H.ResponseHeaders -> FilePath
70fileRange :: H.Status -> H.ResponseHeaders -> FilePath
@@ -80,8 +72,7 @@ fileRange :: H.Status -> H.ResponseHeaders -> FilePath
80 -> IO (Either IOException
72 -> IO (Either IOException
81 (H.Status, H.ResponseHeaders, Integer, Integer))
73 (H.Status, H.ResponseHeaders, Integer, Integer))
82fileRange s0 hs0 path Nothing mRange =
74fileRange s0 hs0 path Nothing mRange =
83− mapRight (fileRangeSized s0 hs0 Nothing mRange . fromIntegral . P.fileSize) <$>
75+ fmap (fileRangeSized s0 hs0 Nothing mRange) <$> tryGetFileSize path
84− try (P.getFileStatus path)
85fileRange s0 hs0 _ mPart@(Just part) mRange =
76fileRange s0 hs0 _ mPart@(Just part) mRange =
86 return . Right $ fileRangeSized s0 hs0 mPart mRange size
77 return . Right $ fileRangeSized s0 hs0 mPart mRange size
@@ -92,40 +83,18 @@ fileRangeSized :: H.Status -> H.ResponseHeaders
92 -> (H.Status, H.ResponseHeaders, Integer, Integer)
83 -> (H.Status, H.ResponseHeaders, Integer, Integer)
93fileRangeSized s0 hs0 mPart mRange fileSize = (s, hs, beg, len)
84fileRangeSized s0 hs0 mPart mRange fileSize = (s, hs, beg, len)
95− (beg, end, len, isEntire) = checkPartRange fileSize mPart mRange
86+ (beg, _end, len, _entire) = checkPartRange fileSize mPart mRange
96− hs1 = addContentLength len hs0
87+ (s, hs) = adjustForFilePart s0 hs0 $ FilePart beg len fileSize
98− | otherwise = addContentRange beg end fileSize hs1
100− | otherwise = H.status206
102checkPartRange :: Integer -> Maybe FilePart -> Maybe HeaderValue
89checkPartRange :: Integer -> Maybe FilePart -> Maybe HeaderValue
103 -> (Integer, Integer, Integer, Bool)
90 -> (Integer, Integer, Integer, Bool)
104−checkPartRange fileSize = checkPart
91+checkPartRange fileSize mpart mrange = (beg, end, len, isEntire)
106− checkPart Nothing Nothing = (0, fileSize - 1, fileSize, True)
93+ part = fromMaybe (chooseFilePart fileSize mrange) mpart
107− checkPart Nothing (Just range) = case parseByteRanges range >>= listToMaybe of
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
114− checkPart (Just part) _ = (beg, end, len, isEntire)
116− beg = filePartOffset part
94+ beg = filePartOffset part
117− len = filePartByteCount part
95+ len = filePartByteCount part
118− end = beg + len - 1
96+ end = beg + len - 1
119− isEntire = beg == 0 && len == fileSize
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)
125− fromRange beg end = (beg, end, len, isEntire)
128− isEntire = beg == 0 && len == fileSize
97+ isEntire = beg == 0 && len == fileSize
130----------------------------------------------------------------
99----------------------------------------------------------------
@@ -396,25 +365,6 @@ addAcceptRanges hdrs = (hAcceptRanges, "bytes") : hdrs
396addTransferEncoding :: H.ResponseHeaders -> H.ResponseHeaders
365addTransferEncoding :: H.ResponseHeaders -> H.ResponseHeaders
397addTransferEncoding hdrs = (hTransferEncoding, "chunked") : hdrs
366addTransferEncoding hdrs = (hTransferEncoding, "chunked") : hdrs
399−addContentLength :: Integer -> H.ResponseHeaders -> H.ResponseHeaders
400−addContentLength cl hdrs = (H.hContentLength, len) : hdrs
402− len = B.pack $ show cl
404−addContentRange :: Integer -> Integer -> Integer
405− -> H.ResponseHeaders -> H.ResponseHeaders
406−addContentRange beg end total hdrs = (hContentRange, range) : hdrs
409− -- building with ShowS
410− $ 'b' : 'y': 't' : 'e' : 's' : ' '
411− : (if beg > end then ('*':) else
418addDate :: D.DateCache -> IndexedHeader -> H.ResponseHeaders -> IO H.ResponseHeaders
368addDate :: D.DateCache -> IndexedHeader -> H.ResponseHeaders -> IO H.ResponseHeaders
419addDate dc rspidxhdr hdrs = case rspidxhdr ! idxDate of
369addDate dc rspidxhdr hdrs = case rspidxhdr ! idxDate of
420 Nothing -> do
370 Nothing -> do