akka/akka-http

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

开放

#46 创建于 2016年9月8日

 (7 条评论) (0 个反应) (0 位负责人)Scala (598 个派生)batch import
1 - triageddiscusshelp wanted

仓库指标

星标
 (1,311 个星标)
PR 合并指标
 (平均合并 1天 10小时) (30 天内合并 2 个 PR)

描述

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" }
  }

贡献者指南