give ParsingErrorHandler access to the request that was rejected - #1246
Open
pjfanning wants to merge 1 commit into
Open
give ParsingErrorHandler access to the request that was rejected#1246pjfanning wants to merge 1 commit into
pjfanning wants to merge 1 commit into
Conversation
pjfanning
force-pushed
the
illegal-request-context
branch
from
August 27, 2026 20:03
6fd107e to
fe874c7
Compare
…che#1245) `ParsingErrorHandler` could not see the request it was rejecting: none of its four arguments describe the method or the request target, and `ParserOutput.MessageStartError` discarded both at the point where the parser gave up. Add `IllegalRequestContext` and a five-argument `handle` overload that receives it. The overload defaults to the existing four-argument method, so existing handlers, `DefaultParsingErrorHandler` included, keep working unchanged. The parser populates the context at the failure site: its `method`, `uri` and `uriBytes` fields are reused across a keep-alive connection, so they are cleared for every message to stop a rejection from reporting the previous request's values. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
pjfanning
force-pushed
the
illegal-request-context
branch
from
August 27, 2026 20:08
fe874c7 to
c9560d6
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1245.
ParsingErrorHandleris 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 onErrorInfo, and cannot recover the method or the request target. The information is not lost anywhere upstream either —ParserOutput.MessageStartErrorcarries only(status, info), so it is discarded at the point where the parser gives up.What this adds
ControllerStagecalls the five-argument overload. The default implementation of it delegates to the existing four-argument method, andDefaultParsingErrorHandlerstill 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.
rawRequestTargetis 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 acontextfield, defaulted toIllegalRequestContext.empty.HttpMessageParsergains an overridableillegalRequestContextthatfailMessageStartand the message-start completion handling pass along; only the request parser populates it.HttpRequestParserclearsmethod/uri/uriBytesat 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.establishAbsoluteUrifills the context for the two rejections it raises itself (CONNECT, and aHostheader that does not match an absolute request target).Tests
RequestParserSpecasserts 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.HttpServerSpecasserts 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