如何检查使用 `http-client` (Haskell) 创建的传出 HTTP 请求的正文

dan*_*nza 6 haskell http

我正在使用 Haskell 通过http-client包发送 POST HTTP 请求,但作为响应,我从远程服务器收到错误。我想检查我的请求,以确保我在正文中发送了预期的参数。

我设法将我的请求绑定到 Haskell 解释器中的一个变量,但我不知道如何查看它的主体。当我requestBody根据我的请求使用时,我得到一个RequestBody类型的值,但它不是 show 的实例。

在图书馆我找不到任何有用的功能。只有许多构造函数和一些与Popper类型相关的函数。

我如何检查该值?这对我来说似乎是一个常见的用例,但库似乎不支持它。我用错了吗?

编辑:

我知道 Wireshark 是什么以及如何使用它,但我希望能够以编程方式检查我发送的内容

zak*_*aps 3

RequestBody有五个构造函数。

data RequestBody
    = RequestBodyLBS L.ByteString
    | RequestBodyBS S.ByteString
    | RequestBodyBuilder Int64 Builder
    | RequestBodyStream Int64 (GivesPopper ())
    | RequestBodyStreamChunked (GivesPopper ())
Run Code Online (Sandbox Code Playgroud)

前两个是字节串的包装器,第三个是Blaze.ByteString.Builder可以轻松转换为字节串的 a,最后两个是类型的函数,(IO ByteString -> IO a) -> IO a如类型同义词所示:

type Popper = IO S.ByteString
type NeedsPopper a = Popper -> IO a
type GivesPopper a = NeedsPopper a -> IO a
Run Code Online (Sandbox Code Playgroud)

>>= print多次喂食它们,您将获得打印到控制台的完整请求正文。

您不应该这样做,因为这些GivesPopper ()生成器只能执行一次:如果您事先提取内容,则请求正文将不会发送到服务器。这就是为什么他们没有提供RequestBody数据类型的 Show 实例。您最好使用Wireshark等捕获包含 http 请求的存储桶。


我的代码中有一个数据结构,但我不明白为什么我不能检查它。您提到检查请求可能会以某种方式消耗它。这对于像 Haskell 这样的语言来说很奇怪,因为不变性和显式副作用是规则

这对于 Haskell 中的大多数类型都是正确的,但Popper实际上是IO S.ByteString由文件处理程序填充的字节串流(通常),而 Haskell 中的处理程序与MVar命令式语言中的变量没有太大区别:它可能是一个值或 null ,可以被分配和重新分配,并且副作用是全局可见的。

一个例子来自Network.HTTP.Client.MultipartFormData

streamFile :: FilePath -> GivesPopper ()
streamFile fp np =
    withFile fp ReadMode $ np . go
  where
    -- go :: Handle -> Popper 
    go h = BS.hGetSome h defaultChunkSize
Run Code Online (Sandbox Code Playgroud)