我连接到juts返回“A”的非有限流的服务器。即:这个
$ nc 1.2.3.4 9001
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA^C
似乎apache http组件库只是从服务器获取整个响应然后解析。如何限制大小以便JVM不会崩溃?
这是我的代码:
w / fluent API:public static void main(String[] args) throws ClientProtocolException, IOException {
Request.Get(url).execute().discardContent();
}
w /低级API:
public static void main(String[] args) throws ClientProtocolException, IOException {
String url = "http://1.2.3.4:9001/";
DefaultHttpClient httpclient = new DefaultHttpClient();
System.out.println("A");
HttpGet request = new HttpGet(url);
System.out.println("B");
HttpResponse hr = httpclient.execute(request);
System.out.println("C");
}
告诉我这个:
A
B
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at org.apache.http.util.ByteArrayBuffer.expand(ByteArrayBuffer.java:62)
at org.apache.http.util.ByteArrayBuffer.append(ByteArrayBuffer.java:92)
at org.apache.http.impl.io.AbstractSessionInputBuffer.readLine(AbstractSessionInputBuffer.java:278)
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:92)
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:62)
at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:254)
at org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:289)
at org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:252)
at org.apache.http.impl.conn.ManagedClientConnectionImpl.receiveResponseHeader(ManagedClientConnectionImpl.java:191)
at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:300)
at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:127)
at org.apache.http.impl.client.DefaultRequestDirector.tryExecute(DefaultRequestDirector.java:712)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:517)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:784)
at com.dudebro.WhatHappen.main(WhatHappen.java:103)
注意related question是无关紧要的,我甚至不会要求API提供响应正文,但它仍然会崩溃。
答案 0 :(得分:3)
您可以尝试设置以下参数:
MAX_LINE_LENGTH = "http.connection.max-line-length"
MAX_HEADER_COUNT = "http.connection.max-header-count"
我认为第一个的默认值是-1,这意味着没有限制。
答案 1 :(得分:1)
从堆栈跟踪中可以清楚地看到:BufferedReader.readLine()
不断增长其缓冲区,因为它无法找到一个行终止符来开始解析响应状态行,直到JVM内存不足为止。您可以将代码包装在try
块中并捕获OutOfMemoryError
,或者甚至向Apache维护者提交补丁,但我认为您不应该真正将此问题考虑在内以用于实际应用程序
该服务器不符合HTTP,因为“A”的无限流并非绝对有效的HTTP响应状态行。通常服务器被设计为对他们所接受的内容采取自由主义,并严格遵守他们发送的内容,即他们应该考虑到可能存在不合规的客户端。
另一方面,客户端开发人员通常认为服务器实现得很好,因为如果不是,那么运行服务器的业务将无法获得任何客户端......
在这种情况下,很明显目标服务器不提供任何有价值的服务,因为它甚至不符合协议,所以没有人可以从中获取任何东西,Google无法对其进行索引,那么谁将会传播这种应用程序的公共URL?我认为客户端在您的开发计算机上崩溃是很好的,因为它告诉服务器程序不能正常工作。如果它在您的控制之下,您可以修复它,否则您将切换服务提供商。同样,这不会发生在现实世界中,因为这样糟糕的服务会使所有客户崩溃,没有人会使用它。
在评论中,您说这是一个接受用户提交的URL的服务器应用程序。在这种情况下,您应该确定行长度的限制,以避免恶意用户关闭服务器。