packages feed

http-reverse-proxy 0.4.3.3 → 0.4.4

raw patch · 4 files changed

+50/−18 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Network.HTTP.ReverseProxy: rawTcpProxyTo :: (MonadBaseControl IO m, MonadIO m) => ProxyDest -> AppData -> m ()

Files

ChangeLog.md view
@@ -1,3 +1,8 @@+## 0.4.4++* add `rawTcpProxyTo` which can handle proxying connections without http headers +  [#21](https://github.com/fpco/http-reverse-proxy/issues/21) + ## 0.4.3.3  * `fixReqHeaders` may create weird `x-real-ip` header [#19](https://github.com/fpco/http-reverse-proxy/issues/19)
Network/HTTP/ReverseProxy.hs view
@@ -10,6 +10,7 @@       ProxyDest (..)       -- * Raw     , rawProxyTo+    , rawTcpProxyTo       -- * WAI + http-conduit     , waiProxyTo     , defaultOnExc@@ -121,15 +122,35 @@   where     fromClient = DCN.appSource appdata     toClient = DCN.appSink appdata-    withServer rsrc appdataServer = do-        x <- newEmptyMVar-        tid1 <- fork $ (rsrc $$+- toServer) `finally` putMVar x True-        tid2 <- fork $ (fromServer $$ toClient) `finally` putMVar x False-        y <- takeMVar x-        killThread $ if y then tid2 else tid1+    withServer rsrc appdataServer = void $ concurrently+        (rsrc $$+- toServer)+        (fromServer $$ toClient)       where         fromServer = DCN.appSource appdataServer         toServer = DCN.appSink appdataServer++-- | Set up a reverse tcp proxy server, which will have a minimal overhead.+--+-- This function uses raw sockets, parsing as little of the request as+-- possible. The workflow is:+--+-- 1. Open up a connection to the given host\/port.+--+-- 2. Pass all bytes across the wire unchanged.+--+-- If you need more control, such as modifying the request or response, use 'waiProxyTo'.+--+-- Since 0.4.4+rawTcpProxyTo :: (MonadBaseControl IO m, MonadIO m)+           => ProxyDest+           -> AppData+           -> m ()+rawTcpProxyTo (ProxyDest host port) appdata = liftIO $+    DCN.runTCPClient (DCN.clientSettings port host) withServer+  where+    withServer appdataServer = void $ concurrently+      (DCN.appSource appdata       $$ DCN.appSink appdataServer)+      (DCN.appSource appdataServer $$ DCN.appSink appdata      )  -- | Sends a simple 502 bad gateway error message with the contents of the -- exception.
http-reverse-proxy.cabal view
@@ -1,5 +1,5 @@ name:                http-reverse-proxy-version:             0.4.3.3+version:             0.4.4 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
@@ -28,7 +28,7 @@ import qualified Network.HTTP.Conduit         as HC import           Network.HTTP.ReverseProxy    (ProxyDest (..),                                                WaiProxyResponse (..),-                                               defaultOnExc, rawProxyTo,+                                               defaultOnExc, rawProxyTo, rawTcpProxyTo,                                                WaiProxySettings (..),                                                SetIpHeader (..),                                                def,@@ -89,16 +89,18 @@ withMan = HC.withManager . (liftIO .)  main :: IO ()-main = hspec $ do+main = hspec $     describe "http-reverse-proxy" $ do         it "works" $             let content = "mainApp"              in withMan $ \manager ->                 withWApp (\_ f -> f $ responseLBS status200 [] content) $ \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 <- HC.simpleHttp $ "http://127.0.0.1:" ++ show port3+                withCApp (rawProxyTo (const $ return $ Right $ ProxyDest "127.0.0.1" port2)) $ \port3 ->+                withCApp (rawTcpProxyTo (ProxyDest "127.0.0.1" port3)) $ \port4 -> do+                    lbs <- HC.simpleHttp $ "http://127.0.0.1:" ++ show port4                     lbs `shouldBe` content+         it "modified path" $             let content = "/somepath"                 app req f = f $ responseLBS status200 [] $ L8.fromChunks [rawPathInfo req]@@ -108,8 +110,9 @@              in withMan $ \manager ->                 withWApp app $ \port1 ->                 withWApp (waiProxyTo (modReq $ ProxyDest "127.0.0.1" port1) defaultOnExc manager) $ \port2 ->-                withCApp (rawProxyTo (const $ return $ Right $ ProxyDest "127.0.0.1" port2)) $ \port3 -> do-                    lbs <- HC.simpleHttp $ "http://127.0.0.1:" ++ show port3+                withCApp (rawProxyTo (const $ return $ Right $ ProxyDest "127.0.0.1" port2)) $ \port3 ->+                withCApp (rawTcpProxyTo (ProxyDest "127.0.0.1" port3)) $ \port4 -> do+                    lbs <- HC.simpleHttp $ "http://127.0.0.1:" ++ show port4                     S8.concat (L8.toChunks lbs) `shouldBe` content         it "deals with streaming data" $             let app _ f = f $ responseStream status200 [] $ \sendChunk flush -> forever $ do@@ -172,8 +175,9 @@              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+                withCApp (rawProxyTo (const $ return $ Right $ ProxyDest "127.0.0.1" port2)) $ \port3 ->+                withCApp (rawTcpProxyTo (ProxyDest "127.0.0.1" port3)) $ \port4 -> do+                    lbs <- httpWithForwardedFor $ "http://127.0.0.1:" ++ show port4                     lbs `shouldBe` "127.0.1.1"         it "get real ip 2" $             let getRealIp req = L8.fromStrict $ fromMaybe "" $ lookup "x-real-ip" (requestHeaders req)@@ -186,8 +190,9 @@              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+                withCApp (rawProxyTo (const $ return $ Right $ ProxyDest "127.0.0.1" port2)) $ \port3 ->+                withCApp (rawTcpProxyTo (ProxyDest "127.0.0.1" port3)) $ \port4 -> do+                    lbs <- httpWithForwardedFor $ "http://127.0.0.1:" ++ show port4                     lbs `shouldBe` "127.0.1.1"         it "get real ip 3" $             let getRealIp req = L8.fromStrict $ fromMaybe "" $ lookup "x-real-ip" (requestHeaders req)@@ -201,7 +206,8 @@                 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+                withCApp (rawTcpProxyTo (ProxyDest "127.0.0.1" port3)) $ \port4 -> do+                    lbs <- httpWithForwardedFor $ "http://127.0.0.1:" ++ show port4                     lbs `shouldBe` "127.0.0.1"     {- FIXME     describe "waiToRaw" $ do