在Haskell WAI中,如何将标题添加为中间件?

时间:2014-11-01 19:49:48

标签: haskell haskell-wai

我试图通过编写一个非常简单的会话管理器来理解中间件。

我需要在响应中添加SetCookie标头。我查看了wai-extra包,找到了wai-session

我使用的是wai-3.0.2,它似乎没有让我直接访问Response的类型构造函数,而且所有我在{{{{{{我发现模式匹配的示例) 1}}添加标题。

你能指出我正确的方向吗?

1 个答案:

答案 0 :(得分:5)

编辑:Wai的3.0.3.0版引入了一个辅助函数mapResponseHeaders,它与下面示例中的mapHeader相同。这意味着该示例不再需要在Response上进行模式匹配。

import Network.HTTP.Types (ResponseHeaders, Header)
import Network.Wai (Middleware, Response, mapResponseHeaders)

withHeader :: Header -> Middleware
withHeader h app req respond = app req $ respond . addHeader h

addHeader :: Header -> Response -> Response
addHeader h = mapResponseHeaders (\hs -> h:hs)

我有一些工作,并认为我理解它,但真的喜欢反馈和建议。我是Haskell的新手,这是我第一次使用Wai。我最大的障碍是没有意识到应用类型在Wai 3.0.0中改变为延续传递方式。 (文档清楚地说明了这个非常;我只是错过了我读过它的前15次。)

import Network.HTTP.Types (ResponseHeaders, Header)
import Network.Wai (Middleware)
import Network.Wai.Internal (Response(..))

withHeader :: Header -> Middleware
withHeader h app req respond = app req $ respond . addHeader h

mapHeader :: (ResponseHeaders -> ResponseHeaders) -> Response -> Response
mapHeader f (ResponseFile s h b1 b2) = ResponseFile s (f h) b1 b2
mapHeader f (ResponseBuilder s h b) = ResponseBuilder s (f h) b
mapHeader f (ResponseStream s h b) = ResponseStream s (f h) b
mapHeader _ r@(ResponseRaw _ _) = r

addHeader :: Header -> Response -> Response
addHeader h = mapHeader (\hs -> h:hs)

我没有尝试修改ResponseRaw的标头,因为我无法弄清楚如何。

我不确定addHeader是否已部分应用并且是传递给内部Application的延续函数。这种形式可能更清晰(或更丑):

withHeader h app req respond = app req $ \resp -> respond $ addHeader h resp

我从wai-session复制了mapHeader,但为ResponseRaw添加了案例。