在我的基于Java / Dropwizard的应用程序中,我有一个端点,允许客户端根据请求下载他们的数据。客户端使用Curl / Wget等工具调用端点。此端点按需构建ZIP存档,并使用ZipOutputStream将其流回客户端。在内部,端点知道它必须处理多少数据,并且能够相当准确地预测进度。但是,由于使用ZIP,它显然无法在响应标头中设置Content-Length之类的内容。数据量可能很大,客户抱怨缺乏下载时间估计。
curl <endpoint> > foo.zip
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 7466k 0 7466k 0 0 10351 0 --:--:-- 0:12:18 --:--:-- 8985
好奇是否有办法通过标准HTTP方法向客户端传达进度?
答案 0 :(得分:1)
您真的应该在发送之前对存档进行压缩。 Content-Length标头对于任何不使用分块传输编码的HTTP事务都是必不可少的......如果您使用Java,我的猜测是您没有使用分块传输编码(我承认我可能)是错的。)
无法更新客户端有关下载进度的信息。我知道这听起来不太令人满意,所以我会解释原因。一旦您的标头被发送并且客户端开始读取HTTP消息正文,则所有收到的数据都将被视为消息正文。您发送到该客户端套接字的任何内容都与压缩存档的字节无法区分。发送任何将被curl或wget解释为元数据的内容是不可能的。
你应该真正发送内容长度的另一个原因是curl和wget不会知道消息何时结束(再次假设你没有使用分块传输编码)。即使关闭OutputStream,curl和wget也会继续侦听更多数据,直到超时,这可能需要15秒的不活动时间。
如果您只是手动压缩存档并发送内容长度,一切都将自行处理。 curl和wget都会自动监视并显示进度,并在收到所有数据后停止监听连接。