Ver código fonte

Merge pull request #3668 from fatedier/dev

bump version to v0.52.1
fatedier 1 ano atrás
pai
commit
31fa3f021a

+ 2 - 0
README.md

@@ -761,6 +761,8 @@ allowPorts = [
 
 `vhostHTTPPort` and `vhostHTTPSPort` in frps can use same port with `bindPort`. frps will detect the connection's protocol and handle it correspondingly.
 
+What you need to pay attention to is that if you want to configure `vhostHTTPSPort` and `bindPort` to the same port, you need to first set `transport.tls.disableCustomTLSFirstByte` to false.
+
 We would like to try to allow multiple proxies bind a same remote port with different protocols in the future.
 
 ### Bandwidth Limit

+ 5 - 8
Release.md

@@ -1,9 +1,6 @@
-### Features
+### Fixes
 
-* Configuration: We now support TOML, YAML, and JSON for configuration. Please note that INI is deprecated and will be removed in future releases. New features will only be available in TOML, YAML, or JSON. Users wanting these new features should switch their configuration format accordingly. #2521
-
-### Breaking Changes
-
-* Change the way to start the visitor through the command line from `frpc stcp --role=visitor xxx` to `frpc stcp visitor xxx`.
-* Modified the semantics of the `server_addr` in the command line, no longer including the port. Added the `server_port` parameter to configure the port.
-* No longer support range ports mapping in TOML/YAML/JSON.
+* `transport.tls.disableCustomTLSFirstByte` doesn't have any effect.
+* The Server API did not return the data correctly.
+* The Dashboard is unable to display data.
+* `natHoleStunServer` is missing a default value.

Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
assets/frps/static/index-9465253b.js


+ 1 - 1
assets/frps/static/index.html

@@ -4,7 +4,7 @@
 <head>
     <meta charset="utf-8">
     <title>frps dashboard</title>
-  <script type="module" crossorigin src="./index-ea3edf22.js"></script>
+  <script type="module" crossorigin src="./index-9465253b.js"></script>
   <link rel="stylesheet" href="./index-1e0c7400.css">
 </head>
 

+ 3 - 0
client/service.go

@@ -476,6 +476,9 @@ func (cm *ConnectionManager) realConnect() (net.Conn, error) {
 		// Make sure that if it is wss, the websocket hook is executed after the tls hook.
 		dialOptions = append(dialOptions, libdial.WithAfterHook(libdial.AfterHook{Hook: utilnet.DialHookWebsocket(protocol, tlsConfig.ServerName), Priority: 110}))
 	default:
+		dialOptions = append(dialOptions, libdial.WithAfterHook(libdial.AfterHook{
+			Hook: utilnet.DialHookCustomTLSHeadByte(tlsConfig != nil, lo.FromPtr(cm.cfg.Transport.TLS.DisableCustomTLSFirstByte)),
+		}))
 		dialOptions = append(dialOptions, libdial.WithTLSConfig(tlsConfig))
 	}
 

+ 1 - 1
conf/frps.toml

@@ -83,7 +83,7 @@ enablePrometheus = true
 # console or real logFile path like ./frps.log
 log.to = "./frps.log"
 # trace, debug, info, warn, error
-log.level = info
+log.level = "info"
 log.maxDays = 3
 # disable log colors when log.to is console, default is false
 log.disablePrintColor = false

+ 1 - 0
pkg/config/legacy/conversion.go

@@ -306,6 +306,7 @@ func Convert_ProxyConf_To_v1(conf ProxyConf) v1.ProxyConfigurer {
 		c := &v1.XTCPProxyConfig{ProxyBaseConfig: *outBase}
 		c.Secretkey = v.Sk
 		c.AllowUsers = v.AllowUsers
+		out = c
 	}
 	return out
 }

+ 1 - 1
pkg/config/legacy/server.go

@@ -27,7 +27,7 @@ type HTTPPluginOptions struct {
 	Addr      string   `ini:"addr"`
 	Path      string   `ini:"path"`
 	Ops       []string `ini:"ops"`
-	TLSVerify bool     `ini:"tls_verify"`
+	TLSVerify bool     `ini:"tlsVerify"`
 }
 
 // ServerCommonConf contains information for a server service. It is

+ 1 - 0
pkg/config/v1/client.go

@@ -76,6 +76,7 @@ func (c *ClientCommonConfig) Complete() {
 	c.ServerAddr = util.EmptyOr(c.ServerAddr, "0.0.0.0")
 	c.ServerPort = util.EmptyOr(c.ServerPort, 7000)
 	c.LoginFailExit = util.EmptyOr(c.LoginFailExit, lo.ToPtr(true))
+	c.NatHoleSTUNServer = util.EmptyOr(c.NatHoleSTUNServer, "stun.easyvoip.com:3478")
 
 	c.Auth.Complete()
 	c.Log.Complete()

+ 1 - 0
pkg/config/v1/client_test.go

@@ -31,4 +31,5 @@ func TestClientConfigComplete(t *testing.T) {
 	require.Equal(true, lo.FromPtr(c.LoginFailExit))
 	require.Equal(true, lo.FromPtr(c.Transport.TLS.Enable))
 	require.Equal(true, lo.FromPtr(c.Transport.TLS.DisableCustomTLSFirstByte))
+	require.NotEmpty(c.NatHoleSTUNServer)
 }

+ 1 - 1
pkg/config/v1/common.go

@@ -109,7 +109,7 @@ type HTTPPluginOptions struct {
 	Addr      string   `json:"addr"`
 	Path      string   `json:"path"`
 	Ops       []string `json:"ops"`
-	TLSVerify bool     `json:"tls_verify,omitempty"`
+	TLSVerify bool     `json:"tlsVerify,omitempty"`
 }
 
 type HeaderOperations struct {

+ 4 - 2
pkg/config/v1/plugin.go

@@ -16,7 +16,6 @@ package v1
 
 import (
 	"encoding/json"
-	"errors"
 	"fmt"
 	"reflect"
 )
@@ -30,7 +29,7 @@ type TypedClientPluginOptions struct {
 
 func (c *TypedClientPluginOptions) UnmarshalJSON(b []byte) error {
 	if len(b) == 4 && string(b) == "null" {
-		return errors.New("type is required")
+		return nil
 	}
 
 	typeStruct := struct {
@@ -41,6 +40,9 @@ func (c *TypedClientPluginOptions) UnmarshalJSON(b []byte) error {
 	}
 
 	c.Type = typeStruct.Type
+	if c.Type == "" {
+		return nil
+	}
 
 	v, ok := clientPluginOptionsTypeMap[typeStruct.Type]
 	if !ok {

+ 1 - 1
pkg/util/version/version.go

@@ -19,7 +19,7 @@ import (
 	"strings"
 )
 
-var version = "0.52.0"
+var version = "0.52.1"
 
 func Full() string {
 	return version

+ 35 - 35
server/dashboard_api.go

@@ -34,24 +34,24 @@ type GeneralResponse struct {
 
 type serverInfoResp struct {
 	Version               string `json:"version"`
-	BindPort              int    `json:"bind_port"`
-	VhostHTTPPort         int    `json:"vhost_http_port"`
-	VhostHTTPSPort        int    `json:"vhost_https_port"`
-	TCPMuxHTTPConnectPort int    `json:"tcpmux_httpconnect_port"`
-	KCPBindPort           int    `json:"kcp_bind_port"`
-	QUICBindPort          int    `json:"quic_bind_port"`
-	SubdomainHost         string `json:"subdomain_host"`
-	MaxPoolCount          int64  `json:"max_pool_count"`
-	MaxPortsPerClient     int64  `json:"max_ports_per_client"`
-	HeartBeatTimeout      int64  `json:"heart_beat_timeout"`
-	AllowPortsStr         string `json:"allow_ports_str,omitempty"`
-	TLSOnly               bool   `json:"tls_only,omitempty"`
-
-	TotalTrafficIn  int64            `json:"total_traffic_in"`
-	TotalTrafficOut int64            `json:"total_traffic_out"`
-	CurConns        int64            `json:"cur_conns"`
-	ClientCounts    int64            `json:"client_counts"`
-	ProxyTypeCounts map[string]int64 `json:"proxy_type_count"`
+	BindPort              int    `json:"bindPort"`
+	VhostHTTPPort         int    `json:"vhostHTTPPort"`
+	VhostHTTPSPort        int    `json:"vhostHTTPSPort"`
+	TCPMuxHTTPConnectPort int    `json:"tcpmuxHTTPConnectPort"`
+	KCPBindPort           int    `json:"kcpBindPort"`
+	QUICBindPort          int    `json:"quicBindPort"`
+	SubdomainHost         string `json:"subdomainHost"`
+	MaxPoolCount          int64  `json:"maxPoolCount"`
+	MaxPortsPerClient     int64  `json:"maxPortsPerClient"`
+	HeartBeatTimeout      int64  `json:"heartbeatTimeout"`
+	AllowPortsStr         string `json:"allowPortsStr,omitempty"`
+	TLSForce              bool   `json:"tlsForce,omitempty"`
+
+	TotalTrafficIn  int64            `json:"totalTrafficIn"`
+	TotalTrafficOut int64            `json:"totalTrafficOut"`
+	CurConns        int64            `json:"curConns"`
+	ClientCounts    int64            `json:"clientCounts"`
+	ProxyTypeCounts map[string]int64 `json:"proxyTypeCount"`
 }
 
 // /healthz
@@ -85,7 +85,7 @@ func (svr *Service) APIServerInfo(w http.ResponseWriter, r *http.Request) {
 		MaxPortsPerClient:     svr.cfg.MaxPortsPerClient,
 		HeartBeatTimeout:      svr.cfg.Transport.HeartbeatTimeout,
 		AllowPortsStr:         types.PortsRangeSlice(svr.cfg.AllowPorts).String(),
-		TLSOnly:               svr.cfg.Transport.TLS.Force,
+		TLSForce:              svr.cfg.Transport.TLS.Force,
 
 		TotalTrafficIn:  serverStats.TotalTrafficIn,
 		TotalTrafficOut: serverStats.TotalTrafficOut,
@@ -104,7 +104,7 @@ type BaseOutConf struct {
 
 type TCPOutConf struct {
 	BaseOutConf
-	RemotePort int `json:"remote_port"`
+	RemotePort int `json:"remotePort"`
 }
 
 type TCPMuxOutConf struct {
@@ -115,14 +115,14 @@ type TCPMuxOutConf struct {
 
 type UDPOutConf struct {
 	BaseOutConf
-	RemotePort int `json:"remote_port"`
+	RemotePort int `json:"remotePort"`
 }
 
 type HTTPOutConf struct {
 	BaseOutConf
 	v1.DomainConfig
 	Locations         []string `json:"locations"`
-	HostHeaderRewrite string   `json:"host_header_rewrite"`
+	HostHeaderRewrite string   `json:"hostHeaderRewrite"`
 }
 
 type HTTPSOutConf struct {
@@ -163,12 +163,12 @@ func getConfByType(proxyType string) any {
 type ProxyStatsInfo struct {
 	Name            string      `json:"name"`
 	Conf            interface{} `json:"conf"`
-	ClientVersion   string      `json:"client_version,omitempty"`
-	TodayTrafficIn  int64       `json:"today_traffic_in"`
-	TodayTrafficOut int64       `json:"today_traffic_out"`
-	CurConns        int64       `json:"cur_conns"`
-	LastStartTime   string      `json:"last_start_time"`
-	LastCloseTime   string      `json:"last_close_time"`
+	ClientVersion   string      `json:"clientVersion,omitempty"`
+	TodayTrafficIn  int64       `json:"todayTrafficIn"`
+	TodayTrafficOut int64       `json:"todayTrafficOut"`
+	CurConns        int64       `json:"curConns"`
+	LastStartTime   string      `json:"lastStartTime"`
+	LastCloseTime   string      `json:"lastCloseTime"`
 	Status          string      `json:"status"`
 }
 
@@ -236,11 +236,11 @@ func (svr *Service) getProxyStatsByType(proxyType string) (proxyInfos []*ProxySt
 type GetProxyStatsResp struct {
 	Name            string      `json:"name"`
 	Conf            interface{} `json:"conf"`
-	TodayTrafficIn  int64       `json:"today_traffic_in"`
-	TodayTrafficOut int64       `json:"today_traffic_out"`
-	CurConns        int64       `json:"cur_conns"`
-	LastStartTime   string      `json:"last_start_time"`
-	LastCloseTime   string      `json:"last_close_time"`
+	TodayTrafficIn  int64       `json:"todayTrafficIn"`
+	TodayTrafficOut int64       `json:"todayTrafficOut"`
+	CurConns        int64       `json:"curConns"`
+	LastStartTime   string      `json:"lastStartTime"`
+	LastCloseTime   string      `json:"lastCloseTime"`
 	Status          string      `json:"status"`
 }
 
@@ -310,8 +310,8 @@ func (svr *Service) getProxyStatsByTypeAndName(proxyType string, proxyName strin
 // /api/traffic/:name
 type GetProxyTrafficResp struct {
 	Name       string  `json:"name"`
-	TrafficIn  []int64 `json:"traffic_in"`
-	TrafficOut []int64 `json:"traffic_out"`
+	TrafficIn  []int64 `json:"trafficIn"`
+	TrafficOut []int64 `json:"trafficOut"`
 }
 
 func (svr *Service) APIProxyTraffic(w http.ResponseWriter, r *http.Request) {

+ 2 - 0
test/e2e/framework/consts/consts.go

@@ -25,6 +25,7 @@ log.level = "trace"
 	DefaultClientConfig = `
 serverAddr = "127.0.0.1"
 serverPort = {{ .%s }}
+loginFailExit = false
 log.level = "trace"
 `
 
@@ -38,6 +39,7 @@ log.level = "trace"
 	[common]
 	server_addr = 127.0.0.1
 	server_port = {{ .%s }}
+	login_fail_exit = false
 	log_level = trace
 	`
 )

+ 1 - 0
test/e2e/framework/process.go

@@ -40,6 +40,7 @@ func (f *Framework) RunProcesses(serverTemplates []string, clientTemplates []str
 		currentServerProcesses = append(currentServerProcesses, p)
 		err = p.Start()
 		ExpectNoError(err)
+		time.Sleep(500 * time.Millisecond)
 	}
 	time.Sleep(1 * time.Second)
 

+ 19 - 1
test/e2e/v1/basic/client_server.go

@@ -291,7 +291,7 @@ var _ = ginkgo.Describe("[Feature: Client-Server]", func() {
 		})
 	})
 
-	ginkgo.Describe("TLS with disable_custom_tls_first_byte set to false", func() {
+	ginkgo.Describe("TLS with disableCustomTLSFirstByte set to false", func() {
 		supportProtocols := []string{"tcp", "kcp", "quic", "websocket"}
 		for _, protocol := range supportProtocols {
 			tmp := protocol
@@ -322,4 +322,22 @@ var _ = ginkgo.Describe("[Feature: Client-Server]", func() {
 			})
 		}
 	})
+
+	ginkgo.Describe("Use same port for bindPort and vhostHTTPSPort", func() {
+		supportProtocols := []string{"tcp", "kcp", "quic", "websocket"}
+		for _, protocol := range supportProtocols {
+			tmp := protocol
+			defineClientServerTest("Use same port for bindPort and vhostHTTPSPort: "+strings.ToUpper(tmp), f, &generalTestConfigures{
+				server: fmt.Sprintf(`
+					vhostHTTPSPort = {{ .%s }}
+					%s
+					`, consts.PortServerName, renderBindPortConfig(protocol)),
+				// transport.tls.disableCustomTLSFirstByte should set to false when vhostHTTPSPort is same as bindPort
+				client: fmt.Sprintf(`
+					transport.protocol = "%s"
+					transport.tls.disableCustomTLSFirstByte = false
+					`, protocol),
+			})
+		}
+	})
 })

+ 3 - 1
web/frps/auto-imports.d.ts

@@ -1,3 +1,5 @@
 // Generated by 'unplugin-auto-import'
 export {}
-declare global {}
+declare global {
+
+}

+ 6 - 6
web/frps/src/components/ProxiesHTTP.vue

@@ -10,16 +10,16 @@ import ProxyView from './ProxyView.vue'
 let proxies = ref<HTTPProxy[]>([])
 
 const fetchData = () => {
-  let vhost_http_port: number
-  let subdomain_host: string
+  let vhostHTTPPort: number
+  let subdomainHost: string
   fetch('../api/serverinfo', { credentials: 'include' })
     .then((res) => {
       return res.json()
     })
     .then((json) => {
-      vhost_http_port = json.vhost_http_port
-      subdomain_host = json.subdomain_host
-      if (vhost_http_port == null || vhost_http_port == 0) {
+      vhostHTTPPort = json.vhostHTTPPort
+      subdomainHost = json.subdomainHost
+      if (vhostHTTPPort == null || vhostHTTPPort == 0) {
         return
       }
       fetch('../api/proxy/http', { credentials: 'include' })
@@ -29,7 +29,7 @@ const fetchData = () => {
         .then((json) => {
           for (let proxyStats of json.proxies) {
             proxies.value.push(
-              new HTTPProxy(proxyStats, vhost_http_port, subdomain_host)
+              new HTTPProxy(proxyStats, vhostHTTPPort, subdomainHost)
             )
           }
         })

+ 6 - 6
web/frps/src/components/ProxiesHTTPS.vue

@@ -10,16 +10,16 @@ import ProxyView from './ProxyView.vue'
 let proxies = ref<HTTPSProxy[]>([])
 
 const fetchData = () => {
-  let vhost_https_port: number
-  let subdomain_host: string
+  let vhostHTTPSPort: number
+  let subdomainHost: string
   fetch('../api/serverinfo', { credentials: 'include' })
     .then((res) => {
       return res.json()
     })
     .then((json) => {
-      vhost_https_port = json.vhost_https_port
-      subdomain_host = json.subdomain_host
-      if (vhost_https_port == null || vhost_https_port == 0) {
+      vhostHTTPSPort = json.vhostHTTPSPort
+      subdomainHost = json.subdomainHost
+      if (vhostHTTPSPort == null || vhostHTTPSPort == 0) {
         return
       }
       fetch('../api/proxy/https', { credentials: 'include' })
@@ -29,7 +29,7 @@ const fetchData = () => {
         .then((json) => {
           for (let proxyStats of json.proxies) {
             proxies.value.push(
-              new HTTPSProxy(proxyStats, vhost_https_port, subdomain_host)
+              new HTTPSProxy(proxyStats, vhostHTTPSPort, subdomainHost)
             )
           }
         })

+ 6 - 6
web/frps/src/components/ProxyView.vue

@@ -14,7 +14,7 @@
             trigger="click"
           >
             <template #default>
-              <Traffic :proxy_name="props.row.name" />
+              <Traffic :proxyName="props.row.name" />
             </template>
 
             <template #reference>
@@ -37,19 +37,19 @@
       </el-table-column>
       <el-table-column
         label="Traffic In"
-        prop="traffic_in"
+        prop="trafficIn"
         :formatter="formatTrafficIn"
         sortable
       >
       </el-table-column>
       <el-table-column
         label="Traffic Out"
-        prop="traffic_out"
+        prop="trafficOut"
         :formatter="formatTrafficOut"
         sortable
       >
       </el-table-column>
-      <el-table-column label="ClientVersion" prop="client_version" sortable>
+      <el-table-column label="ClientVersion" prop="clientVersion" sortable>
       </el-table-column>
       <el-table-column label="Status" prop="status" sortable>
         <template #default="scope">
@@ -75,10 +75,10 @@ defineProps<{
 }>()
 
 const formatTrafficIn = (row: BaseProxy, _: TableColumnCtx<BaseProxy>) => {
-  return Humanize.fileSize(row.traffic_in)
+  return Humanize.fileSize(row.trafficIn)
 }
 
 const formatTrafficOut = (row: BaseProxy, _: TableColumnCtx<BaseProxy>) => {
-  return Humanize.fileSize(row.traffic_out)
+  return Humanize.fileSize(row.trafficOut)
 }
 </script>

+ 6 - 6
web/frps/src/components/ProxyViewExpand.vue

@@ -12,7 +12,7 @@
       <span>{{ row.type }}</span>
     </el-form-item>
     <el-form-item label="Domains">
-      <span>{{ row.custom_domains }}</span>
+      <span>{{ row.customDomains }}</span>
     </el-form-item>
     <el-form-item label="SubDomain">
       <span>{{ row.subdomain }}</span>
@@ -21,7 +21,7 @@
       <span>{{ row.locations }}</span>
     </el-form-item>
     <el-form-item label="HostRewrite">
-      <span>{{ row.host_header_rewrite }}</span>
+      <span>{{ row.hostHeaderRewrite }}</span>
     </el-form-item>
     <el-form-item label="Encryption">
       <span>{{ row.encryption }}</span>
@@ -30,10 +30,10 @@
       <span>{{ row.compression }}</span>
     </el-form-item>
     <el-form-item label="Last Start">
-      <span>{{ row.last_start_time }}</span>
+      <span>{{ row.lastStartTime }}</span>
     </el-form-item>
     <el-form-item label="Last Close">
-      <span>{{ row.last_close_time }}</span>
+      <span>{{ row.lastCloseTime }}</span>
     </el-form-item>
   </el-form>
 
@@ -54,10 +54,10 @@
       <span>{{ row.compression }}</span>
     </el-form-item>
     <el-form-item label="Last Start">
-      <span>{{ row.last_start_time }}</span>
+      <span>{{ row.lastStartTime }}</span>
     </el-form-item>
     <el-form-item label="Last Close">
-      <span>{{ row.last_close_time }}</span>
+      <span>{{ row.lastCloseTime }}</span>
     </el-form-item>
   </el-form>
 </template>

+ 71 - 71
web/frps/src/components/ServerOverview.vue

@@ -12,58 +12,58 @@
               <span>{{ data.version }}</span>
             </el-form-item>
             <el-form-item label="BindPort">
-              <span>{{ data.bind_port }}</span>
+              <span>{{ data.bindPort }}</span>
             </el-form-item>
-            <el-form-item label="KCP Bind Port" v-if="data.kcp_bind_port != 0">
-              <span>{{ data.kcp_bind_port }}</span>
+            <el-form-item label="KCP Bind Port" v-if="data.kcpBindPort != 0">
+              <span>{{ data.kcpBindPort }}</span>
             </el-form-item>
             <el-form-item
               label="QUIC Bind Port"
-              v-if="data.quic_bind_port != 0"
+              v-if="data.quicBindPort != 0"
             >
-              <span>{{ data.quic_bind_port }}</span>
+              <span>{{ data.quicBindPort }}</span>
             </el-form-item>
-            <el-form-item label="Http Port" v-if="data.vhost_http_port != 0">
-              <span>{{ data.vhost_http_port }}</span>
+            <el-form-item label="Http Port" v-if="data.vhostHTTPPort != 0">
+              <span>{{ data.vhostHTTPPort }}</span>
             </el-form-item>
-            <el-form-item label="Https Port" v-if="data.vhost_https_port != 0">
-              <span>{{ data.vhost_https_port }}</span>
+            <el-form-item label="Https Port" v-if="data.vhostHTTPSPort != 0">
+              <span>{{ data.vhostHTTPSPort }}</span>
             </el-form-item>
             <el-form-item
               label="TCPMux HTTPConnect Port"
-              v-if="data.tcpmux_httpconnect_port != 0"
+              v-if="data.tcpmuxHTTPConnectPort != 0"
             >
-              <span>{{ data.tcpmux_httpconnect_port }}</span>
+              <span>{{ data.tcpmuxHTTPConnectPort }}</span>
             </el-form-item>
             <el-form-item
               label="Subdomain Host"
-              v-if="data.subdomain_host != ''"
+              v-if="data.subdomainHost != ''"
             >
-              <LongSpan :content="data.subdomain_host" :length="30"></LongSpan>
+              <LongSpan :content="data.subdomainHost" :length="30"></LongSpan>
             </el-form-item>
             <el-form-item label="Max PoolCount">
-              <span>{{ data.max_pool_count }}</span>
+              <span>{{ data.maxPoolCount }}</span>
             </el-form-item>
             <el-form-item label="Max Ports Per Client">
-              <span>{{ data.max_ports_per_client }}</span>
+              <span>{{ data.maxPortsPerClient }}</span>
             </el-form-item>
-            <el-form-item label="Allow Ports" v-if="data.allow_ports_str != ''">
-              <LongSpan :content="data.allow_ports_str" :length="30"></LongSpan>
+            <el-form-item label="Allow Ports" v-if="data.allowPortsStr != ''">
+              <LongSpan :content="data.allowPortsStr" :length="30"></LongSpan>
             </el-form-item>
-            <el-form-item label="TLS Only" v-if="data.tls_only === true">
-              <span>{{ data.tls_only }}</span>
+            <el-form-item label="TLS Force" v-if="data.tlsForce === true">
+              <span>{{ data.tlsForce }}</span>
             </el-form-item>
             <el-form-item label="HeartBeat Timeout">
-              <span>{{ data.heart_beat_timeout }}</span>
+              <span>{{ data.heartbeatTimeout }}</span>
             </el-form-item>
             <el-form-item label="Client Counts">
-              <span>{{ data.client_counts }}</span>
+              <span>{{ data.clientCounts }}</span>
             </el-form-item>
             <el-form-item label="Current Connections">
-              <span>{{ data.cur_conns }}</span>
+              <span>{{ data.curConns }}</span>
             </el-form-item>
             <el-form-item label="Proxy Counts">
-              <span>{{ data.proxy_counts }}</span>
+              <span>{{ data.proxyCounts }}</span>
             </el-form-item>
           </el-form>
         </div>
@@ -87,21 +87,21 @@ import LongSpan from './LongSpan.vue'
 
 let data = ref({
   version: '',
-  bind_port: 0,
-  kcp_bind_port: 0,
-  quic_bind_port: 0,
-  vhost_http_port: 0,
-  vhost_https_port: 0,
-  tcpmux_httpconnect_port: 0,
-  subdomain_host: '',
-  max_pool_count: 0,
-  max_ports_per_client: '',
-  allow_ports_str: '',
-  tls_only: false,
-  heart_beat_timeout: 0,
-  client_counts: 0,
-  cur_conns: 0,
-  proxy_counts: 0,
+  bindPort: 0,
+  kcpBindPort: 0,
+  quicBindPort: 0,
+  vhostHTTPPort: 0,
+  vhostHTTPSPort: 0,
+  tcpmuxHTTPConnectPort: 0,
+  subdomainHost: '',
+  maxPoolCount: 0,
+  maxPortsPerClient: '',
+  allowPortsStr: '',
+  tlsForce: false,
+  heartbeatTimeout: 0,
+  clientCounts: 0,
+  curConns: 0,
+  proxyCounts: 0,
 })
 
 const fetchData = () => {
@@ -109,50 +109,50 @@ const fetchData = () => {
     .then((res) => res.json())
     .then((json) => {
       data.value.version = json.version
-      data.value.bind_port = json.bind_port
-      data.value.kcp_bind_port = json.kcp_bind_port
-      data.value.quic_bind_port = json.quic_bind_port
-      data.value.vhost_http_port = json.vhost_http_port
-      data.value.vhost_https_port = json.vhost_https_port
-      data.value.tcpmux_httpconnect_port = json.tcpmux_httpconnect_port
-      data.value.subdomain_host = json.subdomain_host
-      data.value.max_pool_count = json.max_pool_count
-      data.value.max_ports_per_client = json.max_ports_per_client
-      if (data.value.max_ports_per_client == '0') {
-        data.value.max_ports_per_client = 'no limit'
+      data.value.bindPort = json.bindPort
+      data.value.kcpBindPort = json.kcpBindPort
+      data.value.quicBindPort = json.quicBindPort
+      data.value.vhostHTTPPort = json.vhostHTTPPort
+      data.value.vhostHTTPSPort = json.vhostHTTPSPort
+      data.value.tcpmuxHTTPConnectPort = json.tcpmuxHTTPConnectPort
+      data.value.subdomainHost = json.subdomainHost
+      data.value.maxPoolCount = json.maxPoolCount
+      data.value.maxPortsPerClient = json.maxPortsPerClient
+      if (data.value.maxPortsPerClient == '0') {
+        data.value.maxPortsPerClient = 'no limit'
       }
-      data.value.allow_ports_str = json.allow_ports_str
-      data.value.tls_only = json.tls_only
-      data.value.heart_beat_timeout = json.heart_beat_timeout
-      data.value.client_counts = json.client_counts
-      data.value.cur_conns = json.cur_conns
-      data.value.proxy_counts = 0
-      if (json.proxy_type_count != null) {
-        if (json.proxy_type_count.tcp != null) {
-          data.value.proxy_counts += json.proxy_type_count.tcp
+      data.value.allowPortsStr = json.allowPortsStr
+      data.value.tlsForce = json.tlsForce
+      data.value.heartbeatTimeout = json.heartbeatTimeout
+      data.value.clientCounts = json.clientCounts
+      data.value.curConns = json.curConns
+      data.value.proxyCounts = 0
+      if (json.proxyTypeCount != null) {
+        if (json.proxyTypeCount.tcp != null) {
+          data.value.proxyCounts += json.proxyTypeCount.tcp
         }
-        if (json.proxy_type_count.udp != null) {
-          data.value.proxy_counts += json.proxy_type_count.udp
+        if (json.proxyTypeCount.udp != null) {
+          data.value.proxyCounts += json.proxyTypeCount.udp
         }
-        if (json.proxy_type_count.http != null) {
-          data.value.proxy_counts += json.proxy_type_count.http
+        if (json.proxyTypeCount.http != null) {
+          data.value.proxyCounts += json.proxyTypeCount.http
         }
-        if (json.proxy_type_count.https != null) {
-          data.value.proxy_counts += json.proxy_type_count.https
+        if (json.proxyTypeCount.https != null) {
+          data.value.proxyCounts += json.proxyTypeCount.https
         }
-        if (json.proxy_type_count.stcp != null) {
-          data.value.proxy_counts += json.proxy_type_count.stcp
+        if (json.proxyTypeCount.stcp != null) {
+          data.value.proxyCounts += json.proxyTypeCount.stcp
         }
-        if (json.proxy_type_count.sudp != null) {
-          data.value.proxy_counts += json.proxy_type_count.sudp
+        if (json.proxyTypeCount.sudp != null) {
+          data.value.proxyCounts += json.proxyTypeCount.sudp
         }
-        if (json.proxy_type_count.xtcp != null) {
-          data.value.proxy_counts += json.proxy_type_count.xtcp
+        if (json.proxyTypeCount.xtcp != null) {
+          data.value.proxyCounts += json.proxyTypeCount.xtcp
         }
       }
 
       // draw chart
-      DrawTrafficChart('traffic', json.total_traffic_in, json.total_traffic_out)
+      DrawTrafficChart('traffic', json.totalTrafficIn, json.totalTrafficOut)
       DrawProxyChart('proxies', json)
     })
     .catch(() => {

+ 4 - 4
web/frps/src/components/Traffic.vue

@@ -1,5 +1,5 @@
 <template>
-  <div :id="proxy_name" style="width: 600px; height: 400px"></div>
+  <div :id="proxyName" style="width: 600px; height: 400px"></div>
 </template>
 
 <script setup lang="ts">
@@ -7,17 +7,17 @@ import { ElMessage } from 'element-plus'
 import { DrawProxyTrafficChart } from '../utils/chart.js'
 
 const props = defineProps<{
-  proxy_name: string
+  proxyName: string
 }>()
 
 const fetchData = () => {
-  let url = '../api/traffic/' + props.proxy_name
+  let url = '../api/traffic/' + props.proxyName
   fetch(url, { credentials: 'include' })
     .then((res) => {
       return res.json()
     })
     .then((json) => {
-      DrawProxyTrafficChart(props.proxy_name, json.traffic_in, json.traffic_out)
+      DrawProxyTrafficChart(props.proxyName, json.trafficIn, json.trafficOut)
     })
     .catch((err) => {
       ElMessage({

+ 21 - 21
web/frps/src/utils/chart.ts

@@ -121,71 +121,71 @@ function DrawProxyChart(elementId: string, serverInfo: any) {
   }
 
   if (
-    serverInfo.proxy_type_count.tcp != null &&
-    serverInfo.proxy_type_count.tcp != 0
+    serverInfo.proxyTypeCount.tcp != null &&
+    serverInfo.proxyTypeCount.tcp != 0
   ) {
     option.series[0].data.push({
-      value: serverInfo.proxy_type_count.tcp,
+      value: serverInfo.proxyTypeCount.tcp,
       name: 'TCP',
     })
     option.legend.data.push('TCP')
   }
   if (
-    serverInfo.proxy_type_count.udp != null &&
-    serverInfo.proxy_type_count.udp != 0
+    serverInfo.proxyTypeCount.udp != null &&
+    serverInfo.proxyTypeCount.udp != 0
   ) {
     option.series[0].data.push({
-      value: serverInfo.proxy_type_count.udp,
+      value: serverInfo.proxyTypeCount.udp,
       name: 'UDP',
     })
     option.legend.data.push('UDP')
   }
   if (
-    serverInfo.proxy_type_count.http != null &&
-    serverInfo.proxy_type_count.http != 0
+    serverInfo.proxyTypeCount.http != null &&
+    serverInfo.proxyTypeCount.http != 0
   ) {
     option.series[0].data.push({
-      value: serverInfo.proxy_type_count.http,
+      value: serverInfo.proxyTypeCount.http,
       name: 'HTTP',
     })
     option.legend.data.push('HTTP')
   }
   if (
-    serverInfo.proxy_type_count.https != null &&
-    serverInfo.proxy_type_count.https != 0
+    serverInfo.proxyTypeCount.https != null &&
+    serverInfo.proxyTypeCount.https != 0
   ) {
     option.series[0].data.push({
-      value: serverInfo.proxy_type_count.https,
+      value: serverInfo.proxyTypeCount.https,
       name: 'HTTPS',
     })
     option.legend.data.push('HTTPS')
   }
   if (
-    serverInfo.proxy_type_count.stcp != null &&
-    serverInfo.proxy_type_count.stcp != 0
+    serverInfo.proxyTypeCount.stcp != null &&
+    serverInfo.proxyTypeCount.stcp != 0
   ) {
     option.series[0].data.push({
-      value: serverInfo.proxy_type_count.stcp,
+      value: serverInfo.proxyTypeCount.stcp,
       name: 'STCP',
     })
     option.legend.data.push('STCP')
   }
   if (
-    serverInfo.proxy_type_count.sudp != null &&
-    serverInfo.proxy_type_count.sudp != 0
+    serverInfo.proxyTypeCount.sudp != null &&
+    serverInfo.proxyTypeCount.sudp != 0
   ) {
     option.series[0].data.push({
-      value: serverInfo.proxy_type_count.sudp,
+      value: serverInfo.proxyTypeCount.sudp,
       name: 'SUDP',
     })
     option.legend.data.push('SUDP')
   }
   if (
-    serverInfo.proxy_type_count.xtcp != null &&
-    serverInfo.proxy_type_count.xtcp != 0
+    serverInfo.proxyTypeCount.xtcp != null &&
+    serverInfo.proxyTypeCount.xtcp != 0
   ) {
     option.series[0].data.push({
-      value: serverInfo.proxy_type_count.xtcp,
+      value: serverInfo.proxyTypeCount.xtcp,
       name: 'XTCP',
     })
     option.legend.data.push('XTCP')

+ 40 - 47
web/frps/src/utils/proxy.ts

@@ -4,42 +4,43 @@ class BaseProxy {
   encryption: boolean
   compression: boolean
   conns: number
-  traffic_in: number
-  traffic_out: number
-  last_start_time: string
-  last_close_time: string
+  trafficIn: number
+  trafficOut: number
+  lastStartTime: string
+  lastCloseTime: string
   status: string
-  client_version: string
+  clientVersion: string
   addr: string
   port: number
 
-  custom_domains: string
-  host_header_rewrite: string
+  customDomains: string
+  hostHeaderRewrite: string
   locations: string
   subdomain: string
 
   constructor(proxyStats: any) {
     this.name = proxyStats.name
     this.type = ''
-    if (proxyStats.conf != null) {
-      this.encryption = proxyStats.conf.use_encryption
-      this.compression = proxyStats.conf.use_compression
-    } else {
-      this.encryption = false
-      this.compression = false
+    this.encryption = false
+    this.compression = false
+    if (proxyStats.conf != null && proxyStats.conf.useEncryption != null) {
+      this.encryption = proxyStats.conf.useEncryption
     }
-    this.conns = proxyStats.cur_conns
-    this.traffic_in = proxyStats.today_traffic_in
-    this.traffic_out = proxyStats.today_traffic_out
-    this.last_start_time = proxyStats.last_start_time
-    this.last_close_time = proxyStats.last_close_time
+    if (proxyStats.conf != null && proxyStats.conf.useCompression != null) {
+      this.compression = proxyStats.conf.useCompression
+    } 
+    this.conns = proxyStats.curConns
+    this.trafficIn = proxyStats.todayTrafficIn
+    this.trafficOut = proxyStats.todayTrafficOut
+    this.lastStartTime = proxyStats.lastStartTime
+    this.lastCloseTime = proxyStats.lastCloseTime
     this.status = proxyStats.status
-    this.client_version = proxyStats.client_version
+    this.clientVersion = proxyStats.clientVersion
 
     this.addr = ''
     this.port = 0
-    this.custom_domains = ''
-    this.host_header_rewrite = ''
+    this.customDomains = ''
+    this.hostHeaderRewrite = ''
     this.locations = ''
     this.subdomain = ''
   }
@@ -50,8 +51,8 @@ class TCPProxy extends BaseProxy {
     super(proxyStats)
     this.type = 'tcp'
     if (proxyStats.conf != null) {
-      this.addr = ':' + proxyStats.conf.remote_port
-      this.port = proxyStats.conf.remote_port
+      this.addr = ':' + proxyStats.conf.remotePort
+      this.port = proxyStats.conf.remotePort
     } else {
       this.addr = ''
       this.port = 0
@@ -64,8 +65,8 @@ class UDPProxy extends BaseProxy {
     super(proxyStats)
     this.type = 'udp'
     if (proxyStats.conf != null) {
-      this.addr = ':' + proxyStats.conf.remote_port
-      this.port = proxyStats.conf.remote_port
+      this.addr = ':' + proxyStats.conf.remotePort
+      this.port = proxyStats.conf.remotePort
     } else {
       this.addr = ''
       this.port = 0
@@ -74,43 +75,35 @@ class UDPProxy extends BaseProxy {
 }
 
 class HTTPProxy extends BaseProxy {
-  constructor(proxyStats: any, port: number, subdomain_host: string) {
+  constructor(proxyStats: any, port: number, subdomainHost: string) {
     super(proxyStats)
     this.type = 'http'
     this.port = port
     if (proxyStats.conf != null) {
-      this.custom_domains = proxyStats.conf.custom_domains
-      this.host_header_rewrite = proxyStats.conf.host_header_rewrite
-      this.locations = proxyStats.conf.locations
-      if (proxyStats.conf.subdomain != '') {
-        this.subdomain = proxyStats.conf.subdomain + '.' + subdomain_host
-      } else {
-        this.subdomain = ''
+      if (proxyStats.conf.customDomains != null) {
+        this.customDomains = proxyStats.conf.customDomains
       }
-    } else {
-      this.custom_domains = ''
-      this.host_header_rewrite = ''
-      this.subdomain = ''
-      this.locations = ''
+      this.hostHeaderRewrite = proxyStats.conf.hostHeaderRewrite
+      this.locations = proxyStats.conf.locations
+      if (proxyStats.conf.subdomain != null && proxyStats.conf.subdomain != '') {
+        this.subdomain = proxyStats.conf.subdomain + '.' + subdomainHost
+      } 
     }
   }
 }
 
 class HTTPSProxy extends BaseProxy {
-  constructor(proxyStats: any, port: number, subdomain_host: string) {
+  constructor(proxyStats: any, port: number, subdomainHost: string) {
     super(proxyStats)
     this.type = 'https'
     this.port = port
     if (proxyStats.conf != null) {
-      this.custom_domains = proxyStats.conf.custom_domains
-      if (proxyStats.conf.subdomain != '') {
-        this.subdomain = proxyStats.conf.subdomain + '.' + subdomain_host
-      } else {
-        this.subdomain = ''
+      if (proxyStats.conf.customDomains != null) {
+        this.customDomains = proxyStats.conf.customDomains
+      }
+      if (proxyStats.conf.subdomain != null && proxyStats.conf.subdomain != '') {
+        this.subdomain = proxyStats.conf.subdomain + '.' + subdomainHost
       }
-    } else {
-      this.custom_domains = ''
-      this.subdomain = ''
     }
   }
 }

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff