@@ -71,10 +71,15 @@ module Network.Wai
7171 , responseLBS
7272 , responseStream
7373 , responseRaw
74− -- * Response accessors
74+ -- ** Response accessors
7575 , responseStatus
7676 , responseHeaders
77+ -- ** Response modifiers
7778 , responseToStream
79+ , mapResponseHeaders
80+ -- * Middleware composition
81+ , ifRequest
82+ , modifyResponse
7883 ) where
7984
8085import Blaze.ByteString.Builder (Builder, fromLazyByteString)
@@ -225,6 +230,13 @@ responseToStream (ResponseBuilder s h b) =
225230 (s, h, \withBody -> withBody $ \sendChunk _flush -> sendChunk b)
226231responseToStream (ResponseRaw _ res) = responseToStream res
227232
233+-- | Apply the provided function to the response header list of the Response.
234+mapResponseHeaders :: (H.ResponseHeaders -> H.ResponseHeaders) -> Response -> Response
235+mapResponseHeaders f (ResponseFile s h b1 b2) = ResponseFile s (f h) b1 b2
236+mapResponseHeaders f (ResponseBuilder s h b) = ResponseBuilder s (f h) b
237+mapResponseHeaders f (ResponseStream s h b) = ResponseStream s (f h) b
238+mapResponseHeaders _ r@(ResponseRaw _ _) = r
239+
228240----------------------------------------------------------------
229241
230242-- | The WAI application.
@@ -242,21 +254,6 @@ responseToStream (ResponseRaw _ res) = responseToStream res
242254-- @
243255type Application = Request -> (Response -> IO ResponseReceived) -> IO ResponseReceived
244256
245−-- | Middleware is a component that sits between the server and application. It
246−-- can do such tasks as GZIP encoding or response caching. What follows is the
247−-- general definition of middleware, though a middleware author should feel
248−-- free to modify this.
249−--
250−-- As an example of an alternate type for middleware, suppose you write a
251−-- function to load up session information. The session information is simply a
252−-- string map \[(String, String)\]. A logical type signature for this middleware
253−-- might be:
254−--
255−-- @ loadSession :: ([(String, String)] -> Application) -> Application @
256−--
257−-- Here, instead of taking a standard 'Application' as its first argument, the
258−-- middleware takes a function which consumes the session information as well.
259−type Middleware = Application -> Application
260257
261258-- | A default, blank request.
262259--
@@ -279,6 +276,36 @@ defaultRequest = Request
279276 , requestHeaderRange = Nothing
280277 }
281278
279+
280+-- | Middleware is a component that sits between the server and application. It
281+-- can do such tasks as GZIP encoding or response caching. What follows is the
282+-- general definition of middleware, though a middleware author should feel
283+-- free to modify this.
284+--
285+-- As an example of an alternate type for middleware, suppose you write a
286+-- function to load up session information. The session information is simply a
287+-- string map \[(String, String)\]. A logical type signature for this middleware
288+-- might be:
289+--
290+-- @ loadSession :: ([(String, String)] -> Application) -> Application @
291+--
292+-- Here, instead of taking a standard 'Application' as its first argument, the
293+-- middleware takes a function which consumes the session information as well.
294+type Middleware = Application -> Application
295+
296+
297+-- | apply a function that modifies a response as a 'Middleware'
298+modifyResponse :: (Response -> Response) -> Middleware
299+modifyResponse f app req respond = app req $ respond . f
300+
301+
302+-- | conditionally apply a 'Middleware'
303+ifRequest :: (Request -> Bool) -> Middleware -> Middleware
304+ifRequest rpred middle app req | rpred req = middle app req
305+ | otherwise = app req
306+
307+
308+
282309-- | Get the request body as a lazy ByteString. However, do /not/ use any lazy
283310-- I\/O, instead reading the entire body into memory strictly.
284311--