代码之家  ›  专栏  ›  技术社区  ›  lepe

如何正确设置spark java中gzip头后的内容长度

  •  0
  • lepe  · 技术社区  · 5 年前

    我在用 Spark 提供不同种类的内容。”“内容长度”的计算是正确的,但我在使用时面临一个问题:

    response.header("Content-Encoding", "gzip")
    

    their documentation ,spark将在设置头时自动将内容gzip。。。它做到了。

    但是,我之前计算的“内容长度”不再有效,因此在浏览器中出现“net::ERR_Content_Length_MISMATCH”错误。

    如何知道火花压缩输出后的结果大小?

    更多细节:

    我在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”作为编码),所以我没有一个可靠的方法来正确设置它。

    我能想到的解决这个问题的方法是:

    1. Spark adds that header automatically (或是我自己的分支)。
    2. 用Spark做的方法压缩它,这样我就可以计算出大小(但是很难看,因为它会压缩输出两次=CPU浪费)。

    我目前的解决方案是不设置 Content-Length 使用时标题 gzip

    我希望这些细节能使情况更加明朗。

    0 回复  |  直到 4 年前
        1
  •  0
  •   K.H.    4 年前

    谢谢你的澄清!

    1. 是的,现在你要手动添加,我会这样做,除非你真的需要 Content-Length 对于你的用例。不知道尺码有点烦人,但也不是很少见。
    2. CountingOutputStream 没有API可以在不更改代码的情况下做到这一点,而且还有其他问题。问题还在于,在spark压缩输出之后,很可能它已经被刷新并发送回客户端,但是这个头必须在数据之前发送。在发送数据之前,您基本上必须知道这一点,所以这是最难的方法。
    3. 是的,实现spark最简单的方法可能是将已经准备好的压缩数据作为 ByteArray (似乎您正在使用kotlin)并禁用自动压缩。 ByteArrayOutputStream Content-Encoding 头,而迫使火花不编码,但这是很容易修补。难看的是,你必须把所有的数据存储在内存中+服务器不会在所有数据都预先计算好之前开始发送数据,所以用户点击下载和下载开始之间会有延迟。