Skip to content

Commit 708e86b

Browse files
luk3skyw4lkerReneWerner87tokelo-12sixcolorsdependabot[bot]
authored
♻️ refactor: Migrate HealthChecker to v3 (#2884)
* Update pull_request_template.md * Update v3-changes.md * Update CONTRIBUTING.md (#2752) Grammar correction. * chore(encryptcookie)!: update default config (#2753) * chore(encryptcookie)!: update default config docs(encryptcookie): enhance documentation and examples BREAKING CHANGE: removed the hardcoded "csrf_" from the Except. * docs(encryptcookie): reads or modifies cookies * chore(encryptcookie): csrf config example * docs(encryptcookie): md table spacing * build(deps): bump actions/setup-go from 4 to 5 (#2754) Bumps [actions/setup-go](https://github.com/actions/setup-go) from 4 to 5. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](actions/setup-go@v4...v5) --- updated-dependencies: - dependency-name: actions/setup-go dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * 🩹 middleware/logger/: log client IP address by default (#2755) * middleware/logger: Log client IP address by default. * Update doc. * fix: don't constrain middlewares' context-keys to strings 🐛 (#2751) * Revert "Revert ":bug: requestid.Config.ContextKey is interface{} (#2369)" (#2742)" This reverts commit 28be17f. * fix: request ContextKey default value condition Should check for `nil` since it is `any`. * fix: don't constrain middlewares' context-keys to strings `context` recommends using "unexported type" as context keys to avoid collisions https://pkg.go.dev/github.com/gofiber/fiber/v2#Ctx.Locals. The official go blog also recommends this https://go.dev/blog/context. `fiber.Ctx.Locals(key any, value any)` correctly allows consumers to use unexported types or e.g. strings. But some fiber middlewares constrain their context-keys to `string` in their "default config structs", making it impossible to use unexported types. This PR removes the `string` _constraint_ from all middlewares, allowing to now use unexported types as per the official guidelines. However the default value is still a string, so it's not a breaking change, and anyone still using strings as context keys is not affected. * 📚 Update app.md for indentation (#2761) Update app.md for indentation * build(deps): bump github.com/google/uuid from 1.4.0 to 1.5.0 (#2762) Bumps [github.com/google/uuid](https://github.com/google/uuid) from 1.4.0 to 1.5.0. - [Release notes](https://github.com/google/uuid/releases) - [Changelog](https://github.com/google/uuid/blob/master/CHANGELOG.md) - [Commits](google/uuid@v1.4.0...v1.5.0) --- updated-dependencies: - dependency-name: github.com/google/uuid dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump github/codeql-action from 2 to 3 (#2763) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2 to 3. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](github/codeql-action@v2...v3) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Changing default log output (#2730) changing default log output Closes #2729 * Update hooks.md fix wrong hooks signature * 🩹 Fix: CORS middleware should use the defined AllowedOriginsFunc config when AllowedOrigins is empty (#2771) * 🐛 [Bug]: Adaptator + otelfiber issue #2641 (#2772) * 🩹🚨 - fix for redirect with query params (#2748) * redirect with query params did not work, fix it and add test for it * redirect middleware - fix test typo * ♻️ logger/middleware colorize logger error message #2593 (#2773) * ✨ feat: add liveness and readiness checks (#2509) * ✨ feat: add liveness and readiness checkers * 📝 docs: add docs for liveness and readiness * ✨ feat: add options method for probe checkers * ✅ tests: add tests for liveness and readiness * ♻️ refactor: change default endpoint values * ♻️ refactor: change default value for liveness endpoint * 📝 docs: add return status for liveness and readiness probes * ♻️ refactor: change probechecker to middleware * 📝 docs: move docs to middleware session * ♻️ refactor: apply gofumpt formatting * ♻️ refactor: remove unused parameter * split config and apply a review * apply reviews and add testcases * add benchmark * cleanup * rename middleware * fix linter * Update docs and config values * Revert change to IsReady * Updates based on code review * Update docs to match other middlewares --------- Co-authored-by: Muhammed Efe Cetin <[email protected]> Co-authored-by: Juan Calderon-Perez <[email protected]> Co-authored-by: Juan Calderon-Perez <[email protected]> * prepare release v2.52.0 - add more Parser tests * fix healthcheck.md * configure workflows for V2 branch * configure workflows for V2 branch * Fix default value to false in docs of QueryBool (#2811) fix default value to false in docs of QueryBool * update queryParser config * Update ctx.md * Update routing.md * merge v2 in v3 * merge v2 in v3 * lint fixes * 📚 Doc: Fix code snippet indentation in /docs/api/middleware/keyauth.md Removes an an extra level of indentation in line 51 of `keyauth.md` [here](https://github.com/gofiber/fiber/blob/v2/docs/api/middleware/keyauth.md?plain=1#L51) * fix: healthcheck middleware not working with route group (#2863) * fix: healthcheck middleware not working with route group * perf: change verification method to improve perf * Update healthcheck_test.go * test: add not matching route test for strict routing * add more test cases * correct tests * correct test helpers * correct tests * correct tests --------- Co-authored-by: Juan Calderon-Perez <[email protected]> Co-authored-by: René Werner <[email protected]> * merge v2 in v3 * Merge pull request from GHSA-fmg4-x8pw-hjhg * Enforce Wildcard Origins with AllowCredentials check * Expand unit-tests, fix issues with subdomains logic, update docs * Update cors.md * Added test using localhost, ipv4, and ipv6 address * improve documentation markdown --------- Co-authored-by: René Werner <[email protected]> * Update app.go prepare release v2.52.1 * fix cors domain normalize * fix sync-docs workflow * test: fix failing tests * fix sync-docs workflow * test: cors middleware use testify require * chore: fix lint warnings * chore: revert test isolation. * feat: migrate healthchecker to v3 * fix: use Get instead of Use for better router matching * docs: update docs to v3 info * fixed the fasthttp ctx race condition problem * Update middleware/cors/utils.go Co-authored-by: Renan Bastos <[email protected]> * fix sync_docs.sh * fix review comments/hints * fix review comments/hints * stabilize Test_Proxy_Timeout_Slow_Server test * stabilize Test_Proxy_.* tests * ignore bodyclose linter for tests use http.NoBody instead of nil * Add parallel benchmark * Update healthcheck_test.go * docs: add comments for next behavior when there are no other handlers defined * revert(tests): undo http.NoBody usage --------- Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: RW <[email protected]> Co-authored-by: tokelo-12 <[email protected]> Co-authored-by: Jason McNeil <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: iRedMail <[email protected]> Co-authored-by: Benjamin Grosse <[email protected]> Co-authored-by: Mehmet Firat KOMURCU <[email protected]> Co-authored-by: Bruno <[email protected]> Co-authored-by: Muhammad Kholid B <[email protected]> Co-authored-by: gilwo <[email protected]> Co-authored-by: Muhammed Efe Cetin <[email protected]> Co-authored-by: Juan Calderon-Perez <[email protected]> Co-authored-by: Juan Calderon-Perez <[email protected]> Co-authored-by: Jongmin Kim <[email protected]> Co-authored-by: Giovanni Rivera <[email protected]> Co-authored-by: Renan Bastos <[email protected]>
1 parent ec48a76 commit 708e86b

File tree

4 files changed

+97
-200
lines changed

4 files changed

+97
-200
lines changed

docs/api/middleware/healthcheck.md

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -39,27 +39,49 @@ import (
3939
After you initiate your [Fiber](https://github.com/gofiber/fiber) app, you can use the following possibilities:
4040

4141
```go
42-
// Provide a minimal config
43-
app.Use(healthcheck.New())
42+
// Provide a minimal config for liveness check
43+
app.Get(healthcheck.DefaultLivenessEndpoint, healthcheck.New())
44+
// Provide a minimal config for readiness check
45+
app.Get(healthcheck.DefaultReadinessEndpoint, healthcheck.New())
46+
// Provide a minimal config for check with custom endpoint
47+
app.Get("/live", healthcheck.New())
4448

4549
// Or extend your config for customization
46-
app.Use(healthcheck.New(healthcheck.Config{
47-
LivenessProbe: func(c fiber.Ctx) bool {
50+
app.Get(healthcheck.DefaultLivenessEndpoint, healthcheck.New(healthcheck.Config{
51+
Probe: func(c fiber.Ctx) bool {
4852
return true
4953
},
50-
LivenessEndpoint: "/live",
51-
ReadinessProbe: func(c fiber.Ctx) bool {
52-
return serviceA.Ready() && serviceB.Ready() && ...
54+
}))
55+
// And it works the same for readiness, just change the route
56+
app.Get(healthcheck.DefaultReadinessEndpoint, healthcheck.New(healthcheck.Config{
57+
Probe: func(c fiber.Ctx) bool {
58+
return true
59+
},
60+
}))
61+
// With a custom route and custom probe
62+
app.Get("/live", healthcheck.New(healthcheck.Config{
63+
Probe: func(c fiber.Ctx) bool {
64+
return true
65+
},
66+
}))
67+
68+
// It can also be used with app.All, although it will only respond to requests with the GET method
69+
// in case of calling the route with any method which isn't GET, the return will be 404 Not Found when app.All is used
70+
// and 405 Method Not Allowed when app.Get is used
71+
app.All(healthcheck.DefaultReadinessEndpoint, healthcheck.New(healthcheck.Config{
72+
Probe: func(c fiber.Ctx) bool {
73+
return true
5374
},
54-
ReadinessEndpoint: "/ready",
5575
}))
5676
```
5777

5878
## Config
5979

6080
```go
6181
type Config struct {
62-
// Next defines a function to skip this middleware when returned true.
82+
// Next defines a function to skip this middleware when returned true. If this function returns true
83+
// and no other handlers are defined for the route, Fiber will return a status 404 Not Found, since
84+
// no other handlers were defined to return a different status.
6385
//
6486
// Optional. Default: nil
6587
Next func(fiber.Ctx) bool
@@ -69,38 +91,17 @@ type Config struct {
6991
// the application is in a state where it can handle requests (e.g., the server is up and running).
7092
//
7193
// Optional. Default: func(c fiber.Ctx) bool { return true }
72-
LivenessProbe HealthChecker
73-
74-
// HTTP endpoint at which the liveness probe will be available.
75-
//
76-
// Optional. Default: "/livez"
77-
LivenessEndpoint string
78-
79-
// Function used for checking the readiness of the application. Returns true if the application
80-
// is ready to process requests and false otherwise. The readiness probe typically checks if all necessary
81-
// services, databases, and other dependencies are available for the application to function correctly.
82-
//
83-
// Optional. Default: func(c fiber.Ctx) bool { return true }
84-
ReadinessProbe HealthChecker
85-
86-
// HTTP endpoint at which the readiness probe will be available.
87-
// Optional. Default: "/readyz"
88-
ReadinessEndpoint string
94+
Probe HealthChecker
8995
}
9096
```
9197

9298
## Default Config
9399

94100
The default configuration used by this middleware is defined as follows:
95101
```go
96-
func defaultLivenessProbe(fiber.Ctx) bool { return true }
97-
98-
func defaultReadinessProbe(fiber.Ctx) bool { return true }
102+
func defaultProbe(fiber.Ctx) bool { return true }
99103

100104
var ConfigDefault = Config{
101-
LivenessProbe: defaultLivenessProbe,
102-
ReadinessProbe: defaultReadinessProbe,
103-
LivenessEndpoint: "/livez",
104-
ReadinessEndpoint: "/readyz",
105+
Probe: defaultProbe,
105106
}
106107
```

middleware/healthcheck/config.go

Lines changed: 11 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import (
66

77
// Config defines the configuration options for the healthcheck middleware.
88
type Config struct {
9-
// Next defines a function to skip this middleware when returned true.
9+
// Next defines a function to skip this middleware when returned true. If this function returns true
10+
// and no other handlers are defined for the route, Fiber will return a status 404 Not Found, since
11+
// no other handlers were defined to return a different status.
1012
//
1113
// Optional. Default: nil
1214
Next func(fiber.Ctx) bool
@@ -16,68 +18,27 @@ type Config struct {
1618
// the application is in a state where it can handle requests (e.g., the server is up and running).
1719
//
1820
// Optional. Default: func(c fiber.Ctx) bool { return true }
19-
LivenessProbe HealthChecker
20-
21-
// HTTP endpoint at which the liveness probe will be available.
22-
//
23-
// Optional. Default: "/livez"
24-
LivenessEndpoint string
25-
26-
// Function used for checking the readiness of the application. Returns true if the application
27-
// is ready to process requests and false otherwise. The readiness probe typically checks if all necessary
28-
// services, databases, and other dependencies are available for the application to function correctly.
29-
//
30-
// Optional. Default: func(c fiber.Ctx) bool { return true }
31-
ReadinessProbe HealthChecker
32-
33-
// HTTP endpoint at which the readiness probe will be available.
34-
// Optional. Default: "/readyz"
35-
ReadinessEndpoint string
21+
Probe HealthChecker
3622
}
3723

3824
const (
3925
DefaultLivenessEndpoint = "/livez"
4026
DefaultReadinessEndpoint = "/readyz"
4127
)
4228

43-
func defaultLivenessProbe(fiber.Ctx) bool { return true }
44-
45-
func defaultReadinessProbe(fiber.Ctx) bool { return true }
46-
47-
// ConfigDefault is the default config
48-
var ConfigDefault = Config{
49-
LivenessProbe: defaultLivenessProbe,
50-
ReadinessProbe: defaultReadinessProbe,
51-
LivenessEndpoint: DefaultLivenessEndpoint,
52-
ReadinessEndpoint: DefaultReadinessEndpoint,
53-
}
29+
func defaultProbe(fiber.Ctx) bool { return true }
5430

55-
// defaultConfig returns a default config for the healthcheck middleware.
56-
func defaultConfig(config ...Config) Config {
31+
func defaultConfigV3(config ...Config) Config {
5732
if len(config) < 1 {
58-
return ConfigDefault
33+
return Config{
34+
Probe: defaultProbe,
35+
}
5936
}
6037

6138
cfg := config[0]
6239

63-
if cfg.Next == nil {
64-
cfg.Next = ConfigDefault.Next
65-
}
66-
67-
if cfg.LivenessProbe == nil {
68-
cfg.LivenessProbe = defaultLivenessProbe
69-
}
70-
71-
if cfg.ReadinessProbe == nil {
72-
cfg.ReadinessProbe = defaultReadinessProbe
73-
}
74-
75-
if cfg.LivenessEndpoint == "" {
76-
cfg.LivenessEndpoint = DefaultLivenessEndpoint
77-
}
78-
79-
if cfg.ReadinessEndpoint == "" {
80-
cfg.ReadinessEndpoint = DefaultReadinessEndpoint
40+
if cfg.Probe == nil {
41+
cfg.Probe = defaultProbe
8142
}
8243

8344
return cfg

middleware/healthcheck/healthcheck.go

Lines changed: 5 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,14 @@
11
package healthcheck
22

33
import (
4-
"strings"
5-
64
"github.com/gofiber/fiber/v3"
75
)
86

97
// HealthChecker defines a function to check liveness or readiness of the application
108
type HealthChecker func(fiber.Ctx) bool
119

12-
// HealthCheckerHandler defines a function that returns a HealthChecker
13-
type HealthCheckerHandler func(HealthChecker) fiber.Handler
14-
15-
func healthCheckerHandler(checker HealthChecker) fiber.Handler {
16-
return func(c fiber.Ctx) error {
17-
if checker == nil {
18-
return c.Next()
19-
}
20-
21-
if checker(c) {
22-
return c.SendStatus(fiber.StatusOK)
23-
}
24-
25-
return c.SendStatus(fiber.StatusServiceUnavailable)
26-
}
27-
}
28-
29-
func New(config ...Config) fiber.Handler {
30-
cfg := defaultConfig(config...)
31-
32-
isLiveHandler := healthCheckerHandler(cfg.LivenessProbe)
33-
isReadyHandler := healthCheckerHandler(cfg.ReadinessProbe)
10+
func NewHealthChecker(config ...Config) fiber.Handler {
11+
cfg := defaultConfigV3(config...)
3412

3513
return func(c fiber.Ctx) error {
3614
// Don't execute middleware if Next returns true
@@ -42,21 +20,10 @@ func New(config ...Config) fiber.Handler {
4220
return c.Next()
4321
}
4422

45-
prefixCount := len(strings.TrimRight(c.Route().Path, "/"))
46-
if len(c.Path()) >= prefixCount {
47-
checkPath := c.Path()[prefixCount:]
48-
checkPathTrimmed := checkPath
49-
if !c.App().Config().StrictRouting {
50-
checkPathTrimmed = strings.TrimRight(checkPath, "/")
51-
}
52-
switch {
53-
case checkPath == cfg.ReadinessEndpoint || checkPathTrimmed == cfg.ReadinessEndpoint:
54-
return isReadyHandler(c)
55-
case checkPath == cfg.LivenessEndpoint || checkPathTrimmed == cfg.LivenessEndpoint:
56-
return isLiveHandler(c)
57-
}
23+
if cfg.Probe(c) {
24+
return c.SendStatus(fiber.StatusOK)
5825
}
5926

60-
return c.Next()
27+
return c.SendStatus(fiber.StatusServiceUnavailable)
6128
}
6229
}

0 commit comments

Comments
 (0)