我想通过编写一个非常简单的会话管理器来了解中间件。在Haskell WAI中,如何添加标题作为中间件?
我需要在响应中添加SetCookie
标头。我看了一下wai-extra
包,发现wai-session
。
我正在使用wai-3.0.2,它似乎没有给我直接访问响应的类型构造函数,并且我发现在Response(..)
上找到模式匹配以添加标题的所有示例。
您能否指点我正确的方向?
我想通过编写一个非常简单的会话管理器来了解中间件。在Haskell WAI中,如何添加标题作为中间件?
我需要在响应中添加SetCookie
标头。我看了一下wai-extra
包,发现wai-session
。
我正在使用wai-3.0.2,它似乎没有给我直接访问响应的类型构造函数,并且我发现在Response(..)
上找到模式匹配以添加标题的所有示例。
您能否指点我正确的方向?
编辑: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 _ [email protected](ResponseRaw _ _) = r
addHeader :: Header -> Response -> Response
addHeader h = mapHeader (\hs -> h:hs)
我没有试图修改标题为ResponseRaw
,因为我无法弄清楚如何。
我不确定这是否足够清楚,addHeader
部分应用,并且是传递给内部应用程序的延续功能。这种形式可能是更清晰的(或丑陋):
withHeader h app req respond = app req $ \resp -> respond $ addHeader h resp
我从wai-session复制mapHeader
,但添加的情况下ResponseRaw。
不幸的是必须从Network.Wai.Internal中导入Response构造函数,但据我所知,这是您完成它的唯一方法。 – hdgarrood 2015-07-03 07:33:28
另外,部分应用的addHeader对我来说很清楚;我宁愿比那个eta扩展版本。最后,在mapHeader的最后一个模式中,由于未使用“f”,我宁愿将'_'用于'f'。 (我认为如果你使用了-Wall,这会产生一个警告) – hdgarrood 2015-07-03 07:35:58
@hdgarrood我把未使用的'f'改成'_'。那更好。随着我对Haskell习以为常,我更喜欢部分应用的版本。感谢您的评论! – rob 2015-07-03 19:46:34
你当然可以导入'Network.Wai.Internal'来模式匹配'Response'的构造函数。 – ibotty 2014-11-01 21:06:10
@ibotty好吧,我感到很傻。我试过了,但失败了。结果失败了,因为其中一个类型构造函数的名称已经改变,我没有注意到。 – rob 2014-11-02 01:29:18
下一次尝试在ghci中探索它。使用':i',你将会了解所有的构造函数以及它们的定义。 – ibotty 2014-11-03 09:19:10