http - 为什么 Tomcat 会为我的 RESTful API 返回不同的 HEAD 和 GET 请求 header ?

标签 http tomcat8 http-method chunked

我最初的目的是验证 HTTP 分块传输。但是无意中发现了这个不一致。

API 旨在将文件返回给客户端。我对它使用 HEADGET 方法。 返回不同的 header 。

对于 GET,我得到了这些 header :(这是我所期望的。)

Transfer-Encoding: chunked, no Content-Length.

对于 HEAD,我得到这些 header :

Content-Length: 1017118720, no Transfer-Encoding.

根据 this threadHEADGET 应该 返回相同的 header ,但不一定

我的问题是:

如果使用Transfer-Encoding: chunked因为文件是动态提供给客户端的,而 Tomcat 服务器无法预先知道它的大小,当使用HEAD 方法时,Tomcat 如何知道Content-Length? Tomcat 是否只是试运行 处理程序并计算所有文件字节数?为什么它不简单地返回相同的 Transfer-Encoding: chunked header ?

下面是我使用 Spring Web MVC 实现的 RESTful API:

@RestController
public class ChunkedTransferAPI {

    @Autowired
    ServletContext servletContext;

    @RequestMapping(value = "bootfile.efi", method = { RequestMethod.GET, RequestMethod.HEAD })
    public void doHttpBoot(HttpServletResponse response) {

        String filename = "/bootfile.efi";
        try {
            ServletOutputStream output = response.getOutputStream();
            InputStream input = servletContext.getResourceAsStream(filename);
            BufferedInputStream bufferedInput = new BufferedInputStream(input);
            int datum = bufferedInput.read();
            while (datum != -1) {
                output.write(datum);
                datum = bufferedInput.read();
            }
            output.flush();
            output.close();

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

添加 1

在我的代码中,我没有明确添加任何 header ,那么一定是 Tomcat 添加了它认为合适的 Content-LengthTransfer-Encoding header .

那么,Tomcat 决定发送哪些 header 的规则是什么?

添加 2

可能与Tomcat的工作方式有关。我希望有人能在这里阐明一些问题。否则,我将调试到 Tomcat 8 的源代码并分享结果。但这可能需要一段时间。

相关:

最佳答案

Does Tomcat just dry-run the handler and count all the file bytes?

是的,javax.servlet.http.HttpServlet.doHead() 的默认实现就是这样做的。

您可以查看 HttpServlet.java 中的帮助类 NoBodyResponse、NoBodyOutputStream

DefaultServlet 类(用于提供静态文件的 Tomcat servlet)更为明智。它能够发送正确的 Content-Length 值,以及为文件的一个子集(Range header )提供 GET 请求。您可以将您的请求转发给该 servlet,使用

  ServletContext.getNamedDispatcher("default").forward(request, response);

关于http - 为什么 Tomcat 会为我的 RESTful API 返回不同的 HEAD 和 GET 请求 header ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34290203/

相关文章:

arrays - 将多个$http返回数据按调用顺序赋值给一个数组

python - 使用自定义状态代码在 Python Bottle 中发送字典作为响应

java - 通过 Spring Boot 应用程序关闭 Tomcat 日志记录

maven - 在 intellij 14 行找不到可执行代码

grails - 具有相同URL值的Grails动态请求映射

asp.net-mvc-3 - 在Html.BeginForm()中使用DELETE表单方法吗?

http - 为什么 get 请求中的百分号会破坏我的网站?

windows - 如何检查开放端口是 TCP 还是 HTTP?

apache - 如何向 Apache tomcat 8 中的管理员用户添加多个角色?

xamarin.ios - Monotouch/iPhone - 当 HTTP 方法为 DELETE 时,调用 HttpWebRequest.GetRequestStream() 连接到服务器