@@ -160,7 +160,9 @@ toApplication ra request respond = ra request routingRespond
160160-- 5. Query parameter checks. They require parsing and can cause 400 if the
161161-- parsing fails. Query parameter checks provide inputs to the handler
162162--
163−-- 6. Body check. The request body check can cause 400.
163+-- 6. Header Checks. They also require parsing and can cause 400 if parsing fails.
164+--
165+-- 7. Body check. The request body check can cause 400.
164166--
165167data Delayed env c where
166168 Delayed :: { capturesD :: env -> DelayedIO captures
@@ -169,9 +171,11 @@ data Delayed env c where
169171 , acceptD :: DelayedIO ()
170172 , contentD :: DelayedIO contentType
171173 , paramsD :: DelayedIO params
174+ , headersD :: DelayedIO headers
172175 , bodyD :: contentType -> DelayedIO body
173176 , serverD :: captures
174177 -> params
178+ -> headers
175179 -> auth
176180 -> body
177181 -> Request
@@ -181,7 +185,7 @@ data Delayed env c where
181185instance Functor (Delayed env) where
182186 fmap f Delayed{..} =
183187 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
185189 , ..
186190 } -- Note [Existential Record Update]
187191
@@ -213,7 +217,7 @@ runDelayedIO m req = transResourceT runRouteResultT $ runReaderT (runDelayedIO'
213217-- | A 'Delayed' without any stored checks.
214218emptyDelayed :: RouteResult a -> Delayed env a
215219emptyDelayed 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)
217221 where
218222 r = return ()
219223
@@ -238,7 +242,7 @@ addCapture :: Delayed env (a -> b)
238242addCapture Delayed{..} new =
239243 Delayed
240244 { 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
242246 , ..
243247 } -- Note [Existential Record Update]
244248
@@ -249,7 +253,18 @@ addParameterCheck :: Delayed env (a -> b)
249253addParameterCheck Delayed {..} new =
250254 Delayed
251255 { 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
257+ , ..
258+ }
259+
260+-- | Add a parameter check to the end of the params block
261+addHeaderCheck :: Delayed env (a -> b)
262+ -> DelayedIO a
263+ -> Delayed env b
264+addHeaderCheck Delayed {..} new =
265+ Delayed
266+ { headersD = (,) <$> headersD <*> new
267+ , serverD = \c p (h, hNew) a b req -> ($ hNew) <$> serverD c p h a b req
253268 , ..
254269 }
255270
@@ -270,7 +285,7 @@ addAuthCheck :: Delayed env (a -> b)
270285addAuthCheck Delayed{..} new =
271286 Delayed
272287 { 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
274289 , ..
275290 } -- Note [Existential Record Update]
276291
@@ -286,7 +301,7 @@ addBodyCheck Delayed{..} newContentD newBodyD =
286301 Delayed
287302 { contentD = (,) <$> contentD <*> newContentD
288303 , 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
290305 , ..
291306 } -- Note [Existential Record Update]
292307
@@ -316,7 +331,7 @@ addAcceptCheck Delayed{..} new =
316331passToServer :: Delayed env (a -> b) -> (Request -> a) -> Delayed env b
317332passToServer Delayed{..} x =
318333 Delayed
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
320335 , ..
321336 } -- Note [Existential Record Update]
322337
@@ -338,8 +353,9 @@ runDelayed Delayed{..} env = runDelayedIO $ do
338353 acceptD
339354 content <- contentD
340355 p <- paramsD -- Has to be before body parsing, but after content-type checks
356+ h <- headersD
341357 b <- bodyD content
342− liftRouteResult (serverD c p a b r)
358+ liftRouteResult (serverD c p h a b r)
343359
344360-- | Runs a delayed server and the resulting action.
345361-- Takes a continuation that lets us send a response.