Compare commits

..

3 Commits

Author SHA1 Message Date
a37952a292 fixed: current show info in Proxies 2023-12-14 18:10:14 +08:00
2ef1bc7469 fixed: current show info in Proxies 2023-12-14 11:44:10 +08:00
8a39342519 fixed: status text of i18n in Overview 2023-12-14 09:27:02 +08:00
6 changed files with 126 additions and 35 deletions

View File

@@ -51,7 +51,9 @@
"Status": "Status", "Status": "Status",
"Info": "Info", "Info": "Info",
"running": "running", "running": "running",
"Local Ip": "Local Ip", "start error": "start error",
"new": "new",
"Local IP": "Local IP",
"Local Port": "Local Port", "Local Port": "Local Port",
"Operation": "Operation", "Operation": "Operation",
"Confirm": "Confirm", "Confirm": "Confirm",

View File

@@ -51,7 +51,9 @@
"Status": "状态", "Status": "状态",
"Info": "消息", "Info": "消息",
"running": "运行中", "running": "运行中",
"Local Ip": "本地IP", "start error": "错误",
"new": "新连接",
"Local IP": "本地IP",
"Local Port": "本地端口", "Local Port": "本地端口",
"Operation": "操作", "Operation": "操作",
"Confirm": "确定", "Confirm": "确定",

View File

@@ -1,7 +1,12 @@
var loadProxyInfo = (function ($) { var loadProxyInfo = (function ($) {
var i18n = {}, currentProxyType, currentTitle; var i18n = {}, currentProxyType, currentTitle;
//param names in Basic tab //param names in Basic tab
var basicParamNames = ['name', 'type', 'local_ip', 'local_port', 'custom_domains', 'subdomain', 'remote_port', 'use_encryption', 'use_compression']; var basicParamNamesIgnore = ['toml'];
var basicParamNames = ['name', 'type', 'localIP', 'localPort', 'customDomains', 'subdomain', 'remotePort', 'useEncryption', 'useCompression'];
var basicParamNamesMap = {
useEncryption: 'transport.useEncryption',
useCompression: 'transport.useCompression'
}
/** /**
* get proxy info * get proxy info
@@ -36,48 +41,46 @@ var loadProxyInfo = (function ($) {
/** /**
* render proxy list table * render proxy list table
* @param data {Map<string,Map<string,string>>} proxy data * @param data {[Map<string,string>]} proxy data
*/ */
function renderProxyListTable(data) { function renderProxyListTable(data) {
var dataList = []; data.forEach(function (temp) {
for (var key in data) { temp.name = temp.name || '-';
var temp = data[key]; temp.localIP = temp.localIP || '-';
temp.name = key; temp.localPort = temp.localPort || '-';
temp.local_ip = temp.local_ip || '-'; temp.transport = temp.transport || {};
temp.local_port = temp.local_port || '-'; temp.transport.useEncryption = temp.transport.useEncryption || false;
temp.use_encryption = temp.use_encryption || false; temp.transport.useCompression = temp.transport.useCompression || false;
temp.use_compression = temp.use_compression || false;
if (currentProxyType === 'http' || currentProxyType === 'https') { if (currentProxyType === 'http' || currentProxyType === 'https') {
temp.custom_domains = temp.custom_domains || '-'; temp.customDomains = temp.customDomains || '-';
temp.subdomain = temp.subdomain || '-'; temp.subdomain = temp.subdomain || '-';
} }
dataList.push(temp); });
}
var $section = $('#content > section'); var $section = $('#content > section');
var cols = [ var cols = [
{type: 'checkbox'}, {type: 'checkbox'},
{field: 'name', title: i18n['Name'], sort: true}, {field: 'name', title: i18n['Name'], sort: true},
{field: 'type', title: i18n['Type'], width: 110, sort: true}, {field: 'type', title: i18n['Type'], width: 110, sort: true},
{field: 'local_ip', title: i18n['LocalIp'], width: 150, sort: true}, {field: 'localIP', title: i18n['LocalIP'], width: 150, sort: true},
{field: 'local_port', title: i18n['LocalPort'], width: 120, sort: true}, {field: 'localPort', title: i18n['LocalPort'], width: 120, sort: true},
]; ];
if (currentProxyType === 'tcp' || currentProxyType === 'udp') { if (currentProxyType === 'tcp' || currentProxyType === 'udp') {
cols.push({field: 'remote_port', title: i18n['RemotePort'], width: 130, sort: true}); cols.push({field: 'remotePort', title: i18n['RemotePort'], width: 130, sort: true});
} else if (currentProxyType === 'http' || currentProxyType === 'https') { } else if (currentProxyType === 'http' || currentProxyType === 'https') {
cols.push({field: 'custom_domains', title: i18n['CustomDomains'], sort: true}); cols.push({field: 'customDomains', title: i18n['CustomDomains'], sort: true});
cols.push({field: 'subdomain', title: i18n['Subdomain'], width: 150, sort: true}); cols.push({field: 'subdomain', title: i18n['Subdomain'], width: 150, sort: true});
} }
cols.push({ cols.push({
field: 'use_encryption', title: i18n['UseEncryption'], width: 170, templet: function (d) { field: 'useEncryption', title: i18n['UseEncryption'], width: 170, templet: function (d) {
return i18n[d.use_encryption] return i18n[d.transport.useEncryption]
}, sort: true }, sort: true
}); });
cols.push({ cols.push({
field: 'use_compression', title: i18n['UseCompression'], width: 170, templet: function (d) { field: 'useCompression', title: i18n['UseCompression'], width: 170, templet: function (d) {
return i18n[d.use_compression] return i18n[d.transport.useCompression]
}, sort: true }, sort: true
}); });
cols.push({title: i18n['Operation'], width: 150, toolbar: '#proxyListOperationTemplate'}); cols.push({title: i18n['Operation'], width: 150, toolbar: '#proxyListOperationTemplate'});
@@ -92,7 +95,7 @@ var loadProxyInfo = (function ($) {
}, },
toolbar: '#proxyListToolbarTemplate', toolbar: '#proxyListToolbarTemplate',
defaultToolbar: false, defaultToolbar: false,
data: dataList, data: data,
initSort: { initSort: {
field: 'name', field: 'name',
type: 'asc' type: 'asc'
@@ -159,12 +162,32 @@ var loadProxyInfo = (function ($) {
var extraData = []; var extraData = [];
if (data != null) { if (data != null) {
var tempData = $.extend(true, {}, data); var tempData = $.extend(true, {}, data);
basicParamNamesIgnore.forEach(function (basicName) {
if (basicParamNamesMap.hasOwnProperty(basicName)) {
try {
eval('delete tempData.' + basicParamNamesMap[basicName])
} catch (e) {
}
} else if (data.hasOwnProperty(basicName)) {
delete tempData[basicName];
}
});
basicParamNames.forEach(function (basicName) { basicParamNames.forEach(function (basicName) {
if (data.hasOwnProperty(basicName)) { if (basicParamNamesMap.hasOwnProperty(basicName)) {
try {
basicData[basicName] = eval('tempData.' + basicParamNamesMap[basicName]);
eval('delete tempData.' + basicParamNamesMap[basicName])
} catch (e) {
basicData[basicName] = true;
}
} else if (data.hasOwnProperty(basicName)) {
basicData[basicName] = tempData[basicName]; basicData[basicName] = tempData[basicName];
delete tempData[basicName]; delete tempData[basicName];
} }
}); });
for (var key in tempData) { for (var key in tempData) {
extraData.push({ extraData.push({
name: key, name: key,

View File

@@ -163,16 +163,16 @@
</div> </div>
</div> </div>
<div class="layui-form-item"> <div class="layui-form-item">
<label class="layui-form-label">${ .LocalIp }</label> <label class="layui-form-label">${ .LocalIP }</label>
<div class="layui-input-block"> <div class="layui-input-block">
<input type="text" name="local_ip" placeholder="${ .LocalIp }" autocomplete="off" <input type="text" name="localIP" placeholder="${ .LocalIP }" autocomplete="off"
class="layui-input"/> class="layui-input"/>
</div> </div>
</div> </div>
<div class="layui-form-item"> <div class="layui-form-item">
<label class="layui-form-label">${ .LocalPort }</label> <label class="layui-form-label">${ .LocalPort }</label>
<div class="layui-input-block"> <div class="layui-input-block">
<input type="text" name="local_port" placeholder="${ .LocalPort }" autocomplete="off" <input type="text" name="localPort" placeholder="${ .LocalPort }" autocomplete="off"
class="layui-input"/> class="layui-input"/>
</div> </div>
</div> </div>
@@ -180,7 +180,7 @@
<div class="layui-form-item http https"> <div class="layui-form-item http https">
<label class="layui-form-label">${ .CustomDomains }</label> <label class="layui-form-label">${ .CustomDomains }</label>
<div class="layui-input-block"> <div class="layui-input-block">
<textarea name="custom_domains" placeholder="${ .CustomDomains }" autocomplete="off" <textarea name="customDomains" placeholder="${ .CustomDomains }" autocomplete="off"
class="layui-textarea"></textarea> class="layui-textarea"></textarea>
</div> </div>
</div> </div>
@@ -196,7 +196,7 @@
<div class="layui-form-item tcp udp"> <div class="layui-form-item tcp udp">
<label class="layui-form-label">${ .RemotePort }</label> <label class="layui-form-label">${ .RemotePort }</label>
<div class="layui-input-block"> <div class="layui-input-block">
<input type="text" name="remote_port" placeholder="${ .RemotePort }" autocomplete="off" <input type="text" name="remotePort" placeholder="${ .RemotePort }" autocomplete="off"
class="layui-input"/> class="layui-input"/>
</div> </div>
</div> </div>
@@ -206,7 +206,7 @@
<div class="layui-form-item"> <div class="layui-form-item">
<label class="layui-form-label">${ .UseEncryption }</label> <label class="layui-form-label">${ .UseEncryption }</label>
<div class="layui-input-block"> <div class="layui-input-block">
<input type="checkbox" name="use_encryption" value="true" title="${ .true }"> <input type="checkbox" name="useEncryption" value="true" title="${ .true }">
</div> </div>
</div> </div>
</div> </div>
@@ -214,7 +214,7 @@
<div class="layui-form-item"> <div class="layui-form-item">
<label class="layui-form-label">${ .UseCompression }</label> <label class="layui-form-label">${ .UseCompression }</label>
<div class="layui-input-block"> <div class="layui-input-block">
<input type="checkbox" name="use_compression" value="true" title="${ .true }"> <input type="checkbox" name="useCompression" value="true" title="${ .true }">
</div> </div>
</div> </div>
</div> </div>

View File

@@ -86,7 +86,7 @@ func (c *HandleController) MakeIndexFunc() func(context *gin.Context) {
"Basic": ginI18n.MustGetMessage(context, "Basic"), "Basic": ginI18n.MustGetMessage(context, "Basic"),
"Extra": ginI18n.MustGetMessage(context, "Extra"), "Extra": ginI18n.MustGetMessage(context, "Extra"),
"ProxyName": ginI18n.MustGetMessage(context, "Proxy Name"), "ProxyName": ginI18n.MustGetMessage(context, "Proxy Name"),
"LocalIp": ginI18n.MustGetMessage(context, "Local Ip"), "LocalIP": ginI18n.MustGetMessage(context, "Local IP"),
"LocalPort": ginI18n.MustGetMessage(context, "Local Port"), "LocalPort": ginI18n.MustGetMessage(context, "Local Port"),
"RemotePort": ginI18n.MustGetMessage(context, "Remote Port"), "RemotePort": ginI18n.MustGetMessage(context, "Remote Port"),
"CustomDomains": ginI18n.MustGetMessage(context, "Custom Domains"), "CustomDomains": ginI18n.MustGetMessage(context, "Custom Domains"),
@@ -114,7 +114,9 @@ func (c *HandleController) MakeLangFunc() func(context *gin.Context) {
"Status": ginI18n.MustGetMessage(context, "Status"), "Status": ginI18n.MustGetMessage(context, "Status"),
"Info": ginI18n.MustGetMessage(context, "Info"), "Info": ginI18n.MustGetMessage(context, "Info"),
"running": ginI18n.MustGetMessage(context, "running"), "running": ginI18n.MustGetMessage(context, "running"),
"LocalIp": ginI18n.MustGetMessage(context, "Local Ip"), "start error": ginI18n.MustGetMessage(context, "start error"),
"new": ginI18n.MustGetMessage(context, "new"),
"LocalIP": ginI18n.MustGetMessage(context, "Local IP"),
"LocalPort": ginI18n.MustGetMessage(context, "Local Port"), "LocalPort": ginI18n.MustGetMessage(context, "Local Port"),
"RemotePort": ginI18n.MustGetMessage(context, "Remote Port"), "RemotePort": ginI18n.MustGetMessage(context, "Remote Port"),
"UseEncryption": ginI18n.MustGetMessage(context, "Use Encryption"), "UseEncryption": ginI18n.MustGetMessage(context, "Use Encryption"),

View File

@@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/config"
v1 "github.com/fatedier/frp/pkg/config/v1" v1 "github.com/fatedier/frp/pkg/config/v1"
"github.com/pelletier/go-toml/v2"
"github.com/vaughan0/go-ini" "github.com/vaughan0/go-ini"
"io" "io"
"log" "log"
@@ -18,6 +19,10 @@ func trimString(str string) string {
return strings.TrimSpace(str) return strings.TrimSpace(str)
} }
func equalIgnoreCase(source string, target string) bool {
return strings.ToUpper(source) == strings.ToUpper(target)
}
func sortSectionKeys(object ini.Section) []string { func sortSectionKeys(object ini.Section) []string {
var keys []string var keys []string
for key := range object { for key := range object {
@@ -133,11 +138,68 @@ func (c *HandleController) parseResponse(res *ProxyResponse, response *http.Resp
log.Printf(res.Message) log.Printf(res.Message)
} }
type MyProxy struct {
Toml string `json:"toml"`
*v1.ProxyBaseConfig
}
func (c *HandleController) parseConfigure(content, proxyType string) (interface{}, error) { func (c *HandleController) parseConfigure(content, proxyType string) (interface{}, error) {
clientConfig := v1.ClientConfig{} clientConfig := v1.ClientConfig{}
err := config.LoadConfigure([]byte(content), &clientConfig) err := config.LoadConfigure([]byte(content), &clientConfig)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return clientConfig, nil
if proxyType == "none" {
return clientConfig, nil
}
allProxies := clientConfig.Proxies
var filterProxies = make([]MyProxy, 0)
for i := range allProxies {
if equalIgnoreCase(allProxies[i].Type, proxyType) {
baseConfig := allProxies[i].GetBaseConfig()
marshal, _ := toml.Marshal(allProxies[i].ProxyConfigurer)
proxy := MyProxy{
string(marshal),
baseConfig,
}
filterProxies = append(filterProxies, proxy)
}
}
var ss = `
Name = 'ssh_random'
Type = 'tcp'
LocalIP = '192.168.31.100'
LocalPort = 22
RemotePort = 0
[Transport]
UseEncryption = false
UseCompression = false
BandwidthLimitMode = ''
ProxyProtocolVersion = ''
[Transport.BandwidthLimit]
[LoadBalancer]
Group = ''
GroupKey = ''
[HealthCheck]
Type = ''
TimeoutSeconds = 0
MaxFailed = 0
IntervalSeconds = 0
Path = ''
[Plugin]
Type = ''
`
v := v1.ProxyType("tcp")
r := v1.NewProxyConfigurerByType(v)
toml.Unmarshal([]byte(ss), r)
return filterProxies, nil
} }