我试图通过编写一个非常简单的会话管理器来理解中间件。
我需要在响应中添加SetCookie
标头。我查看了wai-extra
包,找到了wai-session
。
我使用的是wai-3.0.2,它似乎没有让我直接访问Response的类型构造函数,而且所有我在{{{{{{我发现模式匹配的示例) 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添加了案例。