varion / minih2core-php
Minimal educational HTTP/2 core for PHP
v0.1.0
2026-03-07 12:32 UTC
Requires
- php: ^8.1
Requires (Dev)
- phpunit/phpunit: ^10.0
README
varion/minih2core-php is a minimal educational HTTP/2 core for PHP 8.1+.
This project is intentionally small and incomplete. It is designed for learning and demo servers, not production use.
Purpose
- Show how HTTP/2 frames can be encoded/decoded in a simple way.
- Provide a tiny server-side flow for one request stream and one response.
- Keep implementation readable without full RFC complexity.
Supported Frame Types (Minimal Subset)
SETTINGS(basic ACK handling)PING(basic ACK handling)HEADERS(request stream detection, no header decoding)DATA(request end detection, response trigger)
The frame codec itself can encode/decode generic frame envelopes (9-byte header + payload).
Unsupported Features
- Full HTTP/2 compliance
- Request header decoding (HPACK decode)
- CONTINUATION handling
- Dynamic table (HPACK)
- Huffman encoding (HPACK)
- Flow control enforcement
- Stream prioritization / multiplexing
- Multi-stream request handling (demo is single-stream)
- Production-grade validation and error handling
Server Architecture
Frame: immutable frame value objectFrameCodec: binary frame encoder/decoderHpackEncoder: minimal response header block encoderConnectionState: mutable per-connection stateFrameHandler: tiny server-side state machineResponseBuilder: createsHEADERS+DATAresponse frames
ReactPHP Example
See examples/react-http2-server.php.
What it does:
- Accepts a TCP connection (
h2cprior knowledge). - Reads and validates the HTTP/2 client preface.
- Sends an empty server
SETTINGSframe. - Buffers incoming bytes and repeatedly calls
FrameCodec::tryDecode(). - Passes each decoded frame to
FrameHandler. - Encodes returned frames and writes them back.
- Sends a single plain text response body:
hello from http/2 server\n. - Closes the connection after the response.
Run example:
php examples/react-http2-server.php 8080
Test with curl:
curl -v --http2-prior-knowledge http://127.0.0.1:8080/
Client Architecture
The client example is also intentionally minimal and educational.
ClientConnectionState: mutable state for one connectionRequestBuilder: builds one GET request HEADERS frame on stream 1ClientFrameHandler: handles SETTINGS/ACK flow and minimal response eventsClientConnection: ReactPHP connection wrapper around buffer/decode/write loop
Client Limitations
- client only
- HTTPS + ALPN(h2) only
- single GET request only
- one request stream only
- no response header decoding
- no HPACK decoder
- no CONTINUATION support
- no multiplexing / retries / flow-control enforcement
- small responses / demo only
- not production-ready
Client Example Flow
See examples/http2-client.php.
- Parse
[--insecure] <URI>. - Connect via TLS with ALPN
h2,http/1.1. - Send client preface + empty SETTINGS.
- Decode frames with
FrameCodec::tryDecode(). - On server SETTINGS, send SETTINGS ACK and one GET HEADERS frame.
- Print DATA payload bytes to STDOUT.
- Close on END_STREAM or GOAWAY.