title: Using Play WS and getting java.net.ConnectException: handshake timed out on Amazon Cloudfront
body: <p>Within my Play application I need to download a large number of files from Amazon Cloudfront. Using SSL I'm getting the following error randomly on a link:</p>
  
  <pre><code>play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[ConnectException: handshake timed out]]
  at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:280)
  at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:206)
  at play.api.GlobalSettings$class.onError(GlobalSettings.scala:160)
  at play.api.DefaultGlobal$.onError(GlobalSettings.scala:188)
  at play.api.http.GlobalSettingsHttpErrorHandler.onServerError(HttpErrorHandler.scala:98)
  at play.core.server.netty.PlayRequestHandler$$anonfun$2$$anonfun$apply$1.applyOrElse(PlayRequestHandler.scala:99)
  at play.core.server.netty.PlayRequestHandler$$anonfun$2$$anonfun$apply$1.applyOrElse(PlayRequestHandler.scala:98)
  at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:346)
  at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:345)
  at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
  Caused by: java.net.ConnectException: handshake timed out
  at org.asynchttpclient.netty.channel.NettyConnectListener.onFailure(NettyConnectListener.java:137)
  at org.asynchttpclient.netty.channel.NettyConnectListener$1.onFailure(NettyConnectListener.java:108)
  at org.asynchttpclient.netty.SimpleFutureListener.operationComplete(SimpleFutureListener.java:26)
  at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:514)
  at io.netty.util.concurrent.DefaultPromise.notifyListeners0(DefaultPromise.java:507)
  at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:486)
  at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:427)
  at io.netty.util.concurrent.DefaultPromise.tryFailure(DefaultPromise.java:129)
  at io.netty.handler.ssl.SslHandler.notifyHandshakeFailure(SslHandler.java:1235)
  at io.netty.handler.ssl.SslHandler.access$700(SslHandler.java:160)
  Caused by: javax.net.ssl.SSLException: handshake timed out
  at io.netty.handler.ssl.SslHandler.handshake(...)(Unknown Source)
  </code></pre>
  
  <p>Mostly its also only one that fails. The rest still downloads.</p>
  
  <p>So I have an play 2.5.8 application in which I use the default ws client. This Play version uses by default netty-handler 4.0.33-FINAL version. I even update the netty-handler to 4.0.41.Final but this didn't help.</p>
  
  <p>I'm generating the cloudfront url with the aws-java-sdk-cloudfront" % "1.11.39" library using the CloudFrontUrlSigner.getSignedURLWithCustomPolicy(protocol, host, privateKeyFile, path, keyPairId, dateLessThan, dateGreaterThan, ip)</p>
  
  <pre><code>val data = for {
    records &lt;- (onStore(model) withDomain None).list()
    recordsWithData = addBucketData(withCloudFrontUrl(request.remoteAddress))(records)
  } yield Future.sequence(recordsWithData)
  
  private def addBucketData(urlGenerator: String =&gt; Future[String]): Seq[JsObject] =&gt; Seq[Future[JsObject]] = { records =&gt;
    records.map(record =&gt; {
      val id = (record \ "id").as[String]
  
      urlGenerator(id).map(url =&gt; {
        val encodedString = ws.url(url).get().map(result =&gt;
           org.apache.commons.codec.binary.Base64.encodeBase64String(result.bodyAsBytes.toArray)
        )
  
        encodedString.map(data =&gt; record ++ Json.obj("data" -&gt; data))
      }).flatMap(x =&gt; x)
    })
  }
  </code></pre>
  
  <p>Does anybody have an idea on what the problem is?</p>
  
  <p>After some debugging the (actual) problem seem to be:</p>
  
  <pre><code>%% Invalidated:  [Session-339, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
  AsyncHttpClient-2-8, SEND TLSv1.2 ALERT:  fatal, description = internal_error
  AsyncHttpClient-2-8, Exception sending alert: java.io.IOException: writer side was already closed.
  AsyncHttpClient-2-8, called closeOutbound()
  AsyncHttpClient-2-8, closeOutboundInternal()
  AsyncHttpClient-2-8, SEND TLSv1.2 ALERT:  warning, description = close_notify
  AsyncHttpClient-2-8, WRITE: TLSv1.2 Alert, length = 2
  AsyncHttpClient-2-8, called closeInbound()
  AsyncHttpClient-2-8, fatal error: 80: Inbound closed before receiving peer's close_notify: possible truncation attack?
  javax.net.ssl.SSLException: Inbound closed before receiving peer's close_notify: possible truncation attack?
  %% Invalidated:  [Session-340, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
  AsyncHttpClient-2-8, SEND TLSv1.2 ALERT:  fatal, description = internal_error
  AsyncHttpClient-2-8, Exception sending alert: java.io.IOException: writer side was already closed.
  AsyncHttpClient-2-8, called closeOutbound()
  AsyncHttpClient-2-8, closeOutboundInternal()
  AsyncHttpClient-2-8, SEND TLSv1.2 ALERT:  warning, description = close_notify
  AsyncHttpClient-2-8, WRITE: TLSv1.2 Alert, length = 2
  AsyncHttpClient-2-8, called closeInbound()
  AsyncHttpClient-2-8, fatal error: 80: Inbound closed before receiving peer's close_notify: possible truncation attack?
  javax.net.ssl.SSLException: Inbound closed before receiving peer's close_notify: possible truncation attack?
  %% Invalidated:  [Session-341, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
  AsyncHttpClient-2-8, SEND TLSv1.2 ALERT:  fatal, description = internal_error
  AsyncHttpClient-2-8, Exception sending alert: java.io.IOException: writer side was already closed.
  [Raw read (bb)]: length = 12899
  </code></pre>