You can do this, but I really think you shouldn't. HTTP can act as a server, but is designed to be used client side. I Googled a little and I can't find any examples of someone actually using respondHTTP. If you're doing client side HTTP in 2016 use http-conduit. On the server side, warp or something that depends upon it is probably what you want.
Nevertheless, here's the code.
#!/usr/bin/env stack
-- stack --resolver lts-6.3 --install-ghc runghc --package HTTP
{-# LANGUAGE RecordWildCards #-}
import Control.Monad
import qualified Data.ByteString as B
import Network.HTTP
import Network.Socket
import Network.URI
main = do
lsock <- socket AF_INET Stream defaultProtocol
bind lsock (SockAddrInet 8080 iNADDR_ANY)
listen lsock 1
forever $ do
(csock, _) <- accept lsock
hs <- socketConnection "" 8080 csock
req <- receiveHTTP hs
case req of
Left _ -> error "Receiving request failed"
Right (Request {..}) -> if uriPath rqURI == "/"
then do
respondHTTP hs $
Response (2,0,0) "OK" [] "Hello HTTP"
Network.HTTP.close hs
else do
respondHTTP hs $
Response (4,0,4) "Not found" [] "Nothing here"
Network.HTTP.close hs
The above uses Stack's support for shebang scripts. chmod +x it or run it with stack foo.hs.
The Network module is deprecated. Always use Network.Socket if you need a socket API. For something higher level, use connection.
You do the normal POSIX socket thing, then convert the connected socket to a HandleStream with socketConnection and run respondHTTP and receiveHTTP on it. socketConnection is a weird function. The first two parameters are a hostname and a port which AFAICT aren't used when running a server.
I used the RecordWildCards extension. It lets me write Right (Request {..}) in a pattern and have all the fields of the record in scope on the right hand side.