Corresponding coding directives fail to process gzip- and deflate-compressed HTTP/1.0 requests
- Dominant language
- Scala
- Stars
- 1.4k
- Forks
- 584
- Avg merge
- 14h 33m
- Merged PRs (30d)
- 24
Description
**Issue by [levkhomich](https://github.com/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
``` scala
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.(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:
``` scala
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" }
}
```
Contributor guide
Research direction
Start with DataMapper.scala and CodingDirectives.scala, then inspect the HttpRequest requirement in HttpMessage.scala. Run the supplied HTTP/1.0 gzip reproduction and add or adapt coverage for deflate as well. Done means decodeRequest and decodeRequestWith process both compressed request types without the chunked-entity failure.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- scala
- Domain
- api
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 38/100