我正试着用wai写一个非常简单的“回应”webapp;我想让它做的就是用POSTed返回数据(我真的不关心方法,但是我用的是curl,curl用的是POST,所以这就是我要做的)。我的简单web服务器是这样的:
import Network.Wai
import Network.HTTP.Types (status200)
import Network.Wai.Handler.Warp (run)
import Control.Monad.Trans ( liftIO )
import Blaze.ByteString.Builder.ByteString (fromByteString)
import qualified Data.Conduit.List as CondList
import Data.Conduit ( ($$), ($=), Flush(Chunk) )
application req = do
let src = requestBody req $= CondList.map (Chunk ∘ fromByteString)
return $ ResponseSource status200 [("Content-Type", "text/plain")] src
main = run 3000 application我所期望做的基本上是将请求正文绑定到响应正文,这样当我运行curl --data @/usr/share/dict/words localhost:3000时,它会将我的文字文件返回给我。相反,它提供了一个空的身体。使用"-v“运行curl,显示我的应用程序返回”200OK“,但没有数据。我不确定我到底做错了什么。
如果我用下面的代码替换应用程序函数:
_ ← requestBody req $$ CondList.mapM_ (liftIO ∘ print)
return $ responseLBS status200 [("Content-Type", "text/plain")] "Hello world\n"并添加一个OverloadedStrings杂注以允许"Hello World“部分工作,然后我确实看到我的应用程序将整个请求正文打印到标准输出,因此我知道curl正在正确地提交数据。我还将"Hello World“打印到curl stdout,因此我知道curl按照我所期望的那样工作。我一定是做错了什么,我把我的requestBody绑定到我的ResponseSource上了,但是我看不到它。
发布于 2012-05-30 09:28:13
您正确地使用了conduit,但问题是您尝试获取的流行为在HTTP上下文中不能可靠地工作。本质上,您希望在客户端发送请求正文的同时开始发送响应正文。这可能会导致死锁,因为客户端和服务器都可能卡在发送模式中。为了避免这种情况,Warp在发送响应之前刷新请求正文,这就是为什么在发送响应正文时请求正文看起来是空的。
为了使回显行为正确,您需要严格使用请求正文,然后将其发送回来。显然,如果有很大的请求体,从内存使用的角度来看,这可能是有问题的,但这是HTTP固有的方面。如果您需要恒定的内存回显,我的建议是将请求正文流式传输到一个文件,然后使用ResponseFile作为响应正文。
https://stackoverflow.com/questions/10807824
复制相似问题