在 httpclient 中获取 RequestBody



我想直接使用bloodhound或REST api使用Haskell向Amazon托管的elasticsearch服务器发送请求。

由于服务器具有基于 IAM 的访问策略,因此我需要对签名进行签名。为了对每个请求的签名进行签名,需要计算有效负载的哈希值。我不确定如何将RequestBody(分块与否(放入ByteString。

对于您的特定使用案例:在我看来,wreq库已经支持 AWS IAM 签名(教程(,因此根据您的特定要求,最简单的方法是使用它/查看它是如何工作的。

看起来使用RequestBodys 的最简单方法实际上可能只是编写一个函数来计算 6 种可能的RequestBody中的每一种的签名,或者至少是您需要的签名,而无需尝试重用 http-client 的机器将 6 种中的任何一种转换为一个ByteString。 这是一个特别有用的选项,因为看起来您可能需要对分块请求执行特殊操作。 对于RequestBody可能是什么,只有几个选项(基于流的选项(似乎很难使用;这些通常也值得特殊对待(特别是因为,根据请求的创建者如何实现它们,我不清楚是否可以保证可以从它们中读取并让它们以后仍然工作(。 此源可能对此方法有用。

根据您使用 Haskell 的经验,流构造函数可能有点吓人。然而,这实际上还不错:扩展类型同义词会得到GivesPopper () = (IO ByteString -> IO ()) -> IO ()IO ByteString -> IO ()函数是你可以提供的东西,它接受流区块的生产者(每个评估将产生更多的区块(,并用它做一些有用的事情---例如,将该区块写入IORef的列表中,以便以后可以检查它。 如果在此函数上调用GivesPopper,您将获得一个IO操作,该操作以有用的生产者作为参数运行它。例如:

foo :: NeedsPopper ()
foo pop = do
chunk <- pop
if (chunk == "") then return ()
else BS.putStr chunk >> foo pop

将,当传递给GivesPopper ()时,将流响应正文打印到 stdout。

如果你希望请求可以多次构建而没有问题(任何流GivesPopper都必须多次调用,等等(,并且你希望重用http-client的内部响应渲染,你也许可以摆脱一些非常黑客的东西,比如这样:

getRequest :: Request -> IO BS.ByteString
getRequest req = do
(conn, out, inp) <- dummyConnection []
let req' = req { requestHeaders = (CI.mk "Expect", "100-continue")
: requestHeaders req
}
(Just later) <- requestBuilder req' conn
_ <- out
later
BS.concat <$> out

似乎http-client渲染Response的唯一地方是在requestBuilder中,并且在构建请求时,这将始终发送标头,我认为这不是您想要的。_ <- out行从虚拟连接中清除标头+正文,并且由于给定了Expect: 100-continuelater应该再次将正文写入虚拟连接。 请注意,仅当可以多次构建响应而没有问题时,这才有效。 如果您的请求实际上希望将continue功能用于其他用途,则可能无法很好地工作。 另请注意,这将写出分块请求的编码版本(例如"6rna bodyrn0rnrn"(,这可能是您想要的,也可能不是您想要的。

相关内容

  • 没有找到相关文章

最新更新