Go: fix context (#18061)

Signed-off-by: Jin Hai <haijin.chn@gmail.com>
This commit is contained in:
Jin Hai
2026-08-10 20:49:32 +08:00
committed by GitHub
parent a0438517bc
commit 38c5d7c338
9 changed files with 39 additions and 30 deletions

View File

@@ -165,7 +165,7 @@ func (h *AgentHandler) Webhook(c *gin.Context) {
// 6. Security gate (strict; surfaces all errors as 102).
securityCfg := stringMap(webhookCfg["security"])
if err := validateWebhookSecurity(securityCfg, c, canvasID); err != nil {
if err = validateWebhookSecurity(securityCfg, c, canvasID); err != nil {
common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error())
return
}

View File

@@ -39,12 +39,14 @@ import (
"errors"
"fmt"
"net"
"ragflow/internal/common"
"strconv"
"strings"
"time"
"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt/v5"
"go.uber.org/zap"
rediscli "ragflow/internal/engine/redis"
)
@@ -107,6 +109,7 @@ func validateWebhookSecurity(
c *gin.Context,
canvasID string,
) error {
ctx := c.Request.Context()
if len(securityCfg) == 0 {
return errWebhookFailClosed
}
@@ -116,7 +119,7 @@ func validateWebhookSecurity(
if err := validateIPWhitelist(c, securityCfg); err != nil {
return err
}
if err := validateRateLimit(canvasID, securityCfg); err != nil {
if err := validateRateLimit(ctx, canvasID, securityCfg); err != nil {
return err
}
return validateAuth(c, securityCfg)
@@ -242,7 +245,7 @@ func validateIPWhitelist(c *gin.Context, cfg map[string]any) error {
//
// Strict fail-closed: any Redis error → error. The webhook handler
// surfaces this as 102 so an operator notices a misconfiguration.
func validateRateLimit(canvasID string, cfg map[string]any) error {
func validateRateLimit(ctx context.Context, canvasID string, cfg map[string]any) error {
rawRL, ok := cfg["rate_limit"].(map[string]any)
if !ok || len(rawRL) == 0 {
return nil
@@ -277,15 +280,20 @@ func validateRateLimit(canvasID string, cfg map[string]any) error {
}
key := fmt.Sprintf("rl:tb:%s", canvasID)
ctx, cancel := context.WithTimeout(context.Background(), webhookRateLimitTimeout)
newCtx, cancel := context.WithTimeout(ctx, webhookRateLimitTimeout)
defer cancel()
rdb := rediscli.Get()
if rdb == nil {
return fmt.Errorf("rate limit error: redis not initialised")
}
allowed, err := rdb.EvalTokenBucketStrict(ctx, key, limitF, limitF/window)
allowed, err := rdb.EvalTokenBucketStrict(newCtx, key, limitF, limitF/window)
if err != nil {
if errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled) {
common.Warn("rate limit check ambiguous (timeout/cancel), allowing",
zap.String("canvas_id", canvasID), zap.Error(err))
return nil
}
return fmt.Errorf("rate limit error: %s", err.Error())
}
if !allowed {

View File

@@ -297,14 +297,16 @@ func TestValidateJWTAuth_ReservedClaimRejected(t *testing.T) {
// TestValidateRateLimit_NoConfig covers the no-rate-limit branch.
func TestValidateRateLimit_NoConfig(t *testing.T) {
if err := validateRateLimit("c1", map[string]any{}); err != nil {
ctx := t.Context()
if err := validateRateLimit(ctx, "c1", map[string]any{}); err != nil {
t.Errorf("no rate_limit: err = %v, want nil", err)
}
}
// TestValidateRateLimit_BadPer rejects unknown per window.
func TestValidateRateLimit_BadPer(t *testing.T) {
err := validateRateLimit("c1", map[string]any{
ctx := t.Context()
err := validateRateLimit(ctx, "c1", map[string]any{
"rate_limit": map[string]any{"limit": 10, "per": "week"},
})
if err == nil || !strings.Contains(err.Error(), "invalid rate_limit.per") {
@@ -314,7 +316,8 @@ func TestValidateRateLimit_BadPer(t *testing.T) {
// TestValidateRateLimit_BadLimit rejects non-positive limits.
func TestValidateRateLimit_BadLimit(t *testing.T) {
err := validateRateLimit("c1", map[string]any{
ctx := t.Context()
err := validateRateLimit(ctx, "c1", map[string]any{
"rate_limit": map[string]any{"limit": 0, "per": "minute"},
})
if err == nil || !strings.Contains(err.Error(), "must be > 0") {