【问题标题】:Log all requests and responses for http-conduit记录 http-conduit 的所有请求和响应
【发布时间】:2018-05-07 21:07:43
【问题描述】:

我写了这个ManagerSettings 来记录我的http-conduit 应用程序的所有请求和响应。 (顺便说一下,我正在导入ClassyPrelude)。

tracingManagerSettings :: ManagerSettings
tracingManagerSettings =
  tlsManagerSettings { managerModifyRequest = \req -> do
                         putStr "TRACE: "
                         print req
                         putStrLn ""
                         pure req
                     , managerModifyResponse = \r -> do
                         responseChunks <- brConsume $ responseBody r
                         let fullResponse = mconcat responseChunks
                         putStr "TRACE: RESPONSE: "
                         putStrLn $ decodeUtf8 fullResponse
                         pure $ r { responseBody = pure fullResponse }
                     }

但是,它不起作用 - 当我使用它时,应用程序挂起并试图在打印第一个请求和第一个响应后消耗机器中的所有 RAM,这表明某种无限循环。

此外,请求被打印两次。

我之前做过类似的尝试,但没有修改r。那失败了,因为在我已经完全阅读了响应之后,没有更多的响应数据可以读取。

如果我将其替换为 tlsManagerSettings,http-conduit 将再次起作用。

我的应用程序正在使用 libstackexchange,我已对其进行了修改以允许自定义 ManagerSettings。我正在使用 http-conduit 版本 2.2.4。

如何诊断问题?我该如何解决?

【问题讨论】:

    标签: haskell bytestring http-conduit


    【解决方案1】:

    managerModifyResponse 不适用于 Response ByteString,它适用于 Response BodyReader,其中 type BodyReader = IO ByteString 以及如果它产生非空 ByteString 的合同,则可以有更多输入阅读。

    您遇到的问题是pure fullResponse 永远不会返回一个空的ByteString,除非它总是返回。您需要提供更复杂的 IO 操作来捕获预期的行为。也许是这些方面的东西(未经测试):

    returnOnce :: Monoid a => a -> IO (IO a)
    returnOnce x = do
        ref <- newIORef x
        pure $ readIORef ref <* writeIORef ref mempty
    

    至于如何调试呢?不确定通用方法。我只是怀疑您可能需要类似这些方面的解决方案,the docs for BodyReader 确认了这一点。

    【讨论】:

      猜你喜欢
      • 2021-11-15
      • 1970-01-01
      • 2016-11-21
      • 1970-01-01
      • 2010-12-16
      • 2019-10-04
      • 1970-01-01
      • 2019-03-26
      • 2014-03-22
      相关资源
      最近更新 更多