Skip to content

Commit

Permalink
Add HTTP timeouts (ava-labs#2705)
Browse files Browse the repository at this point in the history
Co-authored-by: Joshua Kim <[email protected]>
  • Loading branch information
StephenButtolph and joshua-kim authored Mar 16, 2023
1 parent 8ceb523 commit d45384d
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 8 deletions.
18 changes: 13 additions & 5 deletions api/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,7 @@ import (
"github.com/ava-labs/avalanchego/utils/logging"
)

const (
baseURL = "/ext"
readHeaderTimeout = 10 * time.Second
)
const baseURL = "/ext"

var (
errUnknownLockOption = errors.New("invalid lock options")
Expand Down Expand Up @@ -79,6 +76,13 @@ type Server interface {
Shutdown() error
}

type HTTPConfig struct {
ReadTimeout time.Duration `json:"readTimeout"`
ReadHeaderTimeout time.Duration `json:"readHeaderTimeout"`
WriteTimeout time.Duration `json:"writeHeaderTimeout"`
IdleTimeout time.Duration `json:"idleTimeout"`
}

type server struct {
// log this server writes to
log logging.Logger
Expand Down Expand Up @@ -114,6 +118,7 @@ func New(
tracer trace.Tracer,
namespace string,
registerer prometheus.Registerer,
httpConfig HTTPConfig,
wrappers ...Wrapper,
) (Server, error) {
m, err := newMetrics(namespace, registerer)
Expand Down Expand Up @@ -155,7 +160,10 @@ func New(
router: router,
srv: &http.Server{
Handler: handler,
ReadHeaderTimeout: readHeaderTimeout,
ReadTimeout: httpConfig.ReadTimeout,
ReadHeaderTimeout: httpConfig.ReadHeaderTimeout,
WriteTimeout: httpConfig.WriteTimeout,
IdleTimeout: httpConfig.IdleTimeout,
},
}, nil
}
Expand Down
12 changes: 9 additions & 3 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (

"github.com/spf13/viper"

"github.com/ava-labs/avalanchego/api/server"
"github.com/ava-labs/avalanchego/chains"
"github.com/ava-labs/avalanchego/genesis"
"github.com/ava-labs/avalanchego/ids"
Expand Down Expand Up @@ -200,6 +201,12 @@ func getHTTPConfig(v *viper.Viper) (node.HTTPConfig, error) {
}

config := node.HTTPConfig{
HTTPConfig: server.HTTPConfig{
ReadTimeout: v.GetDuration(HTTPReadTimeoutKey),
ReadHeaderTimeout: v.GetDuration(HTTPReadHeaderTimeoutKey),
WriteTimeout: v.GetDuration(HTTPWriteTimeoutKey),
IdleTimeout: v.GetDuration(HTTPIdleTimeoutKey),
},
APIConfig: node.APIConfig{
APIIndexerConfig: node.APIIndexerConfig{
IndexAPIEnabled: v.GetBool(IndexEnabledKey),
Expand All @@ -217,9 +224,8 @@ func getHTTPConfig(v *viper.Viper) (node.HTTPConfig, error) {
HTTPSKey: httpsKey,
HTTPSCert: httpsCert,
APIAllowedOrigins: v.GetStringSlice(HTTPAllowedOrigins),

ShutdownTimeout: v.GetDuration(HTTPShutdownTimeoutKey),
ShutdownWait: v.GetDuration(HTTPShutdownWaitKey),
ShutdownTimeout: v.GetDuration(HTTPShutdownTimeoutKey),
ShutdownWait: v.GetDuration(HTTPShutdownWaitKey),
}

config.APIAuthConfig, err = getAPIAuthConfig(v)
Expand Down
4 changes: 4 additions & 0 deletions config/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,10 @@ func addNodeFlags(fs *flag.FlagSet) {
fs.String(HTTPAllowedOrigins, "*", "Origins to allow on the HTTP port. Defaults to * which allows all origins. Example: https://*.avax.network https://*.avax-test.network")
fs.Duration(HTTPShutdownWaitKey, 0, "Duration to wait after receiving SIGTERM or SIGINT before initiating shutdown. The /health endpoint will return unhealthy during this duration")
fs.Duration(HTTPShutdownTimeoutKey, 10*time.Second, "Maximum duration to wait for existing connections to complete during node shutdown")
fs.Duration(HTTPReadTimeoutKey, 30*time.Second, "Maximum duration for reading the entire request, including the body. A zero or negative value means there will be no timeout")
fs.Duration(HTTPReadHeaderTimeoutKey, 30*time.Second, fmt.Sprintf("Maximum duration to read request headers. The connection's read deadline is reset after reading the headers. If %s is zero, the value of %s is used. If both are zero, there is no timeout.", HTTPReadHeaderTimeoutKey, HTTPReadTimeoutKey))
fs.Duration(HTTPWriteTimeoutKey, 30*time.Second, "Maximum duration before timing out writes of the response. It is reset whenever a new request's header is read. A zero or negative value means there will be no timeout.")
fs.Duration(HTTPIdleTimeoutKey, 120*time.Second, fmt.Sprintf("Maximum duration to wait for the next request when keep-alives are enabled. If %s is zero, the value of %s is used. If both are zero, there is no timeout.", HTTPIdleTimeoutKey, HTTPReadTimeoutKey))
fs.Bool(APIAuthRequiredKey, false, "Require authorization token to call HTTP APIs")
fs.String(APIAuthPasswordFileKey, "",
fmt.Sprintf("Password file used to initially create/validate API authorization tokens. Ignored if %s is specified. Leading and trailing whitespace is removed from the password. Can be changed via API call",
Expand Down
4 changes: 4 additions & 0 deletions config/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ const (
HTTPAllowedOrigins = "http-allowed-origins"
HTTPShutdownTimeoutKey = "http-shutdown-timeout"
HTTPShutdownWaitKey = "http-shutdown-wait"
HTTPReadTimeoutKey = "http-read-timeout"
HTTPReadHeaderTimeoutKey = "http-read-header-timeout"
HTTPWriteTimeoutKey = "http-write-timeout"
HTTPIdleTimeoutKey = "http-idle-timeout"
APIAuthRequiredKey = "api-auth-required"
APIAuthPasswordKey = "api-auth-password"
APIAuthPasswordFileKey = "api-auth-password-file"
Expand Down
2 changes: 2 additions & 0 deletions node/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"crypto/tls"
"time"

"github.com/ava-labs/avalanchego/api/server"
"github.com/ava-labs/avalanchego/chains"
"github.com/ava-labs/avalanchego/genesis"
"github.com/ava-labs/avalanchego/ids"
Expand Down Expand Up @@ -43,6 +44,7 @@ type APIIndexerConfig struct {
}

type HTTPConfig struct {
server.HTTPConfig
APIConfig `json:"apiConfig"`
HTTPHost string `json:"httpHost"`
HTTPPort uint16 `json:"httpPort"`
Expand Down
2 changes: 2 additions & 0 deletions node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,7 @@ func (n *Node) initAPIServer() error {
n.tracer,
"api",
n.MetricsRegisterer,
n.Config.HTTPConfig.HTTPConfig,
)
return err
}
Expand All @@ -616,6 +617,7 @@ func (n *Node) initAPIServer() error {
n.tracer,
"api",
n.MetricsRegisterer,
n.Config.HTTPConfig.HTTPConfig,
a,
)
if err != nil {
Expand Down

0 comments on commit d45384d

Please sign in to comment.