Skip to content

Latest commit

 

History

History
145 lines (124 loc) · 9.34 KB

File metadata and controls

145 lines (124 loc) · 9.34 KB

Migration Status

CodeGreen is a 1:1 functional port of GenHTTP to Kotlin, per the acceptance criteria in issue #3. Unlike a "foundation-first" subset, the goal is to reproduce GenHTTP's concepts and structure faithfully (original naming, same project layout), adapting only technical conventions to Kotlin. Work proceeds in staged passes; this document tracks what is done.

Acceptance criteria → status

# Criterion Status
1 1:1 functional, state-of-the-art Kotlin, keep concept names ✅ ongoing
2 Follow GenHTTP's functional structures closely ✅ ongoing
3 Internal engine only; keep engine swappable ✅ (insecure HTTP/1.1; AbstractServerBuilder seam)
4 MemoryView as a fundamental type over the request buffer org.codegreen.api.MemoryView + typed views
5 Glyph11 exposes request memory via that type BinaryRequest fields are MemoryView
6 Same project structure as GenHTTP (public API at root, impl in sub-packages) ✅ root-level API/, Engine/*, Glyph11/, Testing/, Playground/
7 Use the GenHTTP website to understand concepts ✅ (genhttp.org + v11 sources)
8 Start with modules IO, Layouting ✅ both ported (:modules:io, :modules:layouting)
9 1:1-copied acceptance tests + TestHost TestHost + Layouting (5 suites) & IO (11 suites) copied 1:1
10 Webservice layers (functional/webservices/controllers + reflection/conversion; ignore codegen) ✅ all five modules ported (reflection = dynamic path only)
11 Core webservice concepts (registries, formatters, serializers, injectors, interceptors) ✅ ported and exercised
12 Service acceptance tests (e.g. (a, b) => a + b as a web service) ✅ Functional/Webservices/Controllers suites green

Delivered in this pass (the core)

  • API (:api) — full 1:1 port of GenHTTP.Api: content (handlers/concerns/builders), protocol (request/response/target/headers/body/status/…), infrastructure (server/host/endpoint/companion), plus the fundamental MemoryView and the typed memory-view structs (RequestMethod, HttpProtocol, ContentType, PathSegment, AlgorithmName) reproducing the [MemoryView] generator's behavior (FNV-1a hash, ASCII case-insensitive equality) by hand (no codegen, per criterion 4).
  • Glyph11 (:glyph11) — the UltraHardenedParser (fused parse + RFC 9110/9112 hardening) populating BinaryRequest with zero-copy MemoryView slices.
  • Engine (:engine:shared, :engine:internal) — a non-blocking HTTP/1.1 engine on Netty (event-loop + pooled buffers, the JVM analog of System.IO.Pipelines): HostThreadedServerInternalEndPoint (Netty ServerBootstrap) → Glyph11RequestDecoderHttpDispatchHandlerResponseHandler; keep-alive / pipelining, Content-Length & chunked request bodies, chunked responses, CoreRouter (404 / ProviderException / 500). The AbstractServerBuilder (Shared) / ThreadedServerBuilder (Internal) split is the engine-swap seam.
  • Testing (:testing) — the TestHost harness; 7 passing engine acceptance tests.

Delivered in the modules pass (IO + Layouting)

  • Layouting (:modules:layouting) — Layout / LayoutBuilder / LayoutHandler / MultiSegmentSupport / HandlerWrapper: segment routing, index, fallbacks, lazy building, and the trailing-slash redirect. All 5 acceptance suites copied 1:1.
  • IO (:modules:io) — resources (StringResource, FileResource, EmbeddedResource), content serving (Content / ContentProvider), inline Handler / Concern, streaming content (ResourceContent, ByteArrayContent, MemoryContent, StreamContent), content-type guessing, Checksum, range support (RangeSupportConcern + .addRangeSupport()), change tracking, resource trees (directory / embedded / virtual) with ResourceTree / VirtualTree + find, and WebResource. All 11 acceptance suites copied 1:1.
  • Redirects (:modules:redirects) and Basic Authentication (:modules:authentication) — ported because Layouting depends on them (the trailing-slash redirect; the lazy-building auth test).
  • 71 acceptance tests green (7 intentional skips).

Module-pass technical adaptations

  • A C# API interface and its same-named module factory (IResource/Resource, IHandler/Handler, IConcern/Concern) collide once the I prefix is dropped; resolved by package separation (api.content.io.Resource vs modules.io.Resource).
  • .NET's Stream (seekable, read+write) has no single JVM type: RangedStream is an OutputStream, StreamWithDependency an InputStream; the few tests written against the Stream contract are adapted to the JVM equivalents.
  • Embedded-resource trees map to classpath-directory enumeration (clean for the exploded/test class path; jar scanning is a follow-up). The test File.txt has no UTF-8 BOM, so its length is 13 (not .NET's 16).
  • Generic overloads that erase to the same JVM signature (add(Builder<ResourceTree>) vs add(Builder<Resource>)) are disambiguated with @JvmName.
  • Response.rebuild() mutates the response in place (GenHTTP's concern-modification semantics); the root path / is treated as having a trailing slash.

Deferred in the modules pass (await other modules)

Tests whose originals reach into not-yet-ported modules are kept as @Disabled with a reason (so the originals exist, per criterion 9): ErrorHandling (ErrorHandler.Html), Files (Asset), DirectoryBrowsing (Listing), Functional (Inline), and ClientCaching (ETag, applied via Host.Defaults()). My TestHost runs the bare handler; GenHTTP's applies Host.Defaults() — a fidelity item for when those modules land.

Delivered in the webservice-stack pass (criteria 10–12)

  • Conversion (:modules:conversion) — formatters (string/bool/enum/GuidUUID/ DateOnlyLocalDate/primitives) + serialization (SerializationRegistry with the JSON and form formats; JSON via kotlinx.serialization). XML/YAML (xmlutil/kaml) and Protobuf are deferred.
  • Reflection (:modules:reflection) — the dynamic invocation framework (the Generation/ codegen path is intentionally omitted per criterion 10): Operation / SignatureAnalyzer / ArgumentProvider, routing (OperationRouter + literal/variable/ regex/closing segments), injectors (request/handler/user), interceptors, the five result sinks (ResponseProvider), MethodHandler / MethodCollection. KFunction replaces MethodInfo+Delegate; invocation via callBy/callSuspendBy.
  • Functional (:modules:functional) — Inline.create().get(::fn)….
  • Webservices (:modules:webservices) — ServiceResource.from<T>() + @ResourceMethod.
  • Controllers (:modules:controllers) — Controller.from<T>() + @ControllerAction / @FromPath, name-routed actions.
  • 126 acceptance tests passing (12 @Disabled pending other modules / formats).

Webservice-pass technical adaptations

  • Reflection, not codegenkotlin-reflect invokes methods; ExecutionMode.Auto and .Reflection both resolve to reflection. Kotlin's suspend replaces .NET Task/ValueTask result unwrapping.
  • Function references for Functional — Kotlin erases anonymous-lambda parameter names, so Inline takes KFunction references (::fn) to retain names for binding.
  • Annotations carry data, not logic — C# attributes implement IMethodConfiguration; Kotlin annotations (@ResourceMethod, @ControllerAction) are read by the providers to build the configuration. @ResourceMethod(path = …) passes the path by name.
  • kotlinx.serialization (user's choice over Jackson) — DTOs in the service tests are @Serializable; doubles render as 42.0 (System.Text.Json drops the .0), so the JSON test expectations are adapted.
  • Deferred suites kept as @Disabled (originals exist, criterion 9): CycleTests (XML/ YAML/Protobuf), WebserviceTests XML/YAML, and the *.testConcernChaining cases (ErrorHandling module).

Technical mappings (1:1 functional, idiomatic Kotlin)

  • ReadOnlyMemory<byte>MemoryView (zero-copy ByteArray view); ValueTasksuspend; DateTimeInstant; StreamInputStream/OutputStream; IBufferWriter<byte> → the sink's OutputStream.
  • IXxx interface naming and the Async suffix dropped (Kotlin convention); the self-typed IServerBuilder<T> reproduced via covariant return overrides.
  • :glyph11 depends on :api for MemoryView (in C# Glyph11 uses the BCL; Kotlin has no stdlib ReadOnlyMemory). Value-type structs become classes.

Deferred (clearly noted, not silently skipped)

TLS / secure endpoints (SecureEndPoint, the certificate-based Bind overloads), HTTP/2 & HTTP/3, the Kestrel engine, connection pooling, and HeaderAccess.Release zero-allocation retention. Within the webservice stack: XML/YAML/Protobuf serialization (xmlutil/kaml/protobuf) and the supporting modules the deferred tests reach into (ErrorHandling, Files, DirectoryBrowsing, ClientCaching, Pages) are the next passes.

Build & test

./gradlew build           # core + engine smoke tests
./gradlew :glyph11:test   # hardened-parser suite
./gradlew :testing:test   # engine + module acceptance suites (138 tests)