Native HTTP Driver
The native HTTP driver adapts generated HTTP and WebSocket routes to an
Anvil-owned fasthttp runtime.
Install it:
go get github.com/TDB-Group/anvil-http/nativeImport it as:
import httpnative "github.com/TDB-Group/anvil-http/native"Basic Use
Section titled “Basic Use”app := anvil.New( httpnative.Driver(),)When the native driver is the only HTTP-family transport, Anvil starts it
directly on the public address. That avoids the shared net/http edge and gives
HTTP and WebSocket routes the lowest-overhead official path.
When GraphQL or gRPC also need the same public listener, Anvil keeps the shared
edge runtime. In that mode the native driver still works through its
compatibility http.Handler path, so multi-protocol apps keep the same request
classification behavior as the other official drivers.
Configuration
Section titled “Configuration”The driver accepts zero options or one httpnative.Options value:
app := anvil.New( httpnative.Driver(httpnative.Options{ MaxBodyBytes: 8 << 20, WebSocket: httpnative.WebSocketOptions{ OriginPatterns: []string{"app.example.com"}, }, }),)Supported options:
| Option | Behavior |
|---|---|
Server | Cloned *fasthttp.Server settings. Handler and ErrorHandler must be nil because the driver owns them. |
Codecs | Request decoder and response encoder registry. Defaults to Anvil’s default codec registry. |
ErrorPipeline | Error mapper and observer pipeline. Driver fills this from app.ErrorPipeline() when the option is nil. |
TLS | Cert/key pair used when the driver owns the listener or is run standalone. |
WebSocket | Origin policy, compression, read limits, and socket timeouts. |
MaxBodyBytes | Maximum request body size. 0 selects the driver default of 4 MiB; negative values are rejected. |
The driver applies defensive server defaults when the supplied server leaves fields empty:
| Server setting | Default |
|---|---|
ReadTimeout | 30s |
WriteTimeout | 30s |
IdleTimeout | 2m |
MaxRequestBodySize | MaxBodyBytes |
The driver also enables secure error-log messages, removes the default server header, removes the default content type, and marks connections for close during shutdown.
Listener Ownership
Section titled “Listener Ownership”The native driver exposes an internal listener-owner marker to Anvil. Anvil only uses that direct path when exactly one transport claims the listener and no other HTTP-family edge target is registered.
This keeps the architecture explicit:
- Native-only HTTP and WebSocket apps run directly on the native server.
- Apps with GraphQL or gRPC keep Anvil’s shared edge listener.
- Queue transports still run as background transports alongside either path.
If more than one transport claims listener ownership, Anvil rejects the app before it starts.
WebSockets
Section titled “WebSockets”sdk.WS routes use the driver’s native WebSocket integration. HTTP middleware
runs before the upgrade, which is where auth, origin policy, rate limits, and
tenant checks belong.
Origin policy is same-origin by default. Configure OriginPatterns for allowed
cross-origin hosts, using the same host or scheme://host pattern style as the
standard driver. The native driver rejects a bare * pattern; use
InsecureSkipVerify only for explicit test or controlled internal bypasses.
Before the upgrade, middleware and handler errors are mapped into normal HTTP responses. After the upgrade succeeds, failures are mapped and published through the Anvil error pipeline because there is no HTTP response left to write.
The driver uses github.com/fasthttp/websocket. socket.Native() returns
*websocket.Conn. The portable socket.Write method supports text and binary
messages. socket.Close sends a close control frame and closes the connection.
During shutdown, the driver closes active upgraded sockets with
1001 Going Away before shutting down the server. This covers hijacked
connections that the underlying HTTP server cannot close by itself.
Native Context
Section titled “Native Context”ctx.Native() returns:
httpnative.NativeContext{ RequestCtx: requestCtx, Method: method, Path: path, Params: params, Query: query, Headers: headers, Body: body,}For normal HTTP handlers, RequestCtx is the active *fasthttp.RequestCtx.
For WebSocket handlers, RequestCtx is nil and the remaining fields contain a
detached request snapshot, because fasthttp request contexts are reused after an
upgrade.
Use Native() for deliberate driver escape hatches. Portable Anvil code should
prefer ctx.Request(), ctx.Response(), ctx.Locals(), and ctx.Errors().
Standalone and Test Use
Section titled “Standalone and Test Use”httpnative.New creates the transport directly. DriverFrom installs an
existing transport into an app:
transport := httpnative.New()app := anvil.New(httpnative.DriverFrom(transport))Standalone helpers:
Start(addr)listens with the cloned native server.Serve(listener)serves a caller-owned listener.ServeConn(conn)serves one accepted connection.ServeFastHTTP(ctx)executes the native request path directly.ServeHTTP(writer, request)runs the compatibility path used by Anvil’s shared edge.Shutdown(ctx)closes active WebSockets and stops the server.
Testbed Runner
Section titled “Testbed Runner”httpnative.RunTestbed(ctx, suite, opts) executes HTTP,
GraphQL-over-HTTP, and WebSocket cases against a running server. The WebSocket
runner converts http URLs to ws and https URLs to wss, supports text,
binary, ping, and close input messages, and checks expected text, binary, and
close output.