feat: M2 HTTP/HTTPS 完善

- store: Local 增加 customDomains/subdomain/locations/hostHeaderRewrite/httpHeaders/basicAuth;Remote 增加 vhostHttpPort;migrate() 补列;CRUD 读写(JSOm 编解码)

- render: http/https proxy 输出 customDomains/subdomain/locations/hostHeaderRewrite/httpHeaders/basicAuth

- main: renderRemote 透传 M2 字段(customDomains 逗号拆分 splitCSV)

- web: LocalNode 折叠 HTTP 路由高级区;RemoteNode vhostHTTPPort;StatusView 显示 HTTP 访问端口

- 测试: TestRenderHTTPAdvanced / TestRenderHTTPSUsesCustomDomains;端到端 PUT canvas→config 验证通过
This commit is contained in:
2026-08-17 12:59:12 +08:00
parent 07f25ea067
commit 58906c5a81
11 changed files with 323 additions and 116 deletions

View File

@ -2,109 +2,121 @@
// CanvasLocal / CanvasRemote are aliases kept for node components migrated
// from the original prototype; they equal Local / Remote.
export type CanvasLocal = Local
export type CanvasRemote = Remote
export type CanvasLocal = Local;
export type CanvasRemote = Remote;
// CanvasLink mirrors the store.Link JSON shape used by the canvas editor.
export type CanvasLink = Link
export type CanvasLink = Link;
export interface Local {
name: string
ip: string
port: number
protocol: string // tcp | udp | http | https
name: string;
ip: string;
port: number;
protocol: string; // tcp | udp | http | https
// M1 advanced transport knobs (optional; empty/zero = frpc defaults)
useEncryption?: boolean
useCompression?: boolean
bandwidthLimit?: string
poolCount?: number
metadatas?: Record<string, string>
annotations?: Record<string, string>
useEncryption?: boolean;
useCompression?: boolean;
bandwidthLimit?: string;
poolCount?: number;
metadatas?: Record<string, string>;
annotations?: Record<string, string>;
// M2 HTTP/HTTPS routing (http/https only)
customDomains?: string; // comma-separated
subdomain?: string;
locations?: string[];
hostHeaderRewrite?: string;
httpHeaders?: Record<string, string>;
basicAuthUser?: string;
basicAuthPassword?: string;
}
export interface Remote {
name: string
ip: string
port: number // frps connect port
token?: string
url?: string
enabled: boolean
name: string;
ip: string;
port: number; // frps connect port
token?: string;
url?: string;
enabled: boolean;
// M1 transport section
transportProtocol?: string // tcp | quic | kcp | websocket
transportTls?: boolean
transportPool?: number
transportTlsServerName?: string
transportProtocol?: string; // tcp | quic | kcp | websocket
transportTls?: boolean;
transportPool?: number;
transportTlsServerName?: string;
// M2: frps vhostHTTPPort
vhostHttpPort?: number;
}
export interface Link {
id?: number
local: string
remote: string
remotePort: number
offsetX?: number
offsetY?: number
id?: number;
local: string;
remote: string;
remotePort: number;
offsetX?: number;
offsetY?: number;
}
export interface CanvasData {
locals: Local[]
remotes: Remote[]
links: Link[]
locals: Local[];
remotes: Remote[];
links: Link[];
}
export interface Settings {
autoStartProfiles: boolean
restartOnExit: boolean
restartIntervalSeconds: number
binaryPath?: string
autoStartProfiles: boolean;
restartOnExit: boolean;
restartIntervalSeconds: number;
binaryPath?: string;
}
export interface ProcessStatus {
state: string
pid?: number
startTime?: number
restartCount: number
exitCode?: number
err?: string
state: string;
pid?: number;
startTime?: number;
restartCount: number;
exitCode?: number;
err?: string;
}
export interface StatusProfile {
name: string
enabled: boolean
process: ProcessStatus
hasProcess: boolean
forwards: { service: string; remotePort: number; localPort?: number }[]
name: string;
enabled: boolean;
process: ProcessStatus;
hasProcess: boolean;
forwards: { service: string; remotePort: number; localPort?: number }[];
}
export interface StatusResp {
version: string
workDir: string
settings: Settings
services: Local[]
remotes: Remote[]
binaryPath: string
profiles: StatusProfile[]
localStatus: LocalStatus[]
version: string;
workDir: string;
settings: Settings;
services: Local[];
remotes: Remote[];
binaryPath: string;
profiles: StatusProfile[];
localStatus: LocalStatus[];
}
export interface LocalTargetStatus {
remote: string
remotePort: number
workerState: string
remote: string;
remotePort: number;
workerState: string;
}
export interface LocalStatus {
local: Local
targets: LocalTargetStatus[]
local: Local;
targets: LocalTargetStatus[];
}
export interface BinaryStatus {
binaryPath: string
version?: string
binaryPath: string;
version?: string;
}
export interface InstallResult {
path: string
version: string
path: string;
version: string;
}