Skip to content

Commit

Permalink
http timeout fields are configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
Lexman42 committed May 6, 2019
1 parent f250d77 commit 95ec131
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 8 deletions.
53 changes: 53 additions & 0 deletions command/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ type ServerCommand struct {
flagDevAutoSeal bool
flagTestVerifyOnly bool
flagCombineLogs bool
flagTestServerConfig bool
}

type ServerListener struct {
Expand Down Expand Up @@ -305,6 +306,13 @@ func (c *ServerCommand) Flags() *FlagSets {
Hidden: true,
})

f.BoolVar(&BoolVar{
Name: "test-server-config",
Target: &c.flagTestServerConfig,
Default: false,
Hidden: true,
})

// End internal-only flags.

return set
Expand Down Expand Up @@ -1126,6 +1134,7 @@ CLUSTER_SYNTHESIS_COMPLETE:
c.UI.Warn("")
}

// Continuing configuration testing at this point
// Initialize the HTTP servers
for _, ln := range lns {
handler := vaulthttp.Handler(&vault.HandlerProperties{
Expand All @@ -1146,13 +1155,57 @@ CLUSTER_SYNTHESIS_COMPLETE:
}
}

// server defaults
server := &http.Server{
Handler: handler,
ReadHeaderTimeout: 10 * time.Second,
ReadTimeout: 30 * time.Second,
IdleTimeout: 5 * time.Minute,
ErrorLog: c.logger.StandardLogger(nil),
}

// override server defaults with config values for read/write/idle timeouts if configured
if readHeaderTimeoutInterface, ok := ln.config["http_read_header_timeout"]; ok {
readHeaderTimeout, err := parseutil.ParseDurationSecond(readHeaderTimeoutInterface)
if err != nil {
c.UI.Error(fmt.Sprintf("Could not parse a time value for http_read_header_timeout %v", readHeaderTimeout))
return 1
}
server.ReadHeaderTimeout = readHeaderTimeout
}

if readTimeoutInterface, ok := ln.config["http_read_timeout"]; ok {
readTimeout, err := parseutil.ParseDurationSecond(readTimeoutInterface)
if err != nil {
c.UI.Error(fmt.Sprintf("Could not parse a time value for http_read_timeout %v", readTimeout))
return 1
}
server.ReadTimeout = readTimeout
}

if writeTimeoutInterface, ok := ln.config["http_write_timeout"]; ok {
writeTimeout, err := parseutil.ParseDurationSecond(writeTimeoutInterface)
if err != nil {
c.UI.Error(fmt.Sprintf("Could not parse a time value for http_write_timeout %v", writeTimeout))
return 1
}
server.WriteTimeout = writeTimeout
}

if idleTimeoutInterface, ok := ln.config["http_idle_timeout"]; ok {
idleTimeout, err := parseutil.ParseDurationSecond(idleTimeoutInterface)
if err != nil {
c.UI.Error(fmt.Sprintf("Could not parse a time value for http_idle_timeout %v", idleTimeout))
return 1
}
server.IdleTimeout = idleTimeout
}

// server config tests can exit now
if c.flagTestServerConfig {
return 0
}

go server.Serve(ln.Listener)
}

Expand Down
73 changes: 65 additions & 8 deletions command/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,30 @@ func testRandomPort(tb testing.TB) int {
return l.Addr().(*net.TCPAddr).Port
}

func testBaseHCL(tb testing.TB) string {
func testBaseHCL(tb testing.TB, listenerExtras string) string {
tb.Helper()

return strings.TrimSpace(fmt.Sprintf(`
disable_mlock = true
listener "tcp" {
address = "127.0.0.1:%d"
tls_disable = "true"
address = "127.0.0.1:%d"
tls_disable = "true"
%s
}
`, testRandomPort(tb)))
`, testRandomPort(tb), listenerExtras))
}

const (
goodListenerTimeouts = `http_read_header_timeout = 12
http_read_timeout = "34s"
http_write_timeout = "56m"
http_idle_timeout = "78h"`

badListenerReadHeaderTimeout = `http_read_header_timeout = "12km"`
badListenerReadTimeout = `http_read_timeout = "34日"`
badListenerWriteTimeout = `http_write_timeout = "56lbs"`
badListenerIdleTimeout = `http_idle_timeout = "78gophers"`

inmemHCL = `
backend "inmem_ha" {
advertise_addr = "http://127.0.0.1:8200"
Expand Down Expand Up @@ -204,24 +215,70 @@ func TestServer(t *testing.T) {
contents string
exp string
code int
flag string
}{
{
"common_ha",
testBaseHCL(t) + inmemHCL,
testBaseHCL(t, "") + inmemHCL,
"(HA available)",
0,
"-test-verify-only",
},
{
"separate_ha",
testBaseHCL(t) + inmemHCL + haInmemHCL,
testBaseHCL(t, "") + inmemHCL + haInmemHCL,
"HA Storage:",
0,
"-test-verify-only",
},
{
"bad_separate_ha",
testBaseHCL(t) + inmemHCL + badHAInmemHCL,
testBaseHCL(t, "") + inmemHCL + badHAInmemHCL,
"Specified HA storage does not support HA",
1,
"-test-verify-only",
},
{
"good_listener_timeout_config",
testBaseHCL(t, goodListenerTimeouts) + inmemHCL,
"",
0,
"-test-server-config",
},
{
"bad_listener_read_header_timeout_config",
testBaseHCL(t, badListenerReadHeaderTimeout) + inmemHCL,
"Could not parse a time value for http_read_header_timeout",
1,
"-test-server-config",
},
{
"bad_listener_read_header_timeout_config",
testBaseHCL(t, badListenerReadHeaderTimeout) + inmemHCL,
"Could not parse a time value for http_read_header_timeout",
1,
"-test-server-config",
},
{
"bad_listener_read_timeout_config",
testBaseHCL(t, badListenerReadTimeout) + inmemHCL,
"Could not parse a time value for http_read_timeout",
1,
"-test-server-config",
},
{
"bad_listener_write_timeout_config",
testBaseHCL(t, badListenerWriteTimeout) + inmemHCL,
"Could not parse a time value for http_write_timeout",
1,
"-test-server-config",
},
{
"bad_listener_idle_timeout_config",
testBaseHCL(t, badListenerIdleTimeout) + inmemHCL,
"Could not parse a time value for http_idle_timeout",
1,
"-test-server-config",
},
}

Expand All @@ -242,7 +299,7 @@ func TestServer(t *testing.T) {

code := cmd.Run([]string{
"-config", f.Name(),
"-test-verify-only",
tc.flag,
})
output := ui.ErrorWriter.String() + ui.OutputWriter.String()
if code != tc.code {
Expand Down

0 comments on commit 95ec131

Please sign in to comment.