/akka-http2-support/src/test/scala/akka/http/impl/engine/http2/H2cUpgradeSpec.scala

https://github.com/akka/akka-http · Scala · 63 lines · 46 code · 12 blank · 5 comment · 2 complexity · 7764f80cfd87a2b87e34ef8705788edf MD5 · raw file

  1. /*
  2. * Copyright (C) 2019-2020 Lightbend Inc. <https://www.lightbend.com>
  3. */
  4. package akka.http.impl.engine.http2
  5. import akka.http.impl.util._
  6. import akka.http.scaladsl.model.{ HttpResponse, StatusCodes }
  7. import akka.http.scaladsl.{ Http2, HttpConnectionContext }
  8. import akka.stream.scaladsl.{ Source, Tcp }
  9. import akka.util.ByteString
  10. import scala.annotation.tailrec
  11. import scala.concurrent.Future
  12. import scala.concurrent.duration._
  13. class H2cUpgradeSpec extends AkkaSpecWithMaterializer("""
  14. akka.http.server.preview.enable-http2 = on
  15. akka.http.server.http2.log-frames = on
  16. """) {
  17. override implicit val patience = PatienceConfig(5.seconds, 5.seconds)
  18. "An HTTP/1.1 server without TLS that allows upgrading to cleartext HTTP/2" should {
  19. val binding = Http2().bindAndHandleAsync(
  20. _ => Future.successful(HttpResponse(status = StatusCodes.ImATeapot)),
  21. "127.0.0.1",
  22. port = 0,
  23. HttpConnectionContext()
  24. ).futureValue
  25. // https://tools.ietf.org/html/rfc7540#section-3.2
  26. "respond with HTTP 101" in {
  27. // Not the whole frame, but only the identifiers and values - so an empty string for 0 settings is valid:
  28. val settings = ""
  29. val upgradeRequest =
  30. s"""GET / HTTP/1.1
  31. Host: localhost
  32. Upgrade: h2c
  33. HTTP2-Settings: $settings
  34. """
  35. val frameProbe = Http2FrameProbe()
  36. Source.single(ByteString(upgradeRequest)).concat(Source.maybe)
  37. .via(Tcp().outgoingConnection(binding.localAddress.getHostName, binding.localAddress.getPort))
  38. .runWith(frameProbe.sink)
  39. @tailrec def readToEndOfHeader(currentlyRead: String = ""): String =
  40. if (currentlyRead.endsWith("\r\n\r\n")) currentlyRead
  41. else readToEndOfHeader(currentlyRead + frameProbe.plainDataProbe.expectBytes(1).utf8String)
  42. val headers = readToEndOfHeader()
  43. headers should include("HTTP/1.1 101 Switching Protocols")
  44. headers should include("Upgrade: h2c")
  45. headers should include("Connection: upgrade")
  46. frameProbe.expectFrameFlagsStreamIdAndPayload(Http2Protocol.FrameType.SETTINGS)
  47. frameProbe.expectHeaderBlock(1, true)
  48. }
  49. }
  50. }