@@ -42,12 +42,13 @@ import Data.Monoid (mappend, mempty)
42import Data.Version (showVersion)
42import Data.Version (showVersion)
43import qualified Network.HTTP.Types as H
43import qualified Network.HTTP.Types as H
44import Network.Wai
44import Network.Wai
45−import qualified Network.Wai.Handler.Warp.Date as D
46import Network.Wai.Handler.Warp.Buffer (toBlazeBuffer)
45import Network.Wai.Handler.Warp.Buffer (toBlazeBuffer)
46+import qualified Network.Wai.Handler.Warp.Date as D
47+import qualified Network.Wai.Handler.Warp.FdCache as F
47import Network.Wai.Handler.Warp.Header
48import Network.Wai.Handler.Warp.Header
48import Network.Wai.Handler.Warp.IO (toBufIOWith)
49import Network.Wai.Handler.Warp.IO (toBufIOWith)
49−import Network.Wai.Handler.Warp.ResponseHeader
50import Network.Wai.Handler.Warp.RequestHeader (parseByteRanges)
50import Network.Wai.Handler.Warp.RequestHeader (parseByteRanges)
51+import Network.Wai.Handler.Warp.ResponseHeader
51import qualified Network.Wai.Handler.Warp.Timeout as T
52import qualified Network.Wai.Handler.Warp.Timeout as T
52import Network.Wai.Handler.Warp.Types
53import Network.Wai.Handler.Warp.Types
53import Network.Wai.Internal
54import Network.Wai.Internal
@@ -181,7 +182,7 @@ sendResponse defServer conn ii req reqidxhdr src response = do
181 hs <- addServerAndDate hs0
182 hs <- addServerAndDate hs0
182 if hasBody s then do
183 if hasBody s then do
183 -- HEAD comes here even if it does not have body.
184 -- HEAD comes here even if it does not have body.
184− sendRsp conn ver s hs rsp
185+ sendRsp conn mfdc ver s hs rsp
185 T.tickle th
186 T.tickle th
186 return ret
187 return ret
@@ -195,6 +196,7 @@ sendResponse defServer conn ii req reqidxhdr src response = do
195 rspidxhdr = indexResponseHeader hs0
196 rspidxhdr = indexResponseHeader hs0
196 th = threadHandle ii
197 th = threadHandle ii
197 dc = dateCacher ii
198 dc = dateCacher ii
198 addServerAndDate = addDate dc rspidxhdr . addServer defServer rspidxhdr
200 addServerAndDate = addDate dc rspidxhdr . addServer defServer rspidxhdr
199 mRange = reqidxhdr ! idxRange
201 mRange = reqidxhdr ! idxRange
200 (isPersist,isChunked0) = infoFromRequest req reqidxhdr
202 (isPersist,isChunked0) = infoFromRequest req reqidxhdr
@@ -222,28 +224,40 @@ data Rsp = RspFile FilePath (Maybe FilePart) (Maybe HeaderValue) Bool (IO ())
222----------------------------------------------------------------
224----------------------------------------------------------------
224sendRsp :: Connection
226sendRsp :: Connection
227+ -> Maybe F.MutableFdCache
225 -> H.HttpVersion
228 -> H.HttpVersion
226 -> H.Status
229 -> H.Status
227 -> H.ResponseHeaders
230 -> H.ResponseHeaders
230−sendRsp conn ver s0 hs0 (RspFile path mPart mRange isHead hook) = do
233+sendRsp conn mfdc ver s0 hs0 (RspFile path mPart mRange isHead hook) = do
231 ex <- fileRange s0 hs path mPart mRange
234 ex <- fileRange s0 hs path mPart mRange
232 case ex of
235 case ex of
233 Left _ex ->
236 Left _ex ->
234#ifdef WARP_DEBUG
237#ifdef WARP_DEBUG
235 print _ex >>
238 print _ex >>
237− sendRsp conn ver s2 hs2 (RspBuilder body True)
240+ sendRsp conn mfdc ver s2 hs2 (RspBuilder body True)
238 Right (s, hs1, beg, len)
241 Right (s, hs1, beg, len)
239 | len >= 0 ->
242 | len >= 0 ->
240 if isHead then
243 if isHead then
241− sendRsp conn ver s hs1 (RspBuilder mempty False)
244+ sendRsp conn mfdc ver s hs1 (RspBuilder mempty False)
243 lheader <- composeHeader ver s hs1
246 lheader <- composeHeader ver s hs1
248+ (mfd, hook') <- case mfdc of
249+ Nothing -> return (Nothing, hook)
251+ (fd, fresher) <- F.getFd fdc path
252+ return (Just fd, hook >> fresher)
253+ let fid = FileId path mfd
255+ let fid = FileId path Nothing
244− connSendFile conn path beg len hook [lheader]
258+ connSendFile conn fid beg len hook' [lheader]
245 | otherwise -> do
259 | otherwise -> do
246− sendRsp conn ver H.status416
260+ sendRsp conn mfdc ver H.status416
247 (filter (\(k, _) -> k /= "content-length") hs1)
261 (filter (\(k, _) -> k /= "content-length") hs1)
248 (RspBuilder mempty True)
262 (RspBuilder mempty True)
@@ -254,7 +268,7 @@ sendRsp conn ver s0 hs0 (RspFile path mPart mRange isHead hook) = do
255----------------------------------------------------------------
269----------------------------------------------------------------
257−sendRsp conn ver s hs (RspBuilder body needsChunked) = do
271+sendRsp conn _ ver s hs (RspBuilder body needsChunked) = do
258 header <- composeHeaderBuilder ver s hs needsChunked
272 header <- composeHeaderBuilder ver s hs needsChunked
259 let hdrBdy
273 let hdrBdy
260 | needsChunked = header <> chunkedTransferEncoding body
274 | needsChunked = header <> chunkedTransferEncoding body
@@ -266,7 +280,7 @@ sendRsp conn ver s hs (RspBuilder body needsChunked) = do
267----------------------------------------------------------------
281----------------------------------------------------------------
269−sendRsp conn ver s hs (RspStream streamingBody needsChunked th) = do
283+sendRsp conn _ ver s hs (RspStream streamingBody needsChunked th) = do
270 header <- composeHeaderBuilder ver s hs needsChunked
284 header <- composeHeaderBuilder ver s hs needsChunked
271 (recv, finish) <- newBlazeRecv $ reuseBufferStrategy
285 (recv, finish) <- newBlazeRecv $ reuseBufferStrategy
272 $ toBlazeBuffer (connWriteBuffer conn) (connBufferSize conn)
286 $ toBlazeBuffer (connWriteBuffer conn) (connBufferSize conn)
@@ -289,7 +303,7 @@ sendRsp conn ver s hs (RspStream streamingBody needsChunked th) = do
290----------------------------------------------------------------
304----------------------------------------------------------------
292−sendRsp conn _ _ _ (RspRaw withApp src tickle) =
306+sendRsp conn _ _ _ _ (RspRaw withApp src tickle) =
293 withApp recv send
307 withApp recv send
295 recv = do
309 recv = do