Skip to content

Commit 4d1b2a0

Browse files
committed
Add support for Unix domain socket connection
Update corresponding parser in readHostPortM Update showHostPort
1 parent 76d5f84 commit 4d1b2a0

File tree

2 files changed

+38
-11
lines changed

2 files changed

+38
-11
lines changed

Database/MongoDB/Connection.hs

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ import Data.List (intersect, partition, (\\), delete)
2929
import Control.Applicative ((<$>))
3030
#endif
3131

32-
import Control.Monad (forM_)
32+
import Control.Monad (forM_, guard)
3333
import System.IO.Unsafe (unsafePerformIO)
3434
import System.Timeout (timeout)
35-
import Text.ParserCombinators.Parsec (parse, many1, letter, digit, char, eof,
35+
import Text.ParserCombinators.Parsec (parse, many1, letter, digit, char, anyChar, eof,
3636
spaces, try, (<|>))
3737
import qualified Data.List as List
3838

@@ -76,24 +76,31 @@ host hostname = Host hostname defaultPort
7676

7777
showHostPort :: Host -> String
7878
-- ^ Display host as \"host:port\"
79-
-- TODO: Distinguish Service and UnixSocket port
80-
showHostPort (Host hostname port) = hostname ++ ":" ++ portname where
81-
portname = case port of
82-
PortNumber p -> show p
79+
-- TODO: Distinguish Service port
80+
showHostPort (Host hostname (PortNumber port)) = hostname ++ ":" ++ show port
81+
#if !defined(mingw32_HOST_OS) && !defined(cygwin32_HOST_OS) && !defined(_WIN32)
82+
showHostPort (Host _ (UnixSocket path)) = "unix:" ++ path
83+
#endif
8384

8485
readHostPortM :: (Monad m) => String -> m Host
8586
-- ^ Read string \"hostname:port\" as @Host hosthame (PortNumber port)@ or \"hostname\" as @host hostname@ (default port). Fail if string does not match either syntax.
86-
-- TODO: handle Service and UnixSocket port
87+
-- TODO: handle Service port
8788
readHostPortM = either (fail . show) return . parse parser "readHostPort" where
8889
hostname = many1 (letter <|> digit <|> char '-' <|> char '.')
8990
parser = do
9091
spaces
9192
h <- hostname
9293
try (spaces >> eof >> return (host h)) <|> do
9394
_ <- char ':'
94-
port :: Int <- read <$> many1 digit
95-
spaces >> eof
96-
return $ Host h (PortNumber $ fromIntegral port)
95+
try ( do port :: Int <- read <$> many1 digit
96+
spaces >> eof
97+
return $ Host h (PortNumber $ fromIntegral port))
98+
#if !defined(mingw32_HOST_OS) && !defined(cygwin32_HOST_OS) && !defined(_WIN32)
99+
<|> do guard (h == "unix")
100+
p <- many1 anyChar
101+
eof
102+
return $ Host "" (UnixSocket p)
103+
#endif
97104

98105
readHostPort :: String -> Host
99106
-- ^ Read string \"hostname:port\" as @Host hostname (PortNumber port)@ or \"hostname\" as @host hostname@ (default port). Error if string does not match either syntax.

Database/MongoDB/Internal/Network.hs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@ import System.IO (Handle, IOMode(ReadWriteMode))
2121

2222
-- | Wraps network's 'PortNumber'
2323
-- Used to ease compatibility between older and newer network versions.
24-
newtype PortID = PortNumber N.PortNumber deriving (Enum, Eq, Integral, Num, Ord, Read, Real, Show)
24+
data PortID = PortNumber N.PortNumber
25+
#if !defined(mingw32_HOST_OS) && !defined(cygwin32_HOST_OS) && !defined(_WIN32)
26+
| UnixSocket String
27+
#endif
28+
deriving (Eq, Ord, Show)
2529

2630

2731
#if !MIN_VERSION_network(2, 9, 0)
@@ -32,6 +36,10 @@ connectTo :: N.HostName -- Hostname
3236
-> IO Handle -- Connected Socket
3337
connectTo hostname (PortNumber port) = N.connectTo hostname (N.PortNumber port)
3438

39+
#if !defined(mingw32_HOST_OS) && !defined(cygwin32_HOST_OS) && !defined(_WIN32)
40+
connectTo _ (UnixSocket path) = N.connectTo "" (N.UnixSocket path)
41+
#endif
42+
3543
#else
3644

3745
-- Copied implementation from network 2.8's 'connectTo', but using our 'PortID' newtype.
@@ -49,4 +57,16 @@ connectTo hostname (PortNumber port) = do
4957
N.connect sock (N.SockAddrInet port (hostAddress he))
5058
N.socketToHandle sock ReadWriteMode
5159
)
60+
61+
#if !defined(mingw32_HOST_OS) && !defined(cygwin32_HOST_OS) && !defined(_WIN32)
62+
connectTo _ (UnixSocket path) = do
63+
bracketOnError
64+
(N.socket N.AF_UNIX N.Stream 0)
65+
(N.close)
66+
(\sock -> do
67+
N.connect sock (N.SockAddrUnix path)
68+
N.socketToHandle sock ReadWriteMode
69+
)
70+
#endif
71+
5272
#endif

0 commit comments

Comments
 (0)