如何模拟客户端中止请求?

问题描述:

我与解决一个报告的bug,在日志显示如何模拟客户端中止请求?

org.apache.catalina.connector.ClientAbortException: java.io.IOException 
... 
Caused by: java.io.IOException 
    at org.apache.coyote.http11.InternalAprOutputBuffer.flushBuffer(InternalAprOutputBuffer.java:205) 

There are several questions here about the ClientAbortException,并从阅读他们我的理解,并also the Tomcat javadoc任务,是异常是由Tomcat的,当客户端中止HTTP抛出请求。

我无法重现错误。我如何模拟客户端中止?

我已经试过

  • 在请求处理程序添加Thread.sleep(10000),然后关闭浏览器的请求正在运行时 - 但是,这并不这样做。

  • 以角度使用this technique从客户端取消HTTP请求。

+1

'ClientAbortException'可能由多种情况引起。模拟客户端中止将允许您解决您造成的客户端中止,而不是后续客户端中止。例如,这个异常可以由客户端取消下载引发。模拟如何帮助您解决与超时有关的客户端异常终止问题? –

+0

@JonnyHenly - 这是调试应用程序的第一步。如果我明白什么样的事情会导致'ClientAbortException',那么我知道该找什么。 – dwjohnston

+0

发现一个[Tomcat论坛帖子](http://tomcat.10.x6.nabble.com/Question-on-ClientAbortException-td2158595.html),声明 - * APR'flushBuffer()'方法得到了否定的回应来自APR库中的本地'Socket.sendbb()'方法。通常的原因是客户端断开连接,但其他不常见的网络错误可能会触发它。* –

好吧,有一些实验 - 我找到了一种方法来做到这一点。

它看起来像是 - 如果在服务器正在写入/清除输出时,客户端取消/超时的http请求,则会抛出错误。 (注:看起来好像回复的大小也很重要 - 请参阅最后的笔记)。

有三件事情可能发生:


条件1:服务器写入和客户端超时之前刷新输出。

响应被发送回客户端。

条件2:客户端在服务器写入和刷新输出之前超时。

客户端没有收到响应,没有服务器错误。

条件3:服务器写入输出时客户端超时。

客户端未收到回应。服务器抛出ClientAbortExceptionjava.io.IOException)。


为了模拟这三个条件,我们有三个变量玩:

  1. 的时间客户端向超时
  2. 时间服务器烧伤获取其结果。
  3. 服务器响应的大小。

下面是测试代码进行模拟:

服务器端(这是一个Spring MVC的控制器)。

@RequestMapping(value = { "/debugGet" }, method = RequestMethod.GET) 
@ResponseBody 
public List<String> debugGet(@RequestParam int timeout, int numObjects) throws InterruptedException { 
    Thread.sleep(timeout); 

    List<String> l = new ArrayList<String>(); 

    for (int i =0; i< numObjects; i++){ 
     l.add(new String()); 
    } 


    return l; 

} 

客户端侧(角)

this.debugGet = function(server, client, numObjects){  

    var httpProm = $http({ 
     method: "GET", 
     url: "debugGet", 
     timeout: client, 
     params : { 
      timeout: server, 
      numObjects: numObjects} 
    });    

    httpProm.then(function(data){ 
     console.log(data); 
    }, function(data){ 
     console.log("error"); 
     console.log(data); 
    });  
}; 

使用此我可以模拟三个条件与下列PARAMS:

   Client Timeout  Server Burn Time  Num Strings 
Condition 1: 1000    900     10000 
Condition 2: 1000    2000     100 
Condition 3: 1000    950     10000 

NB它显示为如果尺寸的回应也很重要。

例如:

   Client Timeout  Server Burn Time  Num Strings 
Condition 2: 1000    2000     100 
Condition 3: 1000    2000     10000 

这里为10000个字符串,我们得到了java.io.IOException即使发生刷新客户端已经超时后好了,而它不是为100个字符串。