Skip to content

Commit

Permalink
Merge branch 'main' into istrusted-proxy
Browse files Browse the repository at this point in the history
  • Loading branch information
sixcolors committed Apr 22, 2024
2 parents e4413d2 + 4d1e993 commit 458aaba
Show file tree
Hide file tree
Showing 19 changed files with 463 additions and 397 deletions.
2 changes: 1 addition & 1 deletion .github/release-drafter.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name-template: 'v$RESOLVED_VERSION'
tag-template: 'v$RESOLVED_VERSION'
commitish: refs/heads/main
commitish: main
filter-by-commitish: true
include-labels:
- 'v3'
Expand Down
32 changes: 32 additions & 0 deletions .github/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# .github/release.yml

changelog:
exclude:
labels:
- v2
authors:
- dependabot
- dependabot[bot]
categories:
- title: '❗ Breaking Changes'
labels:
- '❗ BreakingChange'
- title: '🚀 New Features'
labels:
- '✏️ Feature'
- '📝 Proposal'
- title: '🧹 Updates'
labels:
- '🧹 Updates'
- title: '🐛 Bug Fixes'
labels:
- '☢️ Bug'
- title: '🛠️ Maintenance'
labels:
- '🤖 Dependencies'
- title: '📚 Documentation'
labels:
- '📒 Documentation'
- title: 'Other Changes'
labels:
- '*'
2 changes: 1 addition & 1 deletion .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
key: ${{ runner.os }}-benchmark

- name: Save Benchmark Results
uses: benchmark-action/github-action-benchmark@v1.19.3
uses: benchmark-action/github-action-benchmark@v1.20.1
with:
tool: "go"
output-file-path: output.txt
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:

- name: Upload coverage reports to Codecov
if: ${{ matrix.platform == 'ubuntu-latest' && matrix.go-version == '1.22.x' }}
uses: codecov/codecov-action@v4.1.0
uses: codecov/codecov-action@v4.3.0
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: ./coverage.txt
Expand Down
2 changes: 1 addition & 1 deletion app.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import (
)

// Version of current fiber package
const Version = "3.0.0-beta.1"
const Version = "3.0.0-beta.2"

// Handler defines a function to serve HTTP requests.
type Handler = func(Ctx) error
Expand Down
62 changes: 52 additions & 10 deletions app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1408,16 +1408,6 @@ func Test_App_Next_Method(t *testing.T) {
require.Equal(t, 404, resp.StatusCode, "Status code")
}

// go test -v -run=^$ -bench=Benchmark_AcquireCtx -benchmem -count=4
func Benchmark_AcquireCtx(b *testing.B) {
app := New()
for n := 0; n < b.N; n++ {
c := app.AcquireCtx(&fasthttp.RequestCtx{})

app.ReleaseCtx(c)
}
}

// go test -v -run=^$ -bench=Benchmark_NewError -benchmem -count=4
func Benchmark_NewError(b *testing.B) {
for n := 0; n < b.N; n++ {
Expand Down Expand Up @@ -1975,3 +1965,55 @@ func Test_Route_Naming_Issue_2671_2685(t *testing.T) {
sRoute2 := app.GetRoute("simple-route2")
require.Equal(t, "/simple-route", sRoute2.Path)
}

// go test -v -run=^$ -bench=Benchmark_Communication_Flow -benchmem -count=4
func Benchmark_Communication_Flow(b *testing.B) {
app := New()

app.Get("/", func(c Ctx) error {
return c.SendString("Hello, World!")
})

h := app.Handler()

fctx := &fasthttp.RequestCtx{}
fctx.Request.Header.SetMethod(MethodGet)
fctx.Request.SetRequestURI("/")

b.ReportAllocs()
b.ResetTimer()

for n := 0; n < b.N; n++ {
h(fctx)
}

require.Equal(b, 200, fctx.Response.Header.StatusCode())
require.Equal(b, "Hello, World!", string(fctx.Response.Body()))
}

// go test -v -run=^$ -bench=Benchmark_Ctx_AcquireReleaseFlow -benchmem -count=4
func Benchmark_Ctx_AcquireReleaseFlow(b *testing.B) {
app := New()

fctx := &fasthttp.RequestCtx{}

b.Run("withoutRequestCtx", func(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()

for n := 0; n < b.N; n++ {
c, _ := app.AcquireCtx(fctx).(*DefaultCtx) //nolint:errcheck // not needed
app.ReleaseCtx(c)
}
})

b.Run("withRequestCtx", func(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()

for n := 0; n < b.N; n++ {
c, _ := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck // not needed
app.ReleaseCtx(c)
}
})
}
53 changes: 9 additions & 44 deletions ctx_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -375,9 +375,6 @@ type Ctx interface {
// ClientHelloInfo return CHI from context
ClientHelloInfo() *tls.ClientHelloInfo

// SetReq resets fields of context that is relating to request.
setReq(fctx *fasthttp.RequestCtx)

// Release is a method to reset context fields when to use ReleaseCtx()
release()
}
Expand Down Expand Up @@ -407,16 +404,6 @@ func NewDefaultCtx(app *App) *DefaultCtx {
return &DefaultCtx{
// Set app reference
app: app,

// Reset route and handler index
indexRoute: -1,
indexHandler: 0,

// Reset matched flag
matched: false,

// reset base uri
baseURI: "",
}
}

Expand Down Expand Up @@ -452,32 +439,26 @@ func (app *App) ReleaseCtx(c Ctx) {

// Reset is a method to reset context fields by given request when to use server handlers.
func (c *DefaultCtx) Reset(fctx *fasthttp.RequestCtx) {
// Reset route and handler index
c.indexRoute = -1
c.indexHandler = 0
// Reset matched flag
c.matched = false
// Set paths
c.pathOriginal = c.app.getString(fctx.URI().PathOriginal())

// Attach *fasthttp.RequestCtx to ctx
c.setReq(fctx)

// Set method
c.method = c.app.getString(fctx.Request.Header.Method())
c.methodINT = c.app.methodInt(c.method)

// Attach *fasthttp.RequestCtx to ctx
c.fasthttp = fctx
// reset base uri
c.baseURI = ""
// Prettify path
c.configDependentPaths()
}

// Release is a method to reset context fields when to use ReleaseCtx()
func (c *DefaultCtx) release() {
// Reset route and handler index
c.indexRoute = -1
c.indexHandler = 0

// Reset matched flag
c.matched = false

// reset base uri
c.baseURI = ""

c.route = nil
c.fasthttp = nil
c.bind = nil
Expand All @@ -489,22 +470,6 @@ func (c *DefaultCtx) release() {
}
}

// SetReq resets fields of context that is relating to request.
func (c *DefaultCtx) setReq(fctx *fasthttp.RequestCtx) {
// Set paths
c.pathOriginal = c.app.getString(fctx.URI().PathOriginal())

// Attach *fasthttp.RequestCtx to ctx
c.fasthttp = fctx

// Set method
c.method = c.app.getString(fctx.Request.Header.Method())
c.methodINT = c.app.methodInt(c.method)

// Prettify path
c.configDependentPaths()
}

// Methods to use with next stack.
func (c *DefaultCtx) getMethodINT() int {
return c.methodINT
Expand Down
2 changes: 1 addition & 1 deletion docs/api/app.md
Original file line number Diff line number Diff line change
Expand Up @@ -664,4 +664,4 @@ Hooks is a method to return [hooks](../guide/hooks.md) property.

```go title="Signature"
func (app *App) Hooks() *Hooks
```
```
49 changes: 26 additions & 23 deletions docs/api/middleware/cors.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,51 +97,54 @@ The following example is prohibited because it can expose your application to se

```go
app.Use(cors.New(cors.Config{
AllowOrigins: "*",
AllowOrigins: []string{"*"},
AllowCredentials: true,
}))
```

This will result in the following panic:

```
panic: [CORS] 'AllowCredentials' is true, but 'AllowOrigins' cannot be set to `"*"`.
panic: [CORS] Configuration error: When 'AllowCredentials' is set to true, 'AllowOrigins' cannot contain a wildcard origin '*'. Please specify allowed origins explicitly or adjust 'AllowCredentials' setting.
```

## Config

| Property | Type | Description | Default |
|:---------------------|:----------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------|
| AllowCredentials | `bool` | AllowCredentials indicates whether or not the response to the request can be exposed when the credentials flag is true. When used as part of a response to a preflight request, this indicates whether or not the actual request can be made using credentials. Note: If true, AllowOrigins cannot be set to a wildcard (`"*"`) to prevent security vulnerabilities. | `false` |
| AllowHeaders | `string` | AllowHeaders defines a list of request headers that can be used when making the actual request. This is in response to a preflight request. | `""` |
| AllowMethods | `string` | AllowMethods defines a list of methods allowed when accessing the resource. This is used in response to a preflight request. | `"GET,POST,HEAD,PUT,DELETE,PATCH"` |
| AllowOrigins | `string` | AllowOrigins defines a comma-separated list of origins that may access the resource. This supports subdomain matching, so you can use a value like "https://*.example.com" to allow any subdomain of example.com to submit requests. | `"*"` |
| AllowOriginsFunc | `func(origin string) bool` | `AllowOriginsFunc` is a function that dynamically determines whether to allow a request based on its origin. If this function returns `true`, the 'Access-Control-Allow-Origin' response header will be set to the request's 'origin' header. This function is only used if the request's origin doesn't match any origin in `AllowOrigins`. | `nil` |
| AllowPrivateNetwork | `bool` | Indicates whether the `Access-Control-Allow-Private-Network` response header should be set to `true`, allowing requests from private networks. This aligns with modern security practices for web applications interacting with private networks. | `false` |
| ExposeHeaders | `string` | ExposeHeaders defines whitelist headers that clients are allowed to access. | `""` |
| MaxAge | `int` | MaxAge indicates how long (in seconds) the results of a preflight request can be cached. If you pass MaxAge 0, the Access-Control-Max-Age header will not be added and the browser will use 5 seconds by default. To disable caching completely, pass MaxAge value negative. It will set the Access-Control-Max-Age header to 0. | `0` |
| Next | `func(fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` |

| Property | Type | Description | Default |
|:---------------------|:----------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------|
| AllowCredentials | `bool` | AllowCredentials indicates whether or not the response to the request can be exposed when the credentials flag is true. When used as part of a response to a preflight request, this indicates whether or not the actual request can be made using credentials. Note: If true, AllowOrigins cannot be set to a wildcard (`"*"`) to prevent security vulnerabilities. | `false` |
| AllowHeaders | `[]string` | AllowHeaders defines a list of request headers that can be used when making the actual request. This is in response to a preflight request. | `[]` |
| AllowMethods | `[]string` | AllowMethods defines a list of methods allowed when accessing the resource. This is used in response to a preflight request. | `"GET, POST, HEAD, PUT, DELETE, PATCH"` |
| AllowOrigins | `[]string` | AllowOrigins defines a list of origins that may access the resource. This supports subdomain matching, so you can use a value like "https://*.example.com" to allow any subdomain of example.com to submit requests. If the special wildcard `"*"` is present in the list, all origins will be allowed. | `["*"]` |
| AllowOriginsFunc | `func(origin string) bool` | `AllowOriginsFunc` is a function that dynamically determines whether to allow a request based on its origin. If this function returns `true`, the 'Access-Control-Allow-Origin' response header will be set to the request's 'origin' header. This function is only used if the request's origin doesn't match any origin in `AllowOrigins`. | `nil` |
| AllowPrivateNetwork | `bool` | Indicates whether the `Access-Control-Allow-Private-Network` response header should be set to `true`, allowing requests from private networks. This aligns with modern security practices for web applications interacting with private networks. | `false` |
| ExposeHeaders | `string` | ExposeHeaders defines whitelist headers that clients are allowed to access. | `[]` |
| MaxAge | `int` | MaxAge indicates how long (in seconds) the results of a preflight request can be cached. If you pass MaxAge 0, the Access-Control-Max-Age header will not be added and the browser will use 5 seconds by default. To disable caching completely, pass MaxAge value negative. It will set the Access-Control-Max-Age header to 0. | `0` |
| Next | `func(fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` |

:::note
If AllowOrigins is a zero value `[]string{}`, and AllowOriginsFunc is provided, the middleware will not default to allowing all origins with the wildcard value "*". Instead, it will rely on the AllowOriginsFunc to dynamically determine whether to allow a request based on its origin. This provides more flexibility and control over which origins are allowed.
:::

## Default Config

```go
var ConfigDefault = Config{
Next: nil,
Next: nil,
AllowOriginsFunc: nil,
AllowOrigins: "*",
AllowMethods: strings.Join([]string{
AllowOrigins: []string{"*"},
AllowMethods: []string{
fiber.MethodGet,
fiber.MethodPost,
fiber.MethodHead,
fiber.MethodPut,
fiber.MethodDelete,
fiber.MethodPatch,
}, ","),
AllowHeaders: "",
AllowCredentials: false,
ExposeHeaders: "",
MaxAge: 0,
},
AllowHeaders: []string{},
AllowCredentials: false,
ExposeHeaders: []string{},
MaxAge: 0,
AllowPrivateNetwork: false,
}
```
Expand Down Expand Up @@ -214,4 +217,4 @@ When configuring CORS, misconfiguration can potentially expose your application

- **Inadequate `AllowOriginsFunc` Validation**: When using `AllowOriginsFunc` for dynamic origin validation, ensure the function includes robust checks to prevent unauthorized origins from being accepted. Overly permissive validation can lead to security vulnerabilities. Never allow `AllowOriginsFunc` to return `true` for all origins. This is particularly crucial when `AllowCredentials` is set to `true`. Doing so can bypass the restriction of using a wildcard origin with credentials, exposing your application to serious security threats. If you need to allow wildcard origins, use `AllowOrigins` with a wildcard `"*"` instead of `AllowOriginsFunc`.

Remember, the key to secure CORS configuration is specificity and caution. By carefully selecting which origins, methods, and headers are allowed, you can help protect your application from cross-origin attacks.
Remember, the key to secure CORS configuration is specificity and caution. By carefully selecting which origins, methods, and headers are allowed, you can help protect your application from cross-origin attacks.

0 comments on commit 458aaba

Please sign in to comment.