Skip to content

Commit e3e3491

Browse files
committed
Add withServer
1 parent 4cb0d5d commit e3e3491

File tree

2 files changed

+35
-12
lines changed

2 files changed

+35
-12
lines changed

src/Network/VCR.hs

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
{-# LANGUAGE NamedFieldPuns #-}
22
module Network.VCR
33
( server
4+
, withServer
45
) where
56

6-
import Control.Exception (SomeException)
7+
import Control.Concurrent (forkIO, killThread, threadDelay)
8+
import Control.Concurrent.MVar (newEmptyMVar, putMVar, takeMVar, MVar)
9+
import Control.Exception (SomeException, bracket)
10+
import Control.Monad
711
import qualified Data.ByteString.Char8 as BS
812
import qualified Data.ByteString.Lazy.Char8 as LBS
913
import qualified Network.HTTP.Client as HC
@@ -17,7 +21,6 @@ import qualified Network.Wai as Wai
1721
import qualified Network.Wai.Handler.Warp as Warp
1822

1923

20-
2124
import Control.Applicative ((<**>))
2225
import Network.VCR.Middleware (die, middleware)
2326
import Network.VCR.Types (Options (..), parseOptions)
@@ -38,24 +41,39 @@ server = execParser opts >>= run
3841
<> header "VCR Proxy" )
3942

4043
run :: Options -> IO ()
41-
run Options { mode, cassettePath, port } = do
44+
run options@Options { mode, cassettePath, port } = do
45+
putStrLn $ "Starting VCR proxy, mode: " <> show mode <> ", cassette file: " <> cassettePath <> ", listening on port: " <> show port
46+
withServer options $ do
47+
putStrLn "VCR proxy started"
48+
forever $ threadDelay 1000000000
49+
50+
withServer :: Options -> IO a -> IO a
51+
withServer Options { mode, cassettePath, port } action = do
4252
-- Set line buffering, because if we use it from a parent process, pipes are full buffered by default
4353
hSetBuffering stdout LineBuffering
44-
putStrLn $ "Starting VCR proxy, mode: " <> show mode <> ", cassette file: " <> cassettePath <> ", listening on port: " <> show port
45-
mgr <- HC.newManager HC.tlsManagerSettings
46-
Warp.runSettings (warpSettings settings) $ middleware mode cassettePath $ HProxy.httpProxyApp settings mgr
47-
where
48-
settings = HProxy.defaultProxySettings { HProxy.proxyPort = port }
54+
started <- newEmptyMVar
55+
bracket (start started) killThread $ \_ -> do
56+
takeMVar started
57+
action
58+
59+
where
60+
start started = forkIO $ do
61+
mgr <- HC.newManager HC.tlsManagerSettings
62+
Warp.runSettings (warpSettings started proxySettings) $ middleware mode cassettePath $ HProxy.httpProxyApp proxySettings mgr
63+
proxySettings = HProxy.defaultProxySettings { HProxy.proxyPort = port }
4964

5065

5166

52-
warpSettings :: HProxy.Settings -> Warp.Settings
53-
warpSettings pset = Warp.setPort (HProxy.proxyPort pset)
67+
warpSettings
68+
:: MVar () -- ^ MVar to put after starting
69+
-> HProxy.Settings
70+
-> Warp.Settings
71+
warpSettings started pset = Warp.setPort (HProxy.proxyPort pset)
5472
. Warp.setHost (HProxy.proxyHost pset)
5573
. Warp.setTimeout (HProxy.proxyTimeout pset)
5674
. Warp.setOnExceptionResponse defaultExceptionResponse
5775
-- This is needed so we know when we start using the proxy if it is run as a child process
58-
. Warp.setBeforeMainLoop (putStrLn "VCR proxy started")
76+
. Warp.setBeforeMainLoop (putMVar started ())
5977
$ Warp.setNoParsePath True Warp.defaultSettings
6078

6179
defaultExceptionResponse :: SomeException -> Wai.Response

src/Network/VCR/Types.hs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
{-# LANGUAGE DeriveAnyClass #-}
22
{-# LANGUAGE DeriveGeneric #-}
33
{-# LANGUAGE NamedFieldPuns #-}
4+
{-# LANGUAGE PatternSynonyms #-}
5+
46
module Network.VCR.Types where
57

68
import qualified Data.ByteString as B
@@ -42,11 +44,14 @@ data Options = Options
4244
, port :: Int
4345
} deriving (Eq, Show)
4446

47+
pattern DEFAULT_PORT :: Int
48+
pattern DEFAULT_PORT = 3128
49+
4550
parseOptions :: Parser Options
4651
parseOptions = Options
4752
<$> strOption (long "cassette" <> short 'c' <> metavar "CASSETTE_FILE" <> help "Cassette yaml file for recording/replaying the API interactions")
4853
<*> (parseRecordMode <|> parseReplayMode)
49-
<*> option auto (long "port" <> help "Port to listen on" <> showDefault <> value 3128 <> metavar "INT")
54+
<*> option auto (long "port" <> help "Port to listen on" <> showDefault <> value DEFAULT_PORT <> metavar "INT")
5055

5156

5257
data SavedRequest = SavedRequest

0 commit comments

Comments
 (0)