This commit is contained in:
yuyulei 2020-12-25 14:43:25 +08:00
parent c7438fd2fd
commit 369c545647
18 changed files with 936 additions and 796 deletions

View File

@ -54,7 +54,7 @@ func (svr *Service) apiReload(w http.ResponseWriter, r *http.Request) {
return
}
newCommonCfg, err := config.LoadClientCommonConf(content)
newCommonCfg, err := config.UnmarshalClientConfFromIni(content)
if err != nil {
res.Code = 400
res.Msg = err.Error()
@ -62,7 +62,7 @@ func (svr *Service) apiReload(w http.ResponseWriter, r *http.Request) {
return
}
pxyCfgs, visitorCfgs, err := config.LoadClientBasicConf(svr.cfg.User, content, newCommonCfg.Start)
pxyCfgs, visitorCfgs, err := config.LoadAllConfFromIni(svr.cfg.User, content, newCommonCfg.Start)
if err != nil {
res.Code = 400
res.Msg = err.Error()

View File

@ -131,7 +131,7 @@ func handleSignal(svr *client.Service) {
func parseClientCommonCfg(fileType int, source interface{}) (cfg config.ClientCommonConf, err error) {
if fileType == CfgFileTypeIni {
cfg, err = config.LoadClientCommonConf(source)
cfg, err = config.UnmarshalClientConfFromIni(source)
} else if fileType == CfgFileTypeCmd {
cfg, err = parseClientCommonCfgFromCmd()
}
@ -147,7 +147,7 @@ func parseClientCommonCfg(fileType int, source interface{}) (cfg config.ClientCo
}
func parseClientCommonCfgFromCmd() (cfg config.ClientCommonConf, err error) {
cfg = config.DefaultClientConf()
cfg = config.GetDefaultClientConf()
strs := strings.Split(serverAddr, ":")
if len(strs) < 2 {
@ -183,24 +183,25 @@ func parseClientCommonCfgFromCmd() (cfg config.ClientCommonConf, err error) {
return
}
func runClient(cfgFilePath string) error {
content, err := config.GetRenderedConfFromFile(cfgFilePath)
func runClient(cfgFilePath string) (err error) {
var content string
content, err = config.GetRenderedConfFromFile(cfgFilePath)
if err != nil {
return err
return
}
cfg, err := parseClientCommonCfg(CfgFileTypeIni, content)
if err != nil {
return err
return
}
pxyCfgs, visitorCfgs, err := config.LoadClientBasicConf(cfg.User, content, cfg.Start)
pxyCfgs, visitorCfgs, err := config.LoadAllConfFromIni(cfg.User, content, cfg.Start)
if err != nil {
return err
return
}
err = startService(cfg, pxyCfgs, visitorCfgs, cfgFilePath)
return err
return
}
func startService(

View File

@ -104,10 +104,9 @@ var rootCmd = &cobra.Command{
var cfg config.ServerCommonConf
var err error
if cfgFile != "" {
log.Info("frps uses config file: %s", cfgFile)
var content []byte
var content string
content, err = config.GetRenderedConfFromFile(cfgFile)
if err != nil {
return err
@ -138,7 +137,7 @@ func Execute() {
func parseServerCommonCfg(fileType int, source interface{}) (cfg config.ServerCommonConf, err error) {
if fileType == CfgFileTypeIni {
cfg, err = config.LoadServerCommonConf(source)
cfg, err = config.UnmarshalServerConfFromIni(source)
} else if fileType == CfgFileTypeCmd {
cfg, err = parseServerCommonCfgFromCmd()
}
@ -154,7 +153,7 @@ func parseServerCommonCfg(fileType int, source interface{}) (cfg config.ServerCo
}
func parseServerCommonCfgFromCmd() (cfg config.ServerCommonConf, err error) {
cfg = config.DefaultServerConf()
cfg = config.GetDefaultServerConf()
cfg.BindAddr = bindAddr
cfg.BindPort = bindPort

View File

@ -177,7 +177,7 @@ use_compression = true
http_user = admin
http_pwd = admin
# if domain for frps is frps.com, then you can access [web01] proxy by URL http://test.frps.com
sub_domain = web01
subdomain = web01
custom_domains = web02.yourdomain.com
# locations is only available for http type
locations = /,/pic

121
pkg/config/bandwidth.go Normal file
View File

@ -0,0 +1,121 @@
// Copyright 2019 fatedier, fatedier@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package config
import (
"encoding/json"
"errors"
"strconv"
"strings"
)
const (
MB = 1024 * 1024
KB = 1024
)
type BandwidthQuantity struct {
s string // MB or KB
i int64 // bytes
}
func NewBandwidthQuantity(s string) (BandwidthQuantity, error) {
q := BandwidthQuantity{}
err := q.UnmarshalString(s)
if err != nil {
return q, err
}
return q, nil
}
func MustBandwidthQuantity(s string) BandwidthQuantity {
q := BandwidthQuantity{}
err := q.UnmarshalString(s)
if err != nil {
panic(err)
}
return q
}
func (q *BandwidthQuantity) Equal(u *BandwidthQuantity) bool {
if q == nil && u == nil {
return true
}
if q != nil && u != nil {
return q.i == u.i
}
return false
}
func (q *BandwidthQuantity) String() string {
return q.s
}
func (q *BandwidthQuantity) UnmarshalString(s string) error {
s = strings.TrimSpace(s)
if s == "" {
return nil
}
var (
base int64
f float64
err error
)
if strings.HasSuffix(s, "MB") {
base = MB
fstr := strings.TrimSuffix(s, "MB")
f, err = strconv.ParseFloat(fstr, 64)
if err != nil {
return err
}
} else if strings.HasSuffix(s, "KB") {
base = KB
fstr := strings.TrimSuffix(s, "KB")
f, err = strconv.ParseFloat(fstr, 64)
if err != nil {
return err
}
} else {
return errors.New("unit not support")
}
q.s = s
q.i = int64(f * float64(base))
return nil
}
func (q *BandwidthQuantity) UnmarshalJSON(b []byte) error {
if len(b) == 4 && string(b) == "null" {
return nil
}
var str string
err := json.Unmarshal(b, &str)
if err != nil {
return err
}
return q.UnmarshalString(str)
}
func (q *BandwidthQuantity) MarshalJSON() ([]byte, error) {
return []byte("\"" + q.s + "\""), nil
}
func (q *BandwidthQuantity) Bytes() int64 {
return q.i
}

View File

@ -0,0 +1,40 @@
// Copyright 2019 fatedier, fatedier@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package config
import (
"encoding/json"
"testing"
"github.com/stretchr/testify/assert"
)
type Wrap struct {
B BandwidthQuantity `json:"b"`
Int int `json:"int"`
}
func TestBandwidthQuantity(t *testing.T) {
assert := assert.New(t)
var w Wrap
err := json.Unmarshal([]byte(`{"b":"1KB","int":5}`), &w)
assert.NoError(err)
assert.EqualValues(1*KB, w.B.Bytes())
buf, err := json.Marshal(&w)
assert.NoError(err)
assert.Equal(`{"b":"1KB","int":5}`, string(buf))
}

View File

@ -1,4 +1,4 @@
// Copyright 2016 fatedier, fatedier@gmail.com
// Copyright 2020 The frp Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -26,7 +26,7 @@ import (
)
// GetDefaultClientConf returns a client configuration with default values.
func DefaultClientConf() ClientCommonConf {
func GetDefaultClientConf() ClientCommonConf {
return ClientCommonConf{
ClientConfig: auth.GetDefaultClientConf(),
ServerAddr: "0.0.0.0",
@ -87,7 +87,7 @@ func (cfg *ClientCommonConf) Check() error {
}
// Supported sources including: string(file path), []byte, Reader interface.
func LoadClientCommonConf(source interface{}) (ClientCommonConf, error) {
func UnmarshalClientConfFromIni(source interface{}) (ClientCommonConf, error) {
f, err := ini.LoadSources(ini.LoadOptions{
Insensitive: false,
InsensitiveSections: false,
@ -105,7 +105,7 @@ func LoadClientCommonConf(source interface{}) (ClientCommonConf, error) {
return ClientCommonConf{}, err
}
common := DefaultClientConf()
common := GetDefaultClientConf()
err = s.MapTo(&common)
if err != nil {
return ClientCommonConf{}, err
@ -118,7 +118,7 @@ func LoadClientCommonConf(source interface{}) (ClientCommonConf, error) {
// if len(startProxy) is 0, start all
// otherwise just start proxies in startProxy map
func LoadClientBasicConf(
func LoadAllConfFromIni(
prefix string,
source interface{},
start []string,

View File

@ -1,3 +1,17 @@
// Copyright 2020 The frp Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package config
import (
@ -277,7 +291,7 @@ func Test_LoadClientCommonConf(t *testing.T) {
UDPPacketSize: 1509,
}
common, err := LoadClientCommonConf(testClientBytesWithFull)
common, err := UnmarshalClientConfFromIni(testClientBytesWithFull)
assert.NoError(err)
assert.Equal(expected, common)
}
@ -446,7 +460,7 @@ func Test_LoadClientBasicConf(t *testing.T) {
},
},
HTTPProxySpec: HTTPProxySpec{
DomainSpec: DomainSpec{
DomainConf: DomainConf{
CustomDomains: []string{"web02.yourdomain.com"},
SubDomain: "web01",
},
@ -472,7 +486,7 @@ func Test_LoadClientBasicConf(t *testing.T) {
ProxyProtocolVersion: "v2",
},
HTTPSProxySpec: HTTPSProxySpec{
DomainSpec: DomainSpec{
DomainConf: DomainConf{
CustomDomains: []string{"web02.yourdomain.com"},
SubDomain: "web01",
},
@ -516,7 +530,7 @@ func Test_LoadClientBasicConf(t *testing.T) {
},
},
TCPMuxProxySpec: TCPMuxProxySpec{
DomainSpec: DomainSpec{
DomainConf: DomainConf{
CustomDomains: []string{"tunnel1"},
SubDomain: "",
},
@ -609,7 +623,7 @@ func Test_LoadClientBasicConf(t *testing.T) {
},
},
HTTPSProxySpec: HTTPSProxySpec{
DomainSpec: DomainSpec{
DomainConf: DomainConf{
CustomDomains: []string{"test.yourdomain.com"},
},
},
@ -629,7 +643,7 @@ func Test_LoadClientBasicConf(t *testing.T) {
},
},
HTTPProxySpec: HTTPProxySpec{
DomainSpec: DomainSpec{
DomainConf: DomainConf{
CustomDomains: []string{"test.yourdomain.com"},
},
},
@ -661,7 +675,7 @@ func Test_LoadClientBasicConf(t *testing.T) {
},
}
proxyActual, visitorActual, err := LoadClientBasicConf(testUser, testClientBytesWithFull, nil)
proxyActual, visitorActual, err := LoadAllConfFromIni(testUser, testClientBytesWithFull, nil)
assert.NoError(err)
assert.Equal(proxyExpected, proxyActual)
assert.Equal(visitorExpected, visitorActual)

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,17 @@
// Copyright 2020 The frp Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package config
import (
@ -171,7 +185,7 @@ func Test_Proxy_UnmarshalFromIni(t *testing.T) {
},
},
HTTPProxySpec: HTTPProxySpec{
DomainSpec: DomainSpec{
DomainConf: DomainConf{
CustomDomains: []string{"web02.yourdomain.com"},
SubDomain: "web01",
},
@ -211,7 +225,7 @@ func Test_Proxy_UnmarshalFromIni(t *testing.T) {
ProxyProtocolVersion: "v2",
},
HTTPSProxySpec: HTTPSProxySpec{
DomainSpec: DomainSpec{
DomainConf: DomainConf{
CustomDomains: []string{"web02.yourdomain.com"},
SubDomain: "web01",
},
@ -290,7 +304,7 @@ func Test_Proxy_UnmarshalFromIni(t *testing.T) {
},
},
TCPMuxProxySpec: TCPMuxProxySpec{
DomainSpec: DomainSpec{
DomainConf: DomainConf{
CustomDomains: []string{"tunnel1"},
SubDomain: "",
},

View File

@ -1,4 +1,4 @@
// Copyright 2016 fatedier, fatedier@gmail.com
// Copyright 2020 The frp Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -27,7 +27,7 @@ import (
// GetDefaultServerConf returns a server configuration with reasonable
// defaults.
func DefaultServerConf() ServerCommonConf {
func GetDefaultServerConf() ServerCommonConf {
return ServerCommonConf{
ServerConfig: auth.GetDefaultServerConf(),
BindAddr: "0.0.0.0",
@ -72,7 +72,7 @@ func (cfg *ServerCommonConf) Check() error {
return nil
}
func LoadServerCommonConf(source interface{}) (ServerCommonConf, error) {
func UnmarshalServerConfFromIni(source interface{}) (ServerCommonConf, error) {
f, err := ini.LoadSources(ini.LoadOptions{
Insensitive: false,
@ -91,7 +91,7 @@ func LoadServerCommonConf(source interface{}) (ServerCommonConf, error) {
return ServerCommonConf{}, err
}
common := DefaultServerConf()
common := GetDefaultServerConf()
err = s.MapTo(&common)
if err != nil {
return ServerCommonConf{}, err

View File

@ -1,3 +1,17 @@
// Copyright 2020 The frp Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package config
import (
@ -184,7 +198,7 @@ func Test_LoadServerCommonConf(t *testing.T) {
}
for _, c := range testcases {
actual, err := LoadServerCommonConf(c.source)
actual, err := UnmarshalServerConfFromIni(c.source)
assert.NoError(err)
assert.Equal(c.expected, actual)
}

View File

@ -1,4 +1,4 @@
// Copyright 2019 fatedier, fatedier@gmail.com
// Copyright 2020 The frp Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -25,7 +25,9 @@ import (
"gopkg.in/ini.v1"
)
// Client
// ClientCommonConf contains information for a client service. It is
// recommended to use GetDefaultClientConf instead of creating this object
// directly, so that all unspecified fields have reasonable default values.
type ClientCommonConf struct {
auth.ClientConfig `ini:",,,,extends",json:"inline"`
// ServerAddr specifies the address of the server to connect to. By
@ -96,7 +98,7 @@ type ClientCommonConf struct {
// Start specifies a set of enabled proxies by name. If this set is empty,
// all supplied proxies are enabled. By default, this value is an empty
// set.
Start []string `ini:"start",json:"start""`
Start []string `ini:"start",json:"start"`
//Start map[string]struct{} `json:"start"`
// Protocol specifies the protocol to use when interacting with the server.
// Valid values are "tcp", "kcp" and "websocket". By default, this value
@ -132,8 +134,6 @@ type ClientCommonConf struct {
UDPPacketSize int64 `ini:"udp_packet_size",json:"udp_packet_size"`
}
// Server
// ServerCommonConf contains information for a server service. It is
// recommended to use GetDefaultServerConf instead of creating this object
// directly, so that all unspecified fields have reasonable default values.
@ -387,7 +387,7 @@ type BaseProxyConf struct {
HealthCheckConf `ini:",,,,extends",json:"inline"`
}
type DomainSpec struct {
type DomainConf struct {
CustomDomains []string `ini:"custom_domains",json:"custom_domains"`
SubDomain string `ini:"subdomain",json:"subdomain"`
}
@ -399,7 +399,7 @@ type HTTPProxyConf struct {
}
type HTTPProxySpec struct {
DomainSpec `ini:",,,,extends",json:"inline"`
DomainConf `ini:",,,,extends",json:"inline"`
Locations []string `ini:"locations",json:"locations"`
HTTPUser string `ini:"http_user",json:"http_user"`
HTTPPwd string `ini:"http_pwd",json:"http_pwd"`
@ -414,7 +414,7 @@ type HTTPSProxyConf struct {
}
type HTTPSProxySpec struct {
DomainSpec `ini:",,,,extends",json:"inline"`
DomainConf `ini:",,,,extends",json:"inline"`
}
// TCP
@ -434,7 +434,7 @@ type TCPMuxProxyConf struct {
}
type TCPMuxProxySpec struct {
DomainSpec `ini:",,,,extends",json:"inline"`
DomainConf `ini:",,,,extends",json:"inline"`
Multiplexer string `ini:"multiplexer"`
}

View File

@ -1,4 +1,4 @@
// Copyright 2016 fatedier, fatedier@gmail.com
// Copyright 2020 The frp Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -15,14 +15,7 @@
package config
import (
"bytes"
"encoding/json"
"errors"
"io/ioutil"
"os"
"strconv"
"strings"
"text/template"
)
func GetMapWithoutPrefix(set map[string]string, prefix string) map[string]string {
@ -56,152 +49,3 @@ func GetMapByPrefix(set map[string]string, prefix string) map[string]string {
return m
}
// Render Env Values
var glbEnvs map[string]string
func init() {
glbEnvs = make(map[string]string)
envs := os.Environ()
for _, env := range envs {
kv := strings.Split(env, "=")
if len(kv) != 2 {
continue
}
glbEnvs[kv[0]] = kv[1]
}
}
type Values struct {
Envs map[string]string // environment vars
}
func GetValues() *Values {
return &Values{
Envs: glbEnvs,
}
}
func RenderContent(in []byte) ([]byte, error) {
tmpl, err := template.New("frp").Parse(string(in))
if err != nil {
return nil, err
}
buffer := bytes.NewBufferString("")
v := GetValues()
err = tmpl.Execute(buffer, v)
if err != nil {
return nil, err
}
return buffer.Bytes(), nil
}
func GetRenderedConfFromFile(path string) ([]byte, error) {
data, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
return RenderContent(data)
}
// BandwidthQuantity
const (
MB = 1024 * 1024
KB = 1024
)
type BandwidthQuantity struct {
s string // MB or KB
i int64 // bytes
}
func NewBandwidthQuantity(s string) (BandwidthQuantity, error) {
q := BandwidthQuantity{}
err := q.UnmarshalString(s)
if err != nil {
return q, err
}
return q, nil
}
func MustBandwidthQuantity(s string) BandwidthQuantity {
q := BandwidthQuantity{}
err := q.UnmarshalString(s)
if err != nil {
panic(err)
}
return q
}
func (q *BandwidthQuantity) Equal(u *BandwidthQuantity) bool {
if q == nil && u == nil {
return true
}
if q != nil && u != nil {
return q.i == u.i
}
return false
}
func (q *BandwidthQuantity) String() string {
return q.s
}
func (q *BandwidthQuantity) UnmarshalString(s string) error {
s = strings.TrimSpace(s)
if s == "" {
return nil
}
var (
base int64
f float64
err error
)
if strings.HasSuffix(s, "MB") {
base = MB
fstr := strings.TrimSuffix(s, "MB")
f, err = strconv.ParseFloat(fstr, 64)
if err != nil {
return err
}
} else if strings.HasSuffix(s, "KB") {
base = KB
fstr := strings.TrimSuffix(s, "KB")
f, err = strconv.ParseFloat(fstr, 64)
if err != nil {
return err
}
} else {
return errors.New("unit not support")
}
q.s = s
q.i = int64(f * float64(base))
return nil
}
func (q *BandwidthQuantity) UnmarshalJSON(b []byte) error {
if len(b) == 4 && string(b) == "null" {
return nil
}
var str string
err := json.Unmarshal(b, &str)
if err != nil {
return err
}
return q.UnmarshalString(str)
}
func (q *BandwidthQuantity) MarshalJSON() ([]byte, error) {
return []byte("\"" + q.s + "\""), nil
}
func (q *BandwidthQuantity) Bytes() int64 {
return q.i
}

78
pkg/config/value.go Normal file
View File

@ -0,0 +1,78 @@
// Copyright 2020 The frp Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package config
import (
"bytes"
"io/ioutil"
"os"
"strings"
"text/template"
)
var (
glbEnvs map[string]string
)
func init() {
glbEnvs = make(map[string]string)
envs := os.Environ()
for _, env := range envs {
kv := strings.Split(env, "=")
if len(kv) != 2 {
continue
}
glbEnvs[kv[0]] = kv[1]
}
}
type Values struct {
Envs map[string]string // environment vars
}
func GetValues() *Values {
return &Values{
Envs: glbEnvs,
}
}
func RenderContent(in string) (out string, err error) {
tmpl, errRet := template.New("frp").Parse(in)
if errRet != nil {
err = errRet
return
}
buffer := bytes.NewBufferString("")
v := GetValues()
err = tmpl.Execute(buffer, v)
if err != nil {
return
}
out = buffer.String()
return
}
func GetRenderedConfFromFile(path string) (out string, err error) {
var b []byte
b, err = ioutil.ReadFile(path)
if err != nil {
return
}
content := string(b)
out, err = RenderContent(content)
return
}

View File

@ -21,7 +21,6 @@ import (
"gopkg.in/ini.v1"
)
// Visitor Conf Loader
// DefaultVisitorConf creates a empty VisitorConf object by visitorType.
// If visitorType doesn't exist, return nil.
func DefaultVisitorConf(visitorType string) VisitorConf {
@ -59,111 +58,67 @@ func NewVisitorConfFromIni(prefix string, name string, section *ini.Section) (Vi
}
// Base
func (c *BaseVisitorConf) GetBaseInfo() *BaseVisitorConf {
return c
func (cfg *BaseVisitorConf) GetBaseInfo() *BaseVisitorConf {
return cfg
}
func (c *BaseVisitorConf) compare(cmp *BaseVisitorConf) bool {
if c.ProxyName != cmp.ProxyName ||
c.ProxyType != cmp.ProxyType ||
c.UseEncryption != cmp.UseEncryption ||
c.UseCompression != cmp.UseCompression ||
c.Role != cmp.Role ||
c.Sk != cmp.Sk ||
c.ServerName != cmp.ServerName ||
c.BindAddr != cmp.BindAddr ||
c.BindPort != cmp.BindPort {
func (cfg *BaseVisitorConf) compare(cmp *BaseVisitorConf) bool {
if cfg.ProxyName != cmp.ProxyName ||
cfg.ProxyType != cmp.ProxyType ||
cfg.UseEncryption != cmp.UseEncryption ||
cfg.UseCompression != cmp.UseCompression ||
cfg.Role != cmp.Role ||
cfg.Sk != cmp.Sk ||
cfg.ServerName != cmp.ServerName ||
cfg.BindAddr != cmp.BindAddr ||
cfg.BindPort != cmp.BindPort {
return false
}
return true
}
func (c *BaseVisitorConf) check() (err error) {
if c.Role != "visitor" {
func (cfg *BaseVisitorConf) check() (err error) {
if cfg.Role != "visitor" {
err = fmt.Errorf("invalid role")
return
}
if c.BindAddr == "" {
if cfg.BindAddr == "" {
err = fmt.Errorf("bind_addr shouldn't be empty")
return
}
if c.BindPort <= 0 {
if cfg.BindPort <= 0 {
err = fmt.Errorf("bind_port is required")
return
}
return
}
func (c *BaseVisitorConf) decorate(prefix string, name string, section *ini.Section) error {
func (cfg *BaseVisitorConf) decorate(prefix string, name string, section *ini.Section) error {
// proxy name
c.ProxyName = prefix + name
cfg.ProxyName = prefix + name
// server_name
c.ServerName = prefix + c.ServerName
cfg.ServerName = prefix + cfg.ServerName
// bind_addr
if c.BindAddr == "" {
c.BindAddr = "127.0.0.1"
if cfg.BindAddr == "" {
cfg.BindAddr = "127.0.0.1"
}
return nil
}
// STCP
var _ VisitorConf = &STCPVisitorConf{}
func (c *STCPVisitorConf) Compare(conf VisitorConf) bool {
cmp, ok := conf.(*STCPVisitorConf)
if !ok {
return false
}
if !c.BaseVisitorConf.compare(&cmp.BaseVisitorConf) {
return false
}
// Add custom login equal, if exists
return true
}
func (c *STCPVisitorConf) UnmarshalFromIni(prefix string, name string, section *ini.Section) error {
err := section.MapTo(c)
if err != nil {
return err
}
err = c.BaseVisitorConf.decorate(prefix, name, section)
if err != nil {
return err
}
// Add custom logic unmarshal, if exists
return nil
}
func (cfg *STCPVisitorConf) Check() error {
if err := cfg.BaseVisitorConf.check(); err != nil {
return err
}
// Add custom logic validate, if exists
return nil
}
// SUDP
var _ VisitorConf = &SUDPVisitorConf{}
func (c *SUDPVisitorConf) Compare(conf VisitorConf) bool {
cmp, ok := conf.(*SUDPVisitorConf)
func (cfg *SUDPVisitorConf) Compare(cmp VisitorConf) bool {
cmpConf, ok := cmp.(*SUDPVisitorConf)
if !ok {
return false
}
if !c.BaseVisitorConf.compare(&cmp.BaseVisitorConf) {
if !cfg.BaseVisitorConf.compare(&cmpConf.BaseVisitorConf) {
return false
}
@ -172,13 +127,13 @@ func (c *SUDPVisitorConf) Compare(conf VisitorConf) bool {
return true
}
func (c *SUDPVisitorConf) UnmarshalFromIni(prefix string, name string, section *ini.Section) error {
err := section.MapTo(c)
func (cfg *SUDPVisitorConf) UnmarshalFromIni(prefix string, name string, section *ini.Section) error {
err := section.MapTo(cfg)
if err != nil {
return err
}
err = c.BaseVisitorConf.decorate(prefix, name, section)
err = cfg.BaseVisitorConf.decorate(prefix, name, section)
if err != nil {
return err
}
@ -188,26 +143,70 @@ func (c *SUDPVisitorConf) UnmarshalFromIni(prefix string, name string, section *
return nil
}
func (cfg *SUDPVisitorConf) Check() error {
if err := cfg.BaseVisitorConf.check(); err != nil {
return err
func (cfg *SUDPVisitorConf) Check() (err error) {
if err = cfg.BaseVisitorConf.check(); err != nil {
return
}
// Add custom logic validate, if exists
return
}
// STCP
var _ VisitorConf = &STCPVisitorConf{}
func (cfg *STCPVisitorConf) Compare(cmp VisitorConf) bool {
cmpConf, ok := cmp.(*STCPVisitorConf)
if !ok {
return false
}
if !cfg.BaseVisitorConf.compare(&cmpConf.BaseVisitorConf) {
return false
}
// Add custom login equal, if exists
return true
}
func (cfg *STCPVisitorConf) UnmarshalFromIni(prefix string, name string, section *ini.Section) error {
err := section.MapTo(cfg)
if err != nil {
return err
}
err = cfg.BaseVisitorConf.decorate(prefix, name, section)
if err != nil {
return err
}
// Add custom logic unmarshal, if exists
return nil
}
func (cfg *STCPVisitorConf) Check() (err error) {
if err = cfg.BaseVisitorConf.check(); err != nil {
return
}
// Add custom logic validate, if exists
return
}
// XTCP
var _ VisitorConf = &XTCPVisitorConf{}
func (c *XTCPVisitorConf) Compare(conf VisitorConf) bool {
cmp, ok := conf.(*XTCPVisitorConf)
func (cfg *XTCPVisitorConf) Compare(cmp VisitorConf) bool {
cmpConf, ok := cmp.(*XTCPVisitorConf)
if !ok {
return false
}
if !c.BaseVisitorConf.compare(&cmp.BaseVisitorConf) {
if !cfg.BaseVisitorConf.compare(&cmpConf.BaseVisitorConf) {
return false
}
@ -216,13 +215,13 @@ func (c *XTCPVisitorConf) Compare(conf VisitorConf) bool {
return true
}
func (c *XTCPVisitorConf) UnmarshalFromIni(prefix string, name string, section *ini.Section) error {
err := section.MapTo(c)
func (cfg *XTCPVisitorConf) UnmarshalFromIni(prefix string, name string, section *ini.Section) error {
err := section.MapTo(cfg)
if err != nil {
return err
}
err = c.BaseVisitorConf.decorate(prefix, name, section)
err = cfg.BaseVisitorConf.decorate(prefix, name, section)
if err != nil {
return err
}
@ -232,12 +231,12 @@ func (c *XTCPVisitorConf) UnmarshalFromIni(prefix string, name string, section *
return nil
}
func (cfg *XTCPVisitorConf) Check() error {
if err := cfg.BaseVisitorConf.check(); err != nil {
return err
func (cfg *XTCPVisitorConf) Check() (err error) {
if err = cfg.BaseVisitorConf.check(); err != nil {
return
}
// Add custom logic validate, if exists
return nil
return
}

View File

@ -1,3 +1,17 @@
// Copyright 2020 The frp Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package config
import (

View File

@ -98,7 +98,7 @@ type TCPOutConf struct {
type TCPMuxOutConf struct {
BaseOutConf
config.DomainSpec
config.DomainConf
Multiplexer string `json:"multiplexer"`
}
@ -109,14 +109,14 @@ type UDPOutConf struct {
type HTTPOutConf struct {
BaseOutConf
config.DomainSpec
config.DomainConf
Locations []string `json:"locations"`
HostHeaderRewrite string `json:"host_header_rewrite"`
}
type HTTPSOutConf struct {
BaseOutConf
config.DomainSpec
config.DomainConf
}
type STCPOutConf struct {