wai-cli 0.2.0 → 0.2.1
raw patch · 3 files changed
+57/−19 lines, 3 filesdep ~network
Dependency ranges changed: network
Files
- README.md +1/−0
- library/Network/Wai/Cli.hs +45/−16
- wai-cli.cabal +11/−3
README.md view
@@ -5,6 +5,7 @@ - `--protocol http --port 8000` TCP sockets - `--protocol unix --socket /var/run/app/sock` UNIX domain sockets - `--protocol cgi` running as a CGI app (the original serverless lambda functions from the 90s)+- `--protocol fastcgi` running as a FastCGI app (OPTIONAL! You need to build with the `fastcgi` cabal flag and you need to have `libfcgi` (e.g. `fcgi-devkit` package on FreeBSD) installed) - `--protocol activate` socket activation (systemd-compatible, but not restricted to systemd in any way. see [soad](https://github.com/myfreeweb/soad) for an interesting use of (de)activation!) - `--protocol (http+tls|unix+tls|activate+tls) --tlskey key.pem --tlscert cert.pem` TLS (can be turned off with a cabal flag to avoid compiling [the TLS library](https://github.com/vincenthz/hs-tls)) - `--graceful (none|serve-normally|serve-503)` graceful shutdown (on TERM signal)
library/Network/Wai/Cli.hs view
@@ -2,7 +2,6 @@ module Network.Wai.Cli where -import Network.Wai (responseLBS, Application) import qualified Network.Wai.Handler.CGI as CGI import Network.Wai.Handler.Warp hiding (run) #ifdef WaiCliTLS@@ -12,17 +11,24 @@ import qualified Network.Wai.Handler.FastCGI as FCGI #endif import Network.Wai.Middleware.RequestLogger (logStdoutDev)+#ifdef WaiCliUnix+import Network.Wai (responseLBS, Application) import Network.HTTP.Types (serviceUnavailable503) import Network.Socket.Activation-import qualified Network.Socket as S-import GHC.Conc (getNumCapabilities, forkIO) import System.Posix.Internals (setNonBlockingFD) import System.Posix.Signals (installHandler, sigTERM, Handler(CatchOnce)) import Data.Streaming.Network (bindPath, bindPortTCP)-import System.Console.ANSI-import Control.Concurrent.STM import Control.Monad import Control.Monad.Trans (liftIO)+import Control.Concurrent.STM+import GHC.Conc (getNumCapabilities, forkIO)+#else+import Network.Wai (Application)+import Data.Streaming.Network (bindPortTCP)+import GHC.Conc (getNumCapabilities)+#endif+import qualified Network.Socket as S+import System.Console.ANSI import Control.Exception (bracket) import Options import Data.List (intercalate)@@ -34,45 +40,54 @@ data WaiOptions = WaiOptions { wHttpPort ∷ Int , wHttpHost ∷ String+#ifdef WaiCliUnix , wUnixSock ∷ String+#endif , wProtocol ∷ String #ifdef WaiCliTLS , wTlsKeyFile ∷ String , wTlsCertFile ∷ String #endif+#ifdef WaiCliUnix , wGracefulMode ∷ String+#endif , wDevlogging ∷ Maybe Bool } instance Options WaiOptions where defineOptions = pure WaiOptions <*> simpleOption "port" 3000 "The port the app should listen for connections on (for http)" <*> simpleOption "host" "*4" "Host preference (for http)"+#ifdef WaiCliUnix <*> simpleOption "socket" "wai.sock" "The UNIX domain socket path the app should listen for connections on (for unix)"+#endif <*> simpleOption "protocol" "http" ("The protocol for the server. One of: " ++ availableProtocols) #ifdef WaiCliTLS <*> simpleOption "tlskey" "" "Path to the TLS private key file for +tls protocols" <*> simpleOption "tlscert" "" "Path to the TLS certificate bundle file for +tls protocols" #endif+#ifdef WaiCliUnix <*> simpleOption "graceful" "serve-normally" "Graceful shutdown mode. One of: none, serve-normally, serve-503"+#endif <*> simpleOption "devlogging" Nothing "Whether development logging should be enabled" where- availableProtocols = intercalate ", " $ concat- [coreProtocols, tlsProtocols, fcgiProtocol]- coreProtocols = ["http", "unix", "activate", "cgi"]- tlsProtocols =+ availableProtocols = intercalate ", " [+ "http", "cgi"+#ifdef WaiCliUnix+ , "unix", "activate"+#endif #ifdef WaiCliTLS- ["http+tls", "unix+tls", "activate+tls"]-#else- []+ , "http+tls" #endif- fcgiProtocol =+#if defined(WaiCliTLS) && defined(WaiCliUnix)+ , "unix+tls", "activate+tls"+#endif #ifdef WaiCliFastCGI- ["fastcgi"]-#else- []+ , "fastcgi" #endif+ ] +#ifdef WaiCliUnix runActivated ∷ (Settings → S.Socket → Application → IO ()) → Settings → Application → IO () runActivated run warps app = do sockets ← getActivatedSockets@@ -83,6 +98,7 @@ forkIO $ run warps sock app Nothing → putStrLn "No sockets to activate" + runGraceful ∷ GracefulMode → (Settings → Application → IO ()) → Settings → Application → IO () runGraceful mode run warps app = do -- based on https://gist.github.com/NathanHowell/5435345@@ -102,6 +118,7 @@ takeTMVar shutdown conns ← readTVar activeConnections when (conns /= 0) retry+#endif -- | Adjusts 'WaiOptions' with an address assigned to a newly created -- server socket, uses those to set a "before main loop" function in@@ -142,20 +159,28 @@ _ → do let run = case wProtocol opts of "http" → runWarp putListening opts runSettingsSocket+#ifdef WaiCliUnix "unix" → \warps' app'' → bracket (bindPath $ wUnixSock opts) S.close (\sock → runSettingsSocket warps' sock app'') "activate" → runActivated runSettingsSocket+#endif #ifdef WaiCliTLS "http+tls" → runWarp putListening opts (runTLSSocket tlss)+#ifdef WaiCliUnix "unix+tls" → \warps' app'' → bracket (bindPath $ wUnixSock opts) S.close (\sock → runTLSSocket tlss warps' sock app'') "activate+tls" → runActivated (runTLSSocket tlss) #endif+#endif x → \_ _ → putStrLn $ "Unsupported protocol: " ++ x putWelcome opts+#ifdef WaiCliUnix case wGracefulMode opts of "none" → run warps app' "serve-normally" → runGraceful ServeNormally run warps app' "serve-503" → runGraceful Serve503 run warps app' x → putStrLn $ "Unsupported graceful mode: " ++ x+#else+ run warps app'+#endif defPutListening ∷ WaiOptions → IO () defPutListening opts = getNumCapabilities >>= putMain@@ -163,12 +188,16 @@ putProto = case wProtocol opts of "http" → reset " host " >> boldMagenta (wHttpHost opts) >> reset ", port " >> boldMagenta (show $ wHttpPort opts)+#ifdef WaiCliUnix "unix" → reset " socket " >> boldMagenta (show $ wUnixSock opts) "activate" → reset " activated socket"+#endif #ifdef WaiCliTLS "http+tls" → reset " (TLS) port " >> boldMagenta (show $ wHttpPort opts)+#ifdef WaiCliUnix "unix+tls" → reset " (TLS) socket " >> boldMagenta (show $ wUnixSock opts) "activate+tls" → reset " (TLS) activated socket"+#endif #endif _ → setReset setReset = setSGR [ Reset ]
wai-cli.cabal view
@@ -1,5 +1,5 @@ name: wai-cli-version: 0.2.0+version: 0.2.1 synopsis: Command line runner for Wai apps (using Warp) with TLS, CGI, socket activation & graceful shutdown description: Command line runner for Wai apps (using Warp) with support for UNIX domain sockets,@@ -32,17 +32,19 @@ description: Include wai-handler-fastcgi default: False +flag unixsockets+ description: Enable Unix sockets+ default: True+ library build-depends: base >= 4.8.0.0 && < 5 , options , warp- , socket-activation , streaming-commons , http-types , monads-tf , stm- , unix , network >= 2.7 , wai , wai-extra@@ -59,3 +61,9 @@ if flag(fastcgi) build-depends: wai-handler-fastcgi cpp-options: -DWaiCliFastCGI+ if !os(windows) && flag(unixsockets)+ cpp-options: -DWaiCliUnix+ build-depends:+ unix+ , socket-activation+