diff --git a/http-core/src/main/scala/org/apache/pekko/http/impl/engine/http2/HttpMessageRendering.scala b/http-core/src/main/scala/org/apache/pekko/http/impl/engine/http2/HttpMessageRendering.scala index b3c6f31a9..e434b857e 100644 --- a/http-core/src/main/scala/org/apache/pekko/http/impl/engine/http2/HttpMessageRendering.scala +++ b/http-core/src/main/scala/org/apache/pekko/http/impl/engine/http2/HttpMessageRendering.scala @@ -99,7 +99,7 @@ private[http2] sealed abstract class MessageRendering[R <: HttpMessage] extends r.attribute(AttributeKeys.trailer) match { case Some(trailer) if trailer.headers.nonEmpty => OptionVal.Some(ParsedHeadersFrame(streamId, endStream = true, trailer.headers, None)) - case None => OptionVal.None + case _ => OptionVal.None } Http2SubStream(r.entity, headersFrame, trailingHeadersFrame, diff --git a/http2-tests/src/test/scala/org/apache/pekko/http/impl/engine/http2/HttpMessageRenderingSpec.scala b/http2-tests/src/test/scala/org/apache/pekko/http/impl/engine/http2/HttpMessageRenderingSpec.scala index 516a2603f..09fc4aca7 100644 --- a/http2-tests/src/test/scala/org/apache/pekko/http/impl/engine/http2/HttpMessageRenderingSpec.scala +++ b/http2-tests/src/test/scala/org/apache/pekko/http/impl/engine/http2/HttpMessageRenderingSpec.scala @@ -14,19 +14,21 @@ package org.apache.pekko.http.impl.engine.http2 import java.time.format.DateTimeFormatter + +import com.typesafe.config.ConfigFactory import org.apache.pekko import pekko.event.NoLogging import pekko.http.impl.engine.rendering.DateHeaderRendering import pekko.http.scaladsl.model.headers._ -import pekko.http.scaladsl.model.{ ContentTypes, DateTime, HttpHeader, TransferEncodings } - -import scala.collection.immutable.Seq -import scala.collection.immutable.VectorBuilder -import scala.util.Try +import pekko.http.scaladsl.model._ +import pekko.http.scaladsl.settings.{ ClientConnectionSettings, ServerSettings } import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec +import scala.collection.immutable.VectorBuilder +import scala.collection.immutable.Seq import scala.collection.immutable +import scala.util.Try object MyCustomHeader extends ModeledCustomHeaderCompanion[MyCustomHeader] { override def name: String = "custom-header" @@ -147,6 +149,22 @@ class HttpMessageRenderingSpec extends AnyWordSpec with Matchers { value1.exists(_._1 == "date") shouldBe false } + "handle empty trailer" in { + val config = ConfigFactory.load("reference.conf") + Try { + val rendering = new RequestRendering(ClientConnectionSettings(config), NoLogging) + rendering(HttpRequest().withAttributes(Map(AttributeKeys.trailer -> Trailer()))) + }.isSuccess shouldBe true + Try { + val rendering = new ResponseRendering(ServerSettings(config), NoLogging, dateHeaderRendering) + rendering( + HttpResponse().withAttributes( + Map( + AttributeKeys.trailer -> Trailer(), + Http2.streamId -> 0))) + }.isSuccess shouldBe true + } + } private def renderClientHeaders(headers: immutable.Seq[HttpHeader], builder: VectorBuilder[(String, String)], @@ -158,10 +176,12 @@ class HttpMessageRenderingSpec extends AnyWordSpec with Matchers { peerIdHeader: Option[(String, String)] = None): Unit = HttpMessageRendering.renderHeaders(headers, builder, peerIdHeader, NoLogging, isServer = true, shouldRenderAutoHeaders = true, - dateHeaderRendering = new DateHeaderRendering { - // fake date rendering - override def renderHeaderPair(): (String, String) = "date" -> DateTime.now.toRfc1123DateTimeString - override def renderHeaderBytes(): Array[Byte] = ??? - override def renderHeaderValue(): String = ??? - }) + dateHeaderRendering = dateHeaderRendering) + + private lazy val dateHeaderRendering: DateHeaderRendering = new DateHeaderRendering { + // fake date rendering + override def renderHeaderPair(): (String, String) = "date" -> DateTime.now.toRfc1123DateTimeString + override def renderHeaderBytes(): Array[Byte] = ??? + override def renderHeaderValue(): String = ??? + } }