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

Backport of Add maximum request duration (timeouts) for all requests except actual monitor and events requests into release/1.17.x #28257

Merged
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
3 changes: 3 additions & 0 deletions changelog/28230.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
core: Fixed an issue where maximum request duration timeout was not being added to all requests containing strings sys/monitor and sys/events. With this change, timeout is now added to all requests except monitor and events endpoint.
```
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package cache
import (
"context"
"fmt"
"os"
"sync"
syncatomic "sync/atomic"
"testing"
Expand Down Expand Up @@ -281,6 +282,8 @@ func TestOpenWebSocketConnection_AutoAuthSelfHeal(t *testing.T) {
// works as expected with the default KVV1 mount, and then the connection can be used to receive an event.
// This acts as more of an event system sanity check than a test of the updater
// logic. It's still important coverage, though.
// It also adds a client timeout of 1 second and checks that the connection does not timeout as this is a
// streaming request.
func TestOpenWebSocketConnectionReceivesEventsDefaultMount(t *testing.T) {
if !constants.IsEnterprise {
t.Skip("test can only run on enterprise due to requiring the event notification system")
Expand All @@ -290,6 +293,11 @@ func TestOpenWebSocketConnectionReceivesEventsDefaultMount(t *testing.T) {
cluster := vault.NewTestCluster(t, nil, &vault.TestClusterOptions{
HandlerFunc: vaulthttp.Handler,
})

oldClientTimeout := os.Getenv("VAULT_CLIENT_TIMEOUT")
os.Setenv("VAULT_CLIENT_TIMEOUT", "1")
defer os.Setenv("VAULT_CLIENT_TIMEOUT", oldClientTimeout)

client := cluster.Cores[0].Client

updater := testNewStaticSecretCacheUpdater(t, client)
Expand Down Expand Up @@ -318,6 +326,7 @@ func TestOpenWebSocketConnectionReceivesEventsDefaultMount(t *testing.T) {

// This method blocks until it gets a secret, so this test
// will only pass if we're receiving events correctly.
// It will fail here if the connection times out.
_, _, err = conn.Read(context.Background())
require.NoError(t, err)
}
Expand Down
4 changes: 3 additions & 1 deletion http/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,9 @@ func wrapGenericHandler(core *vault.Core, h http.Handler, props *vault.HandlerPr
ctx := r.Context()
var cancelFunc context.CancelFunc
// Add our timeout, but not for the monitor or events endpoints, as they are streaming
if strings.HasSuffix(r.URL.Path, "sys/monitor") || strings.Contains(r.URL.Path, "sys/events") {
// Request URL path for sys/monitor looks like /v1/sys/monitor
// Request URL paths for event subscriptions look like /v1/sys/events/subscribe/{eventType}. Example: /v1/sys/events/subscribe/kv*
if r.URL.Path == "/v1/sys/monitor" || strings.HasPrefix(r.URL.Path, "/v1/sys/events/subscribe") {
ctx, cancelFunc = context.WithCancel(ctx)
} else {
ctx, cancelFunc = context.WithTimeout(ctx, maxRequestDuration)
Expand Down
5 changes: 3 additions & 2 deletions http/sys_monitor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ func TestSysMonitorStreamingLogs(t *testing.T) {
}
jsonLog := &jsonlog{}

timeCh := time.After(5 * time.Second)
// default timeout is 90 seconds
timeCh := time.After(120 * time.Second)

for {
select {
Expand All @@ -119,7 +120,7 @@ func TestSysMonitorStreamingLogs(t *testing.T) {
return
}
case <-timeCh:
t.Fatal("Failed to get a DEBUG message after 5 seconds")
t.Fatal("Failed to get a DEBUG message after 120 seconds")
}
}
})
Expand Down
Loading