title: Apache HttpClient throws SocketTimeoutException when using SSL
body: <p>I'm using Apache httpclient 4.3.6 and httpcore 4.3.3 (bundled with opensaml 3.3.0). I'm attempting to fetch a web page through a proxy via HTTPS but get a SocketTimeoutException every time. HTTP connections work fine. The specific timeout doesn't matter; it just takes longer to fail with higher values.</p>
  
  <p>Sample code:</p>
  
  <pre><code>public class TestGet {
      private static final int TIMEOUT = 7000;
  
      public static void main(String[] args) throws Exception {
          URL url   = new URL("https://www.google.com");
          URL proxy = new URL("https://myproxy:9090/");
          try {
              String s = get(url, proxy);
              System.out.println(s);
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
  
      private static String get(URL url, URL proxy) throws IOException, URISyntaxException {
          CloseableHttpClient client  = HttpClients.createDefault();
          HttpGet             request = new HttpGet(url.toURI());
          HttpHost            host    = null;
  
          if (proxy != null) {
              host = new HttpHost(proxy.getHost(), proxy.getPort(), proxy.getProtocol());
          }
  
          RequestConfig config = RequestConfig.custom()
              .setProxy(host)
              .setConnectionRequestTimeout(TIMEOUT)
              .setConnectTimeout(TIMEOUT)
              .setSocketTimeout(TIMEOUT)
              .build();
          request.setConfig(config);
  
          try {
              CloseableHttpResponse response = client.execute(request);
              try {
                  System.out.println(response.getStatusLine());
                  return EntityUtils.toString(response.getEntity());
              } finally {
                  response.close();
              }
          } finally {
              client.close();
          }
      }
  }
  </code></pre>
  
  <p>The exception is thrown when trying to connect to the proxy. The stack trace is</p>
  
  <pre><code>org.apache.http.conn.ConnectTimeoutException: Connect to &lt;proxy&gt; failed: Read timed out
      at org.apache.http.impl.conn.HttpClientConnectionOperator.connect(HttpClientConnectionOperator.java:134)
      at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:319)
      at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:371)
      at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:219)
      at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:195)
      at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:86)
      at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108)
      at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
      at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
      at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:106)
      at authentication.TestGet.get(TestGet.java:47)
      at authentication.TestGet.main(TestGet.java:22)
  Caused by: java.net.SocketTimeoutException: Read timed out
      at java.net.SocketInputStream.socketRead0(Native Method)
      at java.net.SocketInputStream.socketRead(Unknown Source)
      at java.net.SocketInputStream.read(Unknown Source)
      at java.net.SocketInputStream.read(Unknown Source)
      at sun.security.ssl.InputRecord.readFully(Unknown Source)
      at sun.security.ssl.InputRecord.read(Unknown Source)
      at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
      at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
      at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
      at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
      at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:290)
      at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:259)
      at org.apache.http.impl.conn.HttpClientConnectionOperator.connect(HttpClientConnectionOperator.java:125)
      ... 11 more
  </code></pre>
  
  <p>This looks a lot like Apache issue <a href="https://issues.apache.org/jira/browse/HTTPCLIENT-1478" rel="nofollow noreferrer">HTTPCLIENT-1478</a> which had to do with the socket timeout not being set. That bug was marked fixed in 4.3.4 (I'm using 4.3.6) and while some of the comments indicate that work-arounds are still necessary in later versions, they aren't working for me. More to the point, I've stepped into SSLConnectionSocketFactory.createConnection() and confirmed that the socket timeout is being set to a non-zero value.</p>
  
  <p>I'm stuck. I don't know why the connection is failing and haven't been able to step any deeper than the call to SSLSocketImpl.startHandshake() to troubleshoot. What could be wrong, and how do I fix it?</p>