Skip to content

Commit

Permalink
Config max request header size (#174)
Browse files Browse the repository at this point in the history
  • Loading branch information
guscarreon authored May 8, 2024
1 parent 84a0690 commit 4c0c8a0
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 2 deletions.
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)
}
}

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

0 comments on commit 4c0c8a0

Please sign in to comment.