@@ -160,7 +160,9 @@ toApplication ra request respond = ra request routingRespond
160-- 5. Query parameter checks. They require parsing and can cause 400 if the
160-- 5. Query parameter checks. They require parsing and can cause 400 if the
161-- parsing fails. Query parameter checks provide inputs to the handler
161-- parsing fails. Query parameter checks provide inputs to the handler
163+-- 6. Header Checks. They also require parsing and can cause 400 if parsing fails.
163−-- 6. Body check. The request body check can cause 400.
165+-- 7. Body check. The request body check can cause 400.
165data Delayed env c where
167data Delayed env c where
166 Delayed :: { capturesD :: env -> DelayedIO captures
168 Delayed :: { capturesD :: env -> DelayedIO captures
@@ -169,9 +171,11 @@ data Delayed env c where
169 , acceptD :: DelayedIO ()
171 , acceptD :: DelayedIO ()
170 , contentD :: DelayedIO contentType
172 , contentD :: DelayedIO contentType
171 , paramsD :: DelayedIO params
173 , paramsD :: DelayedIO params
174+ , headersD :: DelayedIO headers
172 , bodyD :: contentType -> DelayedIO body
175 , bodyD :: contentType -> DelayedIO body
173 , serverD :: captures
176 , serverD :: captures
174 -> params
177 -> params
177 -> Request
181 -> Request
@@ -181,7 +185,7 @@ data Delayed env c where
181instance Functor (Delayed env) where
185instance Functor (Delayed env) where
182 fmap f Delayed{..} =
186 fmap f Delayed{..} =
184− { serverD = \ c p a b req -> f <$> serverD c p a b req
188+ { serverD = \ c p h a b req -> f <$> serverD c p h a b req
186 } -- Note [Existential Record Update]
190 } -- Note [Existential Record Update]
@@ -213,7 +217,7 @@ runDelayedIO m req = transResourceT runRouteResultT $ runReaderT (runDelayedIO'
213-- | A 'Delayed' without any stored checks.
217-- | A 'Delayed' without any stored checks.
214emptyDelayed :: RouteResult a -> Delayed env a
218emptyDelayed :: RouteResult a -> Delayed env a
215emptyDelayed result =
219emptyDelayed result =
216− Delayed (const r) r r r r r (const r) (\ _ _ _ _ _ -> result)
220+ Delayed (const r) r r r r r r (const r) (\ _ _ _ _ _ _ -> result)
218 r = return ()
222 r = return ()
@@ -238,7 +242,7 @@ addCapture :: Delayed env (a -> b)
238addCapture Delayed{..} new =
242addCapture Delayed{..} new =
240 { capturesD = \ (txt, env) -> (,) <$> capturesD env <*> new txt
244 { capturesD = \ (txt, env) -> (,) <$> capturesD env <*> new txt
241− , serverD = \ (x, v) p a b req -> ($ v) <$> serverD x p a b req
245+ , serverD = \ (x, v) p h a b req -> ($ v) <$> serverD x p h a b req
243 } -- Note [Existential Record Update]
247 } -- Note [Existential Record Update]
@@ -249,7 +253,18 @@ addParameterCheck :: Delayed env (a -> b)
249addParameterCheck Delayed {..} new =
253addParameterCheck Delayed {..} new =
251 { paramsD = (,) <$> paramsD <*> new
255 { paramsD = (,) <$> paramsD <*> new
252− , serverD = \c (p, pNew) a b req -> ($ pNew) <$> serverD c p a b req
256+ , serverD = \c (p, pNew) h a b req -> ($ pNew) <$> serverD c p h a b req
260+-- | Add a parameter check to the end of the params block
261+addHeaderCheck :: Delayed env (a -> b)
264+addHeaderCheck Delayed {..} new =
266+ { headersD = (,) <$> headersD <*> new
267+ , serverD = \c p (h, hNew) a b req -> ($ hNew) <$> serverD c p h a b req
@@ -270,7 +285,7 @@ addAuthCheck :: Delayed env (a -> b)
270addAuthCheck Delayed{..} new =
285addAuthCheck Delayed{..} new =
272 { authD = (,) <$> authD <*> new
287 { authD = (,) <$> authD <*> new
273− , serverD = \ c p (y, v) b req -> ($ v) <$> serverD c p y b req
288+ , serverD = \ c p h (y, v) b req -> ($ v) <$> serverD c p h y b req
275 } -- Note [Existential Record Update]
290 } -- Note [Existential Record Update]
@@ -286,7 +301,7 @@ addBodyCheck Delayed{..} newContentD newBodyD =
287 { contentD = (,) <$> contentD <*> newContentD
302 { contentD = (,) <$> contentD <*> newContentD
288 , bodyD = \(content, c) -> (,) <$> bodyD content <*> newBodyD c
303 , bodyD = \(content, c) -> (,) <$> bodyD content <*> newBodyD c
289− , serverD = \ c p a (z, v) req -> ($ v) <$> serverD c p a z req
304+ , serverD = \ c p h a (z, v) req -> ($ v) <$> serverD c p h a z req
291 } -- Note [Existential Record Update]
306 } -- Note [Existential Record Update]
@@ -316,7 +331,7 @@ addAcceptCheck Delayed{..} new =
316passToServer :: Delayed env (a -> b) -> (Request -> a) -> Delayed env b
331passToServer :: Delayed env (a -> b) -> (Request -> a) -> Delayed env b
317passToServer Delayed{..} x =
332passToServer Delayed{..} x =
319− { serverD = \ c p a b req -> ($ x req) <$> serverD c p a b req
334+ { serverD = \ c p h a b req -> ($ x req) <$> serverD c p h a b req
321 } -- Note [Existential Record Update]
336 } -- Note [Existential Record Update]
@@ -338,8 +353,9 @@ runDelayed Delayed{..} env = runDelayedIO $ do
339 content <- contentD
354 content <- contentD
340 p <- paramsD -- Has to be before body parsing, but after content-type checks
355 p <- paramsD -- Has to be before body parsing, but after content-type checks
341 b <- bodyD content
357 b <- bodyD content
342− liftRouteResult (serverD c p a b r)
358+ liftRouteResult (serverD c p h a b r)
344-- | Runs a delayed server and the resulting action.
360-- | Runs a delayed server and the resulting action.
345-- Takes a continuation that lets us send a response.
361-- Takes a continuation that lets us send a response.