Fix Windows remote URL detection

This commit is contained in:
lutc5
2026-05-06 16:58:27 +08:00
parent 22f793c188
commit a87b2eefe4
3 changed files with 55 additions and 3 deletions

View File

@@ -10,6 +10,7 @@ const saving = ref(false)
const openSelect = ref('') const openSelect = ref('')
const fallbackModelsText = ref('') const fallbackModelsText = ref('')
const isIPCBackend = computed(() => (config.value.Backend || 'ipc') === 'ipc') const isIPCBackend = computed(() => (config.value.Backend || 'ipc') === 'ipc')
const formattedTokenExpireAt = computed(() => formatDateTime(detection.value?.remoteTokenExpireAt))
const selectOptions = { const selectOptions = {
Backend: [ Backend: [
@@ -53,6 +54,21 @@ function chooseOption(field, value) {
refreshDetection() 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 () => { onMounted(async () => {
try { try {
config.value = await GetConfig() config.value = await GetConfig()
@@ -246,7 +262,8 @@ async function save() {
<div v-if="detection.remoteCredentialSuccess"> <div v-if="detection.remoteCredentialSuccess">
<dt>登录态有效期</dt> <dt>登录态有效期</dt>
<dd :class="{ 'warn-text': detection.remoteTokenExpired }"> <dd :class="{ 'warn-text': detection.remoteTokenExpired }">
{{ detection.remoteTokenExpireAt || '未提供' }} {{ formattedTokenExpireAt || '未提供' }}
<span v-if="formattedTokenExpireAt && detection.remoteTokenExpireAt" class="muted-inline">原始 {{ detection.remoteTokenExpireAt }}</span>
<span v-if="detection.remoteTokenExpired">已过期</span> <span v-if="detection.remoteTokenExpired">已过期</span>
</dd> </dd>
</div> </div>

View File

@@ -12,6 +12,7 @@ import (
"net/url" "net/url"
"os" "os"
"path/filepath" "path/filepath"
"regexp"
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
@@ -25,6 +26,8 @@ const (
modelListPath = "/algo/api/v2/model/list" modelListPath = "/algo/api/v2/model/list"
) )
var remoteBaseURLPattern = regexp.MustCompile(`https?://[^\s"'<>),\]}]+`)
type Config struct { type Config struct {
BaseURL string BaseURL string
AuthFile string AuthFile string
@@ -535,12 +538,16 @@ func uniqueStrings(values []string) []string {
} }
func extractBaseURLFromText(text 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{ for _, marker := range []string{
"endpoint config:", "endpoint config:",
"Using service url:", "Using service url:",
"Download asset from:", "Download asset from:",
"https://ai-lingma",
"https://lingma",
} { } {
if value := extractBaseURLAfterMarker(text, marker); value != "" { if value := extractBaseURLAfterMarker(text, marker); value != "" {
return value return value
@@ -574,10 +581,16 @@ func normalizeRemoteBaseURLHint(raw string) string {
if raw == "" { if raw == "" {
return "" return ""
} }
if strings.HasPrefix(raw, "ttps://") {
raw = "h" + raw
}
parsed, err := url.Parse(raw) parsed, err := url.Parse(raw)
if err != nil || parsed.Scheme == "" || parsed.Host == "" { if err != nil || parsed.Scheme == "" || parsed.Host == "" {
return "" return ""
} }
if parsed.Scheme != "http" && parsed.Scheme != "https" {
return ""
}
host := strings.ToLower(parsed.Host) host := strings.ToLower(parsed.Host)
if !strings.Contains(host, "lingma") && !strings.Contains(host, "rdc.aliyuncs.com") { if !strings.Contains(host, "lingma") && !strings.Contains(host, "rdc.aliyuncs.com") {
return "" return ""

View File

@@ -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) { func TestExtractMachineIDFromTextMarkers(t *testing.T) {
got := extractMachineIDFromText(`2026-05-06 info using machine id from file: abcdef1234567890abcdef`) got := extractMachineIDFromText(`2026-05-06 info using machine id from file: abcdef1234567890abcdef`)
if got != "abcdef1234567890abcdef" { if got != "abcdef1234567890abcdef" {