@@ -71,10 +71,15 @@ module Network.Wai
71 , responseLBS
71 , responseLBS
72 , responseStream
72 , responseStream
73 , responseRaw
73 , responseRaw
74− -- * Response accessors
74+ -- ** Response accessors
75 , responseStatus
75 , responseStatus
76 , responseHeaders
76 , responseHeaders
77+ -- ** Response modifiers
77 , responseToStream
78 , responseToStream
80+ -- * Middleware composition
80import Blaze.ByteString.Builder (Builder, fromLazyByteString)
85import Blaze.ByteString.Builder (Builder, fromLazyByteString)
@@ -225,6 +230,13 @@ responseToStream (ResponseBuilder s h b) =
225 (s, h, \withBody -> withBody $ \sendChunk _flush -> sendChunk b)
230 (s, h, \withBody -> withBody $ \sendChunk _flush -> sendChunk b)
226responseToStream (ResponseRaw _ res) = responseToStream res
231responseToStream (ResponseRaw _ res) = responseToStream res
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
228----------------------------------------------------------------
240----------------------------------------------------------------
230-- | The WAI application.
242-- | The WAI application.
@@ -242,21 +254,6 @@ responseToStream (ResponseRaw _ res) = responseToStream res
243type Application = Request -> (Response -> IO ResponseReceived) -> IO ResponseReceived
255type Application = Request -> (Response -> IO ResponseReceived) -> IO ResponseReceived
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.
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
255−-- @ loadSession :: ([(String, String)] -> Application) -> Application @
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
261-- | A default, blank request.
258-- | A default, blank request.
@@ -279,6 +276,36 @@ defaultRequest = Request
279 , requestHeaderRange = Nothing
276 , requestHeaderRange = Nothing
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.
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
290+-- @ loadSession :: ([(String, String)] -> Application) -> Application @
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
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
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
282-- | Get the request body as a lazy ByteString. However, do /not/ use any lazy
309-- | Get the request body as a lazy ByteString. However, do /not/ use any lazy
283-- I\/O, instead reading the entire body into memory strictly.
310-- I\/O, instead reading the entire body into memory strictly.