如何使用Scotty/wai在代理后面记录真实的IP地址



这是我的scotty应用程序,请注意我是如何将请求记录到控制台的:

{-# LANGUAGE OverloadedStrings #-}
import Web.Scotty
import Network.Wai.Middleware.RequestLogger
import Data.Monoid (mconcat)
main = scotty 3000 $ do
    --log requests to console
    middleware logStdoutDev
    get "/:word" $ do
        beam <- param "word"
        html $ mconcat ["<h1>Scotty, ", beam, " me up!</h1>"]

我的scotty应用程序使用代理机制在nginx后面运行。这导致scotty应用程序像这样登录:

127.0.0.1 - - [27/Aug/2014:15:12:00 +0000] "GET / HTTP/1.0" 200 - ...

我希望记录真实IP地址

我在Node.js/Express应用程序中遇到了同样的问题,我这样解决了它:

Express.js:如何获取远程客户端地址

我该如何在斯科蒂解决这个问题?

wai-extra中有一个源自wai-logger包的IPAddrSource数据类型。因此,如果你想让IP地址来自标头,看起来你可以做一些类似的事情:

{-# LANGUAGE OverloadedStrings #-}
import Web.Scotty
import Network.Wai.Middleware.RequestLogger
import Control.Monad.IO.Class
import Data.Monoid (mconcat)
import Data.Default
main = scotty 3000 $ do
    --log requests to console
    logger <- liftIO $ mkRequestLogger def { outputFormat = Apache FromHeader }
    middleware logger
    get "/:word" $ do
        beam <- param "word"
        html $ mconcat ["<h1>Scotty, ", beam, " me up!</h1>"]

从描述中,看起来Apache FromFallback将首先检查标头,如果找不到标头,则使用套接字IP地址。

更新

您也可以在scotty函数之外创建记录器:

main = do
    logger <- mkRequestLogger def { outputFormat = Apache FromHeader }
    scotty 3000 $ do
        middleware logger
        get "/:word" $ do
            beam <- param "word"
            html $ mconcat ["<h1>Scotty, ", beam, " me up!</h1>"]

最新更新