mirror of
https://github.com/yhl452493373/frpc-panel.git
synced 2026-04-04 14:27:01 +08:00
Compare commits
15 Commits
e8d64b9db2
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
| 1bb3028308 | |||
| cd81e22d53 | |||
| 18792a395c | |||
| 83ad03eca3 | |||
| 91c15936ee | |||
| a37952a292 | |||
| 2ef1bc7469 | |||
| 8a39342519 | |||
| e5b0f2c061 | |||
| 28c37efeb5 | |||
| 77d87ac27c | |||
| 3e7fe5c4de | |||
| e163119bb6 | |||
| 5f19db4193 | |||
| 32b0af7f9b |
23
README.md
23
README.md
@@ -6,6 +6,8 @@ frpc-panel 是 https://github.com/fatedier/frp 的一个客户端工具,用于
|
||||
|
||||
frps-panel 会以一个单独的进程运行,通过后台调用frpc的接口实现对frpc的操作。
|
||||
|
||||
## 从版本2.0.0开始,本插件只支持版本号大于等于v0.52.0的frp
|
||||
|
||||
## 功能
|
||||
|
||||
+ 展示客户端基础配置信息
|
||||
@@ -17,14 +19,21 @@ frps-panel 会以一个单独的进程运行,通过后台调用frpc的接口
|
||||
|
||||
## 使用方法
|
||||
|
||||
1、frpc的配置文件`frpc.ini`中,增加如下内容:
|
||||
1、frpc的配置文件`frpc.toml`中,增加如下内容:
|
||||
|
||||
```ini
|
||||
[common]
|
||||
admin_addr = 127.0.0.1
|
||||
admin_port = 7400
|
||||
admin_user = admin
|
||||
admin_pwd = admin
|
||||
```toml
|
||||
webServer.addr = "127.0.0.1"
|
||||
webServer.port = 7400
|
||||
webServer.user = "admin"
|
||||
webServer.password = "admin"
|
||||
```
|
||||
或
|
||||
```toml
|
||||
[webServer]
|
||||
addr = "127.0.0.1"
|
||||
port = 7400
|
||||
user = "admin"
|
||||
password = "admin"
|
||||
```
|
||||
|
||||
2、frpc-panel的配置文件`frpc-panel.toml`的配置如下:
|
||||
|
||||
23
README_en.md
23
README_en.md
@@ -6,6 +6,8 @@ frpc-panel is a client tool of https://github.com/fatedier/frp , it's used to sh
|
||||
|
||||
frps-panel will run as one single process and manage frpc proxy info with frpc's api.
|
||||
|
||||
## Since version 2.0.0,this plugin only support frp version >= v0.52.0
|
||||
|
||||
## Features
|
||||
|
||||
+ Show frpc basic info
|
||||
@@ -17,14 +19,21 @@ frps-panel will run as one single process and manage frpc proxy info with frpc's
|
||||
|
||||
## Usage
|
||||
|
||||
1.add config in frpc's config file '`frpc.ini`:
|
||||
1.add config in frpc's config file '`frpc.toml`:
|
||||
|
||||
```ini
|
||||
[common]
|
||||
admin_addr = 127.0.0.1
|
||||
admin_port = 7400
|
||||
admin_user = admin
|
||||
admin_pwd = admin
|
||||
```toml
|
||||
webServer.addr = "127.0.0.1"
|
||||
webServer.port = 7400
|
||||
webServer.user = "admin"
|
||||
webServer.password = "admin"
|
||||
```
|
||||
or
|
||||
```toml
|
||||
[webServer]
|
||||
addr = "127.0.0.1"
|
||||
port = 7400
|
||||
user = "admin"
|
||||
password = "admin"
|
||||
```
|
||||
|
||||
2.`frpc-panel.toml`:
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
"Extra": "Extra Params",
|
||||
"Proxy Name": "Proxy Name",
|
||||
"Custom Domains": "Custom Domains",
|
||||
"Custom Domains Example": "[\"first.domain.org\",\"second.domain.net\"]",
|
||||
"Subdomain": "Subdomain",
|
||||
"Remote Port": "Remote Port",
|
||||
"Use Encryption": "Use Encryption",
|
||||
@@ -51,8 +52,14 @@
|
||||
"Status": "Status",
|
||||
"Info": "Info",
|
||||
"running": "running",
|
||||
"Local Ip": "Local Ip",
|
||||
"start error": "start error",
|
||||
"new": "new",
|
||||
"Proxy Name Example": "Intranet Penetration",
|
||||
"Local IP": "Local IP",
|
||||
"Local IP Example": "127.0.0.1",
|
||||
"Local Port": "Local Port",
|
||||
"Local Port Example": "8080",
|
||||
"Remote Port Example": "18080",
|
||||
"Operation": "Operation",
|
||||
"Confirm": "Confirm",
|
||||
"Cancel": "Cancel",
|
||||
@@ -66,5 +73,15 @@
|
||||
"Frp Client Error": "Frp client error",
|
||||
"Proxy Exist,": "Proxy name exist",
|
||||
"Proxy Not Exist": "Proxy name not exist",
|
||||
"Client Tips": "Client tips"
|
||||
"Client Tips": "Client tips",
|
||||
"and": " and ",
|
||||
"Require Not All Empty": " can't be empty at the same time",
|
||||
"Require Not Empty": " can't be empty",
|
||||
"Require Number": " should be a number",
|
||||
"Require Boolean": " should be a boolean",
|
||||
"Require Array": " should be an js array",
|
||||
"Total": "Total ",
|
||||
"Items": " items",
|
||||
"Go to": "Go to",
|
||||
"Per Page": " / page"
|
||||
}
|
||||
@@ -37,6 +37,7 @@
|
||||
"Extra": "附加参数",
|
||||
"Proxy Name": "代理名称",
|
||||
"Custom Domains": "自定义域名",
|
||||
"Custom Domains Example": "[\"first.domain.org\",\"second.domain.net\"]",
|
||||
"Subdomain": "子域名",
|
||||
"Remote Port": "服务端端口",
|
||||
"Use Encryption": "加密传输",
|
||||
@@ -51,8 +52,14 @@
|
||||
"Status": "状态",
|
||||
"Info": "消息",
|
||||
"running": "运行中",
|
||||
"Local Ip": "本地IP",
|
||||
"start error": "错误",
|
||||
"new": "新连接",
|
||||
"Proxy Name Example": "内网穿透",
|
||||
"Local IP": "本地IP",
|
||||
"Local IP Example": "127.0.0.1",
|
||||
"Local Port": "本地端口",
|
||||
"Local Port Example": "8080",
|
||||
"Remote Port Example": "18080",
|
||||
"Operation": "操作",
|
||||
"Confirm": "确定",
|
||||
"Cancel": "取消",
|
||||
@@ -66,5 +73,15 @@
|
||||
"Frp Client Error": "Frp客户端错误",
|
||||
"Proxy Exist": "代理名称重复",
|
||||
"Proxy Not Exist": "代理名称不存在",
|
||||
"Client Tips": "客户端提示"
|
||||
"Client Tips": "客户端提示",
|
||||
"and": "和",
|
||||
"Require Not All Empty": "不能同时为空",
|
||||
"Require Not Empty": "不能为空",
|
||||
"Require Number": "应当为数字",
|
||||
"Require Boolean": "应当为布尔值",
|
||||
"Require Array": "应当为JS数组",
|
||||
"Total": "共",
|
||||
"Items": "条记录",
|
||||
"Go to": "到第",
|
||||
"Per Page": "条/页"
|
||||
}
|
||||
@@ -217,12 +217,11 @@ section.client-info .text-row .text-col {
|
||||
}
|
||||
|
||||
.proxy-popup .extra-param-tab-item .layui-form-item .layui-input-inline:nth-child(1) {
|
||||
width: 150px;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.proxy-popup .extra-param-tab-item .layui-form-item .layui-input-inline:nth-child(3) {
|
||||
flex: 1;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
#searchForm input {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,13 +1,9 @@
|
||||
var loadClientInfo = (function ($) {
|
||||
var i18n = {};
|
||||
|
||||
/**
|
||||
* get client info
|
||||
* @param lang {Map<string,string>} language json
|
||||
* @param title {string} page title
|
||||
*/
|
||||
function loadClientInfo(lang, title) {
|
||||
i18n = lang;
|
||||
function loadClientInfo( title) {
|
||||
$("#title").text(title);
|
||||
$('#content').empty();
|
||||
var loading = layui.layer.load();
|
||||
@@ -26,8 +22,8 @@ var loadClientInfo = (function ($) {
|
||||
}
|
||||
|
||||
function renderClientInfo(data) {
|
||||
data.tcp_mux = i18n[data.tcp_mux];
|
||||
data.tls_enable = i18n[data.tls_enable];
|
||||
data.transport.tcpMux = i18n[data.transport.tcpMux];
|
||||
data.transport.tls.enable = i18n[data.transport.tls.enable];
|
||||
var html = layui.laytpl($('#clientInfoTemplate').html()).render(data);
|
||||
$('#content').html(html);
|
||||
}
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
var loadProxyInfo = (function ($) {
|
||||
var i18n = {}, currentProxyType, currentTitle;
|
||||
//param names in Basic tab
|
||||
var basicParamNames = ['name', 'type', 'local_ip', 'local_port', 'custom_domains', 'subdomain', 'remote_port', 'use_encryption', 'use_compression'];
|
||||
var currentProxyType, currentTitle;
|
||||
|
||||
/**
|
||||
* get proxy info
|
||||
* @param lang {{}} language json
|
||||
* @param title page title
|
||||
* @param proxyType proxy type
|
||||
*/
|
||||
function loadProxyInfo(lang, title, proxyType) {
|
||||
if (lang != null)
|
||||
i18n = lang;
|
||||
function loadProxyInfo(title, proxyType) {
|
||||
if (title != null)
|
||||
currentTitle = title;
|
||||
if (proxyType != null)
|
||||
@@ -26,6 +21,7 @@ var loadProxyInfo = (function ($) {
|
||||
if (result.success) {
|
||||
$('#content').html($('#proxyListTableTemplate').html());
|
||||
renderProxyListTable(result.data);
|
||||
loadFrpcConfig();
|
||||
} else {
|
||||
layui.layer.msg(result.message);
|
||||
}
|
||||
@@ -34,50 +30,82 @@ var loadProxyInfo = (function ($) {
|
||||
});
|
||||
}
|
||||
|
||||
function loadFrpcConfig() {
|
||||
$.getJSON('/proxy/api/config', {
|
||||
type: 'none'
|
||||
}).done(function (result) {
|
||||
if (result.success) {
|
||||
var proxies = [];
|
||||
result.data.proxies.forEach(function (proxy) {
|
||||
var items = flatJSON(proxy['ProxyConfigurer']);
|
||||
proxies.push(expandJSON(items))
|
||||
})
|
||||
var visitors = [];
|
||||
result.data.visitors.forEach(function (visitor) {
|
||||
var items = flatJSON(visitor['VisitorConfigurer']);
|
||||
visitors.push(expandJSON(items))
|
||||
});
|
||||
|
||||
window.clientConfig = $.extend(true, {}, result.data);
|
||||
window.clientConfig.proxies = proxies;
|
||||
window.clientConfig.visitors = visitors;
|
||||
} else {
|
||||
window.clientConfig = {};
|
||||
layui.layer.msg(result.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* render proxy list table
|
||||
* @param data {Map<string,Map<string,string>>} proxy data
|
||||
* @param data {[Map<string,string>]} proxy data
|
||||
*/
|
||||
function renderProxyListTable(data) {
|
||||
var dataList = [];
|
||||
for (var key in data) {
|
||||
var temp = data[key];
|
||||
temp.name = key;
|
||||
temp.local_ip = temp.local_ip || '-';
|
||||
temp.local_port = temp.local_port || '-';
|
||||
temp.use_encryption = temp.use_encryption || false;
|
||||
temp.use_compression = temp.use_compression || false;
|
||||
if (currentProxyType === 'http' || currentProxyType === 'https') {
|
||||
temp.custom_domains = temp.custom_domains || '-';
|
||||
temp.subdomain = temp.subdomain || '-';
|
||||
var proxies = [];
|
||||
data.forEach(function (temp) {
|
||||
var proxy = temp.ProxyConfigurer;
|
||||
basicParams.forEach(function (basicParam) {
|
||||
var name = basicParam.name;
|
||||
var defaultValue = basicParam.defaultValue;
|
||||
var value = null;
|
||||
try {
|
||||
value = eval('proxy.' + name);
|
||||
if (value == null) {
|
||||
value = defaultValue;
|
||||
}
|
||||
dataList.push(temp);
|
||||
} catch (e) {
|
||||
value = defaultValue;
|
||||
}
|
||||
eval('proxy.' + name + ' = value');
|
||||
|
||||
});
|
||||
proxies.push(proxy);
|
||||
});
|
||||
|
||||
var $section = $('#content > section');
|
||||
var cols = [
|
||||
{type: 'checkbox'},
|
||||
{field: 'name', title: i18n['Name'], sort: true},
|
||||
{field: 'type', title: i18n['Type'], width: 110, sort: true},
|
||||
{field: 'local_ip', title: i18n['LocalIp'], width: 150, sort: true},
|
||||
{field: 'local_port', title: i18n['LocalPort'], width: 120, sort: true},
|
||||
{field: 'localIP', title: i18n['LocalIP'], width: 150, sort: true},
|
||||
{field: 'localPort', title: i18n['LocalPort'], width: 120, sort: true},
|
||||
];
|
||||
|
||||
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') {
|
||||
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: 'use_encryption', title: i18n['UseEncryption'], width: 170, templet: function (d) {
|
||||
return i18n[d.use_encryption]
|
||||
field: 'useEncryption', title: i18n['UseEncryption'], width: 170, templet: function (d) {
|
||||
return i18n[d.transport.useEncryption]
|
||||
}, sort: true
|
||||
});
|
||||
cols.push({
|
||||
field: 'use_compression', title: i18n['UseCompression'], width: 170, templet: function (d) {
|
||||
return i18n[d.use_compression]
|
||||
field: 'useCompression', title: i18n['UseCompression'], width: 170, templet: function (d) {
|
||||
return i18n[d.transport.useCompression]
|
||||
}, sort: true
|
||||
});
|
||||
cols.push({title: i18n['Operation'], width: 150, toolbar: '#proxyListOperationTemplate'});
|
||||
@@ -88,11 +116,15 @@ var loadProxyInfo = (function ($) {
|
||||
text: {none: i18n['EmptyData']},
|
||||
cols: [cols],
|
||||
page: {
|
||||
layout: navigator.language.indexOf("zh") === -1 ? ['first', 'prev', 'next', 'last'] : ['prev', 'page', 'next', 'skip', 'count', 'limit']
|
||||
limitTemplet: function (item) {
|
||||
return item + i18n['PerPage'];
|
||||
},
|
||||
skipText: [i18n['Goto'], '', i18n['Confirm']],
|
||||
countText: [i18n['Total'], i18n['Items']]
|
||||
},
|
||||
toolbar: '#proxyListToolbarTemplate',
|
||||
defaultToolbar: false,
|
||||
data: dataList,
|
||||
data: proxies,
|
||||
initSort: {
|
||||
field: 'name',
|
||||
type: 'asc'
|
||||
@@ -159,20 +191,32 @@ var loadProxyInfo = (function ($) {
|
||||
var extraData = [];
|
||||
if (data != null) {
|
||||
var tempData = $.extend(true, {}, data);
|
||||
basicParamNames.forEach(function (basicName) {
|
||||
if (data.hasOwnProperty(basicName)) {
|
||||
basicData[basicName] = tempData[basicName];
|
||||
delete tempData[basicName];
|
||||
|
||||
basicParams.forEach(function (basicName) {
|
||||
var name = basicName.name;
|
||||
if (name.indexOf('.') !== -1) {
|
||||
var keys = name.split('.');
|
||||
expandJSONKeys(tempData, keys, null);
|
||||
expandJSONKeys(basicData, keys, basicName.defaultValue);
|
||||
}
|
||||
|
||||
eval('basicData.' + name + ' = ' + 'tempData.' + name);
|
||||
eval('delete tempData.' + name)
|
||||
});
|
||||
for (var key in tempData) {
|
||||
|
||||
var flatted = flatJSON(tempData);
|
||||
for (var key in flatted) {
|
||||
var value = flatted[key];
|
||||
if (value == null || value === '')
|
||||
continue;
|
||||
extraData.push({
|
||||
name: key,
|
||||
value: tempData[key]
|
||||
value: value
|
||||
});
|
||||
}
|
||||
}
|
||||
var html = document.getElementById('addProxyTemplate').innerHTML;
|
||||
|
||||
var html = document.getElementById('proxyFormTemplate').innerHTML;
|
||||
var content = layui.laytpl(html).render({
|
||||
type: currentProxyType,
|
||||
extraData: extraData
|
||||
@@ -181,19 +225,18 @@ var loadProxyInfo = (function ($) {
|
||||
type: 1,
|
||||
title: false,
|
||||
skin: 'proxy-popup',
|
||||
area: ['450px', '400px'],
|
||||
area: ['550px', '400px'],
|
||||
content: content,
|
||||
btn: [i18n['Confirm'], i18n['Cancel']],
|
||||
btn1: function (index) {
|
||||
if (layui.form.validate('#addProxyTemplate')) {
|
||||
var formData = layui.form.val('addProxyForm');
|
||||
var $items = $('#addProxyForm .extra-param-tab-item .extra-param-item');
|
||||
if (layui.form.validate('#proxyForm')) {
|
||||
var formData = layui.form.val('proxyForm');
|
||||
var $items = $('#proxyForm .extra-param-tab-item .extra-param-item');
|
||||
$items.each(function () {
|
||||
var name = $(this).find('input').first().val();
|
||||
var value = $(this).find('input').last().val();
|
||||
formData[name] = value;
|
||||
});
|
||||
|
||||
addOrUpdate(formData, index, update);
|
||||
}
|
||||
},
|
||||
@@ -202,19 +245,19 @@ var loadProxyInfo = (function ($) {
|
||||
},
|
||||
success: function (layero, index, that) {
|
||||
//get and set old name for update form
|
||||
var oldNameKey = layero.find('#oldName').attr('name');
|
||||
basicData[oldNameKey] = basicData.name;
|
||||
layui.form.val('addProxyForm', basicData);
|
||||
var originalNameKey = layero.find('#originalNameKey').attr('name');
|
||||
basicData[originalNameKey] = basicData.name;
|
||||
layui.form.val('proxyForm', flatJSON(basicData));
|
||||
proxyPopupSuccess();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function proxyPopupSuccess() {
|
||||
layui.form.render(null, 'addProxyForm');
|
||||
layui.form.render(null, 'proxyForm');
|
||||
layui.form.on('input-affix(addition)', function (obj) {
|
||||
var $paramValue = $(obj.elem);
|
||||
var $paramName = $paramValue.closest('.layui-form-item').find('input');
|
||||
var $paramName = $paramValue.closest('.layui-form-item').find('input[type=text]');
|
||||
var name = $paramName.first().val();
|
||||
var value = $paramValue.val();
|
||||
var html = document.getElementById('extraParamAddedTemplate').innerHTML;
|
||||
@@ -241,35 +284,25 @@ var loadProxyInfo = (function ($) {
|
||||
* @param update update flag. true - update, false - add
|
||||
*/
|
||||
function addOrUpdate(data, index, update) {
|
||||
var loading = layui.layer.load();
|
||||
var url = '';
|
||||
try {
|
||||
var originalNameKey = $('#originalNameKey').attr('name');
|
||||
var proxies = clientConfig.proxies;
|
||||
if (update) {
|
||||
url = '/update';
|
||||
for (var i = 0; i < proxies.length; i++) {
|
||||
if (data[originalNameKey] === proxies[i].name) {
|
||||
delete data[originalNameKey];
|
||||
proxies[i] = expandJSON(data);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
url = '/add?type=' + currentProxyType;
|
||||
proxies.push(expandJSON(data));
|
||||
}
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: 'post',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify(data),
|
||||
success: function (result) {
|
||||
if (result.success) {
|
||||
layui.layer.close(index);
|
||||
reloadTable();
|
||||
layui.layer.msg(i18n['OperateSuccess']);
|
||||
} else {
|
||||
errorMsg(result);
|
||||
if (result.code === 5) {
|
||||
layui.layer.close(index);
|
||||
reloadTable();
|
||||
} catch (e) {
|
||||
layui.layer.msg(e.message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
complete: function () {
|
||||
layui.layer.close(loading);
|
||||
}
|
||||
});
|
||||
|
||||
updateFrpcConfig(index);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -281,25 +314,36 @@ var loadProxyInfo = (function ($) {
|
||||
layui.layer.msg(i18n['ShouldCheckProxy']);
|
||||
return;
|
||||
}
|
||||
data.forEach(function (temp) {
|
||||
for (var key in temp) {
|
||||
if (typeof temp[key] === 'boolean') {
|
||||
temp[key] = temp[key] + '';
|
||||
}
|
||||
}
|
||||
});
|
||||
layui.layer.confirm(i18n['ConfirmRemoveProxy'], {
|
||||
title: i18n['OperationConfirm'],
|
||||
btn: [i18n['Confirm'], i18n['Cancel']]
|
||||
}, function (index) {
|
||||
layui.layer.close(index);
|
||||
var proxies = clientConfig.proxies;
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
proxies.forEach(function (proxy, j) {
|
||||
if (data[i].name === proxy.name) {
|
||||
proxies.splice(j, 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updateFrpcConfig(index);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* update frpc's config
|
||||
* @param index popup index
|
||||
*/
|
||||
function updateFrpcConfig(index) {
|
||||
var loading = layui.layer.load();
|
||||
$.post({
|
||||
url: '/remove',
|
||||
var content = TOML.stringify(clientConfig);
|
||||
$.ajax({
|
||||
url: '/update',
|
||||
type: 'post',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify(data),
|
||||
contentType: 'text/plain',
|
||||
data: content,
|
||||
success: function (result) {
|
||||
if (result.success) {
|
||||
layui.layer.close(index);
|
||||
@@ -317,14 +361,13 @@ var loadProxyInfo = (function ($) {
|
||||
layui.layer.close(loading);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* reload proxy table
|
||||
*/
|
||||
function reloadTable() {
|
||||
loadProxyInfo(null, null, null);
|
||||
loadProxyInfo(null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
var loadOverview = (function ($) {
|
||||
var i18n = {};
|
||||
|
||||
/**
|
||||
* get proxy info
|
||||
* @param lang {{}} language json
|
||||
* @param title page title
|
||||
*/
|
||||
function loadOverview(lang, title) {
|
||||
i18n = lang;
|
||||
function loadOverview(title) {
|
||||
$("#title").text(title);
|
||||
$('#content').empty();
|
||||
var loading = layui.layer.load();
|
||||
@@ -63,7 +59,11 @@ var loadOverview = (function ($) {
|
||||
text: {none: i18n['EmptyData']},
|
||||
cols: [cols],
|
||||
page: {
|
||||
layout: navigator.language.indexOf("zh") === -1 ? ['first', 'prev', 'next', 'last'] : ['prev', 'page', 'next', 'skip', 'count', 'limit']
|
||||
limitTemplet: function (item) {
|
||||
return item + i18n['PerPage'];
|
||||
},
|
||||
skipText: [i18n['Goto'], '', i18n['Confirm']],
|
||||
countText: [i18n['Total'], i18n['Items']]
|
||||
},
|
||||
data: dataList,
|
||||
initSort: {
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
window.clientConfig = {};
|
||||
window.i18n = {};
|
||||
(function ($) {
|
||||
$(function () {
|
||||
function init() {
|
||||
var langLoading = layui.layer.load()
|
||||
$.getJSON('/lang.json').done(function (lang) {
|
||||
window.i18n = lang;
|
||||
$.ajaxSetup({
|
||||
error: function (xhr,) {
|
||||
if (xhr.status === 401) {
|
||||
@@ -17,13 +20,13 @@
|
||||
var id = elem.attr('id');
|
||||
var title = elem.text();
|
||||
if (id === 'clientInfo') {
|
||||
loadClientInfo(lang, title.trim());
|
||||
loadClientInfo(title.trim());
|
||||
} else if (id === 'overview') {
|
||||
loadOverview(lang, title.trim());
|
||||
loadOverview(title.trim());
|
||||
} else if (elem.closest('.layui-nav-item').attr('id') === 'proxies') {
|
||||
if (id != null && id.trim() !== '') {
|
||||
var suffix = elem.closest('.layui-nav-item').children('a').text().trim();
|
||||
loadProxyInfo(lang, title + " " + suffix, id);
|
||||
loadProxyInfo(title + " " + suffix, id);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -34,6 +37,45 @@
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* add verify rule to layui.form
|
||||
*/
|
||||
function initFormVerifyRule() {
|
||||
layui.form.verify({
|
||||
proxyName: function (value, elem) {
|
||||
if (value.trim() === '') {
|
||||
var nameI18n = $('#proxyName').closest('.layui-form-item').children('.layui-form-label').text();
|
||||
return nameI18n + i18n['RequireNotEmpty'];
|
||||
}
|
||||
},
|
||||
localPort: function (value, elem) {
|
||||
if (value !== '' && !/^\d+$/.test(value)) {
|
||||
var nameI18n = $('#localPort').closest('.layui-form-item').children('.layui-form-label').text();
|
||||
return nameI18n + i18n['RequireNumber'];
|
||||
}
|
||||
},
|
||||
domain: function (value, elem) {
|
||||
var proxyType = $('#proxyType').val().toLowerCase();
|
||||
var $customDomains = $('#customDomains');
|
||||
var customDomains = $customDomains.val();
|
||||
var $subdomain = $('#subdomain');
|
||||
var subdomain = $subdomain.val();
|
||||
if (proxyType === 'http' || proxyType === 'https') {
|
||||
if (customDomains.trim() === '' && subdomain.trim() === '') {
|
||||
var customDomainsNameI18n = $customDomains.closest('.layui-form-item').children('.layui-form-label').text();
|
||||
var subdomainNameI18n = $subdomain.closest('.layui-form-item').children('.layui-form-label').text();
|
||||
return customDomainsNameI18n + i18n['and'] + subdomainNameI18n + i18n['RequireNotAllEmpty'];
|
||||
} else if (customDomains.trim() !== '') {
|
||||
var nameI18n = $customDomains.closest('.layui-form-item').children('.layui-form-label').text();
|
||||
if (!/^\s*\[.*]\s*$/.test(customDomains)) {
|
||||
return nameI18n + i18n['RequireArray'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function logout() {
|
||||
$.get("/logout", function (result) {
|
||||
window.location.reload();
|
||||
@@ -45,5 +87,6 @@
|
||||
});
|
||||
|
||||
init();
|
||||
initFormVerifyRule();
|
||||
});
|
||||
})(layui.$);
|
||||
210
assets/static/js/json-process.js
Normal file
210
assets/static/js/json-process.js
Normal file
@@ -0,0 +1,210 @@
|
||||
(function ($) {
|
||||
//param names in Basic tab
|
||||
var basicParams = [
|
||||
{
|
||||
name: 'name',
|
||||
defaultValue: '-'
|
||||
}, {
|
||||
name: 'type',
|
||||
defaultValue: '-'
|
||||
}, {
|
||||
name: 'localIP',
|
||||
defaultValue: '-'
|
||||
}, {
|
||||
name: 'localPort',
|
||||
defaultValue: '-'
|
||||
}, {
|
||||
name: 'customDomains',
|
||||
defaultValue: '-'
|
||||
}, {
|
||||
name: 'subdomain',
|
||||
defaultValue: '-'
|
||||
}, {
|
||||
name: 'remotePort',
|
||||
defaultValue: '-'
|
||||
}, {
|
||||
name: 'transport.useEncryption',
|
||||
defaultValue: false,
|
||||
}, {
|
||||
name: 'transport.useCompression',
|
||||
defaultValue: false,
|
||||
}
|
||||
];
|
||||
var mapParams = [{
|
||||
name: 'plugin.ClientPluginOptions',
|
||||
map: 'plugin'
|
||||
}];
|
||||
var paramTypes = {
|
||||
number: [
|
||||
'healthCheck.timeoutSeconds',
|
||||
'healthCheck.maxFailed',
|
||||
'healthCheck.intervalSeconds',
|
||||
'localPort',
|
||||
'remotePort'
|
||||
],
|
||||
boolean: [
|
||||
'transport.useEncryption',
|
||||
'transport.useCompression'
|
||||
],
|
||||
array: [
|
||||
'customDomains',
|
||||
'locations',
|
||||
'allowUsers'
|
||||
],
|
||||
map: [
|
||||
'metadatas',
|
||||
'requestHeaders.set',
|
||||
'plugin.ClientPluginOptions.requestHeaders.set'
|
||||
]
|
||||
}
|
||||
|
||||
/**
|
||||
* a.b.c = 1
|
||||
* a.b.d = [2,3]
|
||||
* to
|
||||
* {a: {
|
||||
* b: {
|
||||
* c: 1
|
||||
* d: "[2,3]"
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @param obj json object
|
||||
* @param keys all keys split from key string like 'a.b.c'
|
||||
* @param value default value
|
||||
* @param stringifyArray if true, when value is an array, it will stringify by JSON.stringify(value)
|
||||
*/
|
||||
function expandJSONKeys(obj, keys, value, stringifyArray) {
|
||||
stringifyArray = stringifyArray == null ? true : stringifyArray;
|
||||
var currentIndex = this.index || 0;
|
||||
var childrenIndex = (currentIndex + 1) > keys.length ? null : (currentIndex + 1);
|
||||
var currentKey = keys[currentIndex], currentValue = {};
|
||||
var childrenKey = childrenIndex == null ? null : keys[childrenIndex];
|
||||
if (obj.hasOwnProperty(currentKey)) {
|
||||
currentValue = obj[currentKey];
|
||||
} else {
|
||||
obj[currentKey] = currentValue;
|
||||
}
|
||||
|
||||
if (childrenKey != null) {
|
||||
this.index = childrenIndex;
|
||||
expandJSONKeys(currentValue, keys, value, stringifyArray);
|
||||
} else {
|
||||
if (value != null) {
|
||||
if (Array.isArray(value) && stringifyArray) {
|
||||
obj[currentKey] = JSON.stringify(value);
|
||||
} else {
|
||||
obj[currentKey] = value;
|
||||
}
|
||||
}
|
||||
this.index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function expandJSON(obj) {
|
||||
var newObj = {};
|
||||
var inPopup = $('#proxyForm').length !== 0;
|
||||
for (var name in obj) {
|
||||
var value = obj[name];
|
||||
if (value === '') {
|
||||
continue;
|
||||
}
|
||||
var nameI18n = name;
|
||||
if (inPopup) {
|
||||
nameI18n = $('#proxyForm [name="' + name + '"]').closest('.layui-form-item').children('.layui-form-label').text();
|
||||
if (nameI18n === '') {
|
||||
nameI18n = name;
|
||||
}
|
||||
}
|
||||
|
||||
if (paramTypes.number.indexOf(name) !== -1) {
|
||||
value = parseInt(value);
|
||||
if (isNaN(value)) {
|
||||
throw new Error(nameI18n + i18n['RequireNumber']);
|
||||
}
|
||||
} else if (paramTypes.boolean.indexOf(name) !== -1) {
|
||||
if (typeof value === "string" && (value === 'true' || value === 'false')) {
|
||||
value = value === 'true';
|
||||
} else if (typeof value !== 'boolean') {
|
||||
throw new Error(nameI18n + i18n['RequireBoolean']);
|
||||
}
|
||||
} else if (paramTypes.array.indexOf(name) !== -1) {
|
||||
try {
|
||||
if (/^\s*\[.*]\s*$/.test(value)) {
|
||||
value = eval('(' + value + ')') || [];
|
||||
} else {
|
||||
throw new Error('value format incorrect');
|
||||
}
|
||||
} catch (e) {
|
||||
throw new Error(nameI18n + i18n['RequireArray']);
|
||||
}
|
||||
} else {
|
||||
for (var i = 0; i < paramTypes.map.length; i++) {
|
||||
var key = paramTypes.map[i];
|
||||
if (name.startsWith(key)) {
|
||||
var json = {};
|
||||
json[name.substring(key.length + 1, name.length)] = value;
|
||||
value = json;
|
||||
name = name.substring(0, key.length)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expandJSONKeys(newObj, name.split("."), value, false);
|
||||
}
|
||||
return newObj;
|
||||
}
|
||||
|
||||
/**
|
||||
* {a: {
|
||||
* b: {
|
||||
* c: 1
|
||||
* d: [2,3]
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* to
|
||||
* {
|
||||
* 'a.b.c': 1,
|
||||
* 'a.b.d': '[2,3]'
|
||||
* }
|
||||
*
|
||||
* @param obj json object
|
||||
* @returns {*} flatted json key array
|
||||
*/
|
||||
function flatJSON(obj) {
|
||||
var flat = function (obj, prentKey, flattedJSON) {
|
||||
flattedJSON = flattedJSON || {};
|
||||
prentKey = prentKey || '';
|
||||
if (prentKey !== '')
|
||||
prentKey = prentKey + '.';
|
||||
for (var key in obj) {
|
||||
var value = obj[key];
|
||||
if (typeof value === 'object' && Object.prototype.toString.call(value) === '[object Object]') {
|
||||
flat(value, prentKey + key, flattedJSON);
|
||||
} else {
|
||||
for (var mapParam of mapParams) {
|
||||
if (prentKey.startsWith(mapParam.name)) {
|
||||
prentKey = mapParam.map + '.';
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
flattedJSON[prentKey + key] = JSON.stringify(value);
|
||||
} else {
|
||||
flattedJSON[prentKey + key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return flattedJSON;
|
||||
}
|
||||
return flat(obj);
|
||||
}
|
||||
|
||||
window.basicParams = basicParams;
|
||||
window.expandJSONKeys = expandJSONKeys;
|
||||
window.expandJSON = expandJSON;
|
||||
window.flatJSON = flatJSON;
|
||||
})(layui.$);
|
||||
8337
assets/static/js/toml.js
Normal file
8337
assets/static/js/toml.js
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -7,6 +7,8 @@
|
||||
<link rel="stylesheet" href="./static/css/index.css?v=${ .version }">
|
||||
<link rel="stylesheet" href="./static/css/color.css?v=${ .version }">
|
||||
<script src="./static/lib/layui/layui.js?v=${ .version }"></script>
|
||||
<script src="./static/js/toml.js?v=${ .version }"></script>
|
||||
<script src="./static/js/json-process.js?v=${ .version }"></script>
|
||||
<script src="./static/js/index-client-info.js?v=${ .version }"></script>
|
||||
<script src="./static/js/index-proxy-overview.js?v=${ .version }"></script>
|
||||
<script src="./static/js/index-proxy-list.js?v=${ .version }"></script>
|
||||
@@ -77,19 +79,19 @@
|
||||
<div class="text-info">
|
||||
<div class="text-row">
|
||||
<div class="text-col">${ .ServerAddress }</div>
|
||||
<div class="text-col">{{= d.server_addr || '-' }}</div>
|
||||
<div class="text-col">{{= d.serverAddr || '-' }}</div>
|
||||
</div>
|
||||
<div class="text-row">
|
||||
<div class="text-col">${ .ServerPort }</div>
|
||||
<div class="text-col">{{= d.server_port || '-' }}</div>
|
||||
<div class="text-col">{{= d.serverPort || '-' }}</div>
|
||||
</div>
|
||||
<div class="text-row">
|
||||
<div class="text-col">${ .Protocol }</div>
|
||||
<div class="text-col">{{= d.protocol || '-' }}</div>
|
||||
<div class="text-col">{{= d.transport.protocol || '-' }}</div>
|
||||
</div>
|
||||
<div class="text-row">
|
||||
<div class="text-col">${ .TCPMux }</div>
|
||||
<div class="text-col">{{= d.tcp_mux || '-' }}</div>
|
||||
<div class="text-col">{{= d.transport.tcpMux || '-' }}</div>
|
||||
</div>
|
||||
<div class="text-row">
|
||||
<div class="text-col">${ .User }</div>
|
||||
@@ -97,98 +99,98 @@
|
||||
</div>
|
||||
<div class="text-row">
|
||||
<div class="text-col">${ .UserToken }</div>
|
||||
<div class="text-col">{{= d.metas.token || '-' }}</div>
|
||||
<div class="text-col">{{= d.metadatas.token || '-' }}</div>
|
||||
</div>
|
||||
<div class="text-row">
|
||||
<div class="text-col">${ .AdminAddress }</div>
|
||||
<div class="text-col">{{= d.admin_addr || '-' }}</div>
|
||||
<div class="text-col">{{= d.webServer.addr || '-' }}</div>
|
||||
</div>
|
||||
<div class="text-row">
|
||||
<div class="text-col">${ .AdminPort }</div>
|
||||
<div class="text-col">{{= d.admin_port || '-' }}</div>
|
||||
<div class="text-col">{{= d.webServer.port || '-' }}</div>
|
||||
</div>
|
||||
<div class="text-row">
|
||||
<div class="text-col">${ .AdminUser }</div>
|
||||
<div class="text-col">{{= d.admin_user || '-' }}</div>
|
||||
<div class="text-col">{{= d.webServer.user || '-' }}</div>
|
||||
</div>
|
||||
<div class="text-row">
|
||||
<div class="text-col">${ .AdminPwd }</div>
|
||||
<div class="text-col">{{= d.admin_pwd || '-' }}</div>
|
||||
<div class="text-col">{{= d.webServer.password || '-' }}</div>
|
||||
</div>
|
||||
<div class="text-row">
|
||||
<div class="text-col">${ .HeartbeatInterval }</div>
|
||||
<div class="text-col">{{= d.heartbeat_interval || '-' }}</div>
|
||||
<div class="text-col">{{= d.transport.heartbeatInterval || '-' }}</div>
|
||||
</div>
|
||||
<div class="text-row">
|
||||
<div class="text-col">${ .HeartbeatTimeout }</div>
|
||||
<div class="text-col">{{= d.heartbeat_timeout || '-' }}</div>
|
||||
<div class="text-col">{{= d.transport.heartbeatTimeout || '-' }}</div>
|
||||
</div>
|
||||
<div class="text-row">
|
||||
<div class="text-col">${ .TLSEnable }</div>
|
||||
<div class="text-col">{{= d.tls_enable || '-' }}</div>
|
||||
<div class="text-col">{{= d.transport.tls.enable || '-' }}</div>
|
||||
</div>
|
||||
<div class="text-row">
|
||||
<div class="text-col">${ .TLSKeyFile }</div>
|
||||
<div class="text-col">{{= d.tls_key_file || '-' }}</div>
|
||||
<div class="text-col">{{= d.transport.tls.keyFile || '-' }}</div>
|
||||
</div>
|
||||
<div class="text-row">
|
||||
<div class="text-col">${ .TLSCertFile }</div>
|
||||
<div class="text-col">{{= d.tls_cert_file || '-' }}</div>
|
||||
<div class="text-col">{{= d.transport.tls.certFile || '-' }}</div>
|
||||
</div>
|
||||
<div class="text-row">
|
||||
<div class="text-col">${ .TLSTrustedCAFile }</div>
|
||||
<div class="text-col">{{= d.tls_trusted_ca_file || '-' }}</div>
|
||||
<div class="text-col">{{= d.transport.tls.trustedCaFile || '-' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</script>
|
||||
|
||||
<!--用户列表-添加用户表单模板-->
|
||||
<script type="text/html" id="addProxyTemplate">
|
||||
<form class="layui-form" id="addProxyForm" lay-filter="addProxyForm">
|
||||
<script type="text/html" id="proxyFormTemplate">
|
||||
<form class="layui-form" id="proxyForm" lay-filter="proxyForm">
|
||||
<div class="layui-tab layui-tab-brief">
|
||||
<ul class="layui-tab-title">
|
||||
<li class="layui-this">${ .Basic }</li>
|
||||
<li>${ .Extra }</li>
|
||||
</ul>
|
||||
<div class="layui-tab-content">
|
||||
<input type="hidden" name="type">
|
||||
<input type="hidden" name="${ .OldNameKey }" id="oldName">
|
||||
<input type="hidden" name="type" id="proxyType">
|
||||
<input type="hidden" name="${ .OriginalNameKey }" id="originalNameKey">
|
||||
<div class="layui-tab-item layui-show">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">${ .ProxyName }</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="name" placeholder="${ .ProxyName }" autocomplete="off"
|
||||
class="layui-input"/>
|
||||
<input type="text" name="name" id="proxyName" placeholder="${ .ProxyNameExample }"
|
||||
autocomplete="off" class="layui-input" lay-verify="proxyName"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">${ .LocalIp }</label>
|
||||
<label class="layui-form-label">${ .LocalIP }</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="local_ip" placeholder="${ .LocalIp }" autocomplete="off"
|
||||
class="layui-input"/>
|
||||
<input type="text" name="localIP" id="localIP" placeholder="${ .LocalIPExample }"
|
||||
autocomplete="off" class="layui-input"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">${ .LocalPort }</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="local_port" placeholder="${ .LocalPort }" autocomplete="off"
|
||||
class="layui-input"/>
|
||||
<input type="text" name="localPort" id="localPort" placeholder="${ .LocalPortExample }"
|
||||
autocomplete="off" class="layui-input" lay-verify="localPort"/>
|
||||
</div>
|
||||
</div>
|
||||
{{# if (d.type.toLowerCase() === 'http' || d.type.toLowerCase() === 'https') { }}
|
||||
<div class="layui-form-item http https">
|
||||
<label class="layui-form-label">${ .CustomDomains }</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="custom_domains" placeholder="${ .CustomDomains }" autocomplete="off"
|
||||
class="layui-textarea"></textarea>
|
||||
<textarea name="customDomains" id="customDomains" placeholder="${ .CustomDomainsExample }"
|
||||
autocomplete="off" class="layui-textarea" lay-verify="domain"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-form-text http https">
|
||||
<label class="layui-form-label">${ .Subdomain }</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="subdomain" placeholder="${ .Subdomain }" autocomplete="off"
|
||||
class="layui-textarea"></textarea>
|
||||
<textarea name="subdomain" id="subdomain" placeholder="${ .Subdomain }" autocomplete="off"
|
||||
class="layui-textarea" lay-verify="domain"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
{{# } }}
|
||||
@@ -196,7 +198,8 @@
|
||||
<div class="layui-form-item tcp udp">
|
||||
<label class="layui-form-label">${ .RemotePort }</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="remote_port" placeholder="${ .RemotePort }" autocomplete="off"
|
||||
<input type="text" name="remotePort" placeholder="${ .RemotePortExample }"
|
||||
autocomplete="off"
|
||||
class="layui-input"/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -206,7 +209,8 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">${ .UseEncryption }</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="checkbox" name="use_encryption" value="true" title="${ .true }">
|
||||
<input type="checkbox" name="transport.useEncryption" value="true"
|
||||
title="${ .true }">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -214,7 +218,8 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">${ .UseCompression }</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="checkbox" name="use_compression" value="true" title="${ .true }">
|
||||
<input type="checkbox" name="transport.useCompression" value="true"
|
||||
title="${ .true }">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
const version = "1.0.0"
|
||||
const version = "2.0.0"
|
||||
|
||||
var (
|
||||
showVersion bool
|
||||
@@ -76,7 +76,7 @@ func parseConfigFile(configFile, tokensFile string) (controller.HandleController
|
||||
log.Fatalf("decode config file %v error: %v", configFile, err)
|
||||
}
|
||||
|
||||
common.Common.DashboardTls = strings.HasPrefix("https://", strings.ToLower(common.Common.DashboardAddr))
|
||||
common.Common.DashboardTls = strings.HasPrefix(strings.ToLower(common.Common.DashboardAddr), "https://")
|
||||
|
||||
tls := server.TLS{
|
||||
Enable: common.Common.TlsMode,
|
||||
|
||||
24
go.mod
24
go.mod
@@ -4,11 +4,11 @@ go 1.21
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.0.0
|
||||
github.com/fatedier/frp v0.34.1
|
||||
github.com/fatedier/frp v0.52.3
|
||||
github.com/gin-contrib/i18n v1.0.0
|
||||
github.com/gin-contrib/sessions v0.0.5
|
||||
github.com/gin-gonic/gin v1.9.1
|
||||
github.com/spf13/cobra v0.0.3
|
||||
github.com/spf13/cobra v1.7.0
|
||||
golang.org/x/text v0.11.0
|
||||
)
|
||||
|
||||
@@ -16,20 +16,18 @@ require (
|
||||
github.com/bytedance/sonic v1.10.0-rc3 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
|
||||
github.com/chenzhuoyu/iasm v0.9.0 // indirect
|
||||
github.com/coreos/go-oidc v2.2.1+incompatible // indirect
|
||||
github.com/fatedier/beego v0.0.0-20171024143340-6c6a4f5bd5eb // indirect
|
||||
github.com/fatedier/golib v0.1.1-0.20200901083111-1f870741e185 // indirect
|
||||
github.com/fatedier/golib v0.1.1-0.20230725122706-dcbaee8eef40 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.14.1 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/golang/protobuf v1.5.0 // indirect
|
||||
github.com/gorilla/context v1.1.1 // indirect
|
||||
github.com/gorilla/securecookie v1.1.1 // indirect
|
||||
github.com/gorilla/sessions v1.2.1 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
|
||||
github.com/leodido/go-urn v1.2.4 // indirect
|
||||
@@ -37,19 +35,21 @@ require (
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/nicksnyder/go-i18n/v2 v2.2.1 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.9 // indirect
|
||||
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
|
||||
github.com/samber/lo v1.38.1 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec // indirect
|
||||
golang.org/x/arch v0.4.0 // indirect
|
||||
golang.org/x/crypto v0.11.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect
|
||||
golang.org/x/net v0.12.0 // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect
|
||||
golang.org/x/sys v0.10.0 // indirect
|
||||
google.golang.org/appengine v1.4.0 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
gopkg.in/square/go-jose.v2 v2.4.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/apimachinery v0.27.4 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
|
||||
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||
)
|
||||
|
||||
227
go.sum
227
go.sum
@@ -1,50 +1,27 @@
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
|
||||
github.com/BurntSushi/toml v1.0.0 h1:dtDWrepsVPfW9H/4y7dDgFc2MBUSeJhlaDtK13CxFlU=
|
||||
github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||
github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM=
|
||||
github.com/bytedance/sonic v1.10.0-rc3 h1:uNSnscRapXTwUgTyOF0GVljYD08p9X/Lbr9MweSV3V0=
|
||||
github.com/bytedance/sonic v1.10.0-rc3/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA=
|
||||
github.com/chenzhuoyu/iasm v0.9.0 h1:9fhXjVzq5hUy2gkhhgHl95zG2cEAhw9OSGs8toWWAwo=
|
||||
github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
|
||||
github.com/coreos/go-oidc v2.2.1+incompatible h1:mh48q/BqXqgjVHpy2ZY7WnWAbenxRjsz9N1i1YxjHAk=
|
||||
github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
|
||||
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/fatedier/beego v0.0.0-20171024143340-6c6a4f5bd5eb h1:wCrNShQidLmvVWn/0PikGmpdP0vtQmnvyRg3ZBEhczw=
|
||||
github.com/fatedier/beego v0.0.0-20171024143340-6c6a4f5bd5eb/go.mod h1:wx3gB6dbIfBRcucp94PI9Bt3I0F2c/MyNEWuhzpWiwk=
|
||||
github.com/fatedier/frp v0.34.1 h1:8J0ASuKVqo/IQubIVkMnuuflzhNT661PexUgeye/zUE=
|
||||
github.com/fatedier/frp v0.34.1/go.mod h1:y3PpthszJ+S5HB2J5kcXqoLr5rtgdmMa0RuvnGqGfik=
|
||||
github.com/fatedier/golib v0.1.1-0.20200901083111-1f870741e185 h1:2p4W5xYizIYwhiGQgeHOQcRD2O84j0tjD40P6gUCRrk=
|
||||
github.com/fatedier/golib v0.1.1-0.20200901083111-1f870741e185/go.mod h1:MUs+IH/MGJNz5Cj2JVJBPZBKw2exON7LzO3HrJHmGiQ=
|
||||
github.com/fatedier/kcp-go v2.0.4-0.20190803094908-fe8645b0a904+incompatible/go.mod h1:YpCOaxj7vvMThhIQ9AfTOPW2sfztQR5WDfs7AflSy4s=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/fatedier/frp v0.52.3 h1:YElvJIQ3wXAloJTp7JOmLTpnm/+IyLmzNgeDNqQFI9Q=
|
||||
github.com/fatedier/frp v0.52.3/go.mod h1:M0mqGPc0daWLB9Ziv91rlwUIpxpb/oNDiOAx8NN5i3E=
|
||||
github.com/fatedier/golib v0.1.1-0.20230725122706-dcbaee8eef40 h1:BVdpWT6viE/mpuRa6txNyRNjtHa1Efrii9Du6/gHfJ0=
|
||||
github.com/fatedier/golib v0.1.1-0.20230725122706-dcbaee8eef40/go.mod h1:Lmi9U4VfvdRvonSMh1FgXVy1hCXycVyJk4E9ktokknE=
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
|
||||
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
|
||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gin-contrib/i18n v1.0.0 h1:e5uEOmaAr09Iyr4vuWuvvpByjmvxGDO7iSkmiFpSsk0=
|
||||
github.com/gin-contrib/i18n v1.0.0/go.mod h1:yyyTArpVZeXCFT/kbLbD5CS192+OZ8Y+angnJjvnB98=
|
||||
github.com/gin-contrib/sessions v0.0.5 h1:CATtfHmLMQrMNpJRgzjWXD7worTh7g7ritsQfmF+0jE=
|
||||
@@ -53,15 +30,6 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
|
||||
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
|
||||
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
|
||||
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
|
||||
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
@@ -70,134 +38,53 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.14.1 h1:9c50NUPC30zyuKprjL3vNZ0m5oG+jU0zvx4AqHGnv4k=
|
||||
github.com/go-playground/validator/v10 v10.14.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
|
||||
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||
github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI=
|
||||
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/klauspost/reedsolomon v1.9.1/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4=
|
||||
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
|
||||
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
||||
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
github.com/nicksnyder/go-i18n/v2 v2.2.1 h1:aOzRCdwsJuoExfZhoiXHy4bjruwCMdt5otbYojM/PaA=
|
||||
github.com/nicksnyder/go-i18n/v2 v2.2.1/go.mod h1:fF2++lPHlo+/kPaj3nB0uxtPwzlPm+BlgwGX7MkeGj0=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.12.3/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0=
|
||||
github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
||||
github.com/pires/go-proxyproto v0.0.0-20190111085350-4d51b51e3bfc/go.mod h1:6/gX3+E/IYGa0wMORlSMla999awQFdbaeQCHjSMKIzY=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
|
||||
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 h1:J9b7z+QKAmPf4YLrFg6oQUotqHQeUNWwkvo7jZp1GLU=
|
||||
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.4.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||
github.com/rakyll/statik v0.1.1/go.mod h1:OEi9wJV/fMUAGx1eNjq75DKDsJVuEv1U0oYdX6GX8Zs=
|
||||
github.com/rodaine/table v1.0.0/go.mod h1:YAUzwPOji0DUJNEvggdxyQcUAl4g3hDRcFlyjnnR51I=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM=
|
||||
github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
|
||||
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
|
||||
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
@@ -205,63 +92,31 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/templexxx/cpufeat v0.0.0-20170927014610-3794dfbfb047/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU=
|
||||
github.com/templexxx/xor v0.0.0-20170926022130-0af8e873c554/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4=
|
||||
github.com/tjfoc/gmsm v0.0.0-20171124023159-98aa888b79d8/go.mod h1:XxO4hdhhrzAd+G4CjDqaOkd0hUzmtPR/d3EiBBMn/wc=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec h1:DGmKwyZwEB8dI7tbLt/I/gQuP559o/0FrAkHKlQM/Ks=
|
||||
github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec/go.mod h1:owBmyHYMLkxyrugmfwE/DLJyW8Ro9mkphwuVErQ0iUw=
|
||||
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/arch v0.4.0 h1:A8WCeEWhLwPBKNbFi5Wv5UTCBx5zzubnXDlMOFAzFMc=
|
||||
golang.org/x/arch v0.4.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
|
||||
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
|
||||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o=
|
||||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190228165749-92fc7df08ae7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
|
||||
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@@ -272,63 +127,35 @@ golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
|
||||
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
|
||||
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/square/go-jose.v2 v2.4.1 h1:H0TmLt7/KmzlrDOpa1F+zr0Tk90PbJYBfsVUmRLrf9Y=
|
||||
gopkg.in/square/go-jose.v2 v2.4.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
k8s.io/apimachinery v0.18.3/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko=
|
||||
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
|
||||
k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
|
||||
k8s.io/apimachinery v0.27.4 h1:CdxflD4AF61yewuid0fLl6bM4a3q04jWel0IlP+aYjs=
|
||||
k8s.io/apimachinery v0.27.4/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E=
|
||||
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
|
||||
sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
|
||||
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
||||
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"fmt"
|
||||
ginI18n "github.com/gin-contrib/i18n"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/vaughan0/go-ini"
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
@@ -57,7 +56,7 @@ func (c *HandleController) MakeIndexFunc() func(context *gin.Context) {
|
||||
return func(context *gin.Context) {
|
||||
context.HTML(http.StatusOK, "index.html", gin.H{
|
||||
"version": c.Version,
|
||||
"OldNameKey": OldNameKey,
|
||||
"OriginalNameKey": OriginalNameKey,
|
||||
"showExit": trimString(c.CommonInfo.AdminUser) != "" && trimString(c.CommonInfo.AdminPwd) != "",
|
||||
"FrpcPanel": ginI18n.MustGetMessage(context, "Frpc Panel"),
|
||||
"ClientInfo": ginI18n.MustGetMessage(context, "Client Info"),
|
||||
@@ -86,10 +85,15 @@ func (c *HandleController) MakeIndexFunc() func(context *gin.Context) {
|
||||
"Basic": ginI18n.MustGetMessage(context, "Basic"),
|
||||
"Extra": ginI18n.MustGetMessage(context, "Extra"),
|
||||
"ProxyName": ginI18n.MustGetMessage(context, "Proxy Name"),
|
||||
"LocalIp": ginI18n.MustGetMessage(context, "Local Ip"),
|
||||
"ProxyNameExample": ginI18n.MustGetMessage(context, "Proxy Name Example"),
|
||||
"LocalIP": ginI18n.MustGetMessage(context, "Local IP"),
|
||||
"LocalIPExample": ginI18n.MustGetMessage(context, "Local IP Example"),
|
||||
"LocalPort": ginI18n.MustGetMessage(context, "Local Port"),
|
||||
"LocalPortExample": ginI18n.MustGetMessage(context, "Local Port Example"),
|
||||
"RemotePort": ginI18n.MustGetMessage(context, "Remote Port"),
|
||||
"RemotePortExample": ginI18n.MustGetMessage(context, "Remote Port Example"),
|
||||
"CustomDomains": ginI18n.MustGetMessage(context, "Custom Domains"),
|
||||
"CustomDomainsExample": ginI18n.MustGetMessage(context, "Custom Domains Example"),
|
||||
"Subdomain": ginI18n.MustGetMessage(context, "Subdomain"),
|
||||
"UseEncryption": ginI18n.MustGetMessage(context, "Use Encryption"),
|
||||
"true": ginI18n.MustGetMessage(context, "true"),
|
||||
@@ -103,6 +107,7 @@ func (c *HandleController) MakeIndexFunc() func(context *gin.Context) {
|
||||
func (c *HandleController) MakeLangFunc() func(context *gin.Context) {
|
||||
return func(context *gin.Context) {
|
||||
context.JSON(http.StatusOK, gin.H{
|
||||
"Proxies": ginI18n.MustGetMessage(context, "Proxies"),
|
||||
"EmptyData": ginI18n.MustGetMessage(context, "Empty data"),
|
||||
"true": ginI18n.MustGetMessage(context, "true"),
|
||||
"false": ginI18n.MustGetMessage(context, "false"),
|
||||
@@ -114,7 +119,9 @@ func (c *HandleController) MakeLangFunc() func(context *gin.Context) {
|
||||
"Status": ginI18n.MustGetMessage(context, "Status"),
|
||||
"Info": ginI18n.MustGetMessage(context, "Info"),
|
||||
"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"),
|
||||
"RemotePort": ginI18n.MustGetMessage(context, "Remote Port"),
|
||||
"UseEncryption": ginI18n.MustGetMessage(context, "Use Encryption"),
|
||||
@@ -135,69 +142,22 @@ func (c *HandleController) MakeLangFunc() func(context *gin.Context) {
|
||||
"ProxyExist": ginI18n.MustGetMessage(context, "Proxy Exist"),
|
||||
"ProxyNotExist": ginI18n.MustGetMessage(context, "Proxy Not Exist"),
|
||||
"ClientTips": ginI18n.MustGetMessage(context, "Client Tips"),
|
||||
"and": ginI18n.MustGetMessage(context, "and"),
|
||||
"RequireNotAllEmpty": ginI18n.MustGetMessage(context, "Require Not All Empty"),
|
||||
"RequireNotEmpty": ginI18n.MustGetMessage(context, "Require Not Empty"),
|
||||
"RequireNumber": ginI18n.MustGetMessage(context, "Require Number"),
|
||||
"RequireBoolean": ginI18n.MustGetMessage(context, "Require Boolean"),
|
||||
"RequireArray": ginI18n.MustGetMessage(context, "Require Array"),
|
||||
"Total": ginI18n.MustGetMessage(context, "Total"),
|
||||
"Items": ginI18n.MustGetMessage(context, "Items"),
|
||||
"Goto": ginI18n.MustGetMessage(context, "Go to"),
|
||||
"PerPage": ginI18n.MustGetMessage(context, "Per Page"),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (c *HandleController) MakeAddProxyFunc() func(context *gin.Context) {
|
||||
return func(context *gin.Context) {
|
||||
proxy := ini.Section{}
|
||||
|
||||
response := OperationResponse{
|
||||
Success: true,
|
||||
Code: Success,
|
||||
Message: "proxy add success",
|
||||
}
|
||||
|
||||
err := context.BindJSON(&proxy)
|
||||
if err != nil {
|
||||
response.Success = false
|
||||
response.Code = ParamError
|
||||
response.Message = fmt.Sprintf("proxy add failed, param error : %v", err)
|
||||
log.Printf(response.Message)
|
||||
context.JSON(http.StatusOK, &response)
|
||||
return
|
||||
}
|
||||
|
||||
name := proxy[NameKey]
|
||||
|
||||
if trimString(name) == "" {
|
||||
response.Success = false
|
||||
response.Code = ParamError
|
||||
response.Message = fmt.Sprintf("proxy add failed, proxy name invalid")
|
||||
log.Printf(response.Message)
|
||||
context.JSON(http.StatusOK, &response)
|
||||
return
|
||||
}
|
||||
|
||||
if _, exist := clientProxies[name]; exist {
|
||||
response.Success = false
|
||||
response.Code = ProxyExist
|
||||
response.Message = fmt.Sprintf("proxy add failed, proxy exist")
|
||||
log.Printf(response.Message)
|
||||
context.JSON(http.StatusOK, &response)
|
||||
return
|
||||
}
|
||||
|
||||
clientProxies[name] = proxy
|
||||
|
||||
res := c.UpdateFrpcConfig()
|
||||
if !res.Success {
|
||||
response.Success = false
|
||||
response.Code = res.Code
|
||||
response.Message = fmt.Sprintf("proxy add failed, error : %v", res.Message)
|
||||
log.Printf(response.Message)
|
||||
context.JSON(http.StatusOK, &response)
|
||||
return
|
||||
}
|
||||
|
||||
context.JSON(0, &response)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *HandleController) MakeUpdateProxyFunc() func(context *gin.Context) {
|
||||
return func(context *gin.Context) {
|
||||
proxy := ini.Section{}
|
||||
|
||||
response := OperationResponse{
|
||||
Success: true,
|
||||
@@ -205,119 +165,21 @@ func (c *HandleController) MakeUpdateProxyFunc() func(context *gin.Context) {
|
||||
Message: "proxy update success",
|
||||
}
|
||||
|
||||
err := context.BindJSON(&proxy)
|
||||
data, err := context.GetRawData()
|
||||
if err != nil {
|
||||
response.Success = false
|
||||
response.Code = ParamError
|
||||
response.Message = fmt.Sprintf("update failed, param error : %v", err)
|
||||
response.Code = http.StatusNoContent
|
||||
response.Message = fmt.Sprintf("update failed, error : %v", err)
|
||||
log.Printf(response.Message)
|
||||
context.JSON(http.StatusOK, &response)
|
||||
return
|
||||
}
|
||||
|
||||
oldName := proxy[OldNameKey]
|
||||
name := proxy[NameKey]
|
||||
|
||||
if trimString(oldName) == "" || trimString(name) == "" {
|
||||
response.Success = false
|
||||
response.Code = ParamError
|
||||
response.Message = fmt.Sprintf("proxy add failed, proxy name invalid")
|
||||
log.Printf(response.Message)
|
||||
context.JSON(http.StatusOK, &response)
|
||||
return
|
||||
}
|
||||
|
||||
if _, exist := clientProxies[oldName]; !exist {
|
||||
response.Success = false
|
||||
response.Code = ProxyNotExist
|
||||
response.Message = fmt.Sprintf("proxy update failed, proxy not exist")
|
||||
log.Printf(response.Message)
|
||||
context.JSON(http.StatusOK, &response)
|
||||
return
|
||||
}
|
||||
|
||||
if oldName != name {
|
||||
if _, exist := clientProxies[name]; exist {
|
||||
response.Success = false
|
||||
response.Code = ProxyExist
|
||||
response.Message = fmt.Sprintf("proxy update failed, proxy exist")
|
||||
log.Printf(response.Message)
|
||||
context.JSON(http.StatusOK, &response)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
delete(clientProxies, oldName)
|
||||
clientProxies[name] = proxy
|
||||
|
||||
res := c.UpdateFrpcConfig()
|
||||
res := c.UpdateFrpcConfig(data)
|
||||
if !res.Success {
|
||||
response.Success = false
|
||||
response.Code = res.Code
|
||||
response.Message = fmt.Sprintf("user update failed, error : %v", res.Message)
|
||||
log.Printf(response.Message)
|
||||
context.JSON(http.StatusOK, &response)
|
||||
return
|
||||
}
|
||||
|
||||
context.JSON(http.StatusOK, &response)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *HandleController) MakeRemoveProxyFunc() func(context *gin.Context) {
|
||||
return func(context *gin.Context) {
|
||||
var proxies []ini.Section
|
||||
|
||||
response := OperationResponse{
|
||||
Success: true,
|
||||
Code: Success,
|
||||
Message: "proxy remove success",
|
||||
}
|
||||
|
||||
err := context.BindJSON(&proxies)
|
||||
if err != nil {
|
||||
response.Success = false
|
||||
response.Code = ParamError
|
||||
response.Message = fmt.Sprintf("proxy remove failed, param error : %v", err)
|
||||
log.Printf(response.Message)
|
||||
context.JSON(http.StatusOK, &response)
|
||||
return
|
||||
}
|
||||
|
||||
tempProxyNames := make([]string, len(proxies))
|
||||
for index, proxy := range proxies {
|
||||
name := proxy[NameKey]
|
||||
|
||||
if trimString(name) == "" {
|
||||
response.Success = false
|
||||
response.Code = ParamError
|
||||
response.Message = fmt.Sprintf("proxy remove failed, proxy %v name invalid", name)
|
||||
log.Printf(response.Message)
|
||||
context.JSON(http.StatusOK, &response)
|
||||
return
|
||||
}
|
||||
|
||||
if _, exist := clientProxies[name]; !exist {
|
||||
response.Success = false
|
||||
response.Code = ProxyExist
|
||||
response.Message = fmt.Sprintf("proxy remove failed, proxy %v not exist", name)
|
||||
log.Printf(response.Message)
|
||||
context.JSON(http.StatusOK, &response)
|
||||
return
|
||||
}
|
||||
|
||||
tempProxyNames[index] = name
|
||||
}
|
||||
|
||||
for _, name := range tempProxyNames {
|
||||
delete(clientProxies, name)
|
||||
}
|
||||
|
||||
res := c.UpdateFrpcConfig()
|
||||
if !res.Success {
|
||||
response.Success = false
|
||||
response.Code = res.Code
|
||||
response.Message = fmt.Sprintf("proxy remvoe failed, error : %v", res.Message)
|
||||
response.Message = fmt.Sprintf("update failed, error : %v", res.Message)
|
||||
log.Printf(response.Message)
|
||||
context.JSON(http.StatusOK, &response)
|
||||
return
|
||||
@@ -363,11 +225,11 @@ func (c *HandleController) MakeProxyFunc() func(context *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *HandleController) UpdateFrpcConfig() ProxyResponse {
|
||||
func (c *HandleController) UpdateFrpcConfig(tomlStr []byte) ProxyResponse {
|
||||
res := ProxyResponse{}
|
||||
|
||||
requestUrl := c.buildRequestUrl("/api/config")
|
||||
request, _ := http.NewRequest("PUT", requestUrl, bytes.NewReader(serializeSections()))
|
||||
request, _ := http.NewRequest("PUT", requestUrl, bytes.NewReader(tomlStr))
|
||||
response, err := c.getClientResponse(request, c.buildClient())
|
||||
|
||||
if err != nil {
|
||||
|
||||
@@ -39,8 +39,6 @@ func (c *HandleController) Register(rootDir string, engine *gin.Engine) {
|
||||
group = engine.Group("/")
|
||||
}
|
||||
group.GET("/", c.MakeIndexFunc())
|
||||
group.POST("/add", c.MakeAddProxyFunc())
|
||||
group.POST("/update", c.MakeUpdateProxyFunc())
|
||||
group.POST("/remove", c.MakeRemoveProxyFunc())
|
||||
group.GET("/proxy/*serverApi", c.MakeProxyFunc())
|
||||
}
|
||||
|
||||
@@ -4,11 +4,10 @@ import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"github.com/fatedier/frp/pkg/config"
|
||||
"github.com/vaughan0/go-ini"
|
||||
v1 "github.com/fatedier/frp/pkg/config/v1"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
@@ -17,42 +16,8 @@ func trimString(str string) string {
|
||||
return strings.TrimSpace(str)
|
||||
}
|
||||
|
||||
func sortSectionKeys(object ini.Section) []string {
|
||||
var keys []string
|
||||
for key := range object {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
return keys
|
||||
}
|
||||
|
||||
func serializeSections() []byte {
|
||||
var build strings.Builder
|
||||
build.WriteString("[common]\n")
|
||||
|
||||
for _, key := range sortSectionKeys(clientCommon) {
|
||||
build.WriteString(fmt.Sprintf("%s = %s\n", key, clientCommon[key]))
|
||||
}
|
||||
build.WriteString("\n")
|
||||
|
||||
sections := Sections{clientProxies}
|
||||
|
||||
for _, sectionInfo := range sections.sort() {
|
||||
name := sectionInfo.Name
|
||||
build.WriteString(fmt.Sprintf("[%s]\n", name))
|
||||
section := sectionInfo.Section
|
||||
|
||||
for _, key := range sortSectionKeys(section) {
|
||||
value := section[key]
|
||||
if key == NameKey || key == OldNameKey || trimString(value) == "" {
|
||||
continue
|
||||
}
|
||||
build.WriteString(fmt.Sprintf("%s = %s\n", key, value))
|
||||
}
|
||||
build.WriteString("\n")
|
||||
}
|
||||
|
||||
return []byte(build.String())
|
||||
func equalIgnoreCase(source string, target string) bool {
|
||||
return strings.ToUpper(source) == strings.ToUpper(target)
|
||||
}
|
||||
|
||||
func (c *HandleController) buildRequestUrl(serverApi string) string {
|
||||
@@ -66,6 +31,9 @@ func (c *HandleController) buildRequestUrl(serverApi string) string {
|
||||
|
||||
host := c.CommonInfo.DashboardAddr
|
||||
port := c.CommonInfo.DashboardPort
|
||||
|
||||
host, _ = strings.CutPrefix(host, protocol)
|
||||
|
||||
requestUrl := protocol + host + ":" + strconv.Itoa(port) + serverApi
|
||||
|
||||
return requestUrl
|
||||
@@ -130,32 +98,23 @@ func (c *HandleController) parseResponse(res *ProxyResponse, response *http.Resp
|
||||
}
|
||||
|
||||
func (c *HandleController) parseConfigure(content, proxyType string) (interface{}, error) {
|
||||
currentProxies := make(map[string]ini.Section)
|
||||
clientProxies = make(map[string]ini.Section)
|
||||
common, err := config.UnmarshalClientConfFromIni(content)
|
||||
clientConfig := v1.ClientConfig{}
|
||||
err := config.LoadConfigure([]byte(content), &clientConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cfg, err := ini.Load(strings.NewReader(content))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for name, section := range cfg {
|
||||
if name == "common" {
|
||||
clientCommon = section
|
||||
continue
|
||||
}
|
||||
if strings.ToLower(section["type"]) == strings.ToLower(proxyType) {
|
||||
currentProxies[name] = section
|
||||
}
|
||||
clientProxies[name] = section
|
||||
delete(clientProxies[name], NameKey)
|
||||
}
|
||||
|
||||
if proxyType == "none" {
|
||||
return common, nil
|
||||
return clientConfig, nil
|
||||
}
|
||||
|
||||
return currentProxies, nil
|
||||
allProxies := clientConfig.Proxies
|
||||
var filterProxies = make([]v1.TypedProxyConfig, 0)
|
||||
for i := range allProxies {
|
||||
if equalIgnoreCase(allProxies[i].Type, proxyType) {
|
||||
filterProxies = append(filterProxies, allProxies[i])
|
||||
}
|
||||
}
|
||||
|
||||
return filterProxies, nil
|
||||
}
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/vaughan0/go-ini"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
Success int = iota
|
||||
ParamError
|
||||
@@ -17,7 +11,7 @@ const (
|
||||
|
||||
const (
|
||||
NameKey = "name"
|
||||
OldNameKey = "_old_name"
|
||||
OriginalNameKey = "_original_name"
|
||||
SessionName = "GOSESSION"
|
||||
AuthName = "_PANEL_AUTH"
|
||||
LoginUrl = "/login"
|
||||
@@ -26,16 +20,6 @@ const (
|
||||
LogoutSuccessUrl = "/login"
|
||||
)
|
||||
|
||||
var (
|
||||
clientCommon ini.Section
|
||||
clientProxies map[string]ini.Section
|
||||
)
|
||||
|
||||
func init() {
|
||||
clientCommon = ini.Section{}
|
||||
clientProxies = make(map[string]ini.Section)
|
||||
}
|
||||
|
||||
type HTTPError struct {
|
||||
Code int
|
||||
Err error
|
||||
@@ -75,38 +59,3 @@ type ProxyResponse struct {
|
||||
OperationResponse
|
||||
Data any `json:"data"`
|
||||
}
|
||||
|
||||
type ClientProxies struct {
|
||||
Proxy ini.Section `json:"proxy"`
|
||||
}
|
||||
|
||||
type SectionInfo struct {
|
||||
Name string
|
||||
Section ini.Section
|
||||
}
|
||||
|
||||
type Sections struct {
|
||||
sections map[string]ini.Section
|
||||
}
|
||||
|
||||
func (s *Sections) sort() []SectionInfo {
|
||||
sectionInfos := make([]SectionInfo, 0)
|
||||
|
||||
for key, value := range s.sections {
|
||||
sectionInfos = append(sectionInfos, SectionInfo{Name: key, Section: value})
|
||||
}
|
||||
|
||||
sort.Slice(sectionInfos, func(i, j int) bool {
|
||||
typeCompare := strings.Compare(sectionInfos[i].Section["type"], sectionInfos[j].Section["type"])
|
||||
if typeCompare == -1 {
|
||||
return true
|
||||
} else if typeCompare == 0 {
|
||||
nameCompare := strings.Compare(sectionInfos[i].Name, sectionInfos[j].Name)
|
||||
return nameCompare == -1
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
return sectionInfos
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user