fix(auth, executor): normalize Qwen base URL, adjust RefreshLead duration, and add tests

This commit is contained in:
Luis Pater
2026-04-09 18:07:07 +08:00
parent ad8e3964ff
commit 5e81b65f2f
4 changed files with 74 additions and 2 deletions

View File

@@ -632,6 +632,26 @@ func applyQwenHeaders(r *http.Request, token string, stream bool) {
r.Header.Set("Accept", "application/json")
}
func normaliseQwenBaseURL(resourceURL string) string {
raw := strings.TrimSpace(resourceURL)
if raw == "" {
return ""
}
normalized := raw
lower := strings.ToLower(normalized)
if !strings.HasPrefix(lower, "http://") && !strings.HasPrefix(lower, "https://") {
normalized = "https://" + normalized
}
normalized = strings.TrimRight(normalized, "/")
if !strings.HasSuffix(strings.ToLower(normalized), "/v1") {
normalized += "/v1"
}
return normalized
}
func qwenCreds(a *cliproxyauth.Auth) (token, baseURL string) {
if a == nil {
return "", ""
@@ -649,7 +669,7 @@ func qwenCreds(a *cliproxyauth.Auth) (token, baseURL string) {
token = v
}
if v, ok := a.Metadata["resource_url"].(string); ok {
baseURL = fmt.Sprintf("https://%s/v1", v)
baseURL = normaliseQwenBaseURL(v)
}
}
return

View File

@@ -6,6 +6,7 @@ import (
"testing"
"github.com/router-for-me/CLIProxyAPI/v6/internal/thinking"
cliproxyauth "github.com/router-for-me/CLIProxyAPI/v6/sdk/cliproxy/auth"
"github.com/tidwall/gjson"
)
@@ -176,3 +177,35 @@ func TestWrapQwenError_Maps403QuotaTo429WithoutRetryAfter(t *testing.T) {
t.Fatalf("wrapQwenError retryAfter = %v, want nil", *retryAfter)
}
}
func TestQwenCreds_NormalizesResourceURL(t *testing.T) {
tests := []struct {
name string
resourceURL string
wantBaseURL string
}{
{"host only", "portal.qwen.ai", "https://portal.qwen.ai/v1"},
{"scheme no v1", "https://portal.qwen.ai", "https://portal.qwen.ai/v1"},
{"scheme with v1", "https://portal.qwen.ai/v1", "https://portal.qwen.ai/v1"},
{"scheme with v1 slash", "https://portal.qwen.ai/v1/", "https://portal.qwen.ai/v1"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
auth := &cliproxyauth.Auth{
Metadata: map[string]any{
"access_token": "test-token",
"resource_url": tt.resourceURL,
},
}
token, baseURL := qwenCreds(auth)
if token != "test-token" {
t.Fatalf("qwenCreds token = %q, want %q", token, "test-token")
}
if baseURL != tt.wantBaseURL {
t.Fatalf("qwenCreds baseURL = %q, want %q", baseURL, tt.wantBaseURL)
}
})
}
}

View File

@@ -27,7 +27,7 @@ func (a *QwenAuthenticator) Provider() string {
}
func (a *QwenAuthenticator) RefreshLead() *time.Duration {
return new(3 * time.Hour)
return new(20 * time.Minute)
}
func (a *QwenAuthenticator) Login(ctx context.Context, cfg *config.Config, opts *LoginOptions) (*coreauth.Auth, error) {

View File

@@ -0,0 +1,19 @@
package auth
import (
"testing"
"time"
)
func TestQwenAuthenticator_RefreshLeadIsSane(t *testing.T) {
lead := NewQwenAuthenticator().RefreshLead()
if lead == nil {
t.Fatal("RefreshLead() = nil, want non-nil")
}
if *lead <= 0 {
t.Fatalf("RefreshLead() = %s, want > 0", *lead)
}
if *lead > 30*time.Minute {
t.Fatalf("RefreshLead() = %s, want <= %s", *lead, 30*time.Minute)
}
}