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
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func TestAutomaticPersistedQueries(t *testing.T) {
t.Run("local cache", func(t *testing.T) {
t.Parallel()

t.Run("Sha without query fails", func(t *testing.T) {
t.Run("returns not found when an unknown hash has no query", func(t *testing.T) {
t.Parallel()

testenv.Run(t, &testenv.Config{
Expand All @@ -34,6 +34,9 @@ func TestAutomaticPersistedQueries(t *testing.T) {
},
ApqConfig: config.AutomaticPersistedQueriesConfig{
Enabled: true,
Cache: config.AutomaticPersistedQueriesCacheConfig{
Size: 1024 * 1024,
},
},
}, func(t *testing.T, xEnv *testenv.Environment) {
res := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,15 @@ func TestPersistedOperationOverGET(t *testing.T) {
func TestAutomatedPersistedQueriesOverGET(t *testing.T) {
t.Parallel()

t.Run("Operation not found", func(t *testing.T) {
t.Run("returns not found when the hash is unknown", func(t *testing.T) {
t.Parallel()

testenv.Run(t, &testenv.Config{
ApqConfig: config.AutomaticPersistedQueriesConfig{
Enabled: true,
Cache: config.AutomaticPersistedQueriesCacheConfig{
Size: 1024 * 1024,
},
},
}, func(t *testing.T, xEnv *testenv.Environment) {
header := make(http.Header)
Expand Down
5 changes: 4 additions & 1 deletion router-tests/subscriptions/websocket_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2383,12 +2383,15 @@ func TestWebSockets(t *testing.T) {
})
})

t.Run("cache poisoning is tried but prevented", func(t *testing.T) {
t.Run("rejects cache poisoning when query and hash differ", func(t *testing.T) {
t.Parallel()

testenv.Run(t, &testenv.Config{
ApqConfig: config.AutomaticPersistedQueriesConfig{
Enabled: true,
Cache: config.AutomaticPersistedQueriesCacheConfig{
Size: 1024 * 1024,
},
},
}, func(t *testing.T, xEnv *testenv.Environment) {
conn := xEnv.InitGraphQLWebSocketConnection(nil, nil, []byte(`{"graphql-client-name": "my-client"}`))
Expand Down
22 changes: 5 additions & 17 deletions router/core/operation_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ func (o *OperationKit) FetchPersistedOperation(ctx context.Context, clientInfo *
}
if fromCache {
if fromCacheHasTTL, _ := o.persistedOperationCacheKeyHasTtl(clientInfo.Name, includeOperationName); fromCacheHasTTL {
if err := o.renewAPQTTL(ctx, clientInfo.Name); err != nil {
if err := o.renewAPQTTL(ctx); err != nil {
return false, false, err
}
}
Expand All @@ -468,7 +468,7 @@ func (o *OperationKit) FetchPersistedOperation(ctx context.Context, clientInfo *
isAPQ = true

// If the operation was fetched with APQ, save it again to renew the TTL
err := o.operationProcessor.persistedOperationClient.SaveOperation(ctx, clientInfo.Name, o.parsedOperation.GraphQLRequestExtensions.PersistedQuery.Sha256Hash, o.parsedOperation.Request.Query)
err := o.operationProcessor.persistedOperationClient.SaveOperation(ctx, o.parsedOperation.GraphQLRequestExtensions.PersistedQuery.Sha256Hash, o.parsedOperation.Request.Query)
if err != nil {
return false, true, err
}
Expand Down Expand Up @@ -501,7 +501,7 @@ func (o *OperationKit) FetchPersistedOperation(ctx context.Context, clientInfo *

// If the operation was fetched with APQ, save it again to renew the TTL
if isAPQ {
if err = o.operationProcessor.persistedOperationClient.SaveOperation(ctx, clientInfo.Name, o.parsedOperation.GraphQLRequestExtensions.PersistedQuery.Sha256Hash, o.parsedOperation.Request.Query); err != nil {
if err = o.operationProcessor.persistedOperationClient.SaveOperation(ctx, o.parsedOperation.GraphQLRequestExtensions.PersistedQuery.Sha256Hash, o.parsedOperation.Request.Query); err != nil {
return false, true, err
}
}
Expand All @@ -510,21 +510,9 @@ func (o *OperationKit) FetchPersistedOperation(ctx context.Context, clientInfo *
return false, isAPQ, nil
}

func (o *OperationKit) renewAPQTTL(ctx context.Context, clientName string) error {
func (o *OperationKit) renewAPQTTL(ctx context.Context) error {
sha256Hash := o.parsedOperation.GraphQLRequestExtensions.PersistedQuery.Sha256Hash
// Reload the raw APQ body because normalization can remove conditional fields.
operationBody, isAPQ, err := o.operationProcessor.persistedOperationClient.PersistedOperation(ctx, clientName, sha256Hash)
if err != nil {
return err
}
if !isAPQ {
return nil
}
if len(operationBody) == 0 {
return nil
}

return o.operationProcessor.persistedOperationClient.SaveOperation(ctx, clientName, sha256Hash, string(operationBody))
return o.operationProcessor.persistedOperationClient.RenewOperation(ctx, sha256Hash)
}

const (
Expand Down
Loading
Loading