瀏覽代碼

fix broken server api and dashboard info (#3662)

fatedier 1 年之前
父節點
當前提交
df12cc2b9d

+ 2 - 0
Release.md

@@ -1,3 +1,5 @@
 ### Fixes
 
 * `transport.tls.disableCustomTLSFirstByte` doesn't have any effect.
+* The Server API did not return the data correctly.
+* The Dashboard is unable to display data.

文件差異過大導致無法顯示
+ 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>
 

+ 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 {

+ 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) {

+ 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 = ''
     }
   }
 }

部分文件因文件數量過多而無法顯示