diff --git a/http-core/src/main/scala/org/apache/pekko/http/impl/engine/http2/Http2Demux.scala b/http-core/src/main/scala/org/apache/pekko/http/impl/engine/http2/Http2Demux.scala index f05bbb446..cf42e6779 100644 --- a/http-core/src/main/scala/org/apache/pekko/http/impl/engine/http2/Http2Demux.scala +++ b/http-core/src/main/scala/org/apache/pekko/http/impl/engine/http2/Http2Demux.scala @@ -59,11 +59,12 @@ private[http2] class Http2ClientDemux(http2Settings: Http2ClientSettings, master extends Http2Demux(http2Settings, initialRemoteSettings = Nil, upgraded = false, isServer = false) { def wrapTrailingHeaders(headers: ParsedHeadersFrame): Option[ChunkStreamPart] = { - val headerParser = masterHttpHeaderParser.createShallowCopy() Some(LastChunk(extension = "", headers.keyValuePairs.map { case (name, value: HttpHeader) => value - case (name, value) => parseHeaderPair(headerParser, name, value.asInstanceOf[String]) + case (name, value) => + val headerParser = masterHttpHeaderParser.createShallowCopy() + parseHeaderPair(headerParser, name, value.asInstanceOf[String]) }.toList)) } diff --git a/http-core/src/main/scala/org/apache/pekko/http/impl/engine/http2/RequestParsing.scala b/http-core/src/main/scala/org/apache/pekko/http/impl/engine/http2/RequestParsing.scala index e5f557ee7..07b343a6e 100644 --- a/http-core/src/main/scala/org/apache/pekko/http/impl/engine/http2/RequestParsing.scala +++ b/http-core/src/main/scala/org/apache/pekko/http/impl/engine/http2/RequestParsing.scala @@ -24,7 +24,6 @@ import pekko.http.scaladsl.model._ import pekko.http.scaladsl.model.headers.`Tls-Session-Info` import pekko.http.scaladsl.settings.ServerSettings import pekko.stream.Attributes -import pekko.util.ByteString import pekko.util.OptionVal import scala.annotation.tailrec @@ -191,13 +190,21 @@ private[http2] object RequestParsing { } private[http2] def parseHeaderPair(httpHeaderParser: HttpHeaderParser, name: String, value: String): HttpHeader = { - // FIXME: later modify by adding HttpHeaderParser.parseHttp2Header that would use (name, value) pair directly - // or use a separate, simpler, parser for Http2 - // The odd-looking 'x' below is a by-product of how current parser and HTTP/1.1 work. - // Without '\r\n\x' (x being any additional byte) parsing will fail. See HttpHeaderParserSpec for examples. - val concHeaderLine = name + ": " + value + "\r\nx" - httpHeaderParser.parseHeaderLine(ByteString(concHeaderLine))() - httpHeaderParser.resultHeader + import HttpHeader.ParsingResult + if (name.startsWith(":")) { + // HttpHeader.parse used in `else` block does not support pseudo-headers (that have ':' prefix in header name) + // The odd-looking 'x' below is a by-product of how current parser and HTTP/1.1 work. + // Without '\r\n\x' (x being any additional byte) parsing will fail. See HttpHeaderParserSpec for examples. + val concHeaderLine = s"$name: $value\r\nx" + httpHeaderParser.parseHeaderLine(pekko.util.ByteString(concHeaderLine))() + httpHeaderParser.resultHeader + } else { + HttpHeader.parse(name, value, httpHeaderParser.settings) match { + case ParsingResult.Ok(header, errors) if errors.isEmpty => header + case ParsingResult.Ok(_, errors) => throw ParsingException(errors.head) + case ParsingResult.Error(info) => throw ParsingException(info) + } + } } private[http2] def checkRequiredPseudoHeader(name: String, value: AnyRef): Unit =