【问题标题】:How to consume a conduit with WAI (raw request body)如何使用 WAI(原始请求正文)使用管道
【发布时间】:2012-01-28 02:59:20
【问题描述】:

我正在使用 scotty,它是 WAI 周围的类似 sinatra 的包装器。我想将原始请求正文作为字节字符串获取,以便可以将其解析为 json。以下是接近的。这类似于其他关于使用 WAI 使用 body 的问题,但不同的是,我希望 body 作为字节串,并且因为我在不同的 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"
    ...

这显然行不通,我想我需要某种电梯之类的东西,但我不知道该用什么。 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

【问题讨论】:

    标签: haskell monads conduit haskell-wai


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

      作为替代方案,这里是严格使用字节串并返回它的方法:

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

      【讨论】:

        【解决方案3】:

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

        要使用源,请使用Data.Conduit.List.consume(或Data.Conduit.Lazy.lazyConsume)。结果,您将获得ByteStrings 的列表。然后退出ResourceT monad 转换器,使用runResourceT。结果代码:

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

        【讨论】:

          【解决方案4】:

          这是最终为我工作的代码,改编自 jhickner 的

          rawRequestBody req = mconcat <$> (requestBody req $$ consume)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-01-07
            • 2013-09-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-10-19
            相关资源
            最近更新 更多