【问题标题】:How to remove Content-length header from HTTP response generated in a simple server?如何从简单服务器中生成的 HTTP 响应中删除 Content-length 标头?
【发布时间】:2018-08-25 07:39:56
【问题描述】:

以下是我的示例 HTTP 服务器。我需要删除响应中生成的“内容长度:”标头。我尝试了很多方法,但都没有成功。有没有办法从服务器响应中删除内容长度?

public class SimpleHttpServer {

    public static void main(String[] args) throws Exception {
        HttpServer server = HttpServer.create(new InetSocketAddress(9000), 0);
        server.createContext("/test", new TestHandler());
        server.setExecutor(null); // creates a default executor
        server.start();
    }

    static class TestHandler implements HttpHandler {
        public void handle(HttpExchange t) throws IOException {
            byte[] response = "Welcome to Test Server..!!\n".getBytes();
            t.sendResponseHeaders(200, response.length);
            OutputStream os = t.getResponseBody();
            os.write(response);
            os.close();
        }
    }
}

【问题讨论】:

  • 去掉这个头域的目的是什么。因为基于此,只有客户端才能从您的流中读取内容?这是您的服务器发送的数据量。
  • 我需要为测试目的生成响应
  • 应该是这样的。响应中没有内容长度。 > POST / HTTP/1.1 > 用户代理:curl/7.29.0 > 接受:/ > 内容类型:application/json > 内容长度:115 > 上传完全发送:115 个字节中的 115 个
  • @MariaSekar 链接的答案是针对 Spring 程序的 - 这里的示例使用核心 JDK 类 HttpExchange

标签: java server response response-headers http-content-length


【解决方案1】:

解决方法可能是:

t.sendResponseHeaders(200, 0);

注意

如果响应长度参数是0,则使用分块传输编码,可以发送任意数量的数据

【讨论】:

  • 问题是我需要一个只包含状态码的响应。传输编码:分块不应该在那里。
  • @MPS,为什么响应中不需要标头?这让我很困惑。你想达到什么目标?
【解决方案2】:

您必须在响应长度中发送 0,如 javadoc 中为 sendResponseHeaders 指定的那样:

responseLength - 如果 > 0,则指定一个固定的响应正文长度,并且必须将确切的字节数写入从 getResponseBody() 获取的流中,否则如果等于 0,则使用分块编码,以及任意数字可以写入字节数。如果

t.sendResponseHeaders(200, 0);

这意味着它不会向浏览器发送响应的长度,也不会发送 Content-Length 标头,而是将响应作为 chunked encoding 发送,因为您表示这是为了测试它可能没问题。

分块传输编码是超文本传输​​协议 (HTTP) 1.1 版中可用的流式数据传输机制。在分块传输编码中,数据流被分成一系列不重叠的“块”。这些块彼此独立地发送和接收。在任何给定时间,发送者和接收者都不需要知道当前正在处理的块之外的数据流。

【讨论】:

  • 既然它添加了Transfer-encoding: chunked 作为响应,有什么办法也可以删除它。我需要得到一个只包含状态码的响应。
  • @MPS 不明白您要实现的目标,如果您使用 curl,您可能会以调用 url 的方式使用 curl -I http://localhost:9000/test 来尝试仅获取状态码
【解决方案3】:
Content-Length header is always set, unless it's 0 or -1;

如果你查看HttpExchange sendResponseHeaders()的来源你会发现这个sn-p,其中包含相关逻辑:

正如您所见,当contentLen == 0 和!http10 时,此标头被添加"Transfer-encoding", "chunked"

您可以使用getResponseHeaders()(它返回一个可变的标头映射)来设置任何响应标头,除了 "Date""Transfer-encoding" - 阅读链接的源代码以了解原因。

207        if (contentLen == 0) {
208            if (http10) {
209                o.setWrappedStream (new UndefLengthOutputStream (this, ros));
210                close = true;
211            } else {
212                rspHdrs.set ("Transfer-encoding", "chunked");
213                o.setWrappedStream (new ChunkedOutputStream (this, ros));
214            }
215        } else {
216            if (contentLen == -1) {
217                noContentToSend = true;
218                contentLen = 0;
219            }
220            /* content len might already be set, eg to implement HEAD resp */
221            if (rspHdrs.getFirst ("Content-length") == null) {
222                rspHdrs.set ("Content-length", Long.toString(contentLen));
223            }
224            o.setWrappedStream (new FixedLengthOutputStream (this, ros, contentLen));
225        }

如果您需要更大的灵活性,则需要使用其他构造,而不是简单的HttpExchange。类带有约束、默认行为并以某种方式构建。

【讨论】:

  • sendResponseHeaders 方法中,它根据 contentLen 参数设置两个标头 Date 和 'Content-Lenght` 或 'Transfer-Encoding`,并将这些标头写入输出流 @ 987654335@ 第 226 行,因此即使您可以更改地图并删除标题,响应也会包含这些标题,因为它们已发送到输出流,我尝试清除地图并没有删除标题
猜你喜欢
  • 2016-11-05
  • 1970-01-01
  • 2017-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-06
  • 1970-01-01
相关资源
最近更新 更多