2

以下是我的示例 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();
        }
    }
}
4

3 回答 3

1

一种解决方法可能是:

t.sendResponseHeaders(200, 0);

注意

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

于 2018-03-16T09:47:45.253 回答
0
Content-Length header is always set, unless it's 0 or -1;

如果您检查源代码,HttpExchange sendResponseHeaders()您会发现此代码段,其中包含相关逻辑:

如您所见,当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        }

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

于 2018-03-16T09:51:03.080 回答
0

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

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

t.sendResponseHeaders(200, 0);

这意味着它不会向浏览器发送响应的长度,也不会发送 Content-Length 标头,而是将响应作为分块编码发送,正如您所指出的那样,这是为了测试它可能没问题。

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

于 2018-03-16T09:44:45.417 回答