diff --git a/akka-http-core/src/main/scala/akka/http/impl/model/parser/HeaderParser.scala b/akka-http-core/src/main/scala/akka/http/impl/model/parser/HeaderParser.scala index e45a8f0cea..e54a8bba83 100644 --- a/akka-http-core/src/main/scala/akka/http/impl/model/parser/HeaderParser.scala +++ b/akka-http-core/src/main/scala/akka/http/impl/model/parser/HeaderParser.scala @@ -52,8 +52,10 @@ private[http] class HeaderParser(val input: ParserInput, settings: HeaderParser. type Result = Either[ErrorInfo, HttpHeader] def parser: HeaderParser = this def success(result: HttpHeader :: HNil): Result = Right(result.head) - def parseError(error: ParseError): Result = - Left(ErrorInfo(formatError(error, showLine = false), formatErrorLine(error))) + def parseError(error: ParseError): Result = { + val formatter = new ErrorFormatter(showLine = false) + Left(ErrorInfo(formatter.format(error, input), formatter.formatErrorLine(error, input))) + } def failure(error: Throwable): Result = error match { case IllegalUriException(info) ⇒ Left(info) case NonFatal(e) ⇒ Left(ErrorInfo.fromCompoundString(e.getMessage)) diff --git a/akka-http-core/src/main/scala/akka/http/impl/model/parser/UriParser.scala b/akka-http-core/src/main/scala/akka/http/impl/model/parser/UriParser.scala index c8f32e45a4..c185ea4975 100644 --- a/akka-http-core/src/main/scala/akka/http/impl/model/parser/UriParser.scala +++ b/akka-http-core/src/main/scala/akka/http/impl/model/parser/UriParser.scala @@ -57,8 +57,10 @@ private[http] class UriParser(val input: ParserInput, case Left(error) => fail(error, "query") } - def fail(error: ParseError, target: String): Nothing = - Uri.fail(s"Illegal $target: " + formatError(error, showLine = false), formatErrorLine(error)) + def fail(error: ParseError, target: String): Nothing = { + val formatter = new ErrorFormatter(showLine = false) + Uri.fail(s"Illegal $target: " + formatter.format(error, input), formatter.formatErrorLine(error, input)) + } private[this] val `path-segment-char` = uriParsingMode match { case Uri.ParsingMode.Strict ⇒ `pchar-base` diff --git a/akka-http-core/src/test/scala/akka/http/impl/engine/ws/BitBuilder.scala b/akka-http-core/src/test/scala/akka/http/impl/engine/ws/BitBuilder.scala index d0f4352e9b..bcb824edc7 100644 --- a/akka-http-core/src/test/scala/akka/http/impl/engine/ws/BitBuilder.scala +++ b/akka-http-core/src/test/scala/akka/http/impl/engine/ws/BitBuilder.scala @@ -74,7 +74,7 @@ class BitSpecParser(val input: ParserInput) extends parboiled2.Parser { def parseBits(): Try[Bits] = bits.run() match { case s: Success[Bits] ⇒ s - case Failure(e: ParseError) ⇒ Failure(new RuntimeException(formatError(e, showTraces = true))) + case Failure(e: ParseError) ⇒ Failure(new RuntimeException(formatError(e, new ErrorFormatter(showTraces = true)))) case _ ⇒ throw new IllegalStateException() } diff --git a/akka-http-core/src/test/scala/akka/http/impl/model/parser/HttpHeaderSpec.scala b/akka-http-core/src/test/scala/akka/http/impl/model/parser/HttpHeaderSpec.scala index eded7767c1..2021d5833e 100644 --- a/akka-http-core/src/test/scala/akka/http/impl/model/parser/HttpHeaderSpec.scala +++ b/akka-http-core/src/test/scala/akka/http/impl/model/parser/HttpHeaderSpec.scala @@ -145,7 +145,7 @@ class HttpHeaderSpec extends FreeSpec with Matchers { "Authorization: NoParamScheme" =!= Authorization(GenericHttpCredentials("NoParamScheme", Map.empty[String, String])) "Authorization: QVFJQzV3TTJMWTRTZmN3Zk=" =!= - ErrorInfo("Illegal HTTP header 'Authorization': Invalid input '=', expected tchar, '\\r', WSP, token68-start or 'EOI' (line 1, column 23)", + ErrorInfo("Illegal HTTP header 'Authorization': Invalid input '=', expected auth-param, OWS, token68, 'EOI' or tchar (line 1, column 23)", """QVFJQzV3TTJMWTRTZmN3Zk= | ^""".stripMarginWithNewline("\n")) } @@ -300,7 +300,7 @@ class HttpHeaderSpec extends FreeSpec with Matchers { "Location: https://spray.io/{sec}" =!= Location(Uri("https://spray.io/{sec}")).renderedTo( "https://spray.io/%7Bsec%7D") "Location: https://spray.io/ sec" =!= ErrorInfo("Illegal HTTP header 'Location': Invalid input ' ', " + - "expected path-segment-char, '%', '/', '?', '#' or 'EOI' (line 1, column 18)", "https://spray.io/ sec\n ^") + "expected '/', 'EOI', '#', segment or '?' (line 1, column 18)", "https://spray.io/ sec\n ^") } "Link" in { @@ -471,7 +471,7 @@ class HttpHeaderSpec extends FreeSpec with Matchers { "Set-Cookie: lang=; Expires=xxxx" =!= ErrorInfo( - "Illegal HTTP header 'Set-Cookie': Invalid input 'x', expected '\\r', WSP, 'S', 'M', 'T', 'W', 'F' or '0' (line 1, column 16)", + "Illegal HTTP header 'Set-Cookie': Invalid input 'x', expected OWS or HTTP-date (line 1, column 16)", "lang=; Expires=xxxx\n ^") // extra examples from play @@ -562,10 +562,10 @@ class HttpHeaderSpec extends FreeSpec with Matchers { } "not accept illegal header values" in { parse("Foo", "ba\u0000r") shouldEqual ParsingResult.Error(ErrorInfo( - "Illegal HTTP header value: Invalid input '\\u0000', expected VCHAR, obs-text, WSP, '\\r' or 'EOI' (line 1, column 3)", + "Illegal HTTP header value: Invalid input '\\u0000', expected field-value-char, FWS or 'EOI' (line 1, column 3)", "ba\u0000r\n ^")) parse("Flood-Resistant-Hammerdrill", "árvíztűrő ütvefúrógép") shouldEqual ParsingResult.Error(ErrorInfo( - "Illegal HTTP header value: Invalid input 'ű', expected VCHAR, obs-text, WSP, '\\r' or 'EOI' (line 1, column 7)", + "Illegal HTTP header value: Invalid input 'ű', expected field-value-char, FWS or 'EOI' (line 1, column 7)", "árvíztűrő ütvefúrógép\n ^")) } "compress value whitespace into single spaces and trim" in { diff --git a/akka-http-core/src/test/scala/akka/http/scaladsl/model/UriSpec.scala b/akka-http-core/src/test/scala/akka/http/scaladsl/model/UriSpec.scala index 08881c40ca..e49b19baa4 100644 --- a/akka-http-core/src/test/scala/akka/http/scaladsl/model/UriSpec.scala +++ b/akka-http-core/src/test/scala/akka/http/scaladsl/model/UriSpec.scala @@ -148,7 +148,7 @@ class UriSpec extends WordSpec with Matchers { "not accept illegal IPv6 literals" in { // 5 char quad the[IllegalUriException] thrownBy Host("[::12345]") shouldBe { - IllegalUriException("Illegal URI host: Invalid input '5', expected !HEXDIG, ':' or ']' (line 1, column 8)", + IllegalUriException("Illegal URI host: Invalid input '5', expected ':' or ']' (line 1, column 8)", "[::12345]\n" + " ^") } @@ -465,14 +465,14 @@ class UriSpec extends WordSpec with Matchers { "produce proper error messages for illegal URIs" in { // illegal scheme the[IllegalUriException] thrownBy Uri("foö:/a") shouldBe { - IllegalUriException("Illegal URI reference: Invalid input 'ö', expected scheme-char, ':', path-segment-char, '%', '/', '?', '#' or 'EOI' (line 1, column 3)", + IllegalUriException("Illegal URI reference: Invalid input 'ö', expected scheme-char, 'EOI', '#', ':', '?', slashSegments or pchar (line 1, column 3)", "foö:/a\n" + " ^") } // illegal userinfo the[IllegalUriException] thrownBy Uri("http://user:ö@host") shouldBe { - IllegalUriException("Illegal URI reference: Invalid input 'ö', expected userinfo-char, '%', '@' or DIGIT (line 1, column 13)", + IllegalUriException("Illegal URI reference: Invalid input 'ö', expected userinfo-char, pct-encoded, '@' or port (line 1, column 13)", "http://user:ö@host\n" + " ^") } @@ -486,21 +486,21 @@ class UriSpec extends WordSpec with Matchers { // illegal path the[IllegalUriException] thrownBy Uri("http://www.example.com/name with spaces/") shouldBe { - IllegalUriException("Illegal URI reference: Invalid input ' ', expected path-segment-char, '%', '/', '?', '#' or 'EOI' (line 1, column 28)", + IllegalUriException("Illegal URI reference: Invalid input ' ', expected '/', 'EOI', '#', '?' or pchar (line 1, column 28)", "http://www.example.com/name with spaces/\n" + " ^") } // illegal path with control character the[IllegalUriException] thrownBy Uri("http:///with\newline") shouldBe { - IllegalUriException("Illegal URI reference: Invalid input '\\n', expected path-segment-char, '%', '/', '?', '#' or 'EOI' (line 1, column 13)", + IllegalUriException("Illegal URI reference: Invalid input '\\n', expected '/', 'EOI', '#', '?' or pchar (line 1, column 13)", "http:///with\n" + " ^") } // illegal query the[IllegalUriException] thrownBy Uri("?a=b=c") shouldBe { - IllegalUriException("Illegal URI reference: Invalid input '=', expected '+', query-char, '%', '&', '#' or 'EOI' (line 1, column 5)", + IllegalUriException("Illegal URI reference: Invalid input '=', expected '+', query-char, 'EOI', '#', '&' or pct-encoded (line 1, column 5)", "?a=b=c\n" + " ^") } diff --git a/akka-http-core/src/test/scala/akka/http/scaladsl/model/headers/HeaderSpec.scala b/akka-http-core/src/test/scala/akka/http/scaladsl/model/headers/HeaderSpec.scala index 7485a7ca2a..e3e0948d1d 100644 --- a/akka-http-core/src/test/scala/akka/http/scaladsl/model/headers/HeaderSpec.scala +++ b/akka-http-core/src/test/scala/akka/http/scaladsl/model/headers/HeaderSpec.scala @@ -23,7 +23,7 @@ class HeaderSpec extends FreeSpec with MustMatchers { } "failing parse run" in { val Left(List(ErrorInfo(summary, detail))) = headers.`Last-Modified`.parseFromValueString("abc") - summary mustEqual "Illegal HTTP header 'Last-Modified': Invalid input 'a', expected 'S', 'M', 'T', 'W', 'F' or '0' (line 1, column 1)" + summary mustEqual "Illegal HTTP header 'Last-Modified': Invalid input 'a', expected IMF-fixdate, asctime-date or '0' (line 1, column 1)" detail mustEqual """abc |^""".stripMarginWithNewline("\n") @@ -39,7 +39,7 @@ class HeaderSpec extends FreeSpec with MustMatchers { } "failing parse run" in { val Left(List(ErrorInfo(summary, detail))) = MediaType.parse("application//gnutar") - summary mustEqual "Illegal HTTP header 'Content-Type': Invalid input '/', expected tchar (line 1, column 13)" + summary mustEqual "Illegal HTTP header 'Content-Type': Invalid input '/', expected subtype (line 1, column 13)" detail mustEqual """application//gnutar | ^""".stripMarginWithNewline("\n") @@ -54,7 +54,7 @@ class HeaderSpec extends FreeSpec with MustMatchers { } "failing parse run" in { val Left(List(ErrorInfo(summary, detail))) = ContentType.parse("text/plain, charset=UTF8") - summary mustEqual "Illegal HTTP header 'Content-Type': Invalid input ',', expected tchar, '\\r', WSP, ';' or 'EOI' (line 1, column 11)" + summary mustEqual "Illegal HTTP header 'Content-Type': Invalid input ',', expected tchar, OWS, ws or 'EOI' (line 1, column 11)" detail mustEqual """text/plain, charset=UTF8 | ^""".stripMarginWithNewline("\n")