Skip to content

Drop the bindings and the C core: Glyph11 is managed-only - #84

Merged
MDA2AV merged 3 commits into
mainfrom
chore/drop-bindings
Nov 3, 2026
Merged

MDA2AV merged 3 commits into
mainfrom
chore/drop-bindings

Conversation

@MDA2AV

@MDA2AV MDA2AV commented Nov 2, 2026 •

Copy link
Copy Markdown
Member

Closes #57
Closes #66
Closes #69
Closes #70
Closes #72

Why

Glyph11 no longer supports bindings; the managed parser in src/Glyph11 is the product. Keeping the C core, the two .NET bindings and the Kotlin binding in the tree means maintaining every parsing rule in two or three languages, three native build matrices and a Gradle toolchain, for packages that will not be released again.

These five issues are about code this PR removes, so removal resolves them:

What's removed

  • bindings/: Kotlin (Panama FFM + Gradle), Glyph11.Native (P/Invoke over libglyph11), and Glyph11.Pico (shim + vendored picohttpparser).
  • core/: the C parser and chunked decoder, their tests and fuzz smoke, and the C-vs-C# differential harness.
  • Examples/Glyph11.Native.Example, Examples/Glyph11.Pico.Example, site/glyph11-native.html, site/glyph11-pico.html.
  • Workflows: core-tests.yml, package-native.yml, package-pico.yml. release.yml keeps only the Glyph11 job.
  • src/Glyph11.sln drops the four binding projects. The native-only .gitignore entries go too.
  • Benchmarks: the Native and Pico columns and the native chunked decoder. The Glyph11 calls are unchanged.
  • Docs: README, site, Examples/README.md and Benchmarks/README.md describe one package. The benchmark tables keep the existing Glyph11 numbers; no new numbers were added. The harness link now points at Benchmarks/ (it pointed at a bench/ directory that does not exist).

No friend access for Glyph11.Pico

<InternalsVisibleTo Include="Glyph11.Pico" /> goes from src/Glyph11/Glyph11.csproj too.

  • The published Glyph11.Pico 0.0.1 sets BinaryRequest's internal setters and calls the internal KeyValueList.Add. The runtime enforces friend access at JIT time, so Pico 0.0.1 fails with MethodAccessException next to Glyph11 0.4.0 or later. It keeps working with 0.3.x.
  • GenHTTP, which shipped Pico next to Glyph11, drops it in the same upgrade to 0.4.0 (chore(engines): Update Glyph11 to 0.4.0 and drop Glyph11.Pico Kaliumhexacyanoferrat/GenHTTP#973).
  • So Glyph11's internal members are free to change again.

Published packages

Glyph11.Native and Glyph11.Pico stay on NuGet as they are and get no further releases. The README and the site say so. Glyph11.Pico 0.0.1 keeps working with Glyph11 0.3.x, not with 0.4.0 (see above). Marking both packages deprecated on nuget.org would point their users here.

Overlap with sibling PRs

Tests

  • dotnet build src/Glyph11.sln: 0 errors. The solution now holds Glyph11, Tests, Benchmarks and Glyph11.Example.
  • dotnet build Benchmarks/Benchmarks.csproj -c Release: 0 errors, no new warnings. A smoke run prints the three Glyph11 tables.
  • dotnet test tests/Tests/Tests.csproj -f net10.0: 403 passed, 0 failed (unchanged).
  • Leftover sweep git grep -i -E "pico|glyph11\.native|libglyph11|kotlin|gradle|GLYPH11_NATIVE_PATH|cmake|core/": only the discontinued notes remain.

Glyph11 is managed-only from here on: the bindings are no longer
supported, so carrying them means maintaining a second and third
implementation of every rule (and a Gradle toolchain) for packages that
will not be released again.

Removed: bindings/ (Kotlin, Glyph11.Native, Glyph11.Pico with the
vendored picohttpparser), core/ (the C parser, its tests and the C-vs-C#
differential harness), the two native example projects, and the
core-tests / package-native / package-pico workflows. release.yml now
publishes only Glyph11, and the solution drops the four binding projects.
The benchmark keeps the Glyph11 measurements and loses the native
columns and decoder.

InternalsVisibleTo("Glyph11.Pico") stays in Glyph11.csproj. The published
Glyph11.Pico 0.0.1 sets BinaryRequest's internal setters and calls
KeyValueList.Add, and the runtime enforces friend access, so dropping the
attribute would make Pico fail with MethodAccessException against the
next Glyph11 release - GenHTTP still ships it next to Glyph11.

Closes #57, closes #66, closes #69, closes #70, closes #72.
With the bindings gone, the README, the docs site, the examples index and
the benchmark README described three packages and their native build
steps. They now describe the managed parser only: the three-package
table, the "all three produce the same data" claim, the Native / Pico /
Kotlin sections and the native build instructions are removed; the
benchmark tables keep the existing Glyph11 numbers; the site loses the
Native and Pico pages from its navigation. A short note says that
Glyph11.Native and Glyph11.Pico are discontinued: their published
versions stay on NuGet but get no further releases.

Also fixes the harness link, which pointed at a bench/ directory that
does not exist (the harness lives in Benchmarks/).

Refs #57, #66, #69, #70, #72.
MDA2AV added a commit to Kaliumhexacyanoferrat/GenHTTP that referenced this pull request Nov 2, 2026
Glyph11 discontinues Glyph11.Pico and Glyph11.Native
(dotnet-web-stack/Glyph11#84): they get no further releases. The Ioxide
engine's GENHTTP_IOXIDE_PARSER=pico switch goes with the package, so
requests are always parsed by UltraHardenedParser, and the body
lifecycle tests that need unvalidated framing headers get them from
Glyph11's FlexibleParser instead of picohttpparser.
The friend access was kept so that the published Glyph11.Pico 0.0.1
could keep running next to newer Glyph11 releases, as GenHTTP shipped
it. GenHTTP drops Glyph11.Pico in the same upgrade to 0.4.0
(Kaliumhexacyanoferrat/GenHTTP#973), so nothing needs it any more.
Glyph11.Pico 0.0.1 now fails with MethodAccessException next to Glyph11
0.4.0 or later; it keeps working with 0.3.x.
@MDA2AV
MDA2AV merged commit f9d63b8 into main Nov 3, 2026
1 of 2 checks passed
Kaliumhexacyanoferrat pushed a commit to Kaliumhexacyanoferrat/GenHTTP that referenced this pull request Nov 4, 2026
* Update Glyph11 to 0.4.0 and parse with TryParseRequestHeader

Glyph11 0.4.0 marks TryExtractFullHeaderValidated and TryExtractFullHeaderROM
[Obsolete]: they report one less than the length of the header block, which
is why every call site here sliced at bytesRead + 1. TryParseRequestHeader
reports the length itself, so the body starts at consumed.

With TreatWarningsAsErrors the update does not build without the move, and the
rename and the dropped + 1 have to land together - renaming alone would skip
the first byte of every body or pipelined request. Both engines, the body
lifecycle tests and the benchmark context move. Glyph11.Pico stays at 0.0.1:
PicoParser.TryParse keeps its convention, so the Pico path keeps its + 1.

Closes #972.

* Expect 400 for a malformed HTTP version, 505 for an unsupported one

Glyph11 0.4.0 (dotnet-web-stack/Glyph11#79) splits what it used to report
as one 505: a version that matches HTTP-version ("HTTP/" DIGIT "." DIGIT)
but is not 1.0/1.1 stays a 505, "Unsupported HTTP version.", while bytes
that are not an HTTP-version at all make the request line invalid, a 400
(RFC 9112 2.3 and 3).

"GET / HTTP/1" has no minor version, so it is malformed rather than
unsupported, which is also what http-probe's COMP-VERSION-MISSING-MINOR
expects. HTTP/2.0 keeps its 505, under the new message.

* Expect a truncated chunked body to hand out its data before failing

Glyph11 0.4.0 (dotnet-web-stack/Glyph11#83) hands chunk data out as it
arrives instead of waiting for the whole chunk, so a peer that declares a
huge chunk can no longer make the connection buffer it. For "5\r\nHel" the
first read now returns the three bytes that did arrive, and the truncation
surfaces as the 400 ProviderException on the next read - the point where
the body actually ends early.

* Drop the Glyph11.Pico dependency

Glyph11 discontinues Glyph11.Pico and Glyph11.Native
(dotnet-web-stack/Glyph11#84): they get no further releases. The Ioxide
engine's GENHTTP_IOXIDE_PARSER=pico switch goes with the package, so
requests are always parsed by UltraHardenedParser, and the body
lifecycle tests that need unvalidated framing headers get them from
Glyph11's FlexibleParser instead of picohttpparser.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment