1
0
mirror of https://github.com/labstack/echo.git synced 2026-06-13 21:54:53 +02:00

1881 Commits

Author SHA1 Message Date
Vishal Rana 4f5ac600f8 test: lock in v5 group route method-handling (405 + OPTIONS) (#3003)
* test: guard group catch-all against 405-masking and route shadowing

Adds regression tests around automatic group catch-all (404) route
registration. v5 removed that auto-registration; if it is restored
(e.g. PR #2996) these tests ensure it does not bring back the issues
that motivated the removal:

- wrong HTTP method on an existing group route must still return 405
  (with Allow header), not be masked to 404 by the catch-all;
- the group catch-all must not shadow concrete sibling routes, root
  routes, or other sibling groups' routes.

All four pass on current master (v5). The 405 test fails against the
restore-v4-behavior approach in #2996, pinning down that tradeoff.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* test: rewrite group method-handling tests after review

Addresses review of the original regression file (PR #3003): its comments
described an automatic group catch-all "triggered by middleware" that does
not exist on master (v5), so the tests passed for the wrong reason and the
no-op middleware was inert.

Rewrite to assert v5's actual, verified behavior:
- method mismatch on a group route -> 405 with full Allow header
- OPTIONS on a registered group route -> 204 with Allow (preflight-relevant)
- concrete routes resolve; group prefix does not affect root routes

The 405 and OPTIONS tests are real gates: a group-level catch-all (manual or
the auto-registration proposed in #2996) masks both as 404, which these tests
would then catch. Drops the false premise, the inert middleware, and the
in-comment PR reference.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* test: add rewritten group method-handling tests

The previous commit recorded only the deletion of the old file; this adds
the rewritten suite (group_method_handling_test.go).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* test: add companion test demonstrating group catch-all masking

Addresses final review: converts the "verified empirically" comment into an
actual test. TestGroupRoute_catchAllMasksMethodHandling registers a group-wide
catch-all and asserts it masks both the 405 method-mismatch and the automatic
OPTIONS (204) response as 404 — the regression the 405/OPTIONS gate tests guard
against. Makes the rationale self-proving in-repo.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 12:44:20 -07:00
Vishal Rana b0a391677a docs: liveness signals in README + public ROADMAP (#3002)
* docs: add liveness signals to README and a public ROADMAP

- Add dynamic latest-release and last-commit badges (can't go stale)
- Add positioning vs net/http and an "actively maintained" note
- Add ROADMAP.md with version policy (v5 current, v4 LTS to 2026-12-31)
  and surface it from the README

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs: fix review findings in README/ROADMAP

- Correct net/http interop claim: Echo handlers are not http.Handler;
  interop is via WrapHandler/WrapMiddleware
- Clarify binding ships with a pluggable validator (not built-in validation)
- ROADMAP: reference canonical auto-HEAD issue/PR (#2895/#2949) instead of
  the duplicate PRs (#2944/#2937) slated for closure

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 12:06:48 -07:00
Jihun Kim 9c748c9b11 fix(middleware): reset ContentLength after gzip decompression 2026-06-11 09:00:25 +03:00
kawaway 6a390cb5a7 fix(middleware/proxy): append RealIP to X-Forwarded-For for WebSocket requests (#2994)
* <Description>

The proxy middleware's WebSocket path currently sets `X-Forwarded-For` only
when the header is empty, dropping the proxy's own peer IP from the chain
whenever upstream proxies had already added entries. This breaks downstream
services that rely on the "rightmost untrusted" rule to extract the real
client IP, including echo's own `ExtractIPFromXFFHeader`.

The HTTP path delegates to `net/http/httputil.ReverseProxy`, which appends
`RemoteAddr` to the existing `X-Forwarded-For` chain — either inline in
`ServeHTTP`'s default Director path
([reverseproxy.go#L519-L531](https://github.com/golang/go/blob/go1.26.3/src/net/http/httputil/reverseproxy.go#L519-L531))
or via the explicit
[`(*ProxyRequest).SetXForwarded`](https://github.com/golang/go/blob/go1.26.3/src/net/http/httputil/reverseproxy.go#L82-L96)
when a `Rewrite` callback is configured. The WebSocket path uses `proxyRaw`,
which writes the request verbatim via `r.Write(out)`, so this middleware is
the only place where the appending happens for WebSocket Upgrade requests.

<Change>

Replace the "set if empty" guard with always-append. Read values via map
access to preserve multi-line `X-Forwarded-For` headers (RFC 9110 §5.3
allows combining them by joining values with commas).

<Test>
Added TestProxyWebSocketXForwardedFor exercising 4 cases:

- no incoming X-Forwarded-For → only c.RealIP()
- single-line single-entry → preserved + c.RealIP() at the tail
- ingle-line comma-separated → preserved + c.RealIP() at the tail
- multi-line headers (multiple X-Forwarded-For occurrences) → joined with , + c.RealIP() at the tail

Each case captures the request header at WebSocket Upgrade time inside the
upstream handler and asserts both the appended tail and the preserved prefix.

<Backwards compatibility>
The change is additive: existing entries are preserved and the proxy's own
peer IP is added at the tail. Downstream readers using the standard
"rightmost untrusted" rule (e.g. echo.ExtractIPFromXFFHeader) see no
behavioral difference for chains where they already worked, and start
returning the correct IP for chains where the proxy IP was previously
dropped.

<Background>
We hit this in production with an Echo-based WebSocket reverse proxy
fronting an internal service that uses echo.ExtractIPFromXFFHeader for
IP-based authorization. Multi-hop deployments (customer proxy → our reverse
proxy → backend) broke because the reverse proxy's egress IP was missing
from the chain reaching the backend.

* Set up upstream per test
2026-06-08 23:31:17 +03:00
leestana01 29727ff923 fix(middleware): correct documented KeyAuth KeyLookup default
DefaultKeyAuthConfig sets KeyLookup to "header:Authorization:Bearer "
in v5, but the KeyAuthConfig.KeyLookup comment still shows the v4
default of "header:Authorization". Update the comment to match.

Signed-off-by: leestana01 <leestana01@naver.com>
2026-06-05 11:36:46 +03:00
Charlie Tonneslan dac56bceda fix(binder): MustUnixTime docs say time.Time, not time.Duration
The non-Must variants (UnixTime, UnixTimeMilli, UnixTimeNano) all say
"binds parameter to time.Time variable", but the three Must* versions
copy-pasted the Duration variant's docstring and say time.Duration.
The function signature on each takes *time.Time. Also dropped the stray
double space and fixed "nano second" -> "nanosecond" on the
Nano one while in there.

Signed-off-by: Charlie Tonneslan <cst0520@gmail.com>
2026-05-28 07:55:16 +03:00
Jihun Kim c08ea0fc76 Fix typos in CSRFConfig comments 2026-05-22 14:17:13 +03:00
Jihun Kim 98d99d5c8c fix proxy panic when balancer has no target 2026-05-21 08:55:55 +03:00
toim d17c907c24 Update GitHub actions deps versions 2026-05-11 23:52:56 +03:00
kumapower17 03d9298e7d refactor: modernize code usage using gofix
Modernizes the codebase using the Go 1.26 gofix tool to adopt newer
idioms and library features while maintaining compatibility with
the current toolchain.
2026-05-11 22:44:45 +03:00
box4wangjing 46f2b8be7b refactor: replace Split in loops with more efficient SplitSeq (#2969)
* refactor: replace Split in loops with more efficient SplitSeq

Signed-off-by: box4wangjing <box4wangjing@outlook.com>

* refactor: replace Split in loops with more efficient SplitSeq

Signed-off-by: box4wangjing <box4wangjing@outlook.com>

---------

Signed-off-by: box4wangjing <box4wangjing@outlook.com>
2026-05-11 22:38:51 +03:00
Martti T. 7d1fed0542 Merge pull request #2966 from criciss/master
refactor: use the built-in max/min to simplify the code
2026-05-02 22:08:55 +03:00
criciss 01b45be8d1 refactor: use the built-in max/min to simplify the code
Signed-off-by: criciss <cricis@msn.com>
2026-05-03 00:12:04 +08:00
Martti T. 87a5c22f2f Changelog for v5.1.1 (#2965) v5.1.1 2026-05-01 22:14:30 +03:00
Martti T. f16f84decc Context.Json should not unwrap response and just wrap Response so other middlewares can use their own "wrapping" Responses and see the status code. (#2964) 2026-05-01 21:32:33 +03:00
Martti T. 96be504860 Merge pull request #2958 from tisonkun/fix-typos
chore: fix typos in httperror.go
2026-05-01 21:02:22 +03:00
tison b12f646a74 Update httperror.go 2026-05-02 01:51:23 +08:00
tison 86d0223c7a chore: fix typos in httperror.go
Signed-off-by: tison <wander4096@gmail.com>
2026-04-27 22:07:34 +08:00
Martti T. d1d8ad3f99 Context.Scheme should validate values taken from header (#2953) 2026-04-25 15:12:36 +03:00
llyaz 0143b9da1e fix(lint): resolve staticcheck issues and improve code quality (#2941)
* refactor: apply De Morgan’s law to boolean expressions
2026-04-07 14:03:50 +03:00
Eric Gusmao 607f385cb8 use ListenConfig for StartConfig listeners 2026-04-04 21:03:49 +03:00
toim 492ebd7336 Add golangci linter configuration 2026-04-01 16:59:04 +03:00
toim 597b4faaa9 Changelog for v5.1.0 v5.1.0 2026-03-31 23:52:35 +03:00
Martti T. c192e50a9e Merge pull request #2933 from aldas/LegacyIPExtractor
Remove legacy IP extraction logic from context.RealIP method
2026-03-31 23:42:09 +03:00
toim 22e4b71109 Remove legacy IP extraction logic from context.RealIP method and move it to LegacyIPExtractor IP extraction function. 2026-03-31 23:26:41 +03:00
Martti T. 83e04d265e Do not set http.Server.WriteTimeout in StartConfig this is bad for SSE and static file serving (#2932)
* Do not set http.Server.WriteTimeout in StartConfig this is bad for SSE and static file serving
2026-03-31 15:23:49 +03:00
Martti T. a7005b2f5f Add NewDefaultFS function to help create filesystem that allows absolute paths (#2931)
Add NewDefaultFS function to help create filesystem that allows absolute paths
2026-03-31 14:27:50 +03:00
toim a0e5ff7ea0 Add doc comments to clarify usage of File related methods and leading slash handling 2026-03-29 23:10:50 +03:00
karesansui 3f50cc66c2 Fix rate limiter documentation for default burst value 2026-03-29 22:33:19 +03:00
toim 675712da34 Add StartConfig.Listener so server with custom Listener is easier to create. 2026-03-19 13:32:07 +02:00
toim 7d228b2efe Add https://github.com/labstack/echo-prometheus to the middleware list in README.md 2026-03-19 11:13:32 +02:00
majianhan ec05bc8507 fix: correct spelling mistakes in comments and field name
Fix multiple typos found across the codebase:

- response.go: rename unexported field "commited" to "committed"
- server.go: fix "addres" to "address" in comment
- middleware/csrf.go: fix "formated" to "formatted" in comment
- middleware/request_logger.go: fix "commited" to "committed" in comment
- echotest/context.go: fix "wil" to "will" in comments
2026-03-12 19:08:07 +02:00
toim 1753170a74 Add https://github.com/labstack/echo-opentelemetry to the middleware list in README.md 2026-02-24 01:02:14 +02:00
toim fa5311b26a Add changelog for v5.0.4 release v5.0.4 2026-02-15 17:48:33 +02:00
Martti T. a260cf5d7f Merge pull request #2900 from aldas/v5_resolveresponsestatus
Add ResolveResponseStatus function to help middleware/handlers determine HTTP status code and echo.Response
2026-02-14 17:39:44 +02:00
toim 9183f1e809 CSRF: support older token-based CSRF protection handler that want to render token into template 2026-02-14 17:39:00 +02:00
toim 19364e2b12 use ResolveResponseStatus in RequestLogger middleware 2026-02-12 18:49:39 +02:00
toim 717034fc7a Add ResolveResponseStatus function to help middleware/handlers determine HTTP status code and echo.Response 2026-02-12 18:14:20 +02:00
Martti T. 00991f2969 Add new function "echo.StatusCode" to resolve status code from errors implementing HTTPStatusCoder interface
Add new function "echo.StatusCode" to resolve status code from errors implementing HTTPStatusCoder interface
2026-02-12 17:32:44 +02:00
keitosuwahara 4dd9f46413 rename and moved to HttpStatusCoder below 2026-02-13 00:18:50 +09:00
keitosuwahara 9e37c93010 removed Is method and improved StatusCode method 2026-02-12 22:29:13 +09:00
Martti T. 2c377f1e6f add Go 1.26 to CI flow + update security.md contents
add Go 1.26 to CI flow
2026-02-12 14:22:45 +02:00
toim 817d037a0f Update security version table 2026-02-12 14:18:23 +02:00
toim 909581fd92 Add Go 1.26 (https://go.dev/doc/go1.16) to CI 2026-02-12 14:18:02 +02:00
Marcin Romaszewicz 215808e09f Update location of oapi-codegen in README 2026-02-12 09:55:57 +02:00
toim fa0078cfd6 Graceful shutdown: http.Serve needs to wait for graceful shutdown goroutine to finish. Fixes #2897 2026-02-12 09:15:25 +02:00
keitosuwahara a16859ca8f add/Is_method 2026-02-09 19:46:10 +09:00
Martti T. ea6bb41f76 Merge pull request #2889 from kumapower17/patch-1
Remove unused import 'errors' from README example
2026-02-09 11:26:03 +02:00
Martti T. b1d443086e Merge pull request #2891 from aldas/fix_staticmw
Fix directory traversal vulnerability under Windows in Static middleware when default Echo filesystem is used. Reported by @shblue21.

This applies to cases when:
- Windows is used as OS
- `middleware.StaticConfig.Filesystem` is `nil` (default)
- `echo.Filesystem` is has not been set explicitly (default)

Exposure is restricted to the active process working directory and its subfolders.
v5.0.3
2026-02-06 15:23:31 +02:00
toim 48f25a6c16 Fix test reporting different size due Windows / Linux line ending inconsistencies 2026-02-06 15:21:00 +02:00