2014-03-24 13 views
8

Der Beispielcode here zeigt, wie Warp nur auf bestimmten Hosts zu hören.Warp: Bindung an Unix-Domain-Sockets

Weiter, this post zeigt einige Grundlagen zur Verwendung von Unix-Domain-Sockets in Haskell.

Wie kann ich diese beiden Ansätze kombinieren, um Warp auf einen bestimmten Unix-Domain-Socket (z. B. warp.sock) zu hören (d. H. Zu binden)?

Hinweis: Diese Frage zeigt absichtlich keine Forschungsanstrengungen, da sie Q & A-Style beantwortet wurde.

Antwort

10

Sie können runSettingsSocket mit einem AF_UNIX Sockel verwenden:

{-# 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!" 

Beachten Sie, dass diese auf unixoide Plattformen funktionieren offensichtlich nur werden.

2

FWIW: Will man http-Client verwenden, die UNIX-Socket zu verwenden:

{-# 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)