在 httpclient 中获取 RequestBody

远望 |

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

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

彼得·阿米顿

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

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

根据您使用 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

将在传递给 a 时GivesPopper (),将流式响应正文打印到标准输出。

如果您希望可以多次构建请求而不会出现问题(任何流都GivesPopper必须可以多次调用等),并且您希望重用http-client的内部响应呈现,您可能能够摆脱一些非常hacky 的东西,例如这:

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呈现 a 的地方Response是 in requestBuilder,并且在构建请求时,这将始终发送标头,我认为这不是您想要的。_ <- out行从虚拟连接中清除标题+正文,并且由于Expect: 100-continue给出了,later然后应该再次将正文写入虚拟连接。请注意,这只适用于可以多次构建响应而没有问题的情况。如果您的请求实际上希望将该continue功能用于不同的用途,则这可能效果不佳。另请注意,这将写出分块请求(例如"6\r\na body\r\n0\r\n\r\n"的编码版本,这可能是您想要的,也可能不是。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

Related 相关文章

热门标签

归档