9

此处列出的示例代码显示了如何使 warp 仅在特定主机上侦听。

此外,这篇文章展示了一些关于如何在 Haskell 中使用 unix 域套接字的基础知识。

我如何结合这两种方法以使经编侦听(即绑定到)特定的 unix 域套接字(例如,warp.sock)?

注意:这个问题故意显示没有研究工作,因为它是问答式回答的。

4

2 回答 2

12

您可以使用runSettingsSocket套接字AF_UNIX

{-# LANGUAGE OverloadedStrings #-}

import Network.Wai (responseLBS)
import Network.Wai.Handler.Warp
import Network.Socket
import Network.HTTP.Types (status200)
import Network.HTTP.Types.Header (hContentType)

main = do
    let port = 3000
    -- Open the socket
    sock <- socket AF_UNIX Stream 0
    bind sock $ SockAddrUnix "warp.sock"
    listen sock maxListenQueue
    -- Run the server
    let settings = defaultSettings { settingsPort = port }
    runSettingsSocket settings sock app
    -- Cleanup: Close socket
    close sock

app req f = f $
    responseLBS status200 [(hContentType, "text/plain")] "Hello world!"

请注意,这显然只适用于 unixoid 平台。

于 2014-03-24T22:08:08.713 回答
2

FWIW:如果想使用 http-client 来使用那个 UNIX 套接字:

{-# LANGUAGE OverloadedStrings #-}

import Network.HTTP.Client
import Network.HTTP.Client.Internal (Connection, openSocketConnection, makeConnection)
import Network.Socket.ByteString (sendAll, recv)

import qualified Control.Exception as E
import qualified Network.Socket as NS

main :: IO ()
main = do
    mgr <- newManager defaultManagerSettings {
        managerRawConnection = createUnixConnection
    }
    -- This changes in http-client-0.5, use parseUrlThrow
    req <- parseUrl "http://localhost/whatever"
    res <- httpLbs req mgr
    print (responseBody res)

createUnixConnection :: IO (Maybe NS.HostAddress -> String -> Int -> IO Connection)
createUnixConnection = return $ \_ _ _ -> openUnixConnection "warp.sock"

openUnixConnection :: String -> IO Connection
openUnixConnection addr = E.bracketOnError
    (NS.socket NS.AF_UNIX NS.Stream NS.defaultProtocol)
    (NS.close)
    $ \sock -> do
        NS.connect sock sockAddr
        socketConnection sock chunksize
  where
    sockAddr = NS.SockAddrUnix addr
    chunksize = 8192

-------------------------------------------------------------------------------
-- Copied from http-client
-------------------------------------------------------------------------------

socketConnection :: NS.Socket -> Int -> IO Connection
socketConnection socket chunksize = makeConnection
    (recv socket chunksize)
    (sendAll socket)
    (NS.close socket)
于 2016-07-06T23:35:38.467 回答