@@ -15,26 +15,14 @@ import qualified Data.ByteString.Builder.Extra as B
1515import Foreign.Ptr
1616import Network.HTTP2
1717import Network.HTTP2.Priority
18−import Network.Wai hiding (Response)
19−import Network.Wai.HTTP2 (Trailers, Response(..))
18+import Network.Wai.HTTP2 (Trailers)
2019import Network.Wai.Handler.Warp.Buffer
2120import Network.Wai.Handler.Warp.HTTP2.EncodeFrame
2221import Network.Wai.Handler.Warp.HTTP2.HPACK
2322import Network.Wai.Handler.Warp.HTTP2.Types
2423import Network.Wai.Handler.Warp.IORef
2524import qualified Network.Wai.Handler.Warp.Settings as S
26−import qualified Network.Wai.Handler.Warp.Timeout as T
2725import Network.Wai.Handler.Warp.Types
28−import qualified System.PosixCompat.Files as P
29−
30−#ifdef WINDOWS
31−import qualified System.IO as IO
32−#else
33−import Network.Wai.Handler.Warp.FdCache
34−import Network.Wai.Handler.Warp.SendFile (positionRead)
35−import System.Posix.IO (openFd, OpenFileFlags(..), defaultFileFlags, OpenMode(ReadOnly), closeFd)
36−import System.Posix.Types
37−#endif
3826
3927----------------------------------------------------------------
4028
@@ -98,27 +86,10 @@ frameSender ctx@Context{outputQ,connectionWindow}
9886 lim <- getWindowSize connectionWindow (streamWindow strm)
9987 -- Header frame and Continuation frame
10088 let sid = streamNumber strm
101− endOfStream = case aux of
102− Persist{} -> False
103− Oneshot hb -> not hb
10489 builder <- hpackEncodeHeader ctx ii settings rsp
105− len <- headerContinue sid builder endOfStream
90+ len <- headerContinue sid builder False
10691 let total = len + frameHeaderLength
10792 case aux of
108− Oneshot True -> do -- hasBody
109− -- Data frame payload
110− (off, _) <- sendHeadersIfNecessary total
111− let payloadOff = off + frameHeaderLength
112− Next datPayloadLen mnext <-
113− fillResponseBodyGetNext conn ii payloadOff lim rsp
114− fillDataHeaderSend strm total datPayloadLen mnext
115− maybeEnqueueNext strm mnext
116− Oneshot False -> do
117− -- "closed" must be before "connSendAll". If not,
118− -- the context would be switched to the receiver,
119− -- resulting the inconsistency of concurrency.
120− closed ctx strm Finished
121− flushN total
12293 Persist sq tvar -> do
12394 (off, needSend) <- sendHeadersIfNecessary total
12495 let payloadOff = off + frameHeaderLength
@@ -238,62 +209,6 @@ frameSender ctx@Context{outputQ,connectionWindow}
238209
239210----------------------------------------------------------------
240211
241−{-
242−ResponseFile Status ResponseHeaders FilePath (Maybe FilePart)
243−ResponseBuilder Status ResponseHeaders Builder
244−ResponseStream Status ResponseHeaders StreamingBody
245−ResponseRaw (IO ByteString -> (ByteString -> IO ()) -> IO ()) Response
246−-}
247−
248−fillResponseBodyGetNext :: Connection -> InternalInfo -> Int -> WindowSize -> Response -> IO Next
249−fillResponseBodyGetNext Connection{connWriteBuffer,connBufferSize}
250− _ off lim (ResponseBuilder _ _ bb) = do
251− let datBuf = connWriteBuffer `plusPtr` off
252− room = min (connBufferSize - off) lim
253− (len, signal) <- B.runBuilder bb datBuf room
254− return $ nextForBuilder connWriteBuffer connBufferSize len signal
255−
256−#ifdef WINDOWS
257−fillResponseBodyGetNext Connection{connWriteBuffer,connBufferSize}
258− _ off lim (ResponseFile _ _ path mpart) = do
259− let datBuf = connWriteBuffer `plusPtr` off
260− room = min (connBufferSize - off) lim
261− (start, bytes) <- fileStartEnd path mpart
262− -- fixme: how to close Handle? GC does it at this moment.
263− h <- IO.openBinaryFile path IO.ReadMode
264− IO.hSeek h IO.AbsoluteSeek start
265− len <- IO.hGetBufSome h datBuf (mini room bytes)
266− let bytes' = bytes - fromIntegral len
267− return $ nextForFile len connWriteBuffer connBufferSize h bytes' (return ())
268−#else
269−fillResponseBodyGetNext Connection{connWriteBuffer,connBufferSize}
270− ii off lim (ResponseFile _ _ path mpart) = do
271− (fd, refresh) <- case fdCacher ii of
272− Just fdcache -> getFd fdcache path
273− Nothing -> do
274− fd' <- openFd path ReadOnly Nothing defaultFileFlags{nonBlock=True}
275− th <- T.register (timeoutManager ii) (closeFd fd')
276− return (fd', T.tickle th)
277− let datBuf = connWriteBuffer `plusPtr` off
278− room = min (connBufferSize - off) lim
279− (start, bytes) <- fileStartEnd path mpart
280− len <- positionRead fd datBuf (mini room bytes) start
281− refresh
282− let len' = fromIntegral len
283− return $ nextForFile len connWriteBuffer connBufferSize fd (start + len') (bytes - len') refresh
284−#endif
285−
286−fillResponseBodyGetNext _ _ _ _ _ = error "fillResponseBodyGetNext"
287−
288−fileStartEnd :: FilePath -> Maybe FilePart -> IO (Integer, Integer)
289−fileStartEnd path Nothing = do
290− end <- fromIntegral . P.fileSize <$> P.getFileStatus path
291− return (0, end)
292−fileStartEnd _ (Just part) =
293− return (filePartOffset part, filePartByteCount part)
294−
295−----------------------------------------------------------------
296−
297212fillStreamBodyGetNext :: Connection -> Int -> WindowSize -> TBQueue Sequence -> TVar Sync -> Stream -> IO Next
298213fillStreamBodyGetNext Connection{connWriteBuffer,connBufferSize}
299214 off lim sq tvar strm = do
@@ -304,38 +219,6 @@ fillStreamBodyGetNext Connection{connWriteBuffer,connBufferSize}
304219
305220----------------------------------------------------------------
306221
307−fillBufBuilder :: Buffer -> BufSize -> Leftover -> DynaNext
308−fillBufBuilder buf0 siz0 leftover lim = do
309− let payloadBuf = buf0 `plusPtr` frameHeaderLength
310− room = min (siz0 - frameHeaderLength) lim
311− case leftover of
312− LZero -> error "fillBufBuilder: LZero"
313− LOne writer -> do
314− (len, signal) <- writer payloadBuf room
315− getNext len signal
316− LTwo bs writer
317− | BS.length bs <= room -> do
318− buf1 <- copy payloadBuf bs
319− let len1 = BS.length bs
320− (len2, signal) <- writer buf1 (room - len1)
321− getNext (len1 + len2) signal
322− | otherwise -> do
323− let (bs1,bs2) = BS.splitAt room bs
324− void $ copy payloadBuf bs1
325− getNext room (B.Chunk bs2 writer)
326− where
327− getNext l s = return $ nextForBuilder buf0 siz0 l s
328−
329−nextForBuilder :: Buffer -> BufSize -> BytesFilled -> B.Next -> Next
330−nextForBuilder _ _ len B.Done
331− = Next len CFinish
332−nextForBuilder buf siz len (B.More _ writer)
333− = Next len (CNext (fillBufBuilder buf siz (LOne writer)))
334−nextForBuilder buf siz len (B.Chunk bs writer)
335− = Next len (CNext (fillBufBuilder buf siz (LTwo bs writer)))
336−
337−----------------------------------------------------------------
338−
339222runStreamBuilder :: Buffer -> BufSize -> TBQueue Sequence
340223 -> IO (Leftover, Maybe Trailers, BytesFilled)
341224runStreamBuilder buf0 room0 sq = loop buf0 room0 0
@@ -400,42 +283,3 @@ nextForStream buf siz sq tvar strm LZero Nothing len = do
400283 return $ Next len CNone
401284nextForStream buf siz sq tvar strm leftover Nothing len =
402285 return $ Next len (CNext (fillBufStream buf siz leftover sq tvar strm))
403−
404−----------------------------------------------------------------
405−
406−#ifdef WINDOWS
407−fillBufFile :: Buffer -> BufSize -> IO.Handle -> Integer -> IO () -> DynaNext
408−fillBufFile buf siz h bytes refresh lim = do
409− let payloadBuf = buf `plusPtr` frameHeaderLength
410− room = min (siz - frameHeaderLength) lim
411− len <- IO.hGetBufSome h payloadBuf room
412− refresh
413− let bytes' = bytes - fromIntegral len
414− return $ nextForFile len buf siz h bytes' refresh
415−
416−nextForFile :: BytesFilled -> Buffer -> BufSize -> IO.Handle -> Integer -> IO () -> Next
417−nextForFile 0 _ _ _ _ _ = Next 0 CFinish
418−nextForFile len _ _ _ 0 _ = Next len CFinish
419−nextForFile len buf siz h bytes refresh =
420− Next len (CNext (fillBufFile buf siz h bytes refresh))
421−#else
422−fillBufFile :: Buffer -> BufSize -> Fd -> Integer -> Integer -> IO () -> DynaNext
423−fillBufFile buf siz fd start bytes refresh lim = do
424− let payloadBuf = buf `plusPtr` frameHeaderLength
425− room = min (siz - frameHeaderLength) lim
426− len <- positionRead fd payloadBuf (mini room bytes) start
427− let len' = fromIntegral len
428− refresh
429− return $ nextForFile len buf siz fd (start + len') (bytes - len') refresh
430−
431−nextForFile :: BytesFilled -> Buffer -> BufSize -> Fd -> Integer -> Integer -> IO () -> Next
432−nextForFile 0 _ _ _ _ _ _ = Next 0 CFinish
433−nextForFile len _ _ _ _ 0 _ = Next len CFinish
434−nextForFile len buf siz fd start bytes refresh =
435− Next len (CNext (fillBufFile buf siz fd start bytes refresh))
436−#endif
437−
438−mini :: Int -> Integer -> Int
439−mini i n
440− | fromIntegral i < n = i
441− | otherwise = fromIntegral n