on master help sign in
Merge commit '02c1396c86e3fceb48cb'
commit1112781eb2c16877bde23d1765d7aaa8bc254816 authorMichael <michael@snoyman.com> dateWed 20 Jul 2011, 20:04 (15 years ago) parentabe80be02c1396
1 file changed+25−10
Network/Wai/Handler/Warp.hs+25−10
Network/Wai/Handler/Warp.hs+25−10
@@ -63,15 +63,17 @@ import qualified Data.ByteString.Char8 as B
6363import qualified Data.ByteString.Lazy as L
6464import Network (sClose, Socket)
6565import Network.Socket
66− ( accept, SockAddr (SockAddrInet), Family (AF_INET)
67− , SocketType (Stream), listen, bindSocket, setSocketOption
68− , SocketOption (ReuseAddr), iNADDR_ANY, inet_addr, SockAddr (SockAddrInet)
66+ ( accept, Family (..)
67+ , SocketType (Stream), listen, bindSocket, setSocketOption, maxListenQueue
68+ , SockAddr, SocketOption (ReuseAddr)
69+ , AddrInfo(..), AddrInfoFlag(..), defaultHints, getAddrInfo
6970 )
7071import qualified Network.Socket
7172import qualified Network.Socket.ByteString as Sock
7273import Control.Exception
7374 ( bracket, finally, Exception, SomeException, catch
7475 , fromException, AsyncException (ThreadKilled)
76+ , bracketOnError
7577 )
7678import Control.Concurrent (forkIO)
7779import qualified Data.Char as C
@@ -112,13 +114,26 @@ import Network.Socket (withSocketsDo)
112114
113115bindPort :: Int -> String -> IO Socket
114116bindPort p s = do
115− sock <- Network.Socket.socket AF_INET Stream 0
116− h <- if s == "*" then return iNADDR_ANY else inet_addr s
117− let addr = SockAddrInet (fromIntegral p) h
118− setSocketOption sock ReuseAddr 1
119− bindSocket sock addr
120− listen sock 150
121− return sock
117+ let hints = defaultHints { addrFlags = [AI_PASSIVE
118+ , AI_NUMERICSERV
119+ , AI_NUMERICHOST]
120+ , addrSocketType = Stream }
121+ host = if s == "*" then Nothing else Just s
122+ port = Just . show $ p
123+ addrs <- getAddrInfo (Just hints) host port
124+ -- Choose an IPv6 socket if exists. This ensures the socket can
125+ -- handle both IPv4 and IPv6 if v6only is false.
126+ let addrs' = filter (\x -> addrFamily x == AF_INET6) addrs
127+ addr = if null addrs' then head addrs else head addrs'
128+ bracketOnError
129+ (Network.Socket.socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr))
130+ (sClose)
131+ (\sock -> do
132+ setSocketOption sock ReuseAddr 1
133+ bindSocket sock (addrAddress addr)
134+ listen sock maxListenQueue
135+ return sock
136+ )
122137
123138-- | Run an 'Application' on the given port. This calls 'runSettings' with
124139-- 'defaultSettings'.