Fix compiling on windows(unix socket issue)

Group unix socket functionality into its own module
This commit is contained in:
steve-chavez
2020-04-03 11:22:11 -05:00
committed by Steve Chavez
parent 426637a47c
commit 18e45659ea
4 changed files with 67 additions and 41 deletions
+20 -36
View File
@@ -16,24 +16,13 @@ import Data.Either.Combinators (whenLeft)
import Data.IORef (IORef, atomicWriteIORef, newIORef, import Data.IORef (IORef, atomicWriteIORef, newIORef,
readIORef) readIORef)
import Data.String (IsString (..)) import Data.String (IsString (..))
import Data.Text (pack, replace, strip, stripPrefix, import Data.Text (pack, replace, strip, stripPrefix)
unpack)
import Data.Text.Encoding (decodeUtf8, encodeUtf8) import Data.Text.Encoding (decodeUtf8, encodeUtf8)
import Data.Text.IO (hPutStrLn, readFile) import Data.Text.IO (hPutStrLn, readFile)
import Data.Time.Clock (getCurrentTime) import Data.Time.Clock (getCurrentTime)
import Network.Socket (Family (AF_UNIX),
SockAddr (SockAddrUnix), Socket,
SocketType (Stream), bind, close,
defaultProtocol, listen,
maxListenQueue, socket)
import Network.Wai.Handler.Warp (defaultSettings, runSettings, import Network.Wai.Handler.Warp (defaultSettings, runSettings,
runSettingsSocket, setHost, setPort, setHost, setPort, setServerName)
setServerName)
import System.Directory (removeFile)
import System.IO (BufferMode (..), hSetBuffering) import System.IO (BufferMode (..), hSetBuffering)
import System.IO.Error (isDoesNotExistError)
import System.Posix.Files (setFileMode)
import System.Posix.Types (FileMode)
import PostgREST.App (postgrest) import PostgREST.App (postgrest)
import PostgREST.Config (AppConfig (..), configPoolTimeout', import PostgREST.Config (AppConfig (..), configPoolTimeout',
@@ -50,8 +39,10 @@ import Protolude hiding (hPutStrLn, head, replace)
#ifndef mingw32_HOST_OS #ifndef mingw32_HOST_OS
import System.Posix.Signals import System.Posix.Signals
import UnixSocket
#endif #endif
{-| {-|
The purpose of this worker is to fill the refDbStructure created in 'main' The purpose of this worker is to fill the refDbStructure created in 'main'
with the 'DbStructure' returned from calling 'getDbStructure'. This method with the 'DbStructure' returned from calling 'getDbStructure'. This method
@@ -188,7 +179,6 @@ main = do
whenLeft roleClaimKey $ whenLeft roleClaimKey $
panic $ show roleClaimKey panic $ show roleClaimKey
--
-- create connection pool with the provided settings, returns either -- create connection pool with the provided settings, returns either
-- a 'Connection' or a 'ConnectionError'. Does not throw. -- a 'Connection' or a 'ConnectionError'. Does not throw.
pool <- P.acquire (configPool conf, configPoolTimeout' conf, pgSettings) pool <- P.acquire (configPool conf, configPoolTimeout' conf, pgSettings)
@@ -251,19 +241,17 @@ main = do
schemas schemas
refDbStructure refDbStructure
refIsWorkerOn) refIsWorkerOn)
in case maybeSocketAddr of
Nothing -> do -- run the postgrest application with user defined socket. Only for UNIX systems.
#ifndef mingw32_HOST_OS
whenJust maybeSocketAddr $
runAppInSocket appSettings postgrestApplication socketFileMode
#endif
-- run the postgrest application -- run the postgrest application
whenNothing maybeSocketAddr $ do
putStrLn $ ("Listening on port " :: Text) <> show (configPort conf) putStrLn $ ("Listening on port " :: Text) <> show (configPort conf)
runSettings appSettings postgrestApplication runSettings appSettings postgrestApplication
Just socketAddr -> do
-- run postgrest application with user defined socket
sock <- createAndBindSocket (unpack socketAddr) (rightToMaybe socketFileMode)
listen sock maxListenQueue
putStrLn $ ("Listening on unix socket " :: Text) <> show socketAddr
runSettingsSocket appSettings sock postgrestApplication
-- clean socket up when done
close sock
{-| {-|
The purpose of this function is to load the JWT secret from a file if The purpose of this function is to load the JWT secret from a file if
@@ -332,15 +320,11 @@ loadDbUriFile conf = extractDbUri mDbUri
Just filename -> strip <$> readFile (toS filename) Just filename -> strip <$> readFile (toS filename)
setDbUri dbUri = conf {configDatabase = dbUri} setDbUri dbUri = conf {configDatabase = dbUri}
createAndBindSocket :: FilePath -> Maybe FileMode -> IO Socket -- Utilitarian functions.
createAndBindSocket socketFilePath maybeSocketFileMode = do whenJust :: Applicative f => Maybe a -> (a -> f ()) -> f ()
deleteSocketFileIfExist socketFilePath whenJust (Just x) f = f x
sock <- socket AF_UNIX Stream defaultProtocol whenJust Nothing _ = pass
bind sock $ SockAddrUnix socketFilePath
mapM_ (setFileMode socketFilePath) maybeSocketFileMode whenNothing :: Applicative f => Maybe a -> f () -> f ()
return sock whenNothing Nothing f = f
where whenNothing _ _ = pass
deleteSocketFileIfExist path = removeFile path `catch` handleDoesNotExist
handleDoesNotExist e
| isDoesNotExistError e = return ()
| otherwise = throwIO e
+40
View File
@@ -0,0 +1,40 @@
module UnixSocket (
runAppInSocket
)where
import Network.Socket (Family (AF_UNIX),
SockAddr (SockAddrUnix), Socket,
SocketType (Stream), bind, close,
defaultProtocol, listen,
maxListenQueue, socket)
import Network.Wai (Application)
import Network.Wai.Handler.Warp
import System.Directory (removeFile)
import System.IO.Error (isDoesNotExistError)
import System.Posix.Files (setFileMode)
import System.Posix.Types (FileMode)
import Protolude
createAndBindSocket :: FilePath -> Maybe FileMode -> IO Socket
createAndBindSocket socketFilePath maybeSocketFileMode = do
deleteSocketFileIfExist socketFilePath
sock <- socket AF_UNIX Stream defaultProtocol
bind sock $ SockAddrUnix socketFilePath
mapM_ (setFileMode socketFilePath) maybeSocketFileMode
return sock
where
deleteSocketFileIfExist path = removeFile path `catch` handleDoesNotExist
handleDoesNotExist e
| isDoesNotExistError e = return ()
| otherwise = throwIO e
-- run the postgrest application with user defined socket.
runAppInSocket :: Settings -> Application -> Either Text FileMode -> FilePath -> IO ()
runAppInSocket settings app socketFileMode sockPath = do
sock <- createAndBindSocket sockPath (rightToMaybe socketFileMode)
putStrLn $ ("Listening on unix socket " :: Text) <> show sockPath
listen sock maxListenQueue
runSettingsSocket settings sock app
-- clean socket up when done
close sock
+2
View File
@@ -107,6 +107,7 @@ executable postgrest
, retry >= 0.7.4 && < 0.9 , retry >= 0.7.4 && < 0.9
, text >= 1.2.2 && < 1.3 , text >= 1.2.2 && < 1.3
, time >= 1.6 && < 1.10 , time >= 1.6 && < 1.10
, wai >= 3.2.1 && < 3.3
, warp >= 3.2.12 && < 3.4 , warp >= 3.2.12 && < 3.4
default-language: Haskell2010 default-language: Haskell2010
default-extensions: OverloadedStrings default-extensions: OverloadedStrings
@@ -116,6 +117,7 @@ executable postgrest
if !os(windows) if !os(windows)
build-depends: unix build-depends: unix
other-modules: UnixSocket
test-suite spec test-suite spec
type: exitcode-stdio-1.0 type: exitcode-stdio-1.0
+2 -2
View File
@@ -75,7 +75,7 @@ data AppConfig = AppConfig {
, configSchemas :: NonEmpty Text , configSchemas :: NonEmpty Text
, configHost :: Text , configHost :: Text
, configPort :: Int , configPort :: Int
, configSocket :: Maybe Text , configSocket :: Maybe FilePath
, configSocketMode :: Either Text FileMode , configSocketMode :: Either Text FileMode
, configJwtSecret :: Maybe B.ByteString , configJwtSecret :: Maybe B.ByteString
@@ -159,7 +159,7 @@ readOptions = do
<*> (fromList . splitOnCommas <$> reqValue "db-schema") <*> (fromList . splitOnCommas <$> reqValue "db-schema")
<*> (fromMaybe "!4" <$> optString "server-host") <*> (fromMaybe "!4" <$> optString "server-host")
<*> (fromMaybe 3000 <$> optInt "server-port") <*> (fromMaybe 3000 <$> optInt "server-port")
<*> optString "server-unix-socket" <*> (fmap unpack <$> optString "server-unix-socket")
<*> parseSocketFileMode "server-unix-socket-mode" <*> parseSocketFileMode "server-unix-socket-mode"
<*> (fmap encodeUtf8 <$> optString "jwt-secret") <*> (fmap encodeUtf8 <$> optString "jwt-secret")
<*> (fromMaybe False <$> optBool "secret-is-base64") <*> (fromMaybe False <$> optBool "secret-is-base64")