@@ -22,7 +22,7 @@ import Data.Typeable
22import qualified Network.HTTP.Types as H
22import qualified Network.HTTP.Types as H
23import Network.HTTP2
23import Network.HTTP2
24import Network.HTTP2.Priority
24import Network.HTTP2.Priority
25−import Network.Wai.HTTP2 (Http2Application, Responder, Response, absurd)
25+import Network.Wai.HTTP2 (Http2Application, PushPromise, Responder, Response)
26import Network.Wai hiding (Response, responseStatus)
26import Network.Wai hiding (Response, responseStatus)
27import Network.Wai.Handler.Warp.HTTP2.EncodeFrame
27import Network.Wai.Handler.Warp.HTTP2.EncodeFrame
28import Network.Wai.Handler.Warp.HTTP2.Manager
28import Network.Wai.Handler.Warp.HTTP2.Manager
@@ -92,6 +92,29 @@ cleanupStream ctx@Context{outputQ} set strm req me = do
92 Nothing -> return ()
92 Nothing -> return ()
93 Just e -> S.settingsOnException set req e
93 Just e -> S.settingsOnException set req e
95+pushResponder :: Context -> S.Settings -> Stream -> PushPromise -> Responder -> IO ()
96+pushResponder ctx set strm promise responder = do
97+ let Context{ http2settings
101+ -- Claim the next outgoing stream.
102+ newSid <- atomicModifyIORef nextPushStreamId $ \sid -> (sid+2, sid)
103+ ws <- initialWindowSize <$> readIORef http2settings
105+ newStrm <- newStream newSid ws
107+ insert streamTable newSid newStrm
109+ let pri = Priority False (streamNumber strm) 16
110+ mkOutput = OPush strm promise
112+ respond = runStream ctx mkOutput
114+ -- TODO(awpr): synthesize a Request for 'settingsOnException'?
115+ runResponder responder respond tickle newStrm `E.catch`
116+ (cleanupStream ctx set strm Nothing . Just)
95data Break = Break deriving (Show, Typeable)
118data Break = Break deriving (Show, Typeable)
97instance Exception Break
120instance Exception Break
@@ -118,7 +141,7 @@ worker ctx@Context{inputQ} set tm app respond = do
118 setStreamInfo sinfo strm req
141 setStreamInfo sinfo strm req
119 T.resume th
142 T.resume th
120 T.tickle th
143 T.tickle th
121− let responder = app (req, flip (const absurd))
144+ let responder = app (req, pushResponder ctx set strm)
122 runResponder responder (respond tcont) (T.tickle th) strm
145 runResponder responder (respond tcont) (T.tickle th) strm
123 cont1 <- case ex of
146 cont1 <- case ex of
124 Right () -> return True
147 Right () -> return True