gpt4 book ai didi

spring - 为什么 Firefox 不尊重分块传输编码?

转载 作者:行者123 更新时间:2023-12-03 03:49:45 24 4
gpt4 key购买 nike

我正在通过在 Apache Tomcat/6.0.18 上运行的 Spring MVC Controller 流式传输大型文档

因为它很大,并且(最终)会动态生成,所以我决定使用分块传输编码。

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.inject.Inject;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.httpclient.ChunkedOutputStream;
import org.apache.commons.net.io.CopyStreamException;
import org.apache.commons.net.io.Util;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class QueryController {

@Inject
QueryService queryService;

@RequestMapping(value = "/stream")
public void hellostreamer(HttpServletResponse response) throws CopyStreamException, IOException {

response.setHeader("Transfer-Encoding", "chunked");
response.setHeader("Content-type", "text/xml");
InputStream filestream = new FileInputStream("/lotsrecs.xml");
ChunkedOutputStream chunkStream = new ChunkedOutputStream(response.getOutputStream());
Util.copyStream(filestream,chunkStream);
chunkStream.close();
chunkStream.finish();
}
}

但是,当我在 Firefox 中打开它时,我得到:

XML Parsing Error: syntax error
Location: http://localhost:8082/streaming-mockup-1.0-SNAPSHOT/stream
Line Number 1, Column 1:

800
^

它不是将 block 大小作为流的元数据读取,而是将它们作为流的一部分读取!

使用实时 HTTP header ,我可以看到正在接收 Transfer-Encoding header :

HTTP/1.1 200 OK

Server: Apache-Coyote/1.1

Transfer-Encoding: chunked
Content-Type: text/xml

Date: Thu, 11 Aug 2011 18:08:07 GMT

所以我不知道为什么 block 大小没有被正确解释。如果我使用 wget 发出请求,我还会在返回的文档中看到 block 大小字符,因此不知何故它们没有被正确编码。有人知道为什么吗?

使用wireshark查看传输:(请注意,“800”在整个流中重复出现)请注意0x800 = 2048,这是ChunkedOutputStream类使用的默认 block 大小。

GET /streaming-mockup-1.0-SNAPSHOT/stream HTTP/1.0    
User-Agent: Wget/1.12 (linux-gnu)
Accept: */*
Host: localhost:8082
Connection: Keep-Alive

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Transfer-Encoding: chunked
Content-Type: text/xml
Date: Thu, 11 Aug 2011 18:47:24 GMT
Connection: close

800

<records>
<REC>
<FUID>412286284WOS1</FUID>
<UID>WOS:000292284100013</UID>
<static_data>
<summary>
<EWUID uid="WOS:000292284100013" year="2011">

如果我只是直接复制到输出流而不创建 ChunkedOutputStream,我根本看不到 block 大小:

GET /streaming-mockup-1.0-SNAPSHOT/stream HTTP/1.0
User-Agent: Wget/1.12 (linux-gnu)
Accept: */*
Host: localhost:8082
Connection: Keep-Alive

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Transfer-Encoding: chunked
Content-Type: text/xml
Date: Thu, 11 Aug 2011 18:51:05 GMT
Connection: close

<records>
<REC>
<FUID>412286284WOS1</FUID>
<UID>WOS:000292284100013</UID>
<static_data>
<summary>

那么我怎么知道这是否被分块了呢?如果是的话,我不会看到 block 大小吗?

最佳答案

您确定需要为自己构建一个 ChunkedOutputStream 吗?

我的理解(未受实践污染)是 ServletResponse.getOutputStream() 应该在适当的情况下为您处理分块(例如,如果客户端不是 HTTP 1.0,等等)。如果这是真的,实际发送的回复将在分块编码内进行分块编码,浏览器当然只知道这些层中的一层。

您是否尝试过在网络上的某个位置运行服务器并使用 Wireshark 检查事务?

更新:

GET /streaming-mockup-1.0-SNAPSHOT/stream HTTP/1.0

HTTP/1.0 客户端根本不需要理解分块编码(很自然,因为该编码只是为 1.1 发明的)。

关于spring - 为什么 Firefox 不尊重分块传输编码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7030885/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com