我想通過編寫一個非常簡單的會話管理器來了解中間件。在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