11{-# LANGUAGE NamedFieldPuns #-}
22module 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
711import qualified Data.ByteString.Char8 as BS
812import qualified Data.ByteString.Lazy.Char8 as LBS
913import qualified Network.HTTP.Client as HC
@@ -17,7 +21,6 @@ import qualified Network.Wai as Wai
1721import qualified Network.Wai.Handler.Warp as Warp
1822
1923
20-
2124import Control.Applicative ((<**>) )
2225import Network.VCR.Middleware (die , middleware )
2326import Network.VCR.Types (Options (.. ), parseOptions )
@@ -38,24 +41,39 @@ server = execParser opts >>= run
3841 <> header " VCR Proxy" )
3942
4043run :: 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
6179defaultExceptionResponse :: SomeException -> Wai. Response
0 commit comments