Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: go-chi/chi
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v5.3.1
Choose a base ref
...
head repository: go-chi/chi
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v5.3.2
Choose a head ref
  • 5 commits
  • 9 files changed
  • 3 contributors

Commits on Aug 20, 2026

  1. Configuration menu
    Copy the full SHA
    60ecea5 View commit details
    Browse the repository at this point in the history
  2. docs: deployment recipe + verify checklist for ClientIPFromXFFTrusted…

    …Proxies (#1111)
    
    Replace the counting prose and ASCII diagram with a recipe table mapping
    common deployments to numTrustedProxies values, plus a "verify with a
    known IP" step. Steer users toward ClientIPFromXFF with explicit CIDRs
    (added pointers to CDN-published IP lists from Cloudflare, AWS, Fastly,
    GCP) since CIDR-based trust cannot off-by-one. Add one fail-closed test
    case.
    
    Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
    VojtechVitek and claude authored Aug 20, 2026
    Configuration menu
    Copy the full SHA
    bc02284 View commit details
    Browse the repository at this point in the history
  3. fix: don't drop handlers that collide with a Mount()/Route() pattern (#…

    …1148)
    
    * fix: don't drop handlers that collide with a Mount()/Route() pattern
    
    Mount() (and Route(), which is sugar for it) registers a synthetic
    "stub" handler on its exact mount pattern to connect it to the
    subrouter. node.routes() used that stub as a signal to hide the whole
    node from Routes()/Walk() — but if a real handler was also registered
    on that same pattern (e.g. r.Get("/bar", h) next to
    r.Route("/bar", ...)), it got hidden too, even though the route is
    perfectly routable.
    
    routes() now compares each handler against the stub by identity
    (sameHandler, using reflection since http.HandlerFunc isn't ==
    comparable) and only hides the stub itself, keeping any real handler
    that shares the node. The "*" slot is only filtered on leaf nodes,
    since Walk() also reads Handlers["*"] to detect a *ChainHandler and
    propagate With() middleware into a subrouter — that entry has to
    survive even when it's the same value as the stub.
    
    Fixes #830.
    
    Also adds a regression test for #750 (middlewares registered on a
    Group not reaching handlers on a Route() mounted inside it), which
    turns out to already be fixed on master — this just locks it in.
    
    * Trim comments in routes() to just the why
    
    * Rename sameHandler to equalHandlers; narrow the reflect switch to Func
    
    Chan, Pointer, and UnsafePointer are already == comparable in Go —
    only Func, Map, and Slice aren't, and Map/Slice identity was never a
    real case here (the stub is always http.HandlerFunc or *ChainHandler).
    
    * Explain why Routes() reports /api/* and not /api/{id} in TestRoutesHidesMountStub
    
    * Trim comment in TestRoutesHidesMountStub
    VojtechVitek authored Aug 20, 2026
    Configuration menu
    Copy the full SHA
    29164f0 View commit details
    Browse the repository at this point in the history
  4. Configuration menu
    Copy the full SHA
    9b6ddcd View commit details
    Browse the repository at this point in the history
  5. fix(middleware): reject catch-all compress wildcards "/*" and "*/*" (#…

    …1156)
    
    NewCompressor(level, "/*") passed validation but stored an empty wildcard
    key that never matched any Content-Type, silently compressing nothing.
    Instead of turning it into a compress-everything catch-all, reject both
    "/*" and "*/*" at construction: compressing every response wastes CPU on
    already-compressed types (zip, jpeg, png), which is why the middleware
    keeps a curated default list. Users should pass explicit content types.
    VojtechVitek authored Aug 20, 2026
    Configuration menu
    Copy the full SHA
    3893906 View commit details
    Browse the repository at this point in the history
Loading