2014-11-01 55 views
3

我想通過編寫一個非常簡單的會話管理器來了解中間件。在Haskell WAI中,如何添加標題作爲中間件?

我需要在響應中添加SetCookie標頭。我看了一下wai-extra包,發現wai-session

我正在使用wai-3.0.2,它似乎沒有給我直接訪問響應的類型構造函數,並且我發現在Response(..)上找到模式匹配以添加標題的所有示例。

您能否指點我正確的方向?

+1

你當然可以導入'Network.Wai.Internal'來模式匹配'Response'的構造函數。 – ibotty 2014-11-01 21:06:10

+0

@ibotty好吧,我感到很傻。我試過了,但失敗了。結果失敗了,因爲其中一個類型構造函數的名稱已經改變,我沒有注意到。 – rob 2014-11-02 01:29:18

+0

下一次嘗試在ghci中探索它。使用':i',你將會了解所有的構造函數以及它們的定義。 – ibotty 2014-11-03 09:19:10

回答

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 _ [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。

+0

不幸的是必須從Network.Wai.Internal中導入Response構造函數,但據我所知,這是您完成它的唯一方法。 – hdgarrood 2015-07-03 07:33:28

+0

另外,部分應用的addHeader對我來說很清楚;我寧願比那個eta擴展版本。最後,在mapHeader的最後一個模式中,由於未使用「f」,我寧願將'_'用於'f'。 (我認爲如果你使用了-Wall,這會產生一個警告) – hdgarrood 2015-07-03 07:35:58

+0

@hdgarrood我把未使用的'f'改成'_'。那更好。隨着我對Haskell習以爲常,我更喜歡部分應用的版本。感謝您的評論! – rob 2015-07-03 19:46:34

相關問題