akka/akka-http

Corresponding coding directives fail to process gzip- and deflate-compressed HTTP/1.0 requests

Aberta

#46 aberto em 8 de set. de 2016

 (7 comentários) (0 reação) (0 responsável)Scala (598 forks)batch import
1 - triageddiscusshelp wanted

Métricas do repositório

Stars
 (1.311 estrelas)
Métricas de merge de PR
 (Mesclagem média 1d 10h) (2 fundiu PRs em 30d)

Description

Issue by levkhomich Saturday Jul 16, 2016 at 06:40 GMT Originally opened as https://github.com/akka/akka/issues/20969


The problem is that decodeRequest and decodeRequestWith directives map original request entity to HttpEntity.Chunked which, in turn, fails HttpRequest.copy's requirement

require(
    protocol == HttpProtocols.`HTTP/1.1` || !entity.isInstanceOf[HttpEntity.Chunked],
    "HTTP/1.0 responses must not have a chunked entity")

and produces following stack trace:

java.lang.IllegalArgumentException: requirement failed: HTTP/1.0 requests must not have a chunked entity
    at scala.Predef$.require(Predef.scala:224)
    at akka.http.scaladsl.model.HttpRequest.<init>(HttpMessage.scala:207)
    at akka.http.scaladsl.model.HttpRequest.copy(HttpMessage.scala:271)
    at akka.http.scaladsl.coding.DataMapper$$anonfun$1.apply(DataMapper.scala:32)
    at akka.http.scaladsl.coding.DataMapper$$anonfun$1.apply(DataMapper.scala:28)
    at akka.http.scaladsl.coding.DataMapper$$anon$3.transformDataBytes(DataMapper.scala:41)
    at akka.http.scaladsl.coding.Decoder$class.decodeData(Decoder.scala:25)
    at akka.http.scaladsl.coding.StreamDecoder$$anon$1.decodeData(Decoder.scala:44)
    at akka.http.scaladsl.coding.Decoder$class.decode(Decoder.scala:22)
    at akka.http.scaladsl.coding.StreamDecoder$$anon$1.decode(Decoder.scala:44)
    at akka.http.scaladsl.server.directives.CodingDirectives$$anonfun$applyDecoder$1$1$$anonfun$apply$2.apply(CodingDirectives.scala:86)
    at akka.http.scaladsl.server.directives.CodingDirectives$$anonfun$applyDecoder$1$1$$anonfun$apply$2.apply(CodingDirectives.scala:85)

Steps to reproduce. Test case:

  val echoRequestContent: Route = { ctx ⇒ ctx.complete(ctx.request.entity.dataBytes.utf8String) }
  lazy val helloGzipped = compress("Hello", Gzip)
  def compress(input: String, encoder: Encoder): ByteString = {
    val compressor = encoder.newCompressor
    compressor.compressAndFlush(ByteString(input)) ++ compressor.finish()
  }

  "decode HTTP/1.0 request with 'gzip' encoding" in {
    HttpRequest(POST, Uri("/"), entity = HttpEntity(helloGzipped), protocol = `HTTP/1.0`) ~> `Content-Encoding`(gzip) ~> {
      decodeRequestWith(Gzip) { echoRequestContent }
    } ~> check { responseAs[String] shouldEqual "Hello" }
  }

Guia do colaborador