diff --git a/akka-http-tests/src/test/scala/akka/http/scaladsl/server/directives/CodingDirectivesSpec.scala b/akka-http-tests/src/test/scala/akka/http/scaladsl/server/directives/CodingDirectivesSpec.scala index e74218312e..9006290233 100644 --- a/akka-http-tests/src/test/scala/akka/http/scaladsl/server/directives/CodingDirectivesSpec.scala +++ b/akka-http-tests/src/test/scala/akka/http/scaladsl/server/directives/CodingDirectivesSpec.scala @@ -33,6 +33,10 @@ class CodingDirectivesSpec extends RoutingSpec with Inside { lazy val helloGzipped = compress("Hello", Gzip) lazy val helloDeflated = compress("Hello", Deflate) + val nope = complete((404, "Nope!")) + lazy val nopeGzipped = compress("Nope!", Gzip) + lazy val nopeDeflated = compress("Nope!", Deflate) + "the NoEncoding decoder" should { "decode the request content if it has encoding 'identity'" in { Post("/", "yes") ~> `Content-Encoding`(identity) ~> { @@ -161,6 +165,19 @@ class CodingDirectivesSpec extends RoutingSpec with Inside { } } + "the encoder" should { + "encode the response content with GZIP if the response is not a success and request has no Accept-Encoding header" in { + Post() ~> { + encodeResponseWith(Gzip) { nope } + } ~> check { strictify(responseEntity) shouldEqual HttpEntity(ContentType(`text/plain`, `UTF-8`), nopeGzipped) } + } + "encode the response content with Deflate if the response is not a success and request has no Accept-Encoding header" in { + Post() ~> { + encodeResponseWith(Deflate) { nope } + } ~> check { strictify(responseEntity) shouldEqual HttpEntity(ContentType(`text/plain`, `UTF-8`), nopeDeflated) } + } + } + "the Gzip encoder" should { "encode the response content with GZIP if the client accepts it with a dedicated Accept-Encoding header" in { Post() ~> `Accept-Encoding`(gzip) ~> { diff --git a/akka-http-tests/src/test/scala/akka/http/scaladsl/server/directives/ExecutionDirectivesSpec.scala b/akka-http-tests/src/test/scala/akka/http/scaladsl/server/directives/ExecutionDirectivesSpec.scala index dc6dbef69f..bafe421f2a 100644 --- a/akka-http-tests/src/test/scala/akka/http/scaladsl/server/directives/ExecutionDirectivesSpec.scala +++ b/akka-http-tests/src/test/scala/akka/http/scaladsl/server/directives/ExecutionDirectivesSpec.scala @@ -5,10 +5,13 @@ package akka.http.scaladsl.server package directives -import akka.http.scaladsl.model.{ MediaTypes, MediaRanges, StatusCodes } +import akka.http.scaladsl.coding.Gzip +import akka.http.scaladsl.model._ +import akka.http.scaladsl.model.headers.HttpEncodings._ import akka.http.scaladsl.model.headers._ import scala.concurrent.Future import akka.testkit.EventFilter +import org.scalatest.matchers.Matcher class ExecutionDirectivesSpec extends RoutingSpec { object MyException extends RuntimeException @@ -96,9 +99,39 @@ class ExecutionDirectivesSpec extends RoutingSpec { } } + "The `handleRejections` directive" should { + "handle encodeResponse inside RejectionHandler for non-success responses" in { + val rejectionHandler: RejectionHandler = RejectionHandler.newBuilder() + .handleNotFound { + encodeResponseWith(Gzip) { + complete((404, "Not here!")) + } + }.result() + + Get("/hell0") ~> + get { + handleRejections(rejectionHandler) { + encodeResponseWith(Gzip) { + path("hello") { + get { + complete(HttpEntity(ContentTypes.`text/plain(UTF-8)`, "world")) + } + } + } + } + } ~> check { + response should haveContentEncoding(gzip) + status shouldEqual StatusCodes.NotFound + } + } + } + def exceptionShouldBeHandled(route: Route) = Get("/abc") ~> route ~> check { status shouldEqual StatusCodes.InternalServerError responseAs[String] shouldEqual "Pling! Plong! Something went wrong!!!" } + + def haveContentEncoding(encoding: HttpEncoding): Matcher[HttpResponse] = + be(Some(`Content-Encoding`(encoding))) compose { (_: HttpResponse).header[`Content-Encoding`] } } diff --git a/akka-http/src/main/scala/akka/http/scaladsl/coding/Encoder.scala b/akka-http/src/main/scala/akka/http/scaladsl/coding/Encoder.scala index 4018c8a4e6..6204cd8927 100644 --- a/akka-http/src/main/scala/akka/http/scaladsl/coding/Encoder.scala +++ b/akka-http/src/main/scala/akka/http/scaladsl/coding/Encoder.scala @@ -43,10 +43,7 @@ trait Encoder { } object Encoder { - val DefaultFilter: HttpMessage ⇒ Boolean = { - case req: HttpRequest ⇒ isCompressible(req) - case res @ HttpResponse(status, _, _, _) ⇒ isCompressible(res) && status.isSuccess - } + val DefaultFilter: HttpMessage ⇒ Boolean = isCompressible _ private[coding] def isCompressible(msg: HttpMessage): Boolean = msg.entity.contentType.mediaType.isCompressible