Skip to content

Commit

Permalink
=htc don't encode known to be empty entities (#21393) (#21396) (#297)
Browse files Browse the repository at this point in the history
* =htc don't encode known to be empty entities (#21393)

* =htc added missing headers in the improved marshaller (#21393)
  • Loading branch information
ktoso committed Sep 14, 2016
1 parent cbbc994 commit 0ad8017
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 2 deletions.
Expand Up @@ -47,6 +47,14 @@ class MarshallingSpec extends FreeSpec with Matchers with BeforeAndAfterAll with
marshalToResponse(StatusCodes.EnhanceYourCalm) shouldEqual
HttpResponse(StatusCodes.EnhanceYourCalm, entity = HttpEntity(StatusCodes.EnhanceYourCalm.defaultMessage))
}
"fromStatusCodeAndHeadersAndValue should properly marshal entities that are not supposed to have a body" in {
marshalToResponse((StatusCodes.NoContent, "This Content was intentionally left blank.")) shouldEqual
HttpResponse(StatusCodes.NoContent, entity = HttpEntity.Empty)
}
"fromStatusCodeAndHeadersAndValue should properly marshal entities that contain pre-defined content" in {
marshalToResponse((StatusCodes.EnhanceYourCalm, "Patience, young padawan!")) shouldEqual
HttpResponse(StatusCodes.EnhanceYourCalm, entity = HttpEntity("Patience, young padawan!"))
}
}

"The GenericMarshallers" - {
Expand Down
Expand Up @@ -176,6 +176,29 @@ class CodingDirectivesSpec extends RoutingSpec with Inside {
encodeResponseWith(Deflate) { nope }
} ~> check { strictify(responseEntity) shouldEqual HttpEntity(ContentType(`text/plain`, `UTF-8`), nopeDeflated) }
}
"not encode the response content with GZIP if the response is of status not allowing entity" in {
Post() ~> {
encodeResponseWith(Gzip) { complete { StatusCodes.NoContent } }
} ~> check {
response should haveNoContentEncoding
response shouldEqual HttpResponse(StatusCodes.NoContent, entity = HttpEntity.Empty)
}
}
"not encode the response content with Deflate if the response is of status not allowing entity" in {
Post() ~> {
encodeResponseWith(Deflate) { complete((100, "Let's continue!")) }
} ~> check {
response should haveNoContentEncoding
response shouldEqual HttpResponse(StatusCodes.Continue, entity = HttpEntity.Empty)
}
}
"encode the response content with GZIP if the response is of status allowing entity" in {
Post() ~> {
encodeResponseWith(Gzip) { nope }
} ~> check {
response should haveContentEncoding(gzip)
}
}
}

"the Gzip encoder" should {
Expand Down
Expand Up @@ -43,7 +43,10 @@ trait Encoder {
}

object Encoder {
val DefaultFilter: HttpMessage Boolean = isCompressible _
val DefaultFilter: HttpMessage Boolean = {
case req: HttpRequest isCompressible(req)
case res @ HttpResponse(status, _, _, _) isCompressible(res) && status.allowsEntity
}
private[coding] def isCompressible(msg: HttpMessage): Boolean =
msg.entity.contentType.mediaType.isCompressible

Expand Down
Expand Up @@ -37,6 +37,16 @@ trait PredefinedToResponseMarshallers extends LowPriorityToResponseMarshallerImp
HttpResponse(status, entity = responseEntity)
}

implicit val fromStatusCodeAndHeaders: TRM[(StatusCode, immutable.Seq[HttpHeader])] =
Marshaller.withOpenCharset(`text/plain`) { (statusAndHeaders, charset)
val status = statusAndHeaders._1
val headers = statusAndHeaders._2
val responseEntity =
if (status.allowsEntity) HttpEntity(status.defaultMessage)
else HttpEntity.Empty
HttpResponse(status, headers, entity = responseEntity)
}

implicit def fromStatusCodeAndValue[S, T](implicit sConv: S StatusCode, mt: ToEntityMarshaller[T]): TRM[(S, T)] =
fromStatusCodeAndHeadersAndValue[T] compose { case (status, value) (sConv(status), Nil, value) }

Expand All @@ -47,7 +57,8 @@ trait PredefinedToResponseMarshallers extends LowPriorityToResponseMarshallerImp

implicit def fromStatusCodeAndHeadersAndValue[T](implicit mt: ToEntityMarshaller[T]): TRM[(StatusCode, immutable.Seq[HttpHeader], T)] =
Marshaller(implicit ec {
case (status, headers, value) mt(value).fast map (_ map (_ map (HttpResponse(status, headers, _))))
case (status, headers, value) if (status.allowsEntity) mt(value).fast map (_ map (_ map (HttpResponse(status, headers, _))))
case (status, headers, _) fromStatusCodeAndHeaders((status, headers))
})

implicit def fromEntityStreamingSupportAndByteStringMarshaller[T, M](implicit s: EntityStreamingSupport, m: ToByteStringMarshaller[T]): ToResponseMarshaller[Source[T, M]] = {
Expand Down

0 comments on commit 0ad8017

Please sign in to comment.