4 Commits
Author SHA1 Message Date
zeekayandHanzo Dev e9ad01194d package http — the last element of the module path, as Go expects
v0.3.3 renamed this to package zap, and that was wrong twice. Go resolves an
unaliased import to the package's own name, so github.com/zap-proto/http should
answer to http; and this package IMPORTS zap, the wire format, so naming itself
zap put two different things under one word in the same file. An importer that
also needs net/http aliases one of them, which is the ordinary convention rather
than a reason to invent a name.

zap.Version and zap.HeaderSize are that other package and are untouched.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-10 16:16:08 -07:00
zeekayandHanzo Dev 6d46bc4941 package zap — the module is already called http, so the name said it twice
zaphttp was a compound word invented to disambiguate a module whose path
already reads github.com/zap-proto/http. The package is the ZAP wire; the
module path says what it speaks. An importer that also needs net/http aliases
one of them, which is the ordinary Go convention rather than a reason to build
a compound name into every file.

The file that carried the name in its own filename is zap_test.go now, for the
same reason: a file is named for what it holds.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-10 15:38:07 -07:00
zeekayandHanzo Dev 136bceae3e feat: network is a value — Dial(network, addr) + Server.Network, unix included
The wire was already ZAP binary on both sides; only the plumbing was pinned
to TCP (net.Listen("tcp"), net.DialTimeout("tcp")). Lifting that to a value
mirrors net.Dial/net.Listen — the network is an argument, not a family of
functions — and unix sockets fall out with no change to the frames:

    zaphttp.Dial("unix", "/run/hanzo/billing.sock")
    &zaphttp.Server{Network: "unix", Addr: "/run/hanzo/billing.sock"}

NewTransport is gone in favour of Dial: it was a compound name for what net
already calls dialing, and keeping both would be two ways to do one thing.
All callers migrated.

Serving on unix clears a stale socket first — a crashed predecessor leaves a
file that bind refuses, so restart-in-place needs it. A socket with something
live behind it still fails, loudly, rather than being unlinked out from under
a running process.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 09:03:52 -07:00
zeekay 5deee64a3e feat: streaming responses — server→client push over ZAP (bidirectional)
Adds multi-frame streamed responses so SSE / MCP notifications / progress /
chunked bodies ride ZAP as real server→client push, not a buffered blob. A
streamed response is a head frame (status+headers) + N data frames (one per
handler flush) + an end frame — the analogue of HTTP/2 HEADERS+DATA+END_STREAM.

- wire.go: FrameResponseHead/FrameData/FrameEnd + Marshal/Unmarshal + FrameTypeOf.
- server.go: when ctx.Response.IsBodyStream(), stream via BodyWriteTo→chunkWriter
  (each flush = one FrameData frame on the wire immediately). Non-stream path
  unchanged (single FrameResponse) — fully backward-compatible.
- client.go: Transport.Do dispatches on frame type; a head attaches a streaming
  body (streamReader) that reads data frames until end, releasing the pooled conn
  only when the stream drains (or closes it if abandoned mid-stream).

Verified: TestStream_SSEOverZAP flushes 3 events one-at-a-time and the client
receives each BEFORE the next is released (a buffering regression would deadlock/
time out — the guard proves real incremental push). All existing round-trip +
keep-alive tests pass; go test -race clean; gofmt clean.
2026-07-02 00:43:58 -07:00