packages feed

http-reverse-proxy 0.4.3.2 → 0.4.3.3

raw patch · 4 files changed

+61/−4 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

ChangeLog.md view
@@ -1,3 +1,7 @@+## 0.4.3.3++* `fixReqHeaders` may create weird `x-real-ip` header [#19](https://github.com/fpco/http-reverse-proxy/issues/19)+ ## 0.4.3.2  * Minor doc cleanup
Network/HTTP/ReverseProxy.hs view
@@ -58,13 +58,15 @@ import           Data.Default.Class             (Default (..), def) import           Data.Functor.Identity          (Identity (..)) import           Data.IORef-import           Data.Maybe                     (fromMaybe)+import           Data.Maybe                     (fromMaybe, listToMaybe) import           Data.Monoid                    (mappend, mconcat, (<>)) import           Data.Set                       (Set) import qualified Data.Set                       as Set import           Data.Streaming.Network         (AppData, readLens) import qualified Data.Text.Lazy                 as TL import qualified Data.Text.Lazy.Encoding        as TLE+import qualified Data.Text                      as T+import qualified Data.Text.Encoding             as TE import           Data.Word8                     (isSpace, _colon, _cr) import           Network.HTTP.Client            (BodyReader, brRead) import qualified Network.HTTP.Client            as HC@@ -319,11 +321,14 @@                $ WAI.requestHeaders req   where     fromSocket = (("X-Real-IP", S8.pack $ showSockAddr $ WAI.remoteHost req):)+    fromForwardedFor = do+      h <- lookup "x-forwarded-for" (WAI.requestHeaders req)+      listToMaybe $ map (TE.encodeUtf8 . T.strip) $ T.splitOn "," $ TE.decodeUtf8 h     addXRealIP =         case wpsSetIpHeader wps of             SIHFromSocket -> fromSocket             SIHFromHeader ->-                case lookup "x-real-ip" (WAI.requestHeaders req) <|> lookup "X-Forwarded-For" (WAI.requestHeaders req) of+                case lookup "x-real-ip" (WAI.requestHeaders req) <|> fromForwardedFor of                     Nothing -> fromSocket                     Just ip -> (("X-Real-IP", ip):)             SIHNone -> id
http-reverse-proxy.cabal view
@@ -1,5 +1,5 @@ name:                http-reverse-proxy-version:             0.4.3.2+version:             0.4.3.3 synopsis:            Reverse proxy HTTP requests, either over raw sockets or with WAI description:         Provides a simple means of reverse-proxying HTTP requests. The raw approach uses the same technique as leveraged by keter, whereas the WAI approach performs full request/response parsing via WAI and http-conduit. homepage:            https://github.com/fpco/http-reverse-proxy
test/main.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE OverloadedStrings   #-} {-# LANGUAGE ScopedTypeVariables #-} import           Blaze.ByteString.Builder     (fromByteString)+import           Control.Applicative          ((<$>)) import           Control.Concurrent           (forkIO, killThread, newEmptyMVar,                                                putMVar, takeMVar, threadDelay) import           Control.Exception            (IOException, bracket,@@ -8,6 +9,7 @@ import           Control.Monad                (forever, unless) import           Control.Monad.IO.Class       (liftIO) import           Control.Monad.Trans.Resource (runResourceT)+import           Data.Maybe                   (fromMaybe) import qualified Data.ByteString              as S import qualified Data.ByteString.Char8        as S8 import qualified Data.ByteString.Lazy.Char8   as L8@@ -27,11 +29,15 @@ import           Network.HTTP.ReverseProxy    (ProxyDest (..),                                                WaiProxyResponse (..),                                                defaultOnExc, rawProxyTo,+                                               WaiProxySettings (..),+                                               SetIpHeader (..),+                                               def,+                                               waiProxyToSettings,                                                waiProxyTo) import           Network.HTTP.Types           (status200, status500) import           Network.Socket               (sClose) import           Network.Wai                  (rawPathInfo, responseLBS,-                                               responseStream)+                                               responseStream, requestHeaders) import qualified Network.Wai import           Network.Wai.Handler.Warp     (defaultSettings, runSettings,                                                setBeforeMainLoop, setPort)@@ -155,6 +161,48 @@                         yield "GET / HTTP/1.1\r\nUpgrade: websockET\r\n\r\n" $$ appSink ad                         yield "hello" $$ appSink ad                         (appSource ad $$ CB.take 5) >>= (`shouldBe` "HELLO")+        it "get real ip" $+            let getRealIp req = L8.fromStrict $ fromMaybe "" $ lookup "x-real-ip" (requestHeaders req)+                httpWithForwardedFor url = liftIO $ do+                  man <- HC.newManager HC.tlsManagerSettings+                  oreq <- liftIO $ HC.parseUrl url+                  let req = oreq { HC.requestHeaders = [("X-Forwarded-For", "127.0.1.1, 127.0.0.1"), ("Connection", "close")] }+                  HC.responseBody <$> HC.httpLbs req man+                waiProxyTo' getDest onError = waiProxyToSettings getDest def { wpsOnExc = onError, wpsSetIpHeader = SIHFromHeader }+             in withMan $ \manager ->+                withWApp (\r f -> f $ responseLBS status200 [] $ getRealIp r ) $ \port1 ->+                withWApp (waiProxyTo' (const $ return $ WPRProxyDest $ ProxyDest "127.0.0.1" port1) defaultOnExc manager) $ \port2 ->+                withCApp (rawProxyTo (const $ return $ Right $ ProxyDest "127.0.0.1" port2)) $ \port3 -> do+                    lbs <- httpWithForwardedFor $ "http://127.0.0.1:" ++ show port3+                    lbs `shouldBe` "127.0.1.1"+        it "get real ip 2" $+            let getRealIp req = L8.fromStrict $ fromMaybe "" $ lookup "x-real-ip" (requestHeaders req)+                httpWithForwardedFor url = liftIO $ do+                  man <- HC.newManager HC.tlsManagerSettings+                  oreq <- liftIO $ HC.parseUrl url+                  let req = oreq { HC.requestHeaders = [("X-Forwarded-For", "127.0.1.1"), ("Connection", "close")] }+                  HC.responseBody <$> HC.httpLbs req man+                waiProxyTo' getDest onError = waiProxyToSettings getDest def { wpsOnExc = onError, wpsSetIpHeader = SIHFromHeader }+             in withMan $ \manager ->+                withWApp (\r f -> f $ responseLBS status200 [] $ getRealIp r ) $ \port1 ->+                withWApp (waiProxyTo' (const $ return $ WPRProxyDest $ ProxyDest "127.0.0.1" port1) defaultOnExc manager) $ \port2 ->+                withCApp (rawProxyTo (const $ return $ Right $ ProxyDest "127.0.0.1" port2)) $ \port3 -> do+                    lbs <- httpWithForwardedFor $ "http://127.0.0.1:" ++ show port3+                    lbs `shouldBe` "127.0.1.1"+        it "get real ip 3" $+            let getRealIp req = L8.fromStrict $ fromMaybe "" $ lookup "x-real-ip" (requestHeaders req)+                httpWithForwardedFor url = liftIO $ do+                  man <- HC.newManager HC.tlsManagerSettings+                  oreq <- liftIO $ HC.parseUrl url+                  let req = oreq { HC.requestHeaders = [("Connection", "close")] }+                  HC.responseBody <$> HC.httpLbs req man+                waiProxyTo' getDest onError = waiProxyToSettings getDest def { wpsOnExc = onError, wpsSetIpHeader = SIHFromHeader }+             in withMan $ \manager ->+                withWApp (\r f -> f $ responseLBS status200 [] $ getRealIp r ) $ \port1 ->+                withWApp (waiProxyTo' (const $ return $ WPRProxyDest $ ProxyDest "127.0.0.1" port1) defaultOnExc manager) $ \port2 ->+                withCApp (rawProxyTo (const $ return $ Right $ ProxyDest "127.0.0.1" port2)) $ \port3 -> do+                    lbs <- httpWithForwardedFor $ "http://127.0.0.1:" ++ show port3+                    lbs `shouldBe` "127.0.0.1"     {- FIXME     describe "waiToRaw" $ do         it "works" $ do