http - 如何使用 Network.HTTP.receiveHTTP 在 Haskell 中编写一个简单的 HTTP 服务器

标签 http haskell

模块Network.HTTP 公开函数 receiveHTTPrespondHTTP 我想将其用于非常基本的 Web 服务器。我写了一个只等待客户的 stub :

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

这里 accpet 给了我一个 Handle,现在我不知道如何使用 handlereceiveHTTP.

我找到了 an example与谷歌,但它是从 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

上面使用了 Stack 对 shebang 脚本的支持。 chmod +x 或使用 stack foo.hs 运行它。

Network 模块已弃用。如果您需要套接字 API,请始终使用 Network.Socket。对于更高级别的内容,请使用 connection .

您执行正常的 POSIX 套接字操作,然后使用 socketConnection 将连接的套接字转换为 HandleStream 并运行 respondHTTPreceiveHTTP 就可以了。 socketConnection 是一个奇怪的函数。前两个参数是主机名和端口,AFAICT 在运行服务器时不使用它们。

我使用了 RecordWildCards 扩展。它让我可以在模式中编写 Right (Request {..}) 并在右侧范围内包含记录的所有字段。

关于http - 如何使用 Network.HTTP.receiveHTTP 在 Haskell 中编写一个简单的 HTTP 服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6157256/

相关文章:

http - 当需要一些复杂的参数时,设计 HTTP 请求的最佳方法是什么?

haskell - 为什么 Haskell 不允许两个数据构造函数共享 "Const"和其他定义的数据属性?

haskell - 用于生成 Haskell 函数依赖(控制流)图的工具?

haskell - cabal:如何将文本文件添加为构建依赖项

http - 将数据传递给嵌套模板未按预期工作

json - 基于 JSON 的 REST API 上的 PUT 最常见的预期行为是什么?文档替换或部分更新)?

http - 如何在 Go/Revel 中获取客户端 IP 地址

HTTP 缓存上次修改时间

haskell - 如何在使用 GHC 编译的 Haskell 函数中找到分配?

plugins - 帮助 Haskell 动态插件加载