PlayWS计算http调用的大小而不消耗流

问题描述 投票:0回答:1

我目前正在使用PlayWS http客户端,它返回一个Akka流。根据我的理解,我可以使用流并将其转换为Byte []来计算大小。但是,这也消耗了流,我不能再使用它了。无论如何围绕这个?

scala playframework akka
1个回答
4
投票

我认为这个问题有两个不同的方面。

  1. 您希望事先知道服务器响应的大小以准备缓冲区。不幸的是,没有保证的方法可以做到这一点。当服务器通过chunked transfer encoding事先不知道响应的大小时,HTTP 1.1规范明确允许传输模式。另见3.3.1. Transfer-Encoding的引用:

接收方必须能够解析分块传输编码(第4.1节),因为它在预先知道有效载荷主体大小时在帧消息中起着至关重要的作用。

部分3.3.3. Message Body Length指定了消息体的长度是如何定义的,除了上面提到的分块传输编码之外,它还包含了无用的功能

  1. 否则,这是没有声明的消息体长度的响应消息,因此消息体长度由服务器关闭连接之前接收的八位字节数确定。

这是为了向后兼容而添加的,不鼓励使用,但仍然是法律允许的。

仍然在许多现实世界的场景中,您可以使用服务器可能返回的Content-Length头字段。然而,这里也有一个问题:如果使用gzip Content-Encoding,那么Content-Length将包含压缩体的大小。

总结:在一般情况下,在完全获得服务器响应之前,您无法提前获取消息体的大小,即在代码方面对响应执行阻塞调用。您可以尝试使用Content-Length,它可能会或可能没有帮助您的具体情况。

  1. 你已经有一个完全下载的响应(或者你可以阻止你的StreamedResponse)并且你想通过首先获取大小然后处理实际数据来处理它。在这种情况下,您可能首先使用返回getBodyAsBytesIndexedSeq[Byte]方法,因此具有size,然后使用Source将其转换为新的Source.single,这实际上正是getBodyAsSource的默认(即非流式)实现。
© www.soinside.com 2019 - 2024. All rights reserved.