I am trying to set up a connection between an Akka HTTP Client and an Akka HTTP Server using a chunked+gzip transfer encoding. On the client side, I am using .via(Compression.gzip) and manually setting the Transfer-Encoding: gzip header as the docs say there is no high-level support for this.
On the server side, I am using decodeRequest { extractDataBytes { ... } }. My assumption was that this would take care of both decompression and dechunking, but when I’m running the sample below (Akka HTTP 10.1.3) the data bytes are still gzipped in my inner route. Am I missing something obvious?
Thanks!
object ChunkedGzipTest {
def main(args: Array[String]) {
implicit val system = ActorSystem("my-system")
implicit val materializer = ActorMaterializer()
implicit val executionContext = system.dispatcher
val route =
post {
decodeRequest {
extractDataBytes { dataSource =>
onSuccess(dataSource.runFold(ByteString.empty)(_.concat(_))) { bs =>
println(bs.decodeString("UTF-8"))
complete(HttpEntity("OK"))
}
}
}
}
val bindingFuture = Http().bindAndHandle(route, "localhost", 9999)
val testEntity: MessageEntity = HttpEntity.Chunked
.fromData(ContentTypes.`text/plain(UTF-8)`, Source(immutable.Seq(ByteString("This is my teststring")))
.via(Compression.gzip))
val transferEncHeaders = immutable.Seq(`Transfer-Encoding`(TransferEncodings.gzip))
val response = Http.get(system)
.singleRequest(HttpRequest(HttpMethods.POST, Uri("http://localhost:9999"), transferEncHeaders, testEntity))
Await.result(response, Duration.Inf)
bindingFuture.flatMap(_.unbind()).onComplete(_ => system.terminate())
}
}
I found the problem that seems to cause my issue here. The server-side decodeRequest handles only a Content-Encoding header, but not a Transfer-Encoding header in the request.
Is there a way to correctly handle both cases transparently on the server side? Or do I need to manually inspect the Transfer-Encoding header?
Transfer-Encoding is handled specially in akka-http (through the choice of HttpEntity subclasses). Setting the header manually usually has no effect. On the other hand, akka-http does not support gzip Transfer-Encoding itself.
However…
You should probably use gzip Content-Encoding which is what the decodeRequest will work with. Also Compression.gzip is the akka-streams level gzip support. We also have akka-http level gzip support which will directly set the right headers.