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]

Reply via email to