diff --git a/assets/static/js/index-client-info.js b/assets/static/js/index-client-info.js
index f0a7d66..ee47d9a 100644
--- a/assets/static/js/index-client-info.js
+++ b/assets/static/js/index-client-info.js
@@ -17,20 +17,19 @@ var loadClientInfo = (function ($) {
}).done(function (result) {
if (result.success) {
var proxies = [];
- result.data.proxies.forEach(function (proxy){
+ result.data.proxies.forEach(function (proxy) {
var items = flatJSON(proxy.ProxyConfigurer);
proxies.push(expandJSON(items))
})
var visitors = [];
- result.data.visitors.forEach(function (visitor){
+ result.data.visitors.forEach(function (visitor) {
var items = flatJSON(visitor.VisitorConfigurer);
visitors.push(expandJSON(items))
})
- var newD = $.extend({},result.data,true);
- newD.proxies = proxies;
- newD.visitors = visitors;
- console.log(TOML.stringify(newD))
+ window.clientConfig = $.extend(true, {}, result.data);
+ window.clientConfig.proxies = proxies;
+ window.clientConfig.visitors = visitors;
renderClientInfo(result.data);
} else {
layui.layer.msg(result.message);
diff --git a/assets/static/js/index-proxy-list.js b/assets/static/js/index-proxy-list.js
index bc5a988..339437b 100644
--- a/assets/static/js/index-proxy-list.js
+++ b/assets/static/js/index-proxy-list.js
@@ -219,8 +219,8 @@ 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;
+ var originalNameKey = layero.find('#originalNameKey').attr('name');
+ basicData[originalNameKey] = basicData.name;
layui.form.val('addProxyForm', flatJSON(basicData));
proxyPopupSuccess();
}
@@ -259,22 +259,26 @@ var loadProxyInfo = (function ($) {
*/
function addOrUpdate(data, index, update) {
var loading = layui.layer.load();
- var url = '';
+ var originalNameKey = $('#originalNameKey').attr('name');
+ var proxies = clientConfig.proxies;
if (update) {
- url = '/update?type=' + currentProxyType;
+ 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));
}
- var tomlStr = TOML.stringify(expandJSON(data));
-
- //todo get all proxy and replace or add a new proxy in it
+ var tomlStr = TOML.stringify(clientConfig);
$.ajax({
- url: url,
+ url: '/update',
type: 'post',
- contentType: 'application/json',
- data: JSON.stringify(expandJSON(data)),
+ contentType: 'text/plain',
+ data: tomlStr,
success: function (result) {
if (result.success) {
layui.layer.close(index);
diff --git a/assets/static/js/index.js b/assets/static/js/index.js
index 2c3fd96..5d68fef 100644
--- a/assets/static/js/index.js
+++ b/assets/static/js/index.js
@@ -1,3 +1,4 @@
+window.clientConfig = {};
(function ($) {
$(function () {
function init() {
diff --git a/assets/static/js/json-process.js b/assets/static/js/json-process.js
index 854d083..0fa4176 100644
--- a/assets/static/js/json-process.js
+++ b/assets/static/js/json-process.js
@@ -1,4 +1,4 @@
-(function (){
+(function () {
//param names in Basic tab
var basicParams = [
{
@@ -24,10 +24,10 @@
defaultValue: '-'
}, {
name: 'transport.useEncryption',
- defaultValue: 'true',
+ defaultValue: 'false',
}, {
name: 'transport.useCompression',
- defaultValue: 'true',
+ defaultValue: 'false',
}
];
var mapParams = [{
@@ -177,6 +177,7 @@
return flat(obj);
}
+ window.basicParams = basicParams;
window.expandJSONKeys = expandJSONKeys;
window.expandJSON = expandJSON;
window.flatJSON = flatJSON;
diff --git a/assets/static/js/toml.js b/assets/static/js/toml.js
index f8d9f62..a42f291 100644
--- a/assets/static/js/toml.js
+++ b/assets/static/js/toml.js
@@ -336,7 +336,13 @@ module.exports = Parser
module.exports = stringify
module.exports.value = stringifyInline
-function stringify(obj, separator) {
+/**
+ *
+ * @param obj json object
+ * @param options {{separator: string, indentSize: number}} options
+ * @returns {string|null}
+ */
+function stringify(obj, options) {
if (obj === null) throw typeError('null')
if (obj === void (0)) throw typeError('undefined')
if (typeof obj !== 'object') throw typeError(typeof obj)
@@ -345,7 +351,19 @@ function stringify(obj, separator) {
if (obj == null) return null
const type = tomlType(obj)
if (type !== 'table') throw typeError(type)
- return stringifyObject('', '', obj, separator)
+ var defaultOptions = {
+ separator: '',
+ indentSize: 0,
+ }
+ if (options == null)
+ options = defaultOptions
+ else
+ options = {
+ separator: options.separator || defaultOptions.separator,
+ indentSize: options.indentSize || defaultOptions.indentSize,
+ }
+
+ return stringifyObject('', '', obj, options)
}
function typeError (type) {
@@ -371,7 +389,7 @@ function toJSON (obj) {
return nobj
}
-function stringifyObject (prefix, indent, obj, separator) {
+function stringifyObject (prefix, indent, obj, options) {
obj = toJSON(obj)
let inlineKeys
let complexKeys
@@ -382,13 +400,13 @@ function stringifyObject (prefix, indent, obj, separator) {
inlineKeys.forEach(key => {
var type = tomlType(obj[key])
if (type !== 'undefined' && type !== 'null') {
- result.push(inlineIndent + stringifyKey(key) + ' = ' + stringifyAnyInline(obj[key], true, separator))
+ result.push(inlineIndent + stringifyKey(key) + ' = ' + stringifyAnyInline(obj[key], true, options))
}
})
if (result.length > 0) result.push('')
- const complexIndent = prefix && inlineKeys.length > 0 ? indent + ' ' : ''
+ const complexIndent = prefix && inlineKeys.length > 0 ? (indent + ''.padStart(options.indentSize, ' ')) : ''
complexKeys.forEach(key => {
- result.push(stringifyComplex(prefix, complexIndent, key, obj[key], separator))
+ result.push(stringifyComplex(prefix, complexIndent, key, obj[key], options))
})
return result.join('\n')
}
@@ -479,7 +497,7 @@ function stringifyMultilineString (str) {
return '"""\n' + escaped + '"""'
}
-function stringifyAnyInline (value, multilineOk, separator) {
+function stringifyAnyInline (value, multilineOk, options) {
let type = tomlType(value)
if (type === 'string') {
if (multilineOk && /\n/.test(value)) {
@@ -488,10 +506,10 @@ function stringifyAnyInline (value, multilineOk, separator) {
type = 'string-literal'
}
}
- return stringifyInline(value, type, separator)
+ return stringifyInline(value, type, options)
}
-function stringifyInline (value, type, separator) {
+function stringifyInline (value, type, options) {
/* istanbul ignore if */
if (!type) type = tomlType(value)
switch (type) {
@@ -502,9 +520,9 @@ function stringifyInline (value, type, separator) {
case 'string-literal':
return stringifyLiteralString(value)
case 'integer':
- return stringifyInteger(value, separator)
+ return stringifyInteger(value, options.separator)
case 'float':
- return stringifyFloat(value, separator)
+ return stringifyFloat(value, options.separator)
case 'boolean':
return stringifyBoolean(value)
case 'datetime':
@@ -569,19 +587,19 @@ function stringifyInlineTable (value) {
return '{ ' + result.join(', ') + (result.length > 0 ? ' ' : '') + '}'
}
-function stringifyComplex (prefix, indent, key, value, separator) {
+function stringifyComplex (prefix, indent, key, value, options) {
const valueType = tomlType(value)
/* istanbul ignore else */
if (valueType === 'array') {
- return stringifyArrayOfTables(prefix, indent, key, value, separator)
+ return stringifyArrayOfTables(prefix, indent, key, value, options)
} else if (valueType === 'table') {
- return stringifyComplexTable(prefix, indent, key, value, separator)
+ return stringifyComplexTable(prefix, indent, key, value, options)
} else {
throw typeError(valueType)
}
}
-function stringifyArrayOfTables (prefix, indent, key, values, separator) {
+function stringifyArrayOfTables (prefix, indent, key, values, options) {
values = toJSON(values)
const firstValueType = tomlType(values[0])
/* istanbul ignore if */
@@ -591,18 +609,18 @@ function stringifyArrayOfTables (prefix, indent, key, values, separator) {
values.forEach(table => {
if (result.length > 0) result += '\n'
result += indent + '[[' + fullKey + ']]\n'
- result += stringifyObject(fullKey + '.', indent, table, separator)
+ result += stringifyObject(fullKey + '.', indent, table, options)
})
return result
}
-function stringifyComplexTable (prefix, indent, key, value, separator) {
+function stringifyComplexTable (prefix, indent, key, value, options) {
const fullKey = prefix + stringifyKey(key)
let result = ''
if (getInlineKeys(value).length > 0) {
result += indent + '[' + fullKey + ']\n'
}
- return result + stringifyObject(fullKey + '.', indent, value, separator)
+ return result + stringifyObject(fullKey + '.', indent, value, options)
}
},{}],10:[function(require,module,exports){
diff --git a/assets/templates/index.html b/assets/templates/index.html
index bf36ce7..5714c42 100644
--- a/assets/templates/index.html
+++ b/assets/templates/index.html
@@ -155,7 +155,7 @@
-
+
diff --git a/go.mod b/go.mod
index e5aadb5..b82d355 100644
--- a/go.mod
+++ b/go.mod
@@ -9,7 +9,6 @@ require (
github.com/gin-contrib/sessions v0.0.5
github.com/gin-gonic/gin v1.9.1
github.com/spf13/cobra v1.7.0
- github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec
golang.org/x/text v0.11.0
)
diff --git a/pkg/server/controller/controller.go b/pkg/server/controller/controller.go
index 2fbfa7f..7842c74 100644
--- a/pkg/server/controller/controller.go
+++ b/pkg/server/controller/controller.go
@@ -3,11 +3,8 @@ package controller
import (
"bytes"
"fmt"
- v1 "github.com/fatedier/frp/pkg/config/v1"
ginI18n "github.com/gin-contrib/i18n"
"github.com/gin-gonic/gin"
- "github.com/pelletier/go-toml/v2"
- "github.com/vaughan0/go-ini"
"log"
"net/http"
)
@@ -59,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"),
@@ -143,66 +140,8 @@ func (c *HandleController) MakeLangFunc() func(context *gin.Context) {
}
}
-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) {
- proxyType := context.Query("type")
- proxy := v1.NewProxyConfigurerByType(v1.ProxyType(proxyType))
response := OperationResponse{
Success: true,
@@ -210,27 +149,15 @@ func (c *HandleController) MakeUpdateProxyFunc() func(context *gin.Context) {
Message: "proxy update success",
}
- var b = make([]byte, context.Request.ContentLength)
- context.Request.Body.Read(b)
- var s = string(b)
- log.Print(s)
- toml.Unmarshal(b, &proxy)
+ data, _ := context.GetRawData()
- err := context.BindJSON(&proxy)
- if err != nil {
- response.Success = false
- response.Code = ParamError
- response.Message = fmt.Sprintf("update failed, param error : %v", err)
- log.Printf(response.Message)
- context.JSON(http.StatusOK, &response)
- return
- }
+ c.UpdateFrpcConfig(data)
context.JSON(200, &response)
//proxy.GetBaseConfig()
//
- //oldName := proxy[OldNameKey]
+ //oldName := proxy[OriginalNameKey]
//name := proxy[NameKey]
//
//if trimString(oldName) == "" || trimString(name) == "" {
@@ -279,69 +206,6 @@ func (c *HandleController) MakeUpdateProxyFunc() func(context *gin.Context) {
}
}
-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)
- log.Printf(response.Message)
- context.JSON(http.StatusOK, &response)
- return
- }
-
- context.JSON(http.StatusOK, &response)
- }
-}
-
func (c *HandleController) MakeProxyFunc() func(context *gin.Context) {
return func(context *gin.Context) {
res := ProxyResponse{}
@@ -378,11 +242,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 {
diff --git a/pkg/server/controller/register.go b/pkg/server/controller/register.go
index 677e73f..d3494cf 100644
--- a/pkg/server/controller/register.go
+++ b/pkg/server/controller/register.go
@@ -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())
}
diff --git a/pkg/server/controller/utils.go b/pkg/server/controller/utils.go
index fa5930f..83417b1 100644
--- a/pkg/server/controller/utils.go
+++ b/pkg/server/controller/utils.go
@@ -5,11 +5,9 @@ import (
"fmt"
"github.com/fatedier/frp/pkg/config"
v1 "github.com/fatedier/frp/pkg/config/v1"
- "github.com/vaughan0/go-ini"
"io"
"log"
"net/http"
- "sort"
"strconv"
"strings"
)
@@ -22,44 +20,6 @@ func equalIgnoreCase(source string, target string) bool {
return strings.ToUpper(source) == strings.ToUpper(target)
}
-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 (c *HandleController) buildRequestUrl(serverApi string) string {
var protocol string
diff --git a/pkg/server/controller/variables.go b/pkg/server/controller/variables.go
index 0ddce5a..6c0c6a7 100644
--- a/pkg/server/controller/variables.go
+++ b/pkg/server/controller/variables.go
@@ -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
-}