Skip to content

Commit

Permalink
feat: add configurable timeout (#16 #15)
Browse files Browse the repository at this point in the history
* Add support for configurable timeout

* add documentation about timeoutMillis config

---------

Co-authored-by: Antonio Macrì <[email protected]>
  • Loading branch information
acouvreur and antoniomacri authored Mar 7, 2023
1 parent 3b94fb9 commit 34bee9e
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 6 deletions.
1 change: 1 addition & 0 deletions .traefik.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ summary: 'Traefik plugin to proxy requests to owasp/modsecurity-crs:apache'
testData:
ModsecurityUrl: http://waf:80
MaxBodySize: 10485760
TimeoutMillis: 2000

iconPath: ./img/icon.png
bannerPath: ./img/banner.png
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ The *dummy* service is created so the waf container forward the request to a ser
This plugin supports these configuration:

* `modSecurityUrl`: (**mandatory**) it's the URL for the owasp/modsecurity container.
* `timeoutMillis`: (optional) timeout in milliseconds for the http client to talk with modsecurity container. (default 2 seconds)
* `maxBodySize`: (optional) it's the maximum limit for requests body size. Requests exceeding this value will be rejected using `HTTP 413 Request Entity Too Large`.
The default value for this parameter is 10MB. Zero means "use default value".

Expand Down
19 changes: 13 additions & 6 deletions modsecurity.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,17 @@ import (
"time"
)

// Net client is a custom client to timeout after 2 seconds if the service is not ready
var httpClient = &http.Client{
Timeout: time.Second * 2,
}

// Config the plugin configuration.
type Config struct {
TimeoutMillis int64 `json:"timeoutMillis"`
ModSecurityUrl string `json:"modSecurityUrl,omitempty"`
MaxBodySize int64 `json:"maxBodySize"`
}

// CreateConfig creates the default plugin configuration.
func CreateConfig() *Config {
return &Config{
TimeoutMillis: 2000,
// Safe default: if the max body size was not specified, use 10MB
// Note that this will break any file upload with files > 10MB. Hopefully
// the user will configure this parameter during the installation.
Expand All @@ -40,6 +37,7 @@ type Modsecurity struct {
modSecurityUrl string
maxBodySize int64
name string
httpClient *http.Client
logger *log.Logger
}

Expand All @@ -49,11 +47,20 @@ func New(ctx context.Context, next http.Handler, config *Config, name string) (h
return nil, fmt.Errorf("modSecurityUrl cannot be empty")
}

// Use a custom client with predefined timeout ot 2 seconds
var timeout time.Duration
if config.TimeoutMillis == 0 {
timeout = 2 * time.Second
} else {
timeout = time.Duration(config.TimeoutMillis) * time.Millisecond
}

return &Modsecurity{
modSecurityUrl: config.ModSecurityUrl,
maxBodySize: config.MaxBodySize,
next: next,
name: name,
httpClient: &http.Client{Timeout: timeout},
logger: log.New(os.Stdout, "", log.LstdFlags),
}, nil
}
Expand Down Expand Up @@ -101,7 +108,7 @@ func (a *Modsecurity) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
proxyReq.Header[h] = val
}

resp, err := httpClient.Do(proxyReq)
resp, err := a.httpClient.Do(proxyReq)
if err != nil {
a.logger.Printf("fail to send HTTP request to modsec: %s", err.Error())
http.Error(rw, "", http.StatusBadGateway)
Expand Down
1 change: 1 addition & 0 deletions modsecurity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ func TestModsecurity_ServeHTTP(t *testing.T) {
modSecurityUrl: modsecurityMockServer.URL,
maxBodySize: 1024,
name: "modsecurity-middleware",
httpClient: http.DefaultClient,
logger: log.New(io.Discard, "", log.LstdFlags),
}

Expand Down

0 comments on commit 34bee9e

Please sign in to comment.