native · fastest

Glyph11.Pico

The fastest path to a BinaryRequest. picohttpparser (native, SSE4.2) tokenizes; a thin managed layer fills the same BinaryRequest as Glyph11. The trade: no validation beyond picohttpparser's — raw speed, same request shape.

Install

dotnet add package Glyph11.Pico

Depends on Glyph11 (for BinaryRequest and chunked decoding) and bundles the native libglyph11pico per platform.

Quick start

using System.Text;
using Glyph11.Pico;
using Glyph11.Protocol; // BinaryRequest

// Same reusable BinaryRequest as the managed parser — allocate once, Clear() per request.
var request = new BinaryRequest();

// Contiguous input (a byte[] / ReadOnlyMemory<byte> you already have buffered).
byte[] input = "GET /api/users?page=1 HTTP/1.1\r\nHost: example.com\r\n\r\n"u8.ToArray();

// Returns true on a parsed header block; false if malformed or incomplete.
// `consumed` marks the header block (see "The trade-off" for the off-by-one note).
if (PicoParser.TryParse(input, request, out int consumed))
{
    // Identical BinaryRequest to Glyph11 — Method / Path / Version / Headers / QueryParameters.
    Console.WriteLine(Encoding.ASCII.GetString(request.Method.Span)); // GET
    Console.WriteLine(Encoding.ASCII.GetString(request.Path.Span));   // /api/users
}

Reading the result

Because it fills the same BinaryRequest, reading is identical to Glyph11 — every field is a zero-copy ReadOnlyMemory<byte> slice of your input.

request.Method;          // "GET"
request.Path;            // "/api/users"  (query stripped)
request.Version;         // "HTTP/1.1"
request.Body;            // remainder of the buffer after the header block

for (int i = 0; i < request.Headers.Count; i++)
{
    var (name, value) = request.Headers[i];  // KeyValuePair of byte slices
    // ...
}
for (int i = 0; i < request.QueryParameters.Count; i++)
{
    var (key, val) = request.QueryParameters[i];
    // ...
}

The header capacity per parse is PicoParser.MaxHeaders (256); a request with more headers is rejected (false).

ReadOnlySequence input

picohttpparser needs one contiguous buffer, so a fragmented sequence uses a dedicated overload: single-segment is parsed in place (zero-copy); multi-segment is linearized into a fresh array, which the resulting BinaryRequest slices keep alive (just like the managed parser — no buffer for you to manage).

// `sequence` is a ReadOnlySequence<byte> from a PipeReader, socket, etc.
if (PicoParser.TryParse(sequence, request, out int consumed))
{
    // request.* exactly as in the contiguous case.
}
// Single-segment → zero-copy. Multi-segment → one ToArray() internally; the BinaryRequest
// references that array, so it stays alive as long as you hold the request.

Chunked bodies

Chunked decoding is glyph11's — this package depends on Glyph11, so use ChunkedBodyStream directly (see the Glyph11 page).

using Glyph11.Parser;

var decoder = new ChunkedBodyStream();
var r = decoder.TryReadChunk(input, out int consumed, out int dataOffset, out int dataLength);
// r: Chunk | Completed | NeedMoreData | Error

The trade-off

Glyph11.Pico does the same parsing as Glyph11, but only picohttpparser's validation. It does not do glyph11's hardening:

Glyph11 / Glyph11.NativeGlyph11.Pico
Method / path / version / headers / query✅ (same BinaryRequest)
Token / field-value character validation
Path normalization & traversal checks
Host / limits / Transfer-Encoding+Content-Length conflict
Request-smuggling defenses
Use it when you validate elsewhere or trust the source. For untrusted, internet-facing input that you want hardened in the parser, use Glyph11 or Glyph11.Native.

consumed follows glyph11's convention: it's the header-block length minus one, so the body begins at consumed + 1 — a drop-in match for the managed parser.

Platforms & native resolution

Native libglyph11pico is bundled for linux-x64/arm64, win-x64/arm64, and osx-x64/arm64, resolved automatically. The x86-64 builds use picohttpparser's SSE4.2 fast path. Override with GLYPH11_PICO_NATIVE_PATH (an explicit path to libglyph11pico.{so,dll,dylib}) for local builds.