HttpClient使用过程中的安全隐患
HttpClient使用过程中的安全隐患,这个有些标题党。因为这本身不是HttpClient的问题,而是使用者的问题。
安全隐患场景说明:
一旦请求大数据资源,则HttpClient线程会被长时间占有。即便调用了org.apache.commons.httpclient.HttpMethod#releaseConnection()方法,也无济于事。
如果请求的资源是应用可控的,那么不存在任何问题。可是恰恰我们应用的使用场景是,请求资源由用户自行输入,于是乎,我们不得不重视这个问题。
我们跟踪releaseConnection代码发现:
org.apache.commons.httpclient.HttpMethodBase#releaseConnection()
public void releaseConnection() { try { if ( this .responseStream != null ) { try { // FYI - this may indirectly invoke responseBodyConsumed. this .responseStream.close(); } catch (IOException ignore) { } } } finally { ensureConnectionRelease(); } }
org.apache.commons.httpclient.ChunkedInputStream#close()
public void close() throws IOException { if ( ! closed) { try { if ( ! eof) { exhaustInputStream( this ); } } finally { eof = true ; closed = true ; } } }
org.apache.commons.httpclient.ChunkedInputStream#exhaustInputStream(InputStream inStream)
static void exhaustInputStream(InputStream inStream) throws IOException { // read and discard the remainder of the message byte buffer[] = new byte [ 1024 ]; while (inStream.read(buffer) >= 0 ) { ; } }
看到了吧,所谓的丢弃response,其实是读完了一次请求的response,只是不做任何处理罢了。
想想也是,HttpClient的设计理念是重复使用HttpConnection,岂能轻易被强制close呢。
怎么办?有朋友说,不是有time out设置嘛,设置下就可以下。
我先来解释下Httpclient中两个time out的概念:
1.public static final String CONNECTION_TIMEOUT = "http.connection.timeout";
即创建socket连接的超时时间:java.net.Socket#connect(SocketAddress endpoint, int timeout)中的timeout
2.public static final String SO_TIMEOUT = "http.socket.timeout";
即read data过程中,等待数据的timeout:java.net.Socket#setSoTimeout(int timeout)中的timeout
而在我上面场景中,这两个timeout都不满足,确实是由于资源过大,而占用了大量的请求时间。
问题总是要解决的,解决思路如下:
1.利用DelayQueue,管理所有请求
2.利用一个异步线程监控,关闭超长时间的请求
相关推荐
创建一个 HttpClient 实例,这个实例需要调用 Dispose 方法释放资源,这里使用了 using 语句。接着调用 GetAsync,给它传递要调用的方法的地址,向服务器发送 Get 请求。