packages feed

Blammo 1.0.2.2 → 1.0.2.3

raw patch · 3 files changed

+36/−6 lines, 3 filesPVP: minor bump suggested

API additions: PVP suggests at least a minor version bump

API changes (from Hackage documentation)

+ Network.Wai.Middleware.Logging: setConfigGetClientIp :: (Request -> Text) -> Config -> Config

Files

Blammo.cabal view
@@ -1,6 +1,6 @@ cabal-version:   1.18 name:            Blammo-version:         1.0.2.2+version:         1.0.2.3 license:         MIT license-file:    LICENSE maintainer:      Freckle Education
CHANGELOG.md view
@@ -1,4 +1,8 @@-## [_Unreleased_](https://github.com/freckle/blammo/compare/v1.0.2.2...main)+## [_Unreleased_](https://github.com/freckle/blammo/compare/v1.0.2.3...main)++## [v1.0.2.3](https://github.com/freckle/blammo/compare/v1.0.2.2...v1.0.2.3)++- Fix for localhost `clientIp` value in `requestLogger` ([#18](https://github.com/freckle/blammo/issues/18))  ## [v1.0.2.2](https://github.com/freckle/blammo/compare/v1.0.2.1...v1.0.2.2) 
src/Network/Wai/Middleware/Logging.hs view
@@ -8,12 +8,14 @@   , Config   , defaultConfig   , setConfigLogSource+  , setConfigGetClientIp   , setConfigGetDestinationIp   ) where  import Prelude  import Blammo.Logging+import Control.Applicative ((<|>)) import Control.Arrow ((***)) import Control.Monad.IO.Unlift (withRunInIO) import Data.Aeson@@ -21,7 +23,10 @@ import qualified Data.Aeson.Compat as KeyMap import Data.ByteString (ByteString) import qualified Data.CaseInsensitive as CI+import Data.List (find)+import Data.Maybe (fromMaybe) import Data.Text (Text, pack)+import qualified Data.Text as T import Data.Text.Encoding (decodeUtf8With) import Data.Text.Encoding.Error (lenientDecode) import Network.HTTP.Types.Header (Header, HeaderName)@@ -87,17 +92,23 @@  data Config = Config   { cLogSource :: LogSource+  , cGetClientIp :: Request -> Text   , cGetDestinationIp :: Request -> Maybe Text   }  defaultConfig :: Config defaultConfig = Config   { cLogSource = "requestLogger"-  , cGetDestinationIp = fmap decodeUtf8 . lookupRequestHeader "x-real-ip"+  , cGetClientIp = \req ->+    fromMaybe (pack $ show $ remoteHost req)+      $ (firstValue =<< lookupRequestHeader "x-forwarded-for" req)+      <|> lookupRequestHeader "x-real-ip" req+  , cGetDestinationIp = lookupRequestHeader "x-real-ip"   }+  where firstValue = find (not . T.null) . map T.strip . T.splitOn "," -lookupRequestHeader :: HeaderName -> Request -> Maybe ByteString-lookupRequestHeader h = lookup h . requestHeaders+lookupRequestHeader :: HeaderName -> Request -> Maybe Text+lookupRequestHeader h = fmap decodeUtf8 . lookup h . requestHeaders  -- | Change the source used for log messages --@@ -106,10 +117,25 @@ setConfigLogSource :: LogSource -> Config -> Config setConfigLogSource x c = c { cLogSource = x } +-- | Change how the @clientIp@ field is determined+--+-- Default is looking up the first value in @x-forwarded-for@, then the+-- @x-real-ip@ header, then finally falling back to 'Network.Wai.remoteHost'.+--+setConfigGetClientIp :: (Request -> Text) -> Config -> Config+setConfigGetClientIp x c = c { cGetClientIp = x }+ -- | Change how the @destinationIp@ field is determined -- -- Default is looking up the @x-real-ip@ header. --+-- __NOTE__: Our default uses a somewhat loose definition of /destination/. It+-- would be more accurate to report the resolved IP address of the @Host@+-- header, but we don't have that available. Our default of @x-real-ip@ favors+-- containerized Warp on AWS/ECS, where this value holds the ECS target+-- container's IP address. This is valuable debugging information and could, if+-- you squint, be considered a /destination/.+-- setConfigGetDestinationIp :: (Request -> Maybe Text) -> Config -> Config setConfigGetDestinationIp x c = c { cGetDestinationIp = x } @@ -150,7 +176,7 @@       [ "code" .= statusCode status       , "message" .= decodeUtf8 (statusMessage status)       ]-    , "clientIp" .= show (remoteHost req)+    , "clientIp" .= cGetClientIp req     , "destinationIp" .= cGetDestinationIp req     , "durationMs" .= duration     , "requestHeaders"