该模块Network.HTTP
暴露功能receiveHTTP和respondHTTP我想使用一个非常基本的Web服务器.我写了一个等待客户的存根:
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Network.HTTP
import Network
import Control.Monad
main = withSocketsDo $ do
socket <- listenOn $ PortNumber 8080
forever $ do
(handle, host, port) <- accept socket
print (host, port)
Run Code Online (Sandbox Code Playgroud)
这里accpet给了我Handle,现在我无法弄清楚如何使用Handle带receiveHTTP.
我找到了谷歌的一个例子,但它是从2008年开始的,不再适用了.我无法移植它.
有任何想法吗?
你可以这样做,但我真的认为你不应该这样做.HTTP可以充当服务器,但设计用于客户端.我用Google搜索了一下,我找不到任何实际使用过的人的例子respondHTTP.如果您在2016年使用客户端HTTP http-conduit.在服务器端,warp或依赖它的东西可能是你想要的.
不过,这是代码.
#!/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
Run Code Online (Sandbox Code Playgroud)
以上使用Stack对shebang脚本的支持.chmod +x它或运行它stack foo.hs.
该Network模块已弃用.Network.Socket如果需要套接字API,请始终使用.对于更高级别的东西,请使用connection.
你做普通的POSIX套接字,然后将连接的套接字转换为HandleStreamwith 并在其上socketConnection运行.是一个奇怪的功能.前两个参数是主机名和运行服务器时未使用AFAICT的端口.respondHTTPreceiveHTTPsocketConnection
我用了RecordWildCards扩展名.它允许我Right (Request {..})在一个模式中写入,并在右侧包含记录的所有字段.
也许是希望你使用的accept功能,从Network.Socket代替Network?这给了你一个Socket而不是一个Handle,你应该能够转换为receiveHTTP可以使用的形式.
通常情况下Handle直接使用会更好,但是这里的HTTP库会为你处理它,所以它需要更低级别的接口.
编辑:看了一下之后,看起来socketConnection功能Network.TCP就是你所需要的.有趣的是,它实际上是在将套接字Handle从内部读取之前将其置于内部,但似乎并未提供从外部提供的读取方式Handle.该函数的字符串参数应该是远程主机的名称,但它看起来只是保留供参考; 它实际上并没有启动与该主机或任何东西的连接.