首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >wai的意外管道行为

wai的意外管道行为
EN

Stack Overflow用户
提问于 2012-05-30 06:49:09
回答 1查看 332关注 0票数 3

我正试着用wai写一个非常简单的“回应”webapp;我想让它做的就是用POSTed返回数据(我真的不关心方法,但是我用的是curl,curl用的是POST,所以这就是我要做的)。我的简单web服务器是这样的:

代码语言:javascript
复制
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“,但没有数据。我不确定我到底做错了什么。

如果我用下面的代码替换应用程序函数:

代码语言:javascript
复制
_ ← 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上了,但是我看不到它。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-05-30 09:28:13

您正确地使用了conduit,但问题是您尝试获取的流行为在HTTP上下文中不能可靠地工作。本质上,您希望在客户端发送请求正文的同时开始发送响应正文。这可能会导致死锁,因为客户端和服务器都可能卡在发送模式中。为了避免这种情况,Warp在发送响应之前刷新请求正文,这就是为什么在发送响应正文时请求正文看起来是空的。

为了使回显行为正确,您需要严格使用请求正文,然后将其发送回来。显然,如果有很大的请求体,从内存使用的角度来看,这可能是有问题的,但这是HTTP固有的方面。如果您需要恒定的内存回显,我的建议是将请求正文流式传输到一个文件,然后使用ResponseFile作为响应正文。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10807824

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档