[ 
https://issues.apache.org/jira/browse/HTTPCLIENT-1439?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Oleg Kalnichevski resolved HTTPCLIENT-1439.
-------------------------------------------
       Resolution: Won't Fix
    Fix Version/s:     (was: Future)

> Infinite timeout on entity send
> -------------------------------
>
>                 Key: HTTPCLIENT-1439
>                 URL: https://issues.apache.org/jira/browse/HTTPCLIENT-1439
>             Project: HttpComponents HttpClient
>          Issue Type: Improvement
>          Components: HttpClient (classic)
>    Affects Versions: 4.3.1
>            Reporter: Dmitry Potapov
>            Priority: Minor
>
> Steps to reproduce:
> 1. Create HttpClient with RequestConfig.setSocketTimeout(1000)
> 2. Create ByteArrayEntity with 10 MB entity (entity size must be greater that 
> default socket send/receive buffer size)
> 3. Create ServerSocket and bind it to any port
> 4. Try to send HttpPost to this port with aforementioned entity
> Expected result:
> SocketTimeoutException is raised after 1 second since request start
> Actual result:
> Request send hangs
> Root cause:
> According to javadocs Socket.setSoTimeout() affects only .read() operations 
> and nothing said about write operations. While client tries to send data to 
> the remote port it receives TCP ZeroWindow messages in return, so formally 
> connection is still alive and won't be closed by system.
> Possible solution:
> 1. Start daemon thread somewhere in PoolingHttpClientManager which will 
> perform monitoring of all connections in this pool (say, once per 100 ms)
> 2. Each time new connection created, register it in monitoring thread object
> 3. Each time SessionInputBufferImpl enters .write() function, set connection 
> state to WRITE (and set it to IDLE in finally section)
> 4. Monitoring thread will iterate over all known connections and if 
> connection state is WRITE then compare state timestamp and current time. If 
> difference is more than timeout then close socket
> I've prepared small test which demonstrates the problem. HttpAsyncClient is 
> not affected by this issue (because reactor threads already works as 
> monitoring threads).
> import java.net.ServerSocket;
> import org.apache.http.concurrent.FutureCallback;
> import org.apache.http.config.SocketConfig;
> import org.apache.http.client.config.RequestConfig;
> import org.apache.http.client.methods.HttpPost;
> import org.apache.http.entity.ByteArrayEntity;
> import org.apache.http.impl.client.CloseableHttpClient;
> import org.apache.http.impl.client.HttpClients;
> import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
> import org.apache.http.impl.nio.client.HttpAsyncClients;
> import org.apache.http.nio.entity.NByteArrayEntity;
> public class Main {
>     public static void main(final String[] args) throws Exception {
>         ServerSocket socket = new ServerSocket(0);
>         System.out.println("Listening port " + socket.getLocalPort());
>         CloseableHttpAsyncClient client = HttpAsyncClients.custom()
>             .setDefaultRequestConfig(RequestConfig.custom()
>                 .setSocketTimeout(1000)
>                 .build())
>             .build();
>         client.start();
>         HttpPost post = new HttpPost("http://localhost:"; + 
> socket.getLocalPort());
>         post.setEntity(new NByteArrayEntity(new byte[10000000]));
>         System.out.println("Sending request");
>         client.execute(post, new FutureCallback<HttpResponse>() {
>             public void cancelled() {
>             }
>             public void completed(final HttpResponse response) {
>             }
>             public void failed(final Exception e) {
>                 System.out.println("Request failed: " + e);
>             }
>         });
>         Thread.sleep(2000);
>         CloseableHttpClient client2 = HttpClients.custom()
>             .setDefaultRequestConfig(RequestConfig.custom()
>                 .setSocketTimeout(1000)
>                 .build())
>             .build();
>         post.setEntity(new ByteArrayEntity(new byte[10000000]));
>         System.out.println("\nSending second request");
>         try {
>             client2.execute(post);
>         } catch (Exception e) {
>             System.out.println("Exception caught on second request");
>         }
>         System.out.println("Second request executed");
>     }
> }
> I'm not sure that solution suggested is acceptable.
> Also I'm not sure that I'll have enough time to provide this solution by 
> myself in this year.



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to