如何使用 WAI(原始请求正文)使用管道

发布于 2024-12-29 17:38:07 字数 898 浏览 3 评论 0原文

我使用的是 scotty,它是 WAI 的一个类似 sinatra 的包装器。我想将原始请求正文作为字节字符串获取,以便我可以将其解析为 json。下面是接近的。这与使用 WAI 消耗主体的其他问题类似,但有所不同,因为我希望主体作为字节串,并且因为我处于不同的单子中, ActionM

import Network.Wai (requestBody)
import Web.Scotty (ActionM, request, text)

bodyExample :: ActionM ()
bodyExample = do
    r <- request
    bss <- requestBody r -- this needs a lift or something
    text "ok"
    ...

显然不起作用,我想我需要某种电梯什么的,但我不知道该用什么。 liftIO 不正确,并且 lift 给了我奇怪的错误。

http://hackage.haskell.org /packages/archive/scotty/0.0.1/doc/html/Web-Scotty.html

http://hackage.haskell.org/packages/archive /wai/latest/doc/html/Network-Wai.html

I'm using scotty, which is a sinatra-like wrapper around WAI. I want to get the raw request body as a byte string so I can parse it as json. The following is close. This is similar to other questions about consuming a body using WAI, but is different because I want the body as a bytestring, and because I'm in a different monad, ActionM

import Network.Wai (requestBody)
import Web.Scotty (ActionM, request, text)

bodyExample :: ActionM ()
bodyExample = do
    r <- request
    bss <- requestBody r -- this needs a lift or something
    text "ok"
    ...

It obviously won't work, I think I need some kind of lift or something, but I don't know what to use. liftIO isn't right, and lift gives me weird errors.

http://hackage.haskell.org/packages/archive/scotty/0.0.1/doc/html/Web-Scotty.html

http://hackage.haskell.org/packages/archive/wai/latest/doc/html/Network-Wai.html

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

复古式 2025-01-05 17:38:07

值得一提的是,新版本的 Scotty (0.2.0) 有一个“jsonData”方法可以为您执行此操作。感谢您使用!

For what it's worth, the new version of Scotty (0.2.0) has a 'jsonData' method to do this for you. Thanks for using!

蓝眼泪 2025-01-05 17:38:07

由于 lazyConsume 的工作方式,接受的答案实际上不起作用。它总是返回一个空列表。如果您使用 lazyConsume,则需要在退出 ResourceT 之前使用数据。

作为替代方案,以下是如何严格使用字节串并返回它:

rawRequestBody :: Request -> IO B.ByteString
rawRequestBody req = mconcat <
gt; runResourceT (requestBody req $ consume)

The accepted answer won't actually work due to the way lazyConsume works. It will always return an empty list. You need to consume the data before exiting ResourceT if you're using lazyConsume.

As an alternative, here's how to strictly consume the bytestring and return it:

rawRequestBody :: Request -> IO B.ByteString
rawRequestBody req = mconcat <
gt; runResourceT (requestBody req $ consume)
林空鹿饮溪 2025-01-05 17:38:07

requestBody 不是一个单值。它只是一个返回 Conduit Source IO ByteString 的函数。

要使用源,请使用 Data.Conduit.List.consume (或 数据。 Conduit.Lazy.lazyConsume)。您将得到一个 ByteString 列表作为结果。要退出 ResourceT monad 转换器,请使用 runResourceT。结果代码:

bss <- liftIO . runResourceT . lazyConsume . requestBody $ r
bss :: [ByteString]

requestBody isn't a monadic value. It is simply a function that returns a Conduit Source IO ByteString.

To consume the source, use Data.Conduit.List.consume (or Data.Conduit.Lazy.lazyConsume). You will get a list of ByteStrings as the result. To then exit the ResourceT monad transformer, use runResourceT. The resulting code:

bss <- liftIO . runResourceT . lazyConsume . requestBody $ r
bss :: [ByteString]
潦草背影 2025-01-05 17:38:07

这是最终对我有用的代码,改编自 jhickner 的

rawRequestBody req = mconcat <
gt; (requestBody req $ consume)

This is the code that finally work for me, adapted from jhickner's

rawRequestBody req = mconcat <
gt; (requestBody req $ consume)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文