Glyph11 is a dependency free, low allocation HTTP/1.1 parser for C#. It does not rely on any specific network technology but can be used with any (such as Socket, NetworkStream, PipeReader or anything else).
Glyph11 works with any source that produces a ReadOnlySequence<byte> or ReadOnlyMemory<byte> — PipeReader, Socket, NetworkStream, or raw byte arrays.
using System.Buffers;
using Glyph11;
using Glyph11.Protocol;
using Glyph11.Parser.Hardened;
using Glyph11.Validation;
var request = new BinaryRequest();
var limits = ParserLimits.Default;
ReadOnlySequence<byte> buffer = ...; // from any network source
if (HardenedParser.TryExtractFullHeader(ref buffer, request, in limits, out int bytesRead))
{
// All parsed fields are zero-copy slices into the original buffer:
// request.Method.Span → e.g. "GET"
// request.Path.Span → e.g. "/api/users"
// request.Version.Span → e.g. "HTTP/1.1"
// request.Headers → KeyValueList of name/value pairs
// request.QueryParameters → KeyValueList of query params
// Run post-parse semantic checks on untrusted input:
if (RequestSemantics.HasTransferEncodingWithContentLength(request))
throw new HttpParseException("Request smuggling: TE + CL.");
if (RequestSemantics.HasDotSegments(request))
throw new HttpParseException("Path traversal detected.");
// Process request, then advance your reader by bytesRead.
// Reuse between requests — clear instead of reallocating:
request.Headers.Clear();
request.QueryParameters.Clear();
}For a complete PipeReader integration loop, see the integration guide.
Glyph11 ships two parsers:
HardenedParser— RFC 9110/9112 compliant with full validation and configurable resource limits. Recommended for internet-facing applications.FlexibleParser— Minimal validation for maximum throughput. Suitable for trusted environments where input is pre-validated.
- ROM path is zero-allocation — no GC pressure regardless of request size
- SIMD-accelerated validation keeps the HardenedParser within ~1.4-1.6x of the unvalidated FlexibleParser
- Multi-segment linearization provides ROM-speed parsing with a single upfront allocation
See the live benchmarks for latest numbers and trend charts.
The Benchmark workflow (.github/workflows/benchmark.yml) measures parser throughput and allocation using BenchmarkDotNet.
| Trigger | Job | What it does |
|---|---|---|
pull_request |
Parser Benchmarks | Runs FlexibleParserBenchmark and HardenedParserBenchmark, compares against the baseline on gh-pages, and posts a comment on the PR. Fails if any metric regresses by more than 15%. |
workflow_dispatch |
Full Benchmarks | Runs all benchmarks (parsers + AllSemanticChecksBenchmark), updates the baseline on gh-pages, and triggers a docs site rebuild. |
Data flow: benchmark results are stored as benchmarks/data.js on the gh-pages branch. The docs site loads this file to render trend charts at /benchmarks/.
To publish updated benchmark data:
- Merge your changes to
main. - Go to Actions > Benchmark > Run workflow on
main.
The Probe workflow (.github/workflows/probe.yml) tests HTTP/1.1 compliance across multiple server frameworks using Glyph11.Probe, a tool that sends malformed and ambiguous HTTP requests and checks the server's response against strict RFC 9110/9112 expectations.
Servers tested: Glyph11 (raw TCP + HardenedParser), Kestrel (ASP.NET Core), Flask (Python), Express (Node.js), Spring Boot (Java), Quarkus (Java), Nancy (.NET), Jetty (Java), Nginx (native), Apache (native), Caddy (native), Pingora (Rust).
| Trigger | What it does |
|---|---|
pull_request |
Starts all three servers, probes each one, evaluates results with strict status-code matching (e.g. a parser error must return 400, not 404), and posts a comparison table as a PR comment. Never fails the build — this is informational. |
workflow_dispatch |
Same as above, plus pushes probe/data.js to gh-pages and triggers a docs site rebuild. |
Data flow: probe results are stored as probe/data.js on the gh-pages branch. The docs site loads this file to render the comparison matrix at /probe-results/.
To publish updated probe data:
- Merge your changes to
main. - Go to Actions > Probe > Run workflow on
main.