Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add Drop method to DefaultCtx for silent connection termination #3257

Merged
merged 11 commits into from
Dec 23, 2024
5 changes: 5 additions & 0 deletions ctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -1978,3 +1978,8 @@ func (c *DefaultCtx) setMatched(matched bool) {
func (c *DefaultCtx) setRoute(route *Route) {
c.route = route
}

func (c *DefaultCtx) Drop() error {
ryanbekhen marked this conversation as resolved.
Show resolved Hide resolved
//nolint:wrapcheck // This must not be wrapped
return c.RequestCtx().Conn().Close()
}
1 change: 1 addition & 0 deletions ctx_interface_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 29 additions & 0 deletions ctx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5847,6 +5847,35 @@ func Test_GenericParseTypeBoolean(t *testing.T) {
}
}

// go test -run Test_Ctx_Drop -v
func Test_Ctx_Drop(t *testing.T) {
t.Parallel()

app := New()

// Handler that calls Drop
app.Get("/block-me", func(c Ctx) error {
gaby marked this conversation as resolved.
Show resolved Hide resolved
return c.Drop()
})

// Additional handler that just calls return
app.Get("/no-response", func(_ Ctx) error {
return nil
})

// Test the Drop method
resp, err := app.Test(httptest.NewRequest(MethodGet, "/block-me", nil))
require.Error(t, err)
require.Nil(t, resp)

// Test the no-response handler
resp, err = app.Test(httptest.NewRequest(MethodGet, "/no-response", nil))
require.NoError(t, err)
require.NotNil(t, resp)
require.Equal(t, 200, resp.StatusCode)
ryanbekhen marked this conversation as resolved.
Show resolved Hide resolved
require.Equal(t, "0", resp.Header.Get("Content-Length"))
}

// go test -run Test_GenericParseTypeString
func Test_GenericParseTypeString(t *testing.T) {
t.Parallel()
Expand Down
21 changes: 21 additions & 0 deletions docs/api/ctx.md
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,27 @@ app.Get("/", func(c fiber.Ctx) error {
})
```

## Drop

Terminates the client connection silently without sending any HTTP headers or response body.

This can be used for scenarios where you want to block certain requests without notifying the client, such as mitigating
DDoS attacks or protecting sensitive endpoints from unauthorized access.

```go title="Signature"
func (c fiber.Ctx) Drop() error
```

```go title="Example"
app.Get("/", func(c fiber.Ctx) error {
if c.IP() == "192.168.1.1" {
return c.Drop()
}

return c.SendString("Hello World!")
})
```

## Format

Performs content-negotiation on the [Accept](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept) HTTP header. It uses [Accepts](ctx.md#accepts) to select a proper format from the supplied offers. A default handler can be provided by setting the `MediaType` to `"default"`. If no offers match and no default is provided, a 406 (Not Acceptable) response is sent. The Content-Type is automatically set when a handler is selected.
Expand Down
6 changes: 0 additions & 6 deletions middleware/cache/manager_msgp.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading