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
18 changes: 16 additions & 2 deletions config.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
port = ":8080" # Port to listen on for HTTP routes
timeout = "1m" # How long to wait for a machine to wake / a route to become ready
response_header_timeout = "1m" # How long to wait for a response header, e.g. during slow or long-running requests/uploads
timeout = "1m" # How long to wait for a machine to wake / a route to become ready.
# Cannot be disabled with "0" or a negative value - it would time out immediately.
request_header_timeout = "30s" # How long to wait for request headers;
# Use a negative value (e.g. "-1s") to disable it outright.
# "0" alone falls back to server_read_timeout -
# Set both to "0" to disable that way
response_header_timeout = "1m" # How long to wait for a response header, e.g. during slow or long-running requests/uploads;
# "0" disables it
server_read_timeout = "10m" # How long to wait for the full request body from the client;
# "0" disables it
server_write_timeout = "10m" # How long to wait for the full response to the client;
# "0" disables it
server_idle_timeout = "120s" # How long to wait for the next request when keep-alive is enabled;
# Use a negative value (e.g. "-1s") to disable it outright.
# "0" alone falls back to server_read_timeout -
# Set both to "0" to disable that way
poll_interval = "5s" # How often to check health while waiting
health_check_interval = "30s" # Background health check frequency
health_cache_duration = "10s" # How long to trust a cached health result
Expand Down
52 changes: 48 additions & 4 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,11 @@ func (r *realTicker) Stop() { r.t.Stop() }
type Config struct {
Port string `toml:"port"`
Timeout string `toml:"timeout"`
RequestHeaderTimeout string `toml:"request_header_timeout,omitempty"`
ResponseHeaderTimeout string `toml:"response_header_timeout,omitempty"`
ServerReadTimeout string `toml:"server_read_timeout,omitempty"`
ServerWriteTimeout string `toml:"server_write_timeout,omitempty"`
ServerIdleTimeout string `toml:"server_idle_timeout,omitempty"`
PollInterval string `toml:"poll_interval"`
HealthCheckInterval string `toml:"health_check_interval"`
HealthCacheDuration string `toml:"health_cache_duration"`
Expand Down Expand Up @@ -210,7 +214,11 @@ type routing struct {
type ProxyConfig struct {
Port string
Timeout time.Duration
RequestHeaderTimeout time.Duration
ResponseHeaderTimeout time.Duration
ServerReadTimeout time.Duration
ServerWriteTimeout time.Duration
ServerIdleTimeout time.Duration
PollInterval time.Duration
HealthCheckInterval time.Duration
HealthCacheDuration time.Duration
Expand Down Expand Up @@ -790,10 +798,10 @@ func (p *ProxyService) Start(ctx context.Context) error {
server := &http.Server{
Addr: p.config.Port,
Handler: mux,
ReadTimeout: 10 * time.Minute,
WriteTimeout: 10 * time.Minute,
IdleTimeout: 120 * time.Second, // 2 minutes for keep-alive connections
ReadHeaderTimeout: 30 * time.Second,
ReadTimeout: p.config.ServerReadTimeout,
WriteTimeout: p.config.ServerWriteTimeout,
IdleTimeout: p.config.ServerIdleTimeout,
ReadHeaderTimeout: p.config.RequestHeaderTimeout,
MaxHeaderBytes: 1 << 20,
}

Expand Down Expand Up @@ -1348,6 +1356,14 @@ func LoadConfig(filename string, clock Clock) (*ProxyConfig, error) {
return nil, fmt.Errorf("invalid timeout: %w", err)
}

if config.RequestHeaderTimeout == "" {
config.RequestHeaderTimeout = "30s"
}
requestHeaderTimeout, err := time.ParseDuration(config.RequestHeaderTimeout)
if err != nil {
return nil, fmt.Errorf("invalid request_header_timeout: %w", err)
}

if config.ResponseHeaderTimeout == "" {
config.ResponseHeaderTimeout = "1m"
}
Expand All @@ -1356,6 +1372,30 @@ func LoadConfig(filename string, clock Clock) (*ProxyConfig, error) {
return nil, fmt.Errorf("invalid response_header_timeout: %w", err)
}

if config.ServerReadTimeout == "" {
config.ServerReadTimeout = "10m"
}
serverReadTimeout, err := time.ParseDuration(config.ServerReadTimeout)
if err != nil {
return nil, fmt.Errorf("invalid server_read_timeout: %w", err)
}

if config.ServerWriteTimeout == "" {
config.ServerWriteTimeout = "10m"
}
serverWriteTimeout, err := time.ParseDuration(config.ServerWriteTimeout)
if err != nil {
return nil, fmt.Errorf("invalid server_write_timeout: %w", err)
}

if config.ServerIdleTimeout == "" {
config.ServerIdleTimeout = "120s"
}
serverIdleTimeout, err := time.ParseDuration(config.ServerIdleTimeout)
if err != nil {
return nil, fmt.Errorf("invalid server_idle_timeout: %w", err)
}

pollInterval, err := time.ParseDuration(config.PollInterval)
if err != nil {
return nil, fmt.Errorf("invalid poll_interval: %w", err)
Expand Down Expand Up @@ -1391,7 +1431,11 @@ func LoadConfig(filename string, clock Clock) (*ProxyConfig, error) {
SSLCertificate: config.SSLCertificate,
SSLCertificateKey: config.SSLCertificateKey,
Timeout: timeout,
RequestHeaderTimeout: requestHeaderTimeout,
ResponseHeaderTimeout: responseHeaderTimeout,
ServerReadTimeout: serverReadTimeout,
ServerWriteTimeout: serverWriteTimeout,
ServerIdleTimeout: serverIdleTimeout,
PollInterval: pollInterval,
HealthCheckInterval: healthCheckInterval,
HealthCacheDuration: healthCacheDuration,
Expand Down
Loading