Repository navigation
Add TryParse*Header entry points that report the true header length; obsolete TryExtract* - #81
Merged
Merged
Conversation
TryExtractFullHeader* (and the response and FlexibleParser equivalents)
report one less than the bytes they consumed, while their XML docs said
the opposite. Every caller compensates with "bytesRead + 1", so
correcting the value in place would break them silently: the first body
byte would be read as header and a Content-Length body would arrive one
byte short - a desync on a keep-alive connection, the failure class this
library exists to prevent.
So the correctly-specified methods get new names and the old ones stay,
unchanged in behaviour, marked [Obsolete] with a message naming the
difference. The migration then shows up at compile time, the only place
it can be seen:
UltraHardenedParser.TryExtractFullHeaderROM / ...Validated
-> UltraHardenedParser.TryParseRequestHeader
UltraHardenedParser.TryExtractFullResponseHeaderROM / ...Validated
-> UltraHardenedParser.TryParseResponseHeader
FlexibleParser.TryExtractFullHeaderReadOnlyMemory / TryExtractFullHeader
-> FlexibleParser.TryParseRequestHeader
each with a ReadOnlyMemory<byte> and a ReadOnlySequence<byte> overload.
'consumed' is the length of the header block including its CRLFCRLF, so
the body starts at input[consumed]; it is 0 when the method returns
false. The methods are renamed in place (same files, same bodies); the
legacy names are thin wrappers in *.Obsolete.cs returning consumed - 1,
or -1 when incomplete.
The test project suppresses CS0618 so the existing suites keep pinning
the legacy entry points for as long as they ship; ConsumedCount.Tests.cs
covers the new ones and their parity with the old. README, SECURITY.md,
the docs site and the managed example move to the new API. Glyph11 goes
to 0.4.0.
Fixes #58.
The MemberData sources returned untyped object[] rows (xUnit1042). Same 221 cases.
# Conflicts: # README.md # site/glyph11.html
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 #58
Why
TryExtractFullHeader*(and the response andFlexibleParserequivalents) report one less than the bytes they consumed, and the XML doc said the opposite. Every caller compensates withbytesRead + 1, including GenHTTP and our own example.This takes option 2 from the issue. Fixing the value in place (option 1) would break every one of those callers silently: no compile error and no exception. The first body byte would be read as header, and a
Content-Lengthbody would arrive one byte short, which desyncs a keep-alive connection. Renaming the correct methods and marking the old ones[Obsolete]moves that break to compile time, the only place anyone can see it.What changes
New entry points. Each returns
consumed: the length of the header block including its CRLFCRLF, so the body starts atinput[consumed]. It is0when the method returnsfalse.UltraHardenedParser.TryExtractFullHeaderROM(ref ReadOnlyMemory<byte>, …)UltraHardenedParser.TryParseRequestHeader(ref ReadOnlyMemory<byte>, …)UltraHardenedParser.TryExtractFullHeaderValidated(ref ReadOnlySequence<byte>, …)UltraHardenedParser.TryParseRequestHeader(ref ReadOnlySequence<byte>, …)UltraHardenedParser.TryExtractFullResponseHeaderROM(…)UltraHardenedParser.TryParseResponseHeader(ref ReadOnlyMemory<byte>, …)UltraHardenedParser.TryExtractFullResponseHeaderValidated(…)UltraHardenedParser.TryParseResponseHeader(ref ReadOnlySequence<byte>, …)FlexibleParser.TryExtractFullHeaderReadOnlyMemory(…)FlexibleParser.TryParseRequestHeader(ref ReadOnlyMemory<byte>, …)FlexibleParser.TryExtractFullHeader(…)FlexibleParser.TryParseRequestHeader(ref ReadOnlySequence<byte>, …)Migration: switch to the new name and drop the
+ 1. The parameters are otherwise identical.UltraHardenedParser.Obsolete.cs/FlexibleParser.Obsolete.csas thin wrappers that return exactly the legacy values (consumed - 1, or-1when incomplete). Their docs now say what they actually return.[Obsolete]is a warning (CS0618), not an error. The message names the difference and the replacement. These members are slated for removal in a later release.site/glyph11.html(including the PipeReader sample that advanced bybytesRead + 1), andExamples/Glyph11.Example.Not touched, on purpose:
PicoParser,core/and the diff harness: bindings are being removed in a separate PR.Benchmarks/: the bindings PR (Drop the bindings and the C core: Glyph11 is managed-only #84) rewrites that file, so its two Glyph11 calls stay on the obsolete names here to avoid a conflict. They build with two CS0618 warnings, and once both PRs are merged they need a two-line rename.GenHTTP builds with
TreatWarningsAsErrors, so it needs a migration (new names, no+ 1): Kaliumhexacyanoferrat/GenHTTP#972. The draft PR Kaliumhexacyanoferrat/GenHTTP#973 does it. Its full acceptance suite passes on net10.0 and net11.0 against a local pack of this repo with every open PR merged.Decisions worth reviewing
out intmeans cannot coexist with the old one: same name, same parameter list. Changing it toout longwould makeout varambiguous. New names keep the migration a rename.Overlap with sibling PRs
#59, #64, #65, #68, #71 and #73 edit the bodies of these same methods, which keep their files and structure here. Expect small textual conflicts around the signature and the
bytesReadCountlines. Whichever lands second must also rename any new line it adds that assignsbytesReadCounttoconsumed, keeping the new meaning (the full length, or 0 when incomplete).Tests
New
tests/Tests/ConsumedCount.Tests.cs, 221 cases. Every new entry point is fed four shapes: contiguous memory, a single-segment sequence, three segments, and one byte per segment.consumedequals the header block length, and what follows it (a body or the next pipelined message) starts exactly there.falsewithconsumed == 0.consumed - 1on the same corpus, and-1when incomplete.A mutation check (
consumed = total - 1) fails 35 tests. Full suite: 624 passing, 0 failing (net10.0).dotnet build src/Glyph11.slnis clean; the only CS0618 warnings are the two inBenchmarks/noted above.SonarCloud
Two findings here are expected, and the code stays as is: