X-Git-Url: http://git.cielonegro.org/gitweb.cgi?p=Lucu.git;a=blobdiff_plain;f=Network%2FHTTP%2FLucu%2FHttpd.hs;h=a5f974978a4c6e5ccc4baad408d61bd5ce69f661;hp=595403abd0364f1a2e70c79088d9138d38eeaf90;hb=950640dd241222203778f8167943d30fa52f356a;hpb=3eb69879d3b336c7c3e613c0ce4bfb3c67989ff3 diff --git a/Network/HTTP/Lucu/Httpd.hs b/Network/HTTP/Lucu/Httpd.hs index 595403a..a5f9749 100644 --- a/Network/HTTP/Lucu/Httpd.hs +++ b/Network/HTTP/Lucu/Httpd.hs @@ -1,10 +1,10 @@ {-# LANGUAGE - UnicodeSyntax + CPP + , UnicodeSyntax #-} -- |The entry point of Lucu httpd. module Network.HTTP.Lucu.Httpd - ( FallbackHandler - , runHttpd + ( runHttpd ) where import Control.Concurrent @@ -15,46 +15,53 @@ import Data.Maybe import Network.BSD import Network.Socket import Network.HTTP.Lucu.Config +import Network.HTTP.Lucu.Dispatcher import Network.HTTP.Lucu.Interaction import Network.HTTP.Lucu.RequestReader -import Network.HTTP.Lucu.Resource.Tree import Network.HTTP.Lucu.ResponseWriter import Network.HTTP.Lucu.SocketLike as SL -import System.Posix.Signals +import Prelude.Unicode -- |This is the entry point of Lucu httpd. It listens to a socket and -- waits for clients. 'runHttpd' never stops by itself so the only way -- to stop it is to raise an exception in the thread running it. -- --- Note that 'runHttpd' automatically makes SIGPIPE be ignored by --- calling @'installHandler' 'sigPIPE' 'Ignore' 'Nothing'@. This can --- hardly cause a problem though. --- -- Example: -- --- > {-# LANGUAGE OverloadedStrings #-} --- > module Main where --- > import Network.HTTP.Lucu --- > --- > main :: IO () --- > main = let config = defaultConfig --- > resources = mkResTree [ ([], helloWorld) ] --- > in --- > runHttpd config resourcees [] --- > --- > helloWorld :: ResourceDef --- > helloWorld = emptyResource { --- > resGet --- > = Just $ do setContentType $ parseMIMEType "text/plain" --- > putChunk "Hello, world!" --- > } -runHttpd ∷ Config → ResTree → [FallbackHandler] → IO () -runHttpd cnf tree fbs - = withSocketsDo $ - do void $ installHandler sigPIPE Ignore Nothing - let launchers +-- @ +-- {-\# LANGUAGE OverloadedStrings \#-} +-- {-\# LANGUAGE QuasiQuotes \#-} +-- module Main where +-- import qualified "Data.Collections" as C +-- import "Network" +-- import "Network.HTTP.Lucu" +-- +-- main :: 'IO' () +-- main = let config = 'defaultConfig' +-- tree :: 'ResourceTree' +-- tree = C.fromList [ ([], 'nonGreedy' helloWorld) ] +-- in +-- 'Network.withSocketsDo' '.' 'runHttpd' config '$' 'resourceMap' tree +-- +-- helloWorld :: 'Network.HTTP.Lucu.Resource' +-- helloWorld = C.fromList +-- [ ( 'Network.HTTP.Lucu.GET' +-- , do 'Network.HTTP.Lucu.setContentType' ['Network.HTTP.Lucu.mimeType'| text/plain |] +-- 'Network.HTTP.Lucu.putChunk' \"Hello, world!\" +-- } +-- @ +runHttpd ∷ HostMapper α ⇒ Config → α → IO () +runHttpd cnf hm + = do let launchers = catMaybes - [ do scnf ← cnfSSLConfig cnf + [ do addr ← cnfServerV4Addr cnf + return ( launchListener =≪ listenOn AF_INET addr (cnfServerPort cnf) + ) + , do addr ← cnfServerV6Addr cnf + return ( launchListener =≪ listenOn AF_INET6 addr (cnfServerPort cnf) + ) +#if defined(HAVE_SSL) + , do scnf ← cnfSSLConfig cnf addr ← cnfServerV4Addr cnf return ( do so ← listenOn AF_INET addr (sslServerPort scnf) launchListener (sslContext scnf, so) @@ -64,12 +71,7 @@ runHttpd cnf tree fbs return ( do so ← listenOn AF_INET6 addr (sslServerPort scnf) launchListener (sslContext scnf, so) ) - , do addr ← cnfServerV4Addr cnf - return ( launchListener =≪ listenOn AF_INET addr (cnfServerPort cnf) - ) - , do addr ← cnfServerV6Addr cnf - return ( launchListener =≪ listenOn AF_INET6 addr (cnfServerPort cnf) - ) +#endif ] sequence_ launchers waitForever @@ -78,8 +80,8 @@ runHttpd cnf tree fbs launchListener so = do p ← SL.socketPort so -- FIXME: Don't throw away the thread ID as we can't - -- kill it later then. [1] - void $ forkIO $ httpLoop p so + -- kill it later then. + void ∘ forkIO $ httpLoop p so listenOn ∷ Family → HostName → ServiceName → IO Socket listenOn fam host srv @@ -93,7 +95,9 @@ runHttpd cnf tree fbs addrs ← getAddrInfo (Just hints) (Just host) (Just srv) let addr = head addrs bracketOnError - (socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr)) + (socket (addrFamily addr) + (addrSocketType addr) + (addrProtocol addr)) sClose (\ sock → do setSocketOption sock ReuseAddr 1 @@ -106,9 +110,9 @@ runHttpd cnf tree fbs httpLoop port so = do (h, addr) ← SL.accept so tQueue ← mkInteractionQueue - readerTID ← forkIO $ requestReader cnf tree fbs h port addr tQueue + readerTID ← forkIO $ requestReader cnf hm h port addr tQueue _writerTID ← forkIO $ responseWriter cnf h tQueue readerTID httpLoop port so waitForever ∷ IO () - waitForever = forever (threadDelay 1000000) + waitForever = forever $ threadDelay 1000000