是否可以同时使用 GZIP 和字节范围发送 HTTP 响应?

Is it possible to send HTTP response using GZIP and byte ranges at the same time?

要求:

...
Content-Range: bytes 27482871-41601067/41601068
...

我尝试从文件中读取字节,然后再读取到 GZIP。响应如下所示:

response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);

...
Server: GlassFish Server Open Source Edition  4.1
X-Powered-By: Servlet/3.1 JSP/2.3 (GlassFish Server Open Source Edition  4.1  Java/Oracle Corporation/1.8)
Date: Thu, 26 Nov 2015 21:44:21 GMT
Accept-Ranges: bytes
Connection: keep-alive
Keep-Alive: timeout=1800
Content-Disposition: attachment;filename*=utf-8''Marq_Aurel_Rayman_Rave_-_Intdo_The_Blue_%28Max_R_remix%29.wav
ETag: Marq_Aurel_Rayman_Rave_-_Intdo_The_Blue_%28Max_R_remix%29.wav-41601068-1403655006000
Cache-Control: private,max-age=604800
Last-Modified: Wed, 25 Jun 2014 00:10:06 GMT
Content-Range: bytes 27482871-41601067/41601068
Content-Encoding: gzip
...

如果我暂停并恢复,下载会失败。也许我不应该在范围响应中使用 GZIP?

是的。可以在一定范围内请求 gzip 内容,但只能使用 Transfer-Encoding 而不是 ,使用 Content-Encoding.

Content-Encoding 如果您要求的字节范围将不起作用:这意味着服务器对整个文档进行编码,并且如果整个内容使用 gzip 编码并且您只请求一个范围您对它的了解还不足以解压缩它。 (您不能解压部分 gzip,或者至少不能没有它的开头。)

您可以使用 Transfer-Encoding 而不是使用范围来提供整个压缩文档的一部分。这将为您提供所需的范围,并压缩该范围。好多了!

不直观的是,当你用 Accept-Encoding header 请求 Content-Encoding 时,你用 TE header 请求 Transfer-Encoding

然而,这就是事情变得棘手的地方:很少 web-servers 支持它。例如,如果您从 CloudFlare 提取内容,您会发现它们没有。

这是a discussion from the nginx mailing-list where they discuss exactly this problem, and here's another on making it work in HTTP/2