[英]How to correctly set content-length in spark java after gzip header
我正在使用Spark来提供不同类型的内容。 “内容长度”计算正确,但我在使用时遇到问题:
response.header("Content-Encoding", "gzip")
根据他们的文档,当设置该标头时,spark 会自动对内容进行 gzip 压缩……并且它确实做到了。
但是,我之前计算的“内容长度”不再有效,因此我在浏览器中收到“net::ERR_CONTENT_LENGTH_MISMATCH”错误。
自己压缩它,并计算结果大小是不可能的,因为 spark 会再次压缩输出。
我怎么知道火花压缩输出后的结果大小?
我在 Spark 上创建了一个库,它会自动设置这样的标题,有趣的部分看起来像(简化):
if(request.headers("Accept-Encoding")?.contains("gzip")) {
response.header("Content-Encoding", "gzip")
// How to get or calculate the resulting size?
response.header("Content-Length", ???????)
}
问题是 Spark 没有自动设置“Content-Length”标头,所以我试图添加它。 在那之前计算是正确的(没有压缩),但是由于 Spark 将压缩输出(因为它检测到“gzip”作为编码),我没有正确设置它的可靠方法。
我能想到的解决这个问题的方法是:
我当前的解决方案是在使用gzip
标头时不设置Content-Length
标头(但它不适合大文件,因为浏览器不知道已经下载了多少百分比)。
我希望这些细节能让情况更加明朗。
谢谢澄清!
Content-Length
用于您的用例。 不知道大小有点烦人,但并不少见。CountingOutputStream
拦截 OutputStreams 并且没有 API 可以在不更改代码的情况下做到这一点,并且它也存在其他问题。 问题还在于,在 spark 压缩输出之后,很可能它已经被刷新并发送回客户端,但是这个标头必须在数据之前发送。 在发送数据之前,您基本上必须知道这一点,因此这是最难的方法。ByteArray
提供给他(似乎您正在使用 kotlin)并禁用自动压缩。 ByteArrayOutputStream
是不错的选择。 这样它至少只被压缩一次。 还有关于设置Content-Encoding
标头同时强制 spark 不编码的事情,但这很容易修补。 关于这一点的丑陋之处在于,您必须将整个数据存储在内存中 + 服务器在这一切都被预先计算之前不会开始发送数据,因此用户单击下载和下载开始之间会有延迟。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.