2014-03-24 86 views
8

列出的示例代碼here顯示瞭如何僅在特定主機上進行warp監聽。Warp:綁定到Unix域套接字

另外,this post展示了一些關於如何在Haskell中使用unix域套接字的基礎知識。

如何將這兩種方法結合起來,以使得warp偵聽(即綁定到)特定的unix域套接字(例如,warp.sock)?

注意:這個問題故意顯示沒有研究工作,因爲它被回答Q & A-樣式。

回答

10

可以使用runSettingsSocketAF_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平臺上工作。

2

FWIW:如果想使用http的客戶端來使用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)