Commit Graph
10 Commits
Author SHA1 Message Date
Zakaria El OrcheandClaude Sonnet 5 5a2aaf5a07 feat(core): HTTP/2 Phase 1 — HTTP/1.1 hardening and protocol negotiation
Fixes the request-smuggling and resource-exhaustion debt in the existing
HTTP/1.1 parser, and adds the ALPN/h2c-preface negotiation seam so a
connection's protocol is decided once, before any request is parsed, per
flash/docs/http2/IMPLEMENTATION-PLAN.md Phase 1.

Existing-code defects fixed (EX-nn):
- EX-02: reject Content-Length + Transfer-Encoding together (RFC 9112 6.1
  CL.TE/TE.CL smuggling), and conflicting duplicate Content-Length values.
- EX-03: strict, overflow-safe Content-Length parsing, replacing a parser
  that silently skipped non-digit bytes ("5abc" -> 5, "-1" -> 1).
- EX-07: header-read / idle-keep-alive / body-read timeouts enforced by an
  absolute deadline (dev.relism.flash.transport.BufferedByteSource), not
  merely Socket#setSoTimeout, which never trips against a peer trickling
  one byte per read within the window.
- EX-08: header count / name length / value length / request-line length
  bounds (Http1Limits), 431 on violation.
- EX-10: ChunkedInputStream now reads through BufferedByteSource instead
  of the raw unbuffered socket stream, and the header-parser's read-ahead
  bytes are handed over via a zero-copy prependOnce() instead of a
  SequenceInputStream/ByteArrayInputStream pair.
- EX-17: HttpStatus's status-code bound is computed from values() instead
  of a hand-maintained constant that silently threw
  ArrayIndexOutOfBoundsException when a code above it was added; added
  421, 431, 505, 507, 511 and others HTTP/2 and this hardening need.
- EX-18: bare-CR desync and obsolete line folding rejected.
- EX-30: the TLS handshake is forced explicitly, under a timeout, before
  any protocol decision -- SSLSocket#getApplicationProtocol() returned
  null until the handshake had run, and nothing previously forced it.
- EX-31: TLS 1.2 cipher suites on the RFC 9113 Appendix A blocklist are
  filtered out of a listener's enabled set whenever it offers h2 via ALPN.
- EX-35 (found in this phase): Transfer-Encoding values listing multiple
  codings ("gzip, chunked") were silently treated as not chunked at all,
  corrupting the message boundary -- only the whole value was compared.
- EX-36 (found in this phase): a header line with no ':' was silently
  skipped instead of rejected.

New:
- dev.relism.flash.transport.BufferedByteSource: the single buffered,
  deadline-aware, peekable view over a connection's inbound bytes.
- dev.relism.flash.transport.ProtocolNegotiator/NegotiatedProtocol: ALPN
  and h2c prior-knowledge detection. In this phase an H2 result is always
  closed cleanly -- there is no Http2Connection to hand off to until
  Phase 8. FlashConfiguration.http2Enabled gates the h2c preface peek.
- dev.relism.flash.exceptions.MalformedRequestException: a typed,
  status-carrying rejection distinct from HttpException, caught at the
  parse site so a malformed request never reaches the handler chain or
  the user's exception handler, and the connection is always closed.

Two small plan-document corrections recorded as DEC-12 (Phase 1's Files
list omitted BufferedByteSource.java and MalformedRequestException.java;
the request-line-length check description pointed at the wrong offset).
DEC-13/DEC-14 record the deadline and exception-hierarchy designs.

277/277 tests green (flash module), run twice for stability of the new
wall-clock-based HttpServerTimeoutTest cases. Whole-repo build green.
h1 benchmark regression check is left unverified in the plan's DoD: no
JMH harness exists yet (Phase 3 deliverable).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-13 11:40:03 +00:00
Zakaria El Orche 891ef99b8e refactor(core): make boot and middleware ordering deterministic
CI / Build & Test (pull_request) Canceled after 23s
CI / Build & Test (push) Failing after 4m51s
2026-08-12 16:42:49 +00:00
Zakaria El OrcheandClaude Sonnet 5 d7f36a7aea feat(ext-mcp): add MCP (Model Context Protocol) server extension
CI / Build & Test (push) Failing after 4m57s
Streamable HTTP transport (JSON-RPC 2.0 over POST), one-class-per-tool/resource/prompt
API mirroring RequestHandler, boot-time-precompiled schema/list payloads for a zero-alloc
hot path, and optional OAuth2 protection built on flash-ext-oidc (lazy-loaded, RFC 8707
audience binding, RFC 9728 Protected Resource Metadata). Registers the module in the
root and flash-extensions POMs and adds the ext-mcp commit scope to AGENTS.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 00:22:40 +00:00
Zakaria El OrcheandClaude Sonnet 5 1b48d14b4f feat(core): ALPN configuration and TLS visibility on Request/WebSocketSession
CI / Build & Test (push) Failing after 5m3s
CI / Build & Test (pull_request) Failing after 4m53s
- TlsConfig.applicationProtocols(String...) sets the listener's negotiable
  ALPN protocol list via SSLParameters, inherited by every accepted socket
  like clientAuth — works on both keystore() and ofContext(), untouched
  unless called. Enables TLS-ALPN-01 (RFC 8737) style on-demand cert
  issuance: a custom KeyManager can read the already-resolved protocol via
  engine/socket getHandshakeApplicationProtocol() inside
  chooseEngineServerAlias/chooseServerAlias, since ALPN is resolved during
  ClientHello/ServerHello, always before Certificate production.
- Request gains isSecure()/sslSession(), threaded through RequestParser from
  the accepted SSLSocket exactly like remoteAddress() — reference-only,
  zero per-request allocation. sslSession() defers to SSLSocket#getSession()
  lazily, so it's a cached-field read (handshake already completed by the
  time a handler can call it), never a forced handshake.
- WebSocketSession.isSecure()/sslSession() delegate to the upgrading
  Request rather than tracking the socket a second time.
- Documents TLS end-to-end in README.md (listeners, TlsConfig, SNI, ALPN,
  mTLS, Request/WebSocketSession accessors).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-09 23:34:22 +00:00
Relism 9e19f439be add core view extension with JTE and Thymeleaf support 2026-04-21 00:32:09 +02:00
Relism b5d4481502 preparing for another refactoring... 2026-03-29 23:16:41 +02:00
Relism 2edd68b0aa preparing for a conceptual refactoring... 2026-03-28 14:11:12 +01:00
RelismandClaude Sonnet 4.6 f8c86e315f Untrack .claude/; placeholder README; ignore local config dirs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 22:46:18 +01:00
RelismandClaude Sonnet 4.6 5f0681a922 Remove flash-bench, docs, stray .class files; rewrite README for library
- Remove flash-bench module from git and root pom.xml (kept locally)
- Remove docs/ directory (lifecycle markdown files)
- Remove stray compiled fpr-core .class files tracked by mistake
- Rewrite README.md: concise library overview, quick-start, handler styles, Maven dependency — no wrk/benchmarking content

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 22:39:33 +01:00
Relism b0d606cb5f refactored, pre-buffer reuse 2026-03-15 14:31:52 +01:00