fix: allow HTTP for configurable service endpoints
DeepSeek Harness and Weixin binding configuration rejected non-loopback HTTP endpoints even when users explicitly selected those internal services. Configurable endpoints now accept valid HTTP and HTTPS URLs without host-location restrictions, while retaining the required protocol and API-key checks. Release note: 模型连接、DeepSeek Harness 与微信绑定现在可直接使用局域网或公网 HTTP/HTTPS 服务地址,不再强制公网 HTTPS 或本机回环地址。
This commit is contained in:
@@ -830,7 +830,7 @@ export const runtimeSettingsInputSchema = z
|
||||
code: 'custom',
|
||||
path: ['deepseekHarnessModelSource'],
|
||||
message:
|
||||
'DeepSeek Harness 仅支持使用 API Key 的安全 OpenAI 兼容 Chat Completions 连接'
|
||||
'DeepSeek Harness 仅支持使用 API Key 的 OpenAI 兼容 Chat Completions 连接'
|
||||
})
|
||||
}
|
||||
const compressionSource = settings.contextCompression?.modelSource
|
||||
|
||||
@@ -9,9 +9,14 @@ describe('DeepSeek Harness model compatibility', () => {
|
||||
'https://api.deepseek.com',
|
||||
'https://gateway.example/openai/v1',
|
||||
'https://gateway.example:8443/v1',
|
||||
'http://gateway.example/v1',
|
||||
'http://192.168.1.50:11434/v1',
|
||||
'http://127.0.0.1:11434/v1',
|
||||
'http://localhost:1234/v1',
|
||||
'http://[::1]:8080/v1'
|
||||
'http://[::1]:8080/v1',
|
||||
'https://gateway.example/v1?api-version=2025-01-01',
|
||||
'https://gateway.example/v1#chat',
|
||||
'http://user:password@gateway.example/v1'
|
||||
])('accepts OpenAI-compatible base URL %s', (baseUrl) => {
|
||||
expect(isDeepSeekHarnessCompatibleBaseUrl(baseUrl)).toBe(true)
|
||||
expect(
|
||||
@@ -24,12 +29,10 @@ describe('DeepSeek Harness model compatibility', () => {
|
||||
})
|
||||
|
||||
it.each([
|
||||
'http://gateway.example/v1',
|
||||
'file:///private/config',
|
||||
'https://user:secret@gateway.example/v1',
|
||||
'https://gateway.example/v1?api-version=2025-01-01',
|
||||
'https://gateway.example/v1#chat'
|
||||
])('rejects unsafe or unsupported base URL %s', (baseUrl) => {
|
||||
'ftp://gateway.example/v1',
|
||||
'not-a-url'
|
||||
])('rejects unsupported base URL %s', (baseUrl) => {
|
||||
expect(isDeepSeekHarnessCompatibleBaseUrl(baseUrl)).toBe(false)
|
||||
})
|
||||
|
||||
|
||||
@@ -4,35 +4,14 @@ type DeepSeekHarnessModelProfile = {
|
||||
authentication: string
|
||||
}
|
||||
|
||||
function isLoopbackHostname(hostname: string): boolean {
|
||||
const normalized = hostname
|
||||
.toLowerCase()
|
||||
.replace(/^\[|\]$/gu, '')
|
||||
return (
|
||||
normalized === 'localhost' ||
|
||||
normalized === '127.0.0.1' ||
|
||||
normalized === '::1'
|
||||
)
|
||||
}
|
||||
|
||||
export function isDeepSeekHarnessCompatibleBaseUrl(
|
||||
value: string
|
||||
): boolean {
|
||||
try {
|
||||
const url = new URL(value)
|
||||
if (
|
||||
!url.hostname ||
|
||||
url.username ||
|
||||
url.password ||
|
||||
url.search ||
|
||||
url.hash
|
||||
) {
|
||||
return false
|
||||
}
|
||||
return (
|
||||
url.protocol === 'https:' ||
|
||||
(url.protocol === 'http:' &&
|
||||
isLoopbackHostname(url.hostname))
|
||||
Boolean(url.hostname) &&
|
||||
(url.protocol === 'http:' || url.protocol === 'https:')
|
||||
)
|
||||
} catch {
|
||||
return false
|
||||
|
||||
Reference in New Issue
Block a user