Uploaded image for project: 'HttpComponents HttpClient'
  1. HttpComponents HttpClient
  2. HTTPCLIENT-1958

Thread interrupt flag leaking when aborting httpRequest during connection leasing stage

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 4.5.5, 4.5.6
    • Fix Version/s: 4.5.7, 5.0 Beta4
    • Component/s: HttpClient (classic)
    • Labels:
      None

      Description

      When calling HttpRequestBase#abort during the leasing connection phase, the thread is being interrupted and `RequestAbortedException` will be thrown.

      It is an unexpected behavior that aborting the http request would cause the interrupt flag to be set on the caller thread.

      Here is what happened looking from the source code of 4.5.5, 

      1. Aborting the request invokes future.cancel(true) and it throws InterruptedException https://github.com/apache/httpcomponents-client/blob/4.5.5/httpclient/src/main/java/org/apache/http/impl/conn/PoolingHttpClientConnectionManager.java#L272 
      2. InterruptedException is caught in MainClientExec and then it re-interrupts the thread and throws RequestAbortedException

      The second step is expected and the first step seems to be the root cause. Should we use `future.cancel(false)` instead as it causes the side effect for a simple httprequest#abort to interrupt the caller's thread?

       

      Code to reproduce:

      ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);

      try (
           PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager();
            CloseableHttpClient httpclient = HttpClients.custom().setConnectionManager(poolingHttpClientConnectionManager).build())

      {           HttpGet httpGet = new HttpGet("https://somehost.com");    // Aborting the request when it's getting a connection from the connection pool       scheduledExecutorService.schedule(httpGet::abort, 40, TimeUnit.MILLISECONDS);       CloseableHttpResponse response = httpclient.execute(httpGet);       HttpEntity entity = response.getEntity();       EntityUtils.consume(entity);    }

      catch (Exception e)

      {        e.printStackTrace();    }

      finally

      {    scheduledExecutorService.shutdown();    }

      System.out.println("Interrupted ?" + Thread.currentThread().isInterrupted());

       

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              Zoe Wang Zoe Wang
            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: