on master help sign in
Cleanup: import wrangling and comments
commita45c7354fc5130f80dfbff08457352013a9e8328 authorAndrew Pritchard <awpr@google.com> dateSat 29 Aug 2015, 14:35 (11 years ago) parent64486f8
4 files changed+65−10
wai/Network/Wai/HTTP2.hs+19 warp/Network/Wai/Handler/Warp/HTTP2/Sender.hs+18−8 warp/Network/Wai/Handler/Warp/HTTP2/Types.hs+14 warp/Network/Wai/Handler/Warp/HTTP2/Worker.hs+14−2
wai/Network/Wai/HTTP2.hs+19
@@ -35,23 +35,42 @@ data PushPromise = PushPromise
3535-- | The HTTP\/2-aware equivalent of 'Network.Wai.Application'.
3636type HTTP2Application = Request -> PushFunc -> Responder
3737
38+-- | Part of a streaming response -- either a 'Builder' or a range of a file.
3839data Chunk = FileChunk FilePath (Maybe FilePart) | BuilderChunk Builder
3940
41+-- TODO send -> write
42+-- | Given the write function of a stream body, write the given 'Builder'.
4043sendBuilder :: (Chunk -> IO ()) -> Builder -> IO ()
4144sendBuilder = (. BuilderChunk)
4245
46+-- | Given the write function of a stream body, write part or all of the given
47+-- file.
4348sendFilePart :: (Chunk -> IO ()) -> FilePath -> Maybe FilePart -> IO ()
4449sendFilePart = (.: FileChunk)
4550 where f .: g = curry $ f . uncurry g
4651
52+-- | The streaming body of a response. Equivalent to
53+-- 'Network.Wai.StreamingBody' except that it can also write file ranges and
54+-- return a result of type @a@.
4755type Body a = (Chunk -> IO ()) -> IO () -> IO a
4856
57+-- | A function given to an 'HTTP2Application' used to send the response. This
58+-- is similar to the respond function in 'Network.Wai.Application', but the
59+-- status and headers are curried, and it passes on any result value from the
60+-- stream body.
4961type RespondFunc = forall a. H.Status -> H.ResponseHeaders -> Body a -> IO a
5062
63+-- | A continuation-passing style function that provides a response by calling
64+-- the 'RespondFunc', then returns the request's 'Trailers'.
5165type Responder = RespondFunc -> IO Trailers
5266
67+-- | A function given to an 'HTTP2Application' to initiate a server-pushed
68+-- stream. Its argument is the same as the result of an 'HTTP2Application', so
69+-- you can either implement the response inline, or call your own application
70+-- to create the response.
5371type PushFunc = PushPromise -> Responder -> IO Bool
5472
73+-- | Create the 'H.RequestHeaders' corresponding to the given 'PushPromise'.
5574promiseHeaders :: PushPromise -> H.RequestHeaders
5675promiseHeaders p =
5776 [ (":method", promisedMethod p)
warp/Network/Wai/Handler/Warp/HTTP2/Sender.hs+18−8
@@ -22,8 +22,6 @@ import Network.HTTP2.Priority
2222import Network.Wai (FilePart(..))
2323import Network.Wai.HTTP2 (Trailers, promiseHeaders)
2424import Network.Wai.Handler.Warp.Buffer
25−import Network.Wai.Handler.Warp.FdCache (getFd)
26−import Network.Wai.Handler.Warp.SendFile (positionRead)
2725import Network.Wai.Handler.Warp.HTTP2.EncodeFrame
2826import Network.Wai.Handler.Warp.HTTP2.HPACK
2927import Network.Wai.Handler.Warp.HTTP2.Types
@@ -31,25 +29,37 @@ import Network.Wai.Handler.Warp.IORef
3129import qualified Network.Wai.Handler.Warp.Settings as S
3230import qualified Network.Wai.Handler.Warp.Timeout as T
3331import Network.Wai.Handler.Warp.Types
32+import qualified System.PosixCompat.Files as P
33+
34+#ifdef WINDOWS
35+import qualified System.IO as IO
36+#else
37+import Network.Wai.Handler.Warp.FdCache (getFd)
38+import Network.Wai.Handler.Warp.SendFile (positionRead)
3439import System.Posix.IO (openFd, OpenFileFlags(..), defaultFileFlags, OpenMode(ReadOnly), closeFd)
3540import System.Posix.Types (Fd)
36−import qualified System.PosixCompat.Files as P
41+#endif
3742
3843----------------------------------------------------------------
3944
40−data Leftover = LZero
41− | LOne B.BufferWriter
42− | LTwo BS.ByteString B.BufferWriter
43− | LFile OpenFile Integer Integer (IO ())
44−
45+-- | The platform-specific type of an open file to stream from. On Windows we
46+-- don't have pread, so this is just a Handle; on Unix platforms with pread,
47+-- this is a file descriptor supplied by the fd cache.
4548#ifdef WINDOWS
4649type OpenFile = IO.Handle
4750#else
4851type OpenFile = Fd
4952#endif
5053
54+data Leftover = LZero
55+ | LOne B.BufferWriter
56+ | LTwo BS.ByteString B.BufferWriter
57+ | LFile OpenFile Integer Integer (IO ())
58+
5159----------------------------------------------------------------
5260
61+-- | Run the given action if the stream is not closed; handle any exceptions by
62+-- resetting the stream.
5363unlessClosed :: Connection -> Stream -> IO () -> IO Bool
5464unlessClosed Connection{connSendAll}
5565 strm@Stream{streamState,streamNumber}
warp/Network/Wai/Handler/Warp/HTTP2/Types.hs+14
@@ -87,15 +87,29 @@ outputStream _ = error "outputStream"
8787
8888----------------------------------------------------------------
8989
90+-- | An element on the queue between a running stream and the sender; the order
91+-- should consist of any number of 'SFile', 'SBuilder', and 'SFlush', followed
92+-- by a single 'SFinish'.
9093data Sequence = SFinish Trailers
94+ -- ^ The stream is over; its trailers are provided.
9195 | SFlush
96+ -- ^ Any buffered data should be sent immediately.
9297 | SBuilder Builder
98+ -- ^ Append a chunk of data to the stream.
9399 | SFile FilePath (Maybe FilePart)
100+ -- ^ Append a chunk of a file's contents to the stream.
94101
102+-- | A message from the sender to a stream's dedicated waiter thread.
95103data Sync = SyncNone
104+ -- ^ Nothing interesting has happened. Go back to sleep.
96105 | SyncFinish Trailers
106+ -- ^ The stream has ended; enqueue 'OTrailers' and quit.
97107 | SyncNext Output
108+ -- ^ The stream's queue has been drained; wait for more to be
109+ -- available and re-enqueue the given 'Output'.
98110
111+-- | Auxiliary information needed to communicate with a running stream: a queue
112+-- of stream elements ('Sequence') and a 'TVar' connected to its waiter thread.
99113data Aux = Persist (TBQueue Sequence) (TVar Sync)
100114
101115----------------------------------------------------------------
warp/Network/Wai/Handler/Warp/HTTP2/Worker.hs+14−2
@@ -57,6 +57,8 @@ response ctx mgr tconf tickle strm sq s h strmbdy = do
5757
5858 runStream ctx OResponse tickle strm sq s h strmbdy
5959
60+-- | Set up a waiter thread and run the stream body with functions to enqueue
61+-- 'Sequence's on the stream's queue.
6062runStream :: Context
6163 -> (Stream -> H.Status -> H.ResponseHeaders -> Aux -> Output)
6264 -> Respond
@@ -68,14 +70,17 @@ runStream Context{outputQ} mkOutput tickle strm sq s h strmbdy = do
6870 -- queue is not empty.
6971 void $ forkIO $ waiter tvar sq strm outputQ
7072 atomically $ writeTVar tvar (SyncNext out)
71− let push chunk = do
73+ let write chunk = do
7274 atomically $ writeTBQueue sq $ case chunk of
7375 BuilderChunk b -> SBuilder b
7476 FileChunk path part -> SFile path part
7577 tickle
7678 flush = atomically $ writeTBQueue sq SFlush
77− strmbdy push flush
79+ strmbdy write flush
7880
81+-- | Set up a queue for the stream and use the given 'Respond' to actually run
82+-- it. This will be 'response' for client-initiated streams and just plain
83+-- 'runStream' for pushed streams.
7984runResponder :: Responder -> Respond -> IO () -> Stream -> IO ()
8085runResponder responder respond tickle strm = do
8186 -- Since 'Body' is loop, we cannot control it.
@@ -84,6 +89,8 @@ runResponder responder respond tickle strm = do
8489 trailers <- responder $ respond tickle strm sq
8590 atomically $ writeTBQueue sq $ SFinish trailers
8691
92+-- | Handle abnormal termination of a stream: mark it as closed, send a reset
93+-- frame, and call the user's 'settingsOnException' handler if applicable.
8794cleanupStream :: Context -> S.Settings -> Stream -> Maybe Request -> Maybe SomeException -> IO ()
8895cleanupStream Context{outputQ} set strm req me = do
8996 closed strm Killed
@@ -199,6 +206,11 @@ worker ctx@Context{inputQ} set tm app respond = do
199206 cleanupStream ctx set strm (Just req) me
200207 clearStreamInfo sinfo
201208
209+-- | A dedicated waiter thread to re-enqueue the stream in the priority tree
210+-- whenever output becomes available. When the sender drains the queue and
211+-- moves on to another stream, it drops a message in the 'TVar', and this
212+-- thread wakes up, waits for more output to become available, and re-enqueues
213+-- the stream.
202214waiter :: TVar Sync -> TBQueue Sequence -> Stream -> PriorityTree Output -> IO ()
203215waiter tvar sq strm outQ = do
204216 -- waiting for actions other than SyncNone