mirror of
https://gitcode.com/JianFeeeee/webui4frpc.git
synced 2026-09-20 08:57:55 +00:00
feat: M1 高级传输参数(P0)
- store: Local 增加 useEncryption/useCompression/bandwidthLimit/poolCount/metadatas/annotations;Remote 增加 transportProtocol/transportTls/transportPool/transportTlsServerName;新增 migrate() ALTER TABLE 迁移旧库 - render: 输出 transport 段(protocol/tls/poolCount)与 proxy 高级字段;补 TestRenderTransportAdvanced/OmittedWhenEmpty - main: renderRemote 闭包透传 M1 字段到 render.Proxy - web: LocalNode/RemoteNode 折叠高级区表单,types.ts 接口扩展 - 验证:go test 全绿、vue-tsc/build 通过、端到端 PUT canvas→frpc JSON 输出完整
This commit is contained in:
@ -24,6 +24,14 @@ type Proxy struct {
|
||||
SubDomain string
|
||||
// CustomDomains is used by http/https proxies when set.
|
||||
CustomDomains []string
|
||||
|
||||
// Advanced transport knobs (M1): proxy-level encryption/compression/limit.
|
||||
UseEncryption bool
|
||||
UseCompression bool
|
||||
BandwidthLimit string
|
||||
PoolCount int
|
||||
Metadatas map[string]string
|
||||
Annotations map[string]string
|
||||
}
|
||||
|
||||
// frpcAuth mirrors frpc's auth section.
|
||||
@ -34,7 +42,15 @@ type frpcAuth struct {
|
||||
|
||||
// frpcTransport is the transport section used by frpc.
|
||||
type frpcTransport struct {
|
||||
Protocol string `json:"protocol,omitempty"`
|
||||
Protocol string `json:"protocol,omitempty"`
|
||||
TLS *frpcTLS `json:"tls,omitempty"`
|
||||
PoolCount int `json:"poolCount,omitempty"`
|
||||
}
|
||||
|
||||
// frpcTLS mirrors frpc's transport.tls section.
|
||||
type frpcTLS struct {
|
||||
Enable bool `json:"enable,omitempty"`
|
||||
ServerName string `json:"serverName,omitempty"`
|
||||
}
|
||||
|
||||
// frpcProxy is the serialized proxy object. Different types use different
|
||||
@ -47,6 +63,14 @@ type frpcProxy struct {
|
||||
RemotePort int `json:"remotePort,omitempty"`
|
||||
CustomDomains []string `json:"customDomains,omitempty"`
|
||||
SubDomain string `json:"subdomain,omitempty"`
|
||||
|
||||
// M1 advanced transport fields.
|
||||
UseEncryption bool `json:"useEncryption,omitempty"`
|
||||
UseCompression bool `json:"useCompression,omitempty"`
|
||||
BandwidthLimit string `json:"bandwidthLimit,omitempty"`
|
||||
PoolCount int `json:"poolCount,omitempty"`
|
||||
Metadatas map[string]string `json:"metadatas,omitempty"`
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
}
|
||||
|
||||
// Config is a complete frpc configuration document.
|
||||
@ -69,15 +93,33 @@ func Render(remote store.Remote, proxies []Proxy) ([]byte, error) {
|
||||
LoginFailExit: false,
|
||||
Proxies: make([]frpcProxy, 0, len(proxies)),
|
||||
}
|
||||
if remote.TransportProtocol != "" || remote.TransportTLS || remote.TransportPool > 0 || remote.TransportTLSServerName != "" {
|
||||
cfg.Transport = frpcTransport{
|
||||
Protocol: remote.TransportProtocol,
|
||||
PoolCount: remote.TransportPool,
|
||||
}
|
||||
if remote.TransportTLS || remote.TransportTLSServerName != "" {
|
||||
cfg.Transport.TLS = &frpcTLS{
|
||||
Enable: remote.TransportTLS,
|
||||
ServerName: remote.TransportTLSServerName,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nameCounts := make(map[string]int)
|
||||
for _, p := range proxies {
|
||||
frpcP := frpcProxy{
|
||||
Name: p.Name,
|
||||
Type: p.Type,
|
||||
LocalIP: p.LocalIP,
|
||||
LocalPort: p.LocalPort,
|
||||
SubDomain: p.SubDomain,
|
||||
Name: p.Name,
|
||||
Type: p.Type,
|
||||
LocalIP: p.LocalIP,
|
||||
LocalPort: p.LocalPort,
|
||||
SubDomain: p.SubDomain,
|
||||
UseEncryption: p.UseEncryption,
|
||||
UseCompression: p.UseCompression,
|
||||
BandwidthLimit: p.BandwidthLimit,
|
||||
PoolCount: p.PoolCount,
|
||||
Metadatas: p.Metadatas,
|
||||
Annotations: p.Annotations,
|
||||
}
|
||||
// http/https proxies use customDomains instead of remotePort. The
|
||||
// default domain is <name>.local; frps matches it by Host header.
|
||||
|
||||
@ -46,3 +46,58 @@ func TestRenderDuplicateServiceGetsPortSuffix(t *testing.T) {
|
||||
t.Fatalf("second proxy name = %q", cfg.Proxies[1].Name)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRenderTransportAdvanced(t *testing.T) {
|
||||
remote := store.Remote{
|
||||
Name: "srv", IP: "1.2.3.4", Port: 7000, Token: "secret",
|
||||
TransportProtocol: "kcp", TransportTLS: true, TransportPool: 3, TransportTLSServerName: "frps.local",
|
||||
}
|
||||
data, err := Render(remote, []Proxy{
|
||||
{Name: "web", Type: "tcp", LocalIP: "127.0.0.1", LocalPort: 8080, RemotePort: 8080,
|
||||
UseEncryption: true, UseCompression: true, BandwidthLimit: "1MB", PoolCount: 2,
|
||||
Metadatas: map[string]string{"env": "prod"}, Annotations: map[string]string{"owner": "ops"}},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var cfg Config
|
||||
if err := json.Unmarshal(data, &cfg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if cfg.Transport.Protocol != "kcp" {
|
||||
t.Fatalf("transport.protocol = %q, want kcp", cfg.Transport.Protocol)
|
||||
}
|
||||
if cfg.Transport.TLS == nil || !cfg.Transport.TLS.Enable || cfg.Transport.TLS.ServerName != "frps.local" {
|
||||
t.Fatalf("transport.tls = %+v", cfg.Transport.TLS)
|
||||
}
|
||||
if cfg.Transport.PoolCount != 3 {
|
||||
t.Fatalf("transport.poolCount = %d, want 3", cfg.Transport.PoolCount)
|
||||
}
|
||||
p := cfg.Proxies[0]
|
||||
if !p.UseEncryption || !p.UseCompression || p.BandwidthLimit != "1MB" || p.PoolCount != 2 {
|
||||
t.Fatalf("proxy advanced fields = %+v", p)
|
||||
}
|
||||
if p.Metadatas["env"] != "prod" || p.Annotations["owner"] != "ops" {
|
||||
t.Fatalf("proxy metadatas/annotations = %+v", p)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRenderTransportOmittedWhenEmpty(t *testing.T) {
|
||||
remote := store.Remote{Name: "srv", IP: "1.2.3.4", Port: 7000}
|
||||
data, err := Render(remote, []Proxy{
|
||||
{Name: "web", Type: "tcp", LocalIP: "127.0.0.1", LocalPort: 8080, RemotePort: 8080},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var cfg Config
|
||||
if err := json.Unmarshal(data, &cfg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if cfg.Transport.Protocol != "" || cfg.Transport.TLS != nil || cfg.Transport.PoolCount != 0 {
|
||||
t.Fatalf("transport should be empty, got %+v", cfg.Transport)
|
||||
}
|
||||
if cfg.Proxies[0].UseEncryption || cfg.Proxies[0].BandwidthLimit != "" {
|
||||
t.Fatalf("proxy advanced should be empty, got %+v", cfg.Proxies[0])
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user