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.利用一个异步线程监控,关闭超长时间的请求

相关推荐