Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"gopls": {
"buildFlags": [
"-tags=race"
]
}
}
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ SRouter is a high-performance HTTP router for Go that wraps [julienschmidt/httpr
- **Advanced Features**
- [IP Configuration](./docs/ip-configuration.md)
- [Rate Limiting](./docs/rate-limiting.md)
- [WebSocket Support](#websocket-support)
- [Authentication](./docs/authentication.md)
- [Context Management](./docs/context-management.md)
- [Custom Error Handling](./docs/error-handling.md)
Expand Down Expand Up @@ -321,6 +322,26 @@ func GetUserHandler(w http.ResponseWriter, r *http.Request) {
}
```

### WebSocket Support

SRouter supports WebSocket connections by allowing you to disable the automatic request timeout for specific routes. This is crucial for long-lived connections.

To enable WebSocket support for a route, set the `DisableTimeout` flag to `true` in your `RouteConfigBase`. This will prevent the global or sub-router timeout from terminating the connection. This is also useful for other long-lived connections such as Server-Sent Events (SSE).

```go
// Register a WebSocket route
r.RegisterRoute(router.RouteConfigBase{
Path: "/ws",
Methods: []router.HttpMethod{router.MethodGet},
DisableTimeout: true, // Disables timeout for this route
Handler: func(w http.ResponseWriter, r *http.Request) {
// Upgrade the connection to a WebSocket
// conn, err := upgrader.Upgrade(w, r, nil)
// ... handle connection ...
},
})
```

### Trace ID Logging

SRouter provides built-in support for trace ID logging, which allows you to correlate log entries across different parts of your application for a single request. Each request is assigned a unique trace ID (UUID) that is automatically included in all log entries when `EnableTraceLogging` is true.
Expand Down Expand Up @@ -1224,6 +1245,7 @@ type RouteConfigBase struct {
Overrides common.RouteOverrides // Optional per-route overrides
Handler http.HandlerFunc // Standard HTTP handler function
Middlewares []common.Middleware // Middlewares applied to this specific route
DisableTimeout bool // Indicates if the timeout should be disabled for this route (e.g., for WebSockets or long-lived connections).
}
```

Expand Down
146 changes: 146 additions & 0 deletions examples/websocket/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package main

import (
"context"
"fmt"
"io"
"log"
"net/http"
"net/url"
"time"

"github.com/Suhaibinator/SRouter/pkg/router"
"github.com/gorilla/websocket"
"go.uber.org/zap"
)

var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
// Allow all origins for this example
CheckOrigin: func(r *http.Request) bool { return true },
}

func main() {
// 1. Setup Server
logger, _ := zap.NewProduction()
defer logger.Sync()

routerConfig := router.RouterConfig{
ServiceName: "websocket-example",
Logger: logger,
GlobalTimeout: 5 * time.Second, // Global timeout to test DisableTimeout bypass
}

// Simple auth - accept everything
authFunc := func(ctx context.Context, token string) (*string, bool) {
user := "generic-user"
return &user, true
}
userIdFunc := func(user *string) string { return *user }

r := router.NewRouter(routerConfig, authFunc, userIdFunc)

// REST Endpoint
r.RegisterRoute(router.RouteConfigBase{
Path: "/hello",
Methods: []router.HttpMethod{router.MethodGet},
Handler: func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("Hello, World!"))
},
})

// WebSocket Endpoint
r.RegisterRoute(router.RouteConfigBase{
Path: "/ws",
Methods: []router.HttpMethod{router.MethodGet},
DisableTimeout: true, // Crucial: disables global timeout
Handler: func(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
logger.Error("upgrade failed", zap.Error(err))
return
}
defer conn.Close()

for {
messageType, p, err := conn.ReadMessage()
if err != nil {
return
}
// Echo message back
if err := conn.WriteMessage(messageType, p); err != nil {
return
}
}
},
})

// Start server in goroutine
port := "8089"
server := &http.Server{Addr: ":" + port, Handler: r}

go func() {
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("ListenAndServe(): %v", err)
}
}()
fmt.Printf("Server started on port %s\n", port)

// Give server a moment to start
time.Sleep(100 * time.Millisecond)

// 2. Test Client Logic
testREST(port)
testWebSocket(port)

// Shutdown
server.Shutdown(context.Background())
fmt.Println("Done.")
}

func testREST(port string) {
fmt.Println("--- Testing REST Endpoint ---")
resp, err := http.Get(fmt.Sprintf("http://localhost:%s/hello", port))
if err != nil {
log.Fatalf("REST request failed: %v", err)
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
log.Fatalf("REST expected status 200, got %d", resp.StatusCode)
}

body, _ := io.ReadAll(resp.Body)
fmt.Printf("REST Response: %s\n", string(body))
fmt.Println("REST Test Passed!")
}

func testWebSocket(port string) {
fmt.Println("--- Testing WebSocket Endpoint ---")
u := url.URL{Scheme: "ws", Host: "localhost:" + port, Path: "/ws"}

c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
if err != nil {
log.Fatalf("WebSocket dial failed: %v", err)
}
defer c.Close()

msg := "hello websocket"
err = c.WriteMessage(websocket.TextMessage, []byte(msg))
if err != nil {
log.Fatalf("WebSocket write failed: %v", err)
}

_, message, err := c.ReadMessage()
if err != nil {
log.Fatalf("WebSocket read failed: %v", err)
}

fmt.Printf("WebSocket Response: %s\n", string(message))
if string(message) != msg {
log.Fatalf("WebSocket expected echo '%s', got '%s'", msg, string(message))
}
fmt.Println("WebSocket Test Passed!")
}
20 changes: 11 additions & 9 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,23 @@ go 1.24.0

require (
github.com/julienschmidt/httprouter v1.3.0
go.uber.org/zap v1.27.0
go.uber.org/zap v1.27.1
)

require (
github.com/google/uuid v1.6.0
github.com/stretchr/testify v1.10.0
gorm.io/gorm v1.30.1
github.com/gorilla/websocket v1.5.3
github.com/stretchr/testify v1.11.1
gorm.io/gorm v1.31.1
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/text v0.28.0 // indirect
go.yaml.in/yaml/v2 v2.4.3 // indirect
golang.org/x/text v0.32.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

Expand All @@ -28,14 +30,14 @@ require (
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/prometheus/client_model v0.6.2
github.com/prometheus/common v0.65.0 // indirect
github.com/prometheus/procfs v0.17.0 // indirect
github.com/prometheus/common v0.67.4 // indirect
github.com/prometheus/procfs v0.19.2 // indirect
go.uber.org/ratelimit v0.3.1
golang.org/x/sys v0.35.0 // indirect
google.golang.org/protobuf v1.36.7
golang.org/x/sys v0.39.0 // indirect
google.golang.org/protobuf v1.36.11
)

require (
github.com/prometheus/client_golang v1.23.0
github.com/prometheus/client_golang v1.23.2
go.uber.org/multierr v1.11.0 // indirect
)
58 changes: 22 additions & 36 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
Expand All @@ -28,24 +30,18 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
github.com/prometheus/client_golang v1.23.0 h1:ust4zpdl9r4trLY/gSjlm07PuiBq2ynaXXlptpfy8Uc=
github.com/prometheus/client_golang v1.23.0/go.mod h1:i/o0R9ByOnHX0McrTMTyhYvKE4haaf2mW08I+jGAjEE=
github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.64.0 h1:pdZeA+g617P7oGv1CzdTzyeShxAGrTBsolKNOLQPGO4=
github.com/prometheus/common v0.64.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8=
github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE=
github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8=
github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0=
github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw=
github.com/prometheus/common v0.67.4 h1:yR3NqWO1/UyO1w2PhUvXlGQs/PtFmoveVO0KZ4+Lvsc=
github.com/prometheus/common v0.67.4/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI=
github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws=
github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
Expand All @@ -54,30 +50,20 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/ratelimit v0.3.1 h1:K4qVE+byfv/B3tC+4nYWP7v/6SimcO7HzHekoMNBma0=
go.uber.org/ratelimit v0.3.1/go.mod h1:6euWsTB6U/Nb3X++xEUXA8ciPJvr19Q/0h1+oDcJhRk=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
google.golang.org/protobuf v1.36.7 h1:IgrO7UwFQGJdRNXH/sQux4R1Dj1WAKcLElzeeRaXV2A=
google.golang.org/protobuf v1.36.7/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/gorm v1.30.0 h1:qbT5aPv1UH8gI99OsRlvDToLxW5zR7FzS9acZDOZcgs=
gorm.io/gorm v1.30.0/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE=
gorm.io/gorm v1.30.1 h1:lSHg33jJTBxs2mgJRfRZeLDG+WZaHYCk3Wtfl6Ngzo4=
gorm.io/gorm v1.30.1/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE=
gorm.io/gorm v1.31.1 h1:7CA8FTFz/gRfgqgpeKIBcervUn3xSyPUmr6B2WXJ7kg=
gorm.io/gorm v1.31.1/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs=
13 changes: 7 additions & 6 deletions pkg/router/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,12 +189,13 @@ type SubRouterConfig struct {
// - Sub-router settings override global settings
// - Middlewares are additive (not replaced)
type RouteConfigBase struct {
Path string // Route path (will be prefixed with sub-router path prefix if applicable)
Methods []HttpMethod // HTTP methods this route handles (use constants like MethodGet)
AuthLevel *AuthLevel // Authentication level for this route. If nil, inherits from sub-router or defaults to NoAuth
Overrides common.RouteOverrides // Configuration overrides for this specific route
Handler http.HandlerFunc // Standard HTTP handler function
Middlewares []common.Middleware // Middlewares applied to this specific route (combined with sub-router and global middlewares)
Path string // Route path (will be prefixed with sub-router path prefix if applicable)
Methods []HttpMethod // HTTP methods this route handles (use constants like MethodGet)
AuthLevel *AuthLevel // Authentication level for this route. If nil, inherits from sub-router or defaults to NoAuth
Overrides common.RouteOverrides // Configuration overrides for this specific route
Handler http.HandlerFunc // Standard HTTP handler function
Middlewares []common.Middleware // Middlewares applied to this specific route (combined with sub-router and global middlewares)
DisableTimeout bool // Indicates if the timeout should be disabled for this route (e.g., for WebSockets or long-lived connections).
}

// Implement RouteDefinition for RouteConfigBase
Expand Down
6 changes: 3 additions & 3 deletions pkg/router/handler_error_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func TestGenericRouteHandlerError(t *testing.T) {
return 0
}

router := NewRouter[int, interface{}](RouterConfig{
router := NewRouter(RouterConfig{
Logger: zap.NewNop(),
}, getUserByID, getUserID)

Expand Down Expand Up @@ -177,11 +177,11 @@ func TestHandlerErrorWithMultipleMiddleware(t *testing.T) {
getUserByID := func(ctx context.Context, userID string) (*interface{}, bool) {
return nil, false
}
getUserID := func(user *interface{}) int {
getUserID := func(user *any) int {
return 0
}

router := NewRouter[int, interface{}](RouterConfig{
router := NewRouter(RouterConfig{
Logger: zap.NewNop(),
}, getUserByID, getUserID)

Expand Down
6 changes: 6 additions & 0 deletions pkg/router/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ import (
func (r *Router[T, U]) RegisterRoute(route RouteConfigBase) {
// Get effective timeout, max body size, and rate limit for this route
timeout := r.getEffectiveTimeout(route.Overrides.Timeout, 0)

// If route has timeout disabled, set timeout to 0
if route.DisableTimeout {
timeout = 0
}

maxBodySize := r.getEffectiveMaxBodySize(route.Overrides.MaxBodySize, 0)
// Pass the specific route config (which is *common.RateLimitConfig[any, any])
// to getEffectiveRateLimit. The conversion happens inside getEffectiveRateLimit.
Expand Down
Loading