pjfanning opened a new pull request, #1246:
URL: https://github.com/apache/pekko-http/pull/1246
Fixes #1245.
`ParsingErrorHandler` is the extension point for the response to a request
that fails to parse, but none of its four arguments describe the request that
was rejected: a custom handler can branch on the status code and on
`ErrorInfo`, and cannot recover the method or the request target. The
information is not lost anywhere upstream either —
`ParserOutput.MessageStartError` carries only `(status, info)`, so it is
discarded at the point where the parser gives up.
### What this adds
```scala
final class IllegalRequestContext private[http] (
val method: Option[HttpMethod],
val rawRequestTarget: Option[String],
val protocol: Option[HttpProtocol])
abstract class ParsingErrorHandler {
def handle(status: StatusCode, error: ErrorInfo, log: LoggingAdapter,
settings: ServerSettings): HttpResponse
def handle(status: StatusCode, error: ErrorInfo, log: LoggingAdapter,
settings: ServerSettings, context: IllegalRequestContext):
HttpResponse =
handle(status, error, log, settings)
}
```
`ControllerStage` calls the five-argument overload. The default
implementation of it delegates to the existing four-argument method, and
`DefaultParsingErrorHandler` still implements only that one, so existing
handlers — and anything matching the four-argument signature — keep working
unchanged.
Every field is optional because a request can be rejected before that part
of it was read: an unsupported method fails before the request target is seen,
an unparsable request target fails before the protocol is seen.
`rawRequestTarget` is deliberately the raw bytes of the request target, which
is attacker-controlled and malformed whenever it caused the rejection; the
scaladoc says so.
### Internals
- `ParserOutput.MessageStartError` (`@InternalApi`) gains a `context` field,
defaulted to `IllegalRequestContext.empty`.
- `HttpMessageParser` gains an overridable `illegalRequestContext` that
`failMessageStart` and the message-start completion handling pass along; only
the request parser populates it.
- `HttpRequestParser` clears `method`/`uri`/`uriBytes` at the start of each
message and tracks whether the protocol belongs to the message being parsed.
The parser instance is reused across a keep-alive connection and those fields
were never reset, so populating the context at the failure site is what keeps a
rejection from reporting the *previous* request's values.
- `HttpServerBluePrint.establishAbsoluteUri` fills the context for the two
rejections it raises itself (CONNECT, and a `Host` header that does not match
an absolute request target).
### Tests
`RequestParserSpec` asserts the context for an illegal request target, for a
rejection after the request line parsed, for a rejection before the method was
known, and that nothing leaks from the previous request on the same connection.
`HttpServerSpec` asserts end to end that a handler overriding the five-argument
method sees the method, target and protocol, while the existing test for a
handler that overrides only the four-argument method still passes unchanged.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]