@@ -48,7 +48,6 @@ module Network.Wai.Handler.Warp
4848 , parseRequest
4949 , sendResponse
5050 , registerKillThread
51− , bindPort
5251 , pause
5352 , resume
5453 , T.cancel
@@ -68,19 +67,11 @@ import qualified Data.ByteString.Unsafe as SU
6867import qualified Data.ByteString.Char8 as B
6968import qualified Data.ByteString.Lazy as L
7069import Network (sClose, Socket)
71−import Network.Socket
72− ( accept, Family (..)
73− , SocketType (Stream), listen, bindSocket, setSocketOption, maxListenQueue
74− , SockAddr, SocketOption (ReuseAddr)
75− , AddrInfo(..), AddrInfoFlag(..), defaultHints, getAddrInfo
76− )
77−import qualified Network.Socket
70+import Network.Socket (accept, SockAddr)
7871import qualified Network.Socket.ByteString as Sock
7972import Control.Exception
8073 ( bracket, finally, Exception, SomeException, catch
8174 , fromException, AsyncException (ThreadKilled)
82− , bracketOnError
83− , IOException
8475 , try
8576 )
8677import Control.Concurrent (forkIO)
@@ -113,8 +104,8 @@ import qualified Network.HTTP.Types as H
113104import qualified Data.CaseInsensitive as CI
114105import System.IO (hPrint, stderr)
115106import qualified Data.IORef as I
116−import Data.String (IsString (..))
117107import qualified Data.ByteString.Lex.Integral as LI
108+import Data.Conduit.Network (bindPort, HostPreference (HostIPv4))
118109
119110#if WINDOWS
120111import Control.Concurrent (threadDelay)
@@ -162,47 +153,6 @@ socketConnection s = Connection
162153 , connRecv = Sock.recv s bytesPerRead
163154 }
164155
165−
166−bindPort :: Int -> HostPreference -> IO Socket
167−bindPort p s = do
168− let hints = defaultHints { addrFlags = [AI_PASSIVE
169− , AI_NUMERICSERV
170− , AI_NUMERICHOST]
171− , addrSocketType = Stream }
172− host =
173− case s of
174− Host s' -> Just s'
175− _ -> Nothing
176− port = Just . show $ p
177− addrs <- getAddrInfo (Just hints) host port
178− -- Choose an IPv6 socket if exists. This ensures the socket can
179− -- handle both IPv4 and IPv6 if v6only is false.
180− let addrs4 = filter (\x -> addrFamily x /= AF_INET6) addrs
181− addrs6 = filter (\x -> addrFamily x == AF_INET6) addrs
182− addrs' =
183− case s of
184− HostIPv4 -> addrs4 ++ addrs6
185− HostIPv6 -> addrs6 ++ addrs4
186− _ -> addrs
187−
188− tryAddrs (addr1:rest@(_:_)) =
189− catch
190− (theBody addr1)
191− (\(_ :: IOException) -> tryAddrs rest)
192− tryAddrs (addr1:[]) = theBody addr1
193− tryAddrs _ = error "bindPort: addrs is empty"
194− theBody addr =
195− bracketOnError
196− (Network.Socket.socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr))
197− sClose
198− (\sock -> do
199− setSocketOption sock ReuseAddr 1
200− bindSocket sock (addrAddress addr)
201− listen sock maxListenQueue
202− return sock
203− )
204− tryAddrs addrs'
205−
206156-- | Run an 'Application' on the given port. This calls 'runSettings' with
207157-- 'defaultSettings'.
208158run :: Port -> Application -> IO ()
@@ -643,38 +593,6 @@ data Settings = Settings
643593 , settingsManager :: Maybe Manager -- ^ Use an existing timeout manager instead of spawning a new one. If used, 'settingsTimeout' is ignored. Default is 'Nothing'
644594 }
645595
646−-- | Which host to bind.
647−--
648−-- Note: The @IsString@ instance recognizes the following special values:
649−--
650−-- * @*@ means @HostAny@
651−--
652−-- * @*4@ means @HostIPv4@
653−--
654−-- * @*6@ means @HostIPv6@
655−data HostPreference =
656− HostAny
657− | HostIPv4
658− | HostIPv6
659− | Host String
660− deriving (Show, Eq, Ord)
661−
662−instance IsString HostPreference where
663− -- The funny code coming up is to get around some irritating warnings from
664− -- GHC. I should be able to just write:
665− {-
666− fromString "*" = HostAny
667− fromString "*4" = HostIPv4
668− fromString "*6" = HostIPv6
669− -}
670− fromString s'@('*':s) =
671− case s of
672− [] -> HostAny
673− ['4'] -> HostIPv4
674− ['6'] -> HostIPv6
675− _ -> Host s'
676− fromString s = Host s
677−
678596-- | The default settings for the Warp server. See the individual settings for
679597-- the default value.
680598defaultSettings :: Settings