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

Config max request header size #174

Merged
merged 5 commits into from
May 8, 2024
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
9 changes: 9 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package config

import (
"net/http"
"strings"
"time"

Expand Down Expand Up @@ -95,6 +96,7 @@ func setConfigDefaults(v *viper.Viper) {
v.SetDefault("request_limits.max_size_bytes", utils.REQUEST_MAX_SIZE_BYTES)
v.SetDefault("request_limits.max_num_values", utils.REQUEST_MAX_NUM_VALUES)
v.SetDefault("request_limits.max_ttl_seconds", utils.REQUEST_MAX_TTL_SECONDS)
v.SetDefault("request_limits.max_header_size_bytes", http.DefaultMaxHeaderBytes)
v.SetDefault("routes.allow_public_write", true)
}

Expand Down Expand Up @@ -179,6 +181,7 @@ type RequestLimits struct {
MaxNumValues int `mapstructure:"max_num_values"`
MaxTTLSeconds int `mapstructure:"max_ttl_seconds"`
AllowSettingKeys bool `mapstructure:"allow_setting_keys"`
MaxHeaderSize int `mapstructure:"max_header_size_bytes"`
}

func (cfg *RequestLimits) validateAndLog() {
Expand All @@ -201,6 +204,12 @@ func (cfg *RequestLimits) validateAndLog() {
} else {
log.Fatalf("invalid config.request_limits.max_num_values: %d. Value cannot be negative.", cfg.MaxNumValues)
}

if cfg.MaxHeaderSize >= 0 {
log.Infof("config.request_limits.max_header_size_bytes: %d", cfg.MaxHeaderSize)
} else {
log.Fatalf("invalid config.request_limits.max_header_size_bytes: %d. Value cannot be negative.", cfg.MaxHeaderSize)
AlexBVolcy marked this conversation as resolved.
Show resolved Hide resolved
}
}

type Compression struct {
Expand Down
15 changes: 15 additions & 0 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -867,6 +867,18 @@ func TestRequestLimitsValidateAndLog(t *testing.T) {
},
expectFatal: true,
},
{
description: "Negative max_header_size_bytes, expect fatal level log and early exit",
inRequestLimitsCfg: &RequestLimits{MaxHeaderSize: -1},
expectedLogInfo: []logComponents{
{msg: `config.request_limits.allow_setting_keys: false`, lvl: logrus.InfoLevel},
{msg: `config.request_limits.max_ttl_seconds: 0`, lvl: logrus.InfoLevel},
{msg: `config.request_limits.max_size_bytes: 0`, lvl: logrus.InfoLevel},
{msg: `config.request_limits.max_num_values: 0`, lvl: logrus.InfoLevel},
{msg: `invalid config.request_limits.max_header_size_bytes: -1. Value cannot be negative.`, lvl: logrus.FatalLevel},
},
expectFatal: true,
},
}

//substitute logger exit function so execution doesn't get interrupted
Expand Down Expand Up @@ -1078,6 +1090,7 @@ func TestConfigurationValidateAndLog(t *testing.T) {
{msg: fmt.Sprintf("config.request_limits.max_ttl_seconds: %d", expectedConfig.RequestLimits.MaxTTLSeconds), lvl: logrus.InfoLevel},
{msg: fmt.Sprintf("config.request_limits.max_size_bytes: %d", expectedConfig.RequestLimits.MaxSize), lvl: logrus.InfoLevel},
{msg: fmt.Sprintf("config.request_limits.max_num_values: %d", expectedConfig.RequestLimits.MaxNumValues), lvl: logrus.InfoLevel},
{msg: fmt.Sprintf("config.request_limits.max_header_size_bytes: %d", expectedConfig.RequestLimits.MaxHeaderSize), lvl: logrus.InfoLevel},
{msg: fmt.Sprintf("config.backend.type: %s", expectedConfig.Backend.Type), lvl: logrus.InfoLevel},
{msg: fmt.Sprintf("config.compression.type: %s", expectedConfig.Compression.Type), lvl: logrus.InfoLevel},
{msg: fmt.Sprintf("Prebid Cache will run without metrics"), lvl: logrus.InfoLevel},
Expand Down Expand Up @@ -1219,6 +1232,7 @@ func getExpectedDefaultConfig() Configuration {
MaxSize: 10240,
MaxNumValues: 10,
MaxTTLSeconds: 3600,
MaxHeaderSize: 1048576,
},
Routes: Routes{
AllowPublicWrite: true,
Expand All @@ -1244,6 +1258,7 @@ func getExpectedFullConfigForTestFile() Configuration {
MaxNumValues: 10,
MaxTTLSeconds: 5000,
AllowSettingKeys: true,
MaxHeaderSize: 16384, //16KiB
},
Backend: Backend{
Type: BackendMemory,
Expand Down
1 change: 1 addition & 0 deletions config/configtest/sample_full_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ request_limits:
max_num_values: 10
max_ttl_seconds: 5000
allow_setting_keys: true
max_header_size_bytes: 16384
backend:
type: "memory"
aerospike:
Expand Down
21 changes: 19 additions & 2 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,20 +74,37 @@ func Listen(cfg config.Configuration, publicHandler http.Handler, adminHandler h
return
}

// newAdminServer returns an http.Server with the AdminPort and RequestLimits.MaxHeaderBytes
// from Prebid Cache's config files or environment variables. If RequestLimits.MaxHeaderBytes
// is zero or was not specified, the http library's DefaultMaxHeaderBytes value of 1 MB
// is set instead.
func newAdminServer(cfg config.Configuration, handler http.Handler) *http.Server {
return &http.Server{
server := &http.Server{
Addr: ":" + strconv.Itoa(cfg.AdminPort),
Handler: handler,
}
if cfg.RequestLimits.MaxHeaderSize > 0 {
server.MaxHeaderBytes = cfg.RequestLimits.MaxHeaderSize
}
return server
}

// newMainServer returns an http.Server with the configured Port and
// RequestLimits.MaxHeaderBytes values specified in Prebid Cache's config files
// or environment variables. If RequestLimits.MaxHeaderBytes is zero or was not
// specified, 1 MB, which is the value of the http library's DefaultMaxHeaderBytes,
// is set instead.
func newMainServer(cfg config.Configuration, handler http.Handler) *http.Server {
return &http.Server{
server := &http.Server{
Addr: ":" + strconv.Itoa(cfg.Port),
Handler: handler,
ReadTimeout: 15 * time.Second,
WriteTimeout: 15 * time.Second,
}
if cfg.RequestLimits.MaxHeaderSize > 0 {
server.MaxHeaderBytes = cfg.RequestLimits.MaxHeaderSize
}
return server
}

func runServer(server *http.Server, name string, listener net.Listener) {
Expand Down
Loading