Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to log the real IP address when behind a proxy using Scotty / wai

This is my scotty app, notice how I am logging requests to the console:

{-# 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>"]

My scotty app runs behind nginx using the proxy mechanism. This causes the scotty app to log like this:

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

I want the REAL IP ADDRESS to be logged.

I had the same issue in my Node.js/Express apps, where I solved it like this:

Express.js: how to get remote client address

How do I solve this problem in Scotty?

like image 340
stackoverflowuser Avatar asked Aug 27 '14 21:08

stackoverflowuser


1 Answers

There's an IPAddrSource data type in wai-extra which originates in the wai-logger package. So, if you want the IP address to come from a header, it looks like you can do something like:

{-# 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>"]

From the description, it also looks like Apache FromFallback will check the headers first, and use the socket IP address if no header is found.

Update

You can also just create the logger outside the scotty function:

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>"]
like image 105
Shaun the Sheep Avatar answered Sep 23 '22 02:09

Shaun the Sheep