Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Large response entity is truncated over https with 'Connection: close' header #1219

Closed
anilgursel opened this issue Jun 21, 2017 · 3 comments
Labels
3 - in progress Someone is working on this ticket bug help wanted Identifies issues that the core team will likely not have time to work on t:core Issues related to the akka-http-core module
Milestone

Comments

@anilgursel
Copy link
Contributor

When a client sends Connection: close header and response entity is large, the entity gets truncated over https. It is ok with http. We see this behaviour only with larger entities. Please see below reproducer:

import java.io.InputStream
import java.security.{KeyStore, SecureRandom}
import javax.net.ssl.{KeyManagerFactory, SSLContext, TrustManagerFactory}

import akka.actor.ActorSystem
import akka.http.scaladsl.server.Route
import akka.http.scaladsl.{ConnectionContext, Http, HttpsConnectionContext}
import akka.stream.ActorMaterializer
import akka.http.scaladsl.server.Directives._

import scala.util.Random

object HttpsWithLargeResponseEntity extends App {

  implicit val system = ActorSystem()
  implicit val mat = ActorMaterializer()
  implicit val dispatcher = system.dispatcher

  // Manual HTTPS configuration

  val password: Array[Char] = "changeit".toCharArray // do not store passwords in code, read them from somewhere safe!

  val ks: KeyStore = KeyStore.getInstance("JKS")
  val keystore: InputStream = getClass.getClassLoader.getResourceAsStream("example.com.jks")

  require(keystore != null, "Keystore required!")
  ks.load(keystore, password)

  val keyManagerFactory: KeyManagerFactory = KeyManagerFactory.getInstance("SunX509")
  keyManagerFactory.init(ks, password)

  val tmf: TrustManagerFactory = TrustManagerFactory.getInstance("SunX509")
  tmf.init(ks)

  val sslContext: SSLContext = SSLContext.getInstance("TLS")
  sslContext.init(keyManagerFactory.getKeyManagers, tmf.getTrustManagers, new SecureRandom)
  val https: HttpsConnectionContext = ConnectionContext.https(sslContext)

  val routes: Route = get { complete(Random.nextString(1024 * 100)) }
  Http().bindAndHandle(routes, "127.0.0.1", 8443, connectionContext = https)
  Http().bindAndHandle(routes, "127.0.0.1", 8080)
}

With the following commands, I see the entire entity is retrieved:

  • curl -kv https://localhost:8443/
  • curl -v http://localhost:8080/ -H 'Connection: close'
  • curl -v http://localhost:8080/

However, when the Connection: close' header is sent and the protocol is https, the entity gets truncated:

  • curl -kv https://localhost:8443/ -H 'Connection: close'
transfer closed with 90231 bytes remaining to read
* Curl_http_done: called premature == 1
* Closing connection 0
curl: (18) transfer closed with 90231 bytes remaining to read
@jonas
Copy link
Member

jonas commented Jun 21, 2017

Looks similar to #459 (and tickets referenced from it) but for HTTPS.

@jrudolph jrudolph added 1 - triaged Tickets that are safe to pick up for contributing in terms of likeliness of being accepted bug help wanted Identifies issues that the core team will likely not have time to work on t:core Issues related to the akka-http-core module labels Jun 26, 2017
@jrudolph
Copy link
Member

I can reproduce this issue. Here's source code and log for that issue: https://gist.github.com/jrudolph/a4f3adc3a1bbe57e6ebffd4c2fe8c649

I agree with @jonas that this issue looks very similar to #459. It seems the connection closure triggers stream completion and cancellation at the same time, which makes the TLS buffer drop still outstanding outgoing bytes.

I guess the problem here might be that the DelayCancellation stage is inserted at the wrong position, i.e. between TCP and TLS and not between SSL and HTTP.

jrudolph added a commit to jrudolph/akka-http that referenced this issue Jun 26, 2017
@jrudolph
Copy link
Member

That was it exactly. I posted a preliminary fix as #1235, pending proper tests. If someone wants to pick up until I get to it, please do.

anilgursel pushed a commit to anilgursel/akka-http that referenced this issue Jul 28, 2017
@jrudolph jrudolph added 3 - in progress Someone is working on this ticket and removed 1 - triaged Tickets that are safe to pick up for contributing in terms of likeliness of being accepted labels Aug 15, 2017
jrudolph added a commit that referenced this issue Aug 21, 2017
…https

Prevent early connection closure over https #1219
@jrudolph jrudolph added this to the 10.0.10 milestone Aug 21, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3 - in progress Someone is working on this ticket bug help wanted Identifies issues that the core team will likely not have time to work on t:core Issues related to the akka-http-core module
Projects
None yet
Development

No branches or pull requests

3 participants