Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin' into v3-params
Browse files Browse the repository at this point in the history
  • Loading branch information
dozheiny committed Feb 11, 2024
2 parents bcfe218 + 92dd8d6 commit 986886a
Show file tree
Hide file tree
Showing 24 changed files with 270 additions and 124 deletions.
7 changes: 7 additions & 0 deletions .github/workflows/linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,14 @@ on:
- master
- main
pull_request:

permissions:
# Required: allow read access to the content for analysis.
contents: read
# Optional: allow read access to pull request. Use with `only-new-issues` option.
pull-requests: read
# Optional: Allow write access to checks to allow the action to annotate code in the PR.
checks: write

jobs:
golangci:
Expand All @@ -21,6 +27,7 @@ jobs:
with:
# NOTE: Keep this in sync with the version from go.mod
go-version: "1.20.x"
cache: false

- name: golangci-lint
uses: golangci/golangci-lint-action@v3
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
Build:
strategy:
matrix:
go-version: [1.20.x, 1.21.x]
go-version: [1.20.x, 1.21.x, 1.22.x]
platform: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.platform }}
steps:
Expand Down
14 changes: 10 additions & 4 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ linters-settings:
check-type-assertions: true
check-blank: true
disable-default-exclusions: true
exclude-functions:
- '(*bytes.Buffer).Write' # always returns nil error
- '(*github.com/valyala/bytebufferpool.ByteBuffer).Write' # always returns nil error
- '(*github.com/valyala/bytebufferpool.ByteBuffer).WriteByte' # always returns nil error
- '(*github.com/valyala/bytebufferpool.ByteBuffer).WriteString' # always returns nil error

errchkjson:
report-no-exported: true
Expand All @@ -40,7 +45,7 @@ linters-settings:

gosec:
excludes:
- G104
- G104 # Provided by errcheck
config:
global:
audit: true
Expand Down Expand Up @@ -104,8 +109,6 @@ linters-settings:
disabled: true
- name: exported
disabled: true
arguments:
- disableStutteringCheck # TODO https://github.com/gofiber/fiber/issues/2816
- name: file-header
disabled: true
- name: function-result-limit
Expand All @@ -124,6 +127,9 @@ linters-settings:
disabled: true
- name: unchecked-type-assertion
disabled: true # TODO https://github.com/gofiber/fiber/issues/2816
# Provided by errcheck
- name: unhandled-error
disabled: true

stylecheck:
checks:
Expand Down Expand Up @@ -185,7 +191,7 @@ linters:
# - gosmopolitan # TODO https://github.com/gofiber/fiber/issues/2816
- govet
- grouper
# - inamedparam # TODO https://github.com/gofiber/fiber/issues/2816
- inamedparam
- loggercheck
# - mirror # TODO https://github.com/gofiber/fiber/issues/2816
- misspell
Expand Down
4 changes: 2 additions & 2 deletions bind.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import (
type CustomBinder interface {
Name() string
MIMETypes() []string
Parse(Ctx, any) error
Parse(c Ctx, out any) error
}

// An interface to register custom struct validator for binding.
type StructValidator interface {
Engine() any
ValidateStruct(any) error
ValidateStruct(out any) error
}

// Bind struct
Expand Down
51 changes: 38 additions & 13 deletions ctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ type Cookie struct {
// Views is the interface that wraps the Render function.
type Views interface {
Load() error
Render(io.Writer, string, any, ...string) error
Render(out io.Writer, name string, binding any, layout ...string) error
}

// ResFmt associates a Content Type to a fiber.Handler for c.Format
Expand Down Expand Up @@ -829,11 +829,11 @@ func (c *DefaultCtx) Links(link ...string) {
bb := bytebufferpool.Get()
for i := range link {
if i%2 == 0 {
_ = bb.WriteByte('<') //nolint:errcheck // This will never fail
_, _ = bb.WriteString(link[i]) //nolint:errcheck // This will never fail
_ = bb.WriteByte('>') //nolint:errcheck // This will never fail
bb.WriteByte('<')
bb.WriteString(link[i])
bb.WriteByte('>')
} else {
_, _ = bb.WriteString(`; rel="` + link[i] + `",`) //nolint:errcheck // This will never fail
bb.WriteString(`; rel="` + link[i] + `",`)
}
}
c.setCanonical(HeaderLink, strings.TrimRight(c.app.getString(bb.Bytes()), ","))
Expand Down Expand Up @@ -1588,14 +1588,39 @@ func (c *DefaultCtx) Status(status int) Ctx {
//
// The returned value may be useful for logging.
func (c *DefaultCtx) String() string {
return fmt.Sprintf(
"#%016X - %s <-> %s - %s %s",
c.fasthttp.ID(),
c.fasthttp.LocalAddr(),
c.fasthttp.RemoteAddr(),
c.fasthttp.Request.Header.Method(),
c.fasthttp.URI().FullURI(),
)
// Get buffer from pool
buf := bytebufferpool.Get()

// Start with the ID, converting it to a hex string without fmt.Sprintf
buf.WriteByte('#')
// Convert ID to hexadecimal
id := strconv.FormatUint(c.fasthttp.ID(), 16)
// Pad with leading zeros to ensure 16 characters
for i := 0; i < (16 - len(id)); i++ {
buf.WriteByte('0')
}
buf.WriteString(id)
buf.WriteString(" - ")

// Add local and remote addresses directly
buf.WriteString(c.fasthttp.LocalAddr().String())
buf.WriteString(" <-> ")
buf.WriteString(c.fasthttp.RemoteAddr().String())
buf.WriteString(" - ")

// Add method and URI
buf.Write(c.fasthttp.Request.Header.Method())
buf.WriteByte(' ')
buf.Write(c.fasthttp.URI().FullURI())

// Allocate string
str := buf.String()

// Reset buffer
buf.Reset()
bytebufferpool.Put(buf)

return str
}

// Type sets the Content-Type HTTP header to the MIME type specified by the file extension.
Expand Down
18 changes: 16 additions & 2 deletions ctx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3883,7 +3883,7 @@ func Test_Ctx_RenderWithBindVars(t *testing.T) {
err = c.Render("./.github/testdata/index.tmpl", Map{})
require.NoError(t, err)
buf := bytebufferpool.Get()
_, _ = buf.WriteString("overwrite") //nolint:errcheck // This will never fail
buf.WriteString("overwrite")
defer bytebufferpool.Put(buf)

require.NoError(t, err)
Expand All @@ -3906,7 +3906,7 @@ func Test_Ctx_RenderWithOverwrittenBind(t *testing.T) {
require.NoError(t, err)

buf := bytebufferpool.Get()
_, _ = buf.WriteString("overwrite") //nolint:errcheck // This will never fail
buf.WriteString("overwrite")
defer bytebufferpool.Put(buf)

require.Equal(t, "<h1>Hello from Fiber!</h1>", string(c.Response().Body()))
Expand Down Expand Up @@ -4751,6 +4751,20 @@ func Test_Ctx_String(t *testing.T) {
require.Equal(t, "#0000000000000000 - 0.0.0.0:0 <-> 0.0.0.0:0 - GET http:///", c.String())
}

// go test -v -run=^$ -bench=Benchmark_Ctx_String -benchmem -count=4
func Benchmark_Ctx_String(b *testing.B) {
var str string
app := New()
ctx := app.NewCtx(&fasthttp.RequestCtx{})
b.ReportAllocs()
b.ResetTimer()

for n := 0; n < b.N; n++ {
str = ctx.String()
}
require.Equal(b, "#0000000000000000 - 0.0.0.0:0 <-> 0.0.0.0:0 - GET http:///", str)
}

func TestCtx_ParamsInt(t *testing.T) {
// Create a test context and set some strings (or params)
// create a fake app to be used within this test
Expand Down
8 changes: 3 additions & 5 deletions docs/api/middleware/csrf.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ By default, the middleware generates and stores tokens using the `fiber.Storage`
When the authorization status changes, the previously issued token MUST be deleted, and a new one generated. See [Token Lifecycle](#token-lifecycle) [Deleting Tokens](#deleting-tokens) for more information.

:::caution
When using this pattern, it's important to set the `CookieSameSite` option to `Lax` or `Strict` and ensure that the Extractor is not `CsrfFromCookie`, and KeyLookup is not `cookie:<name>`.
When using this pattern, it's important to set the `CookieSameSite` option to `Lax` or `Strict` and ensure that the Extractor is not `FromCookie`, and KeyLookup is not `cookie:<name>`.
:::

:::note
Expand Down Expand Up @@ -146,8 +146,6 @@ KeyLookup will be ignored if Extractor is explicitly set.

Getting the CSRF token in a handler:

```go

```go
func handler(c fiber.Ctx) error {
handler := csrf.HandlerFromContext(c)
Expand Down Expand Up @@ -206,7 +204,7 @@ var ConfigDefault = Config{
Expiration: 1 * time.Hour,
KeyGenerator: utils.UUIDv4,
ErrorHandler: defaultErrorHandler,
Extractor: CsrfFromHeader(HeaderName),
Extractor: FromHeader(HeaderName),
SessionKey: "csrfToken",
}
```
Expand All @@ -226,7 +224,7 @@ var ConfigDefault = Config{
Expiration: 1 * time.Hour,
KeyGenerator: utils.UUIDv4,
ErrorHandler: defaultErrorHandler,
Extractor: CsrfFromHeader(HeaderName),
Extractor: FromHeader(HeaderName),
Session: session.Store,
SessionKey: "csrfToken",
}
Expand Down
4 changes: 4 additions & 0 deletions docs/api/middleware/logger.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ app.Use(logger.New(logger.Config{
}))
```

:::tip
Writing to os.File is goroutine-safe, but if you are using a custom Output that is not goroutine-safe, make sure to implement locking to properly serialize writes.
:::

## Config

### Config
Expand Down
2 changes: 1 addition & 1 deletion docs/guide/routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ We have adapted the routing strongly to the express routing, but currently witho
Route constraints execute when a match has occurred to the incoming URL and the URL path is tokenized into route values by parameters. The feature was intorduced in `v2.37.0` and inspired by [.NET Core](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/routing?view=aspnetcore-6.0#route-constraints).

:::caution
Constraints aren't validation for parameters. If constraint aren't valid for parameter value, Fiber returns **404 handler**.
Constraints aren't validation for parameters. If constraints aren't valid for a parameter value, Fiber returns **404 handler**.
:::

| Constraint | Example | Example matches |
Expand Down
23 changes: 13 additions & 10 deletions listen.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ var figletFiberText = `
/ ____(_) /_ ___ _____
/ /_ / / __ \/ _ \/ ___/
/ __/ / / /_/ / __/ /
/_/ /_/_.___/\___/_/ %s`
/_/ /_/_.___/\___/_/ %s`

const (
globalIpv4Addr = "0.0.0.0"
Expand Down Expand Up @@ -354,27 +354,27 @@ func (app *App) startupMessage(addr string, isTLS bool, pids string, cfg ListenC

if host == "0.0.0.0" {
_, _ = fmt.Fprintf(out,
"%sINFO%s Server started on %s%s://127.0.0.1:%s%s (bound on host 0.0.0.0 and port %s)\n",
"%sINFO%s Server started on: \t%s%s://127.0.0.1:%s%s (bound on host 0.0.0.0 and port %s)\n",
colors.Green, colors.Reset, colors.Blue, scheme, port, colors.Reset, port)
} else {
_, _ = fmt.Fprintf(out,
"%sINFO%s Server started on %s%s%s\n",
"%sINFO%s Server started on: \t%s%s%s\n",
colors.Green, colors.Reset, colors.Blue, fmt.Sprintf("%s://%s:%s", scheme, host, port), colors.Reset)
}

if app.config.AppName != "" {
_, _ = fmt.Fprintf(out, "%sINFO%s Application name: %s%s%s\n", colors.Green, colors.Reset, colors.Blue, app.config.AppName, colors.Reset)
_, _ = fmt.Fprintf(out, "%sINFO%s Application name: \t\t%s%s%s\n", colors.Green, colors.Reset, colors.Blue, app.config.AppName, colors.Reset)
}
_, _ = fmt.Fprintf(out,
"%sINFO%s Total handlers count: %s%s%s\n",
"%sINFO%s Total handlers count: \t%s%s%s\n",
colors.Green, colors.Reset, colors.Blue, strconv.Itoa(int(app.handlersCount)), colors.Reset)
if isPrefork == "Enabled" {
_, _ = fmt.Fprintf(out, "%sINFO%s Prefork: %s%s%s\n", colors.Green, colors.Reset, colors.Blue, isPrefork, colors.Reset)
_, _ = fmt.Fprintf(out, "%sINFO%s Prefork: \t\t\t%s%s%s\n", colors.Green, colors.Reset, colors.Blue, isPrefork, colors.Reset)
} else {
_, _ = fmt.Fprintf(out, "%sINFO%s Prefork: %s%s%s\n", colors.Green, colors.Reset, colors.Red, isPrefork, colors.Reset)
_, _ = fmt.Fprintf(out, "%sINFO%s Prefork: \t\t\t%s%s%s\n", colors.Green, colors.Reset, colors.Red, isPrefork, colors.Reset)
}
_, _ = fmt.Fprintf(out, "%sINFO%s PID: %s%v%s\n", colors.Green, colors.Reset, colors.Blue, os.Getpid(), colors.Reset)
_, _ = fmt.Fprintf(out, "%sINFO%s Total process count: %s%s%s\n", colors.Green, colors.Reset, colors.Blue, procs, colors.Reset)
_, _ = fmt.Fprintf(out, "%sINFO%s PID: \t\t\t%s%v%s\n", colors.Green, colors.Reset, colors.Blue, os.Getpid(), colors.Reset)
_, _ = fmt.Fprintf(out, "%sINFO%s Total process count: \t%s%s%s\n", colors.Green, colors.Reset, colors.Blue, procs, colors.Reset)

if cfg.EnablePrefork {
// Turn the `pids` variable (in the form ",a,b,c,d,e,f,etc") into a slice of PIDs
Expand All @@ -385,7 +385,7 @@ func (app *App) startupMessage(addr string, isTLS bool, pids string, cfg ListenC
}
}

_, _ = fmt.Fprintf(out, "%sINFO%s Child PIDs: %s", colors.Green, colors.Reset, colors.Blue)
_, _ = fmt.Fprintf(out, "%sINFO%s Child PIDs: \t\t%s", colors.Green, colors.Reset, colors.Blue)
totalPids := len(pidSlice)
rowTotalPidCount := 10
for i := 0; i < totalPids; i += rowTotalPidCount {
Expand All @@ -403,6 +403,9 @@ func (app *App) startupMessage(addr string, isTLS bool, pids string, cfg ListenC
_, _ = fmt.Fprintf(out, "\n%s", colors.Reset)
}
}

// add new Line as spacer
_, _ = fmt.Fprintf(out, "\n%s", colors.Reset)
}

// printRoutesMessage print all routes with method, path, name and handlers
Expand Down
4 changes: 2 additions & 2 deletions listen_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ func Test_Listen_Master_Process_Show_Startup_Message(t *testing.T) {
require.Contains(t, startupMessage, "(bound on host 0.0.0.0 and port 3000)")
require.Contains(t, startupMessage, "Child PIDs")
require.Contains(t, startupMessage, "11111, 22222, 33333, 44444, 55555, 60000")
require.Contains(t, startupMessage, fmt.Sprintf("Prefork: %sEnabled%s", colors.Blue, colors.Reset))
require.Contains(t, startupMessage, fmt.Sprintf("Prefork: \t\t\t%sEnabled%s", colors.Blue, colors.Reset))
}

// go test -run Test_Listen_Master_Process_Show_Startup_MessageWithAppName
Expand Down Expand Up @@ -402,7 +402,7 @@ func Test_Listen_Master_Process_Show_Startup_MessageWithDisabledPreforkAndCustom
require.Contains(t, startupMessage, fmt.Sprintf("%sINFO%s", colors.Green, colors.Reset))
require.Contains(t, startupMessage, fmt.Sprintf("%s%s%s", colors.Blue, appName, colors.Reset))
require.Contains(t, startupMessage, fmt.Sprintf("%s%s%s", colors.Blue, "https://server.com:8081", colors.Reset))
require.Contains(t, startupMessage, fmt.Sprintf("Prefork: %sDisabled%s", colors.Red, colors.Reset))
require.Contains(t, startupMessage, fmt.Sprintf("Prefork: \t\t\t%sDisabled%s", colors.Red, colors.Reset))
}

// go test -run Test_Listen_Print_Route
Expand Down
Loading

0 comments on commit 986886a

Please sign in to comment.