Skip to content

Commit

Permalink
Merge branch 'main' into reqres
Browse files Browse the repository at this point in the history
  • Loading branch information
gaby authored Jan 28, 2025
2 parents 4b3dc9a + 2eb6808 commit cf05889
Show file tree
Hide file tree
Showing 55 changed files with 2,359 additions and 444 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ jobs:
uses: golangci/golangci-lint-action@v6
with:
# NOTE: Keep this in sync with the version from .golangci.yml
version: v1.62.0
version: v1.62.2
2 changes: 1 addition & 1 deletion .github/workflows/markdown.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
uses: actions/checkout@v4

- name: Run markdownlint-cli2
uses: DavidAnson/markdownlint-cli2-action@v18
uses: DavidAnson/markdownlint-cli2-action@v19
with:
globs: |
**/*.md
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:

- name: Upload coverage reports to Codecov
if: ${{ matrix.platform == 'ubuntu-latest' && matrix.go-version == '1.23.x' }}
uses: codecov/codecov-action@v5.1.2
uses: codecov/codecov-action@v5.3.0
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: ./coverage.txt
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ markdown:
## lint: 🚨 Run lint checks
.PHONY: lint
lint:
go run github.com/golangci/golangci-lint/cmd/[email protected].0 run ./...
go run github.com/golangci/golangci-lint/cmd/[email protected].2 run ./...

## test: 🚦 Execute all tests
.PHONY: test
Expand Down
34 changes: 29 additions & 5 deletions app.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import (
)

// Version of current fiber package
const Version = "3.0.0-beta.3"
const Version = "3.0.0-beta.4"

// Handler defines a function to serve HTTP requests.
type Handler = func(Ctx) error
Expand Down Expand Up @@ -341,6 +341,13 @@ type Config struct { //nolint:govet // Aligning the struct fields is not necessa
// Default: xml.Marshal
XMLEncoder utils.XMLMarshal `json:"-"`

// XMLDecoder set by an external client of Fiber it will use the provided implementation of a
// XMLUnmarshal
//
// Allowing for flexibility in using another XML library for decoding
// Default: xml.Unmarshal
XMLDecoder utils.XMLUnmarshal `json:"-"`

// If you find yourself behind some sort of proxy, like a load balancer,
// then certain header information may be sent to you using special X-Forwarded-* headers or the Forwarded header.
// For example, the Host HTTP header is usually used to return the requested host.
Expand Down Expand Up @@ -560,6 +567,9 @@ func New(config ...Config) *App {
if app.config.XMLEncoder == nil {
app.config.XMLEncoder = xml.Marshal
}
if app.config.XMLDecoder == nil {
app.config.XMLDecoder = xml.Unmarshal
}
if len(app.config.RequestMethods) == 0 {
app.config.RequestMethods = DefaultMethods
}
Expand Down Expand Up @@ -606,6 +616,10 @@ func (app *App) handleTrustedProxy(ipAddress string) {
// Note: It doesn't allow adding new methods, only customizing exist methods.
func (app *App) NewCtxFunc(function func(app *App) CustomCtx) {
app.newCtxFunc = function

if app.server != nil {
app.server.Handler = app.customRequestHandler
}
}

// RegisterCustomConstraint allows to register custom constraint.
Expand Down Expand Up @@ -858,7 +872,11 @@ func (app *App) Config() Config {
func (app *App) Handler() fasthttp.RequestHandler { //revive:disable-line:confusing-naming // Having both a Handler() (uppercase) and a handler() (lowercase) is fine. TODO: Use nolint:revive directive instead. See https://github.com/golangci/golangci-lint/issues/3476
// prepare the server for the start
app.startupProcess()
return app.requestHandler

if app.newCtxFunc != nil {
return app.customRequestHandler
}
return app.defaultRequestHandler
}

// Stack returns the raw router stack.
Expand Down Expand Up @@ -923,6 +941,8 @@ func (app *App) Hooks() *Hooks {
return app.hooks
}

var ErrTestGotEmptyResponse = errors.New("test: got empty response")

// TestConfig is a struct holding Test settings
type TestConfig struct {
// Timeout defines the maximum duration a
Expand Down Expand Up @@ -1004,7 +1024,7 @@ func (app *App) Test(req *http.Request, config ...TestConfig) (*http.Response, e
}

// Check for errors
if err != nil && !errors.Is(err, fasthttp.ErrGetOnly) {
if err != nil && !errors.Is(err, fasthttp.ErrGetOnly) && !errors.Is(err, errTestConnClosed) {
return nil, err
}

Expand All @@ -1015,7 +1035,7 @@ func (app *App) Test(req *http.Request, config ...TestConfig) (*http.Response, e
res, err := http.ReadResponse(buffer, req)
if err != nil {
if errors.Is(err, io.ErrUnexpectedEOF) {
return nil, errors.New("test: got empty response")
return nil, ErrTestGotEmptyResponse
}
return nil, fmt.Errorf("failed to read response: %w", err)
}
Expand Down Expand Up @@ -1047,7 +1067,11 @@ func (app *App) init() *App {
}

// fasthttp server settings
app.server.Handler = app.requestHandler
if app.newCtxFunc != nil {
app.server.Handler = app.customRequestHandler
} else {
app.server.Handler = app.defaultRequestHandler
}
app.server.Name = app.config.ServerHeader
app.server.Concurrency = app.config.Concurrency
app.server.NoDefaultDate = app.config.DisableDefaultDate
Expand Down
58 changes: 46 additions & 12 deletions app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -581,32 +581,51 @@ func Test_App_Use_StrictRouting(t *testing.T) {

func Test_App_Add_Method_Test(t *testing.T) {
t.Parallel()
defer func() {
if err := recover(); err != nil {
require.Equal(t, "add: invalid http method JANE\n", fmt.Sprintf("%v", err))
}
}()

methods := append(DefaultMethods, "JOHN") //nolint:gocritic // We want a new slice here
app := New(Config{
RequestMethods: methods,
})

app.Add([]string{"JOHN"}, "/doe", testEmptyHandler)
app.Add([]string{"JOHN"}, "/john", testEmptyHandler)

resp, err := app.Test(httptest.NewRequest("JOHN", "/doe", nil))
resp, err := app.Test(httptest.NewRequest("JOHN", "/john", nil))
require.NoError(t, err, "app.Test(req)")
require.Equal(t, StatusOK, resp.StatusCode, "Status code")

resp, err = app.Test(httptest.NewRequest(MethodGet, "/doe", nil))
resp, err = app.Test(httptest.NewRequest(MethodGet, "/john", nil))
require.NoError(t, err, "app.Test(req)")
require.Equal(t, StatusMethodNotAllowed, resp.StatusCode, "Status code")

resp, err = app.Test(httptest.NewRequest("UNKNOWN", "/doe", nil))
resp, err = app.Test(httptest.NewRequest("UNKNOWN", "/john", nil))
require.NoError(t, err, "app.Test(req)")
require.Equal(t, StatusNotImplemented, resp.StatusCode, "Status code")

app.Add([]string{"JANE"}, "/doe", testEmptyHandler)
// Add a new method
require.Panics(t, func() {
app.Add([]string{"JANE"}, "/jane", testEmptyHandler)
})
}

func Test_App_All_Method_Test(t *testing.T) {
t.Parallel()

methods := append(DefaultMethods, "JOHN") //nolint:gocritic // We want a new slice here
app := New(Config{
RequestMethods: methods,
})

// Add a new method with All
app.All("/doe", testEmptyHandler)

resp, err := app.Test(httptest.NewRequest("JOHN", "/doe", nil))
require.NoError(t, err, "app.Test(req)")
require.Equal(t, StatusOK, resp.StatusCode, "Status code")

// Add a new method
require.Panics(t, func() {
app.Add([]string{"JANE"}, "/jane", testEmptyHandler)
})
}

// go test -run Test_App_GETOnly
Expand Down Expand Up @@ -1472,7 +1491,7 @@ func Test_App_Test_timeout(t *testing.T) {
Timeout: 100 * time.Millisecond,
FailOnTimeout: true,
})
require.Equal(t, os.ErrDeadlineExceeded, err)
require.ErrorIs(t, err, os.ErrDeadlineExceeded)
}

func Test_App_Test_timeout_empty_response(t *testing.T) {
Expand All @@ -1488,7 +1507,22 @@ func Test_App_Test_timeout_empty_response(t *testing.T) {
Timeout: 100 * time.Millisecond,
FailOnTimeout: false,
})
require.Equal(t, errors.New("test: got empty response"), err)
require.ErrorIs(t, err, ErrTestGotEmptyResponse)
}

func Test_App_Test_drop_empty_response(t *testing.T) {
t.Parallel()

app := New()
app.Get("/", func(c Ctx) error {
return c.Drop()
})

_, err := app.Test(httptest.NewRequest(MethodGet, "/", nil), TestConfig{
Timeout: 0,
FailOnTimeout: false,
})
require.ErrorIs(t, err, ErrTestGotEmptyResponse)
}

func Test_App_SetTLSHandler(t *testing.T) {
Expand Down
Loading

0 comments on commit cf05889

Please sign in to comment.