Publishes the module to Gitea Package Registry on tag push (v*).
Runs vet and tests before publishing to prevent broken releases.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
README: add PATCH, NewFormRequest, CORS, RateLimit, MaxBodySize,
Timeout, WriteJSON/WriteError, request ID propagation, response body
limit, and custom 404 handler examples. CLAUDE.md: document new
architecture details for all added components.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Wraps response body with io.LimitedReader when configured, preventing
unbounded reads from io.ReadAll in Response.Bytes(). Protects against
upstream services returning unexpectedly large responses.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Introduces internal/requestid package with shared context key to avoid
circular imports between server and middleware packages. Server's
RequestID middleware now uses the shared key. Client middleware picks up
the ID from context and sets X-Request-Id on outgoing requests.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Protects against abuse with configurable rate/burst per client IP.
Supports custom key functions, X-Forwarded-For extraction, and
Retry-After headers on 429 responses. Uses internal/clock for
testability.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Wraps http.TimeoutHandler to return 503 when handlers exceed the
configured duration. Unlike http.Server.WriteTimeout, this allows
handlers to complete gracefully via context cancellation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Wraps request body with http.MaxBytesReader to limit incoming payload
size. Without this, any endpoint accepting a body is vulnerable to
large uploads consuming all available memory.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Creates requests with application/x-www-form-urlencoded body from
url.Values. Supports GetBody for retry compatibility, following the
same pattern as NewJSONRequest.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Follows the same pattern as Put/Post, accepting context, URL, and body.
Closes an obvious gap in the REST client API.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add server package description, component table, and usage example to
README. Document server architecture, middleware chain, and test
conventions in CLAUDE.md.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Cover edge cases: statusWriter multi-call/default/unwrap, UUID v4 format
and uniqueness, non-string panics, recovery body and log attributes,
4xx log level, default status in logging, request ID propagation,
server defaults/options/listen-error/multiple-hooks/logger, router
groups with empty prefix/inherited middleware/ordering/path params/
isolation, mount trailing slash, health content-type and POST rejection.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Introduces server/ sub-package as the server-side companion to the existing Client.
Includes Router (over http.ServeMux with groups and mounting), graceful shutdown with
signal handling, health endpoints (/healthz, /readyz), and built-in middlewares
(RequestID, Recovery, Logging). Zero external dependencies.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Deduplicate sentinel errors: httpx.ErrNoHealthy, ErrCircuitOpen, and
ErrRetryExhausted are now aliases to the canonical sub-package values
so errors.Is works across package boundaries
- Retry transport returns ErrRetryExhausted only when all attempts are
actually exhausted, not on early policy exit
- Balancer: pre-parse endpoint URLs at construction, replace req.Clone
with cheap shallow struct copy to avoid per-request allocations
- Circuit breaker: Load before LoadOrStore to avoid allocating a Breaker
on every request for known hosts
- Health checker: drain response body before close for connection reuse,
probe endpoints concurrently, run initial probe synchronously in Start
- Client: add Close() to shut down health checker goroutine, propagate
URL resolution errors instead of silently discarding them
- MockClock: fix lock ordering in Reset (clock.mu before t.mu), fix
timer slice compaction to avoid backing-array aliasing, extract
fireExpired to deduplicate Advance/Set
Implements the top-level httpx.Client that composes the full chain:
Logging → User Middlewares → Retry → Circuit Breaker → Balancer → Transport
- Response wrapper with JSON/XML/Bytes decoding and body caching
- NewJSONRequest helper with Content-Type and GetBody support
- Functional options: WithBaseURL, WithTimeout, WithRetry, WithEndpoints, etc.
- Integration tests covering retry, balancing, error mapping, and JSON round-trips
Implements balancer middleware with URL rewriting per-request:
- RoundRobin, Failover, and WeightedRandom endpoint selection strategies
- Background HealthChecker with configurable probe interval and path
- Thread-safe health state tracking with sync.RWMutex
Implements circuit breaker as a RoundTripper middleware:
- Closed → Open after consecutive failure threshold
- Open → HalfOpen after configurable duration
- HalfOpen → Closed on success, back to Open on failure
- Per-host tracking via sync.Map for independent endpoint isolation
Implements retry middleware as a RoundTripper wrapper:
- Exponential and constant backoff strategies with jitter
- RFC 7231 Retry-After header parsing (seconds and HTTP-date)
- Default policy retries idempotent methods on 429/5xx and network errors
- Body restoration via GetBody, context cancellation, response body cleanup
Introduce the core building blocks for the httpx library:
- middleware.Middleware type and Chain() composer
- Error struct with sentinel errors (ErrRetryExhausted, ErrCircuitOpen, ErrNoHealthy)
- internal/clock package with Clock interface and MockClock for deterministic testing