sumitsu
sumitsu

Reputation: 1511

Apache HTTPClient ignores timeout configuration when outbound stream interrupted by remote failure?

I have a client on Host A using Apache HTTPClient (4.2.5) to POST a message to a server on Host B. On Host A, I am setting the connect and read/socket timeouts in (what I believe to be) the recommended fashion:

client = new DefaultHttpClient();
params = client.getParams();
HttpConnectionParams.setConnectionTimeout(params, 5000);
HttpConnectionParams.setSoTimeout(params, 20000);

I am attempting to test the timeout behavior in the event that the client transmission is abruptly terminated (e.g. by a crash of the target server on Host B) after some but not all of the data stream has been transmitted. My testing methodology has been thus:

  1. Initiate HTTP POST from client application on Host A.
  2. Shortly after the logs indicate that the client has invoked the underlying Apache HTTPClient framework, enable a firewall rule on Host B to block traffic from Host A.

I can confirm (via packet captures) that the test is, in fact, cutting off the request data mid-stream.

I would have expected the client application to subsequently time out after the read timeout interval (20 seconds), but what I'm seeing instead is that the client hangs for a much longer interval (in the 500-600 seconds range) before finally encountering a connect timeout.

Can anyone explain (or failing that, venture a guess) as to why the client is ignoring what I have specified as the timeout? Is there any way that I can enforce a timeout in this case?

Upvotes: 1

Views: 2083

Answers (2)

Abhijeet Saxena
Abhijeet Saxena

Reputation: 41

So what happens is, the timeout property is applicable on each address that is obtained by DNS resolution. E.g abc.come resolved to 4 different ip address and you have set a timeout of 10 sec. So your request will wait for 4 x 10 = 40 sec in total before timing out.

Upvotes: 0

Boris Remus
Boris Remus

Reputation: 191

Not sure why that isn't working but you could try an alternate approach where you create the Params object prior to instantiating the HttpClient.

Something to this effect:

HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, 5000);
HttpConnectionParams.setSoTimeout(params, 20000);
HttpClient httpClient = new DefaultHttpClient(params);

There is also a set of parameters unique to each http message which would override the setting of the client connection object. You might want to check to see if they specify the timeout themselves and thus leave the one you set unused (shouldn't happen unless explicitly set, but worth checking) HttpMessage#getParam

Further, you could try to explicity set those parameters on your HttpGet or HttPost objects yourself and see if that alters the behavior.

Upvotes: 1

Related Questions