From a87b2eefe4f5d7b201b34ace25721fef33573db8 Mon Sep 17 00:00:00 2001 From: lutc5 Date: Wed, 6 May 2026 16:58:27 +0800 Subject: [PATCH] Fix Windows remote URL detection --- desktop/frontend/src/views/Settings.vue | 19 ++++++++++++++++++- internal/remote/client.go | 17 +++++++++++++++-- internal/remote/client_test.go | 22 ++++++++++++++++++++++ 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/desktop/frontend/src/views/Settings.vue b/desktop/frontend/src/views/Settings.vue index 9b3df27..206a1d6 100644 --- a/desktop/frontend/src/views/Settings.vue +++ b/desktop/frontend/src/views/Settings.vue @@ -10,6 +10,7 @@ const saving = ref(false) const openSelect = ref('') const fallbackModelsText = ref('') const isIPCBackend = computed(() => (config.value.Backend || 'ipc') === 'ipc') +const formattedTokenExpireAt = computed(() => formatDateTime(detection.value?.remoteTokenExpireAt)) const selectOptions = { Backend: [ @@ -53,6 +54,21 @@ function chooseOption(field, value) { refreshDetection() } +function formatDateTime(value) { + if (!value) return '' + const date = new Date(value) + if (Number.isNaN(date.getTime())) return value + return new Intl.DateTimeFormat('zh-CN', { + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit', + second: '2-digit', + hour12: false, + }).format(date) +} + onMounted(async () => { try { config.value = await GetConfig() @@ -246,7 +262,8 @@ async function save() {
登录态有效期
- {{ detection.remoteTokenExpireAt || '未提供' }} + {{ formattedTokenExpireAt || '未提供' }} + 原始 {{ detection.remoteTokenExpireAt }} (已过期)
diff --git a/internal/remote/client.go b/internal/remote/client.go index 991dfcc..1e4b0d4 100644 --- a/internal/remote/client.go +++ b/internal/remote/client.go @@ -12,6 +12,7 @@ import ( "net/url" "os" "path/filepath" + "regexp" "sort" "strconv" "strings" @@ -25,6 +26,8 @@ const ( modelListPath = "/algo/api/v2/model/list" ) +var remoteBaseURLPattern = regexp.MustCompile(`https?://[^\s"'<>),\]}]+`) + type Config struct { BaseURL string AuthFile string @@ -535,12 +538,16 @@ func uniqueStrings(values []string) []string { } func extractBaseURLFromText(text string) string { + matches := remoteBaseURLPattern.FindAllString(text, -1) + for i := len(matches) - 1; i >= 0; i-- { + if value := normalizeRemoteBaseURLHint(matches[i]); value != "" { + return value + } + } for _, marker := range []string{ "endpoint config:", "Using service url:", "Download asset from:", - "https://ai-lingma", - "https://lingma", } { if value := extractBaseURLAfterMarker(text, marker); value != "" { return value @@ -574,10 +581,16 @@ func normalizeRemoteBaseURLHint(raw string) string { if raw == "" { return "" } + if strings.HasPrefix(raw, "ttps://") { + raw = "h" + raw + } parsed, err := url.Parse(raw) if err != nil || parsed.Scheme == "" || parsed.Host == "" { return "" } + if parsed.Scheme != "http" && parsed.Scheme != "https" { + return "" + } host := strings.ToLower(parsed.Host) if !strings.Contains(host, "lingma") && !strings.Contains(host, "rdc.aliyuncs.com") { return "" diff --git a/internal/remote/client_test.go b/internal/remote/client_test.go index 0ab9729..03824a9 100644 --- a/internal/remote/client_test.go +++ b/internal/remote/client_test.go @@ -37,6 +37,28 @@ func TestExtractBaseURLFromMarketplaceLog(t *testing.T) { } } +func TestExtractBaseURLFromRawWindowsLogURL(t *testing.T) { + got := extractBaseURLFromText(`2026-05-06T12:00:00 endpoint=https://ai-lingma-cmb01-cn-beijing.rdc.aliyuncs.com/algo/api/v2/model/list`) + want := "https://ai-lingma-cmb01-cn-beijing.rdc.aliyuncs.com" + if got != want { + t.Fatalf("got %q, want %q", got, want) + } +} + +func TestNormalizeBaseURLRepairsMissingLeadingH(t *testing.T) { + got := normalizeRemoteBaseURLHint(`ttps://ai-lingma-cmb01-cn-beijing.rdc.aliyuncs.com`) + want := "https://ai-lingma-cmb01-cn-beijing.rdc.aliyuncs.com" + if got != want { + t.Fatalf("got %q, want %q", got, want) + } +} + +func TestNormalizeBaseURLRejectsUnsupportedScheme(t *testing.T) { + if got := normalizeRemoteBaseURLHint(`ftp://ai-lingma-cmb01-cn-beijing.rdc.aliyuncs.com`); got != "" { + t.Fatalf("got %q, want empty", got) + } +} + func TestExtractMachineIDFromTextMarkers(t *testing.T) { got := extractMachineIDFromText(`2026-05-06 info using machine id from file: abcdef1234567890abcdef`) if got != "abcdef1234567890abcdef" {