forked from Mxmilu666/frp
Merge remote-tracking branch 'upstream/dev' into dev
This commit is contained in:
@@ -15,14 +15,12 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"slices"
|
||||
|
||||
"github.com/samber/lo"
|
||||
|
||||
"github.com/fatedier/frp/pkg/util/jsonx"
|
||||
"github.com/fatedier/frp/pkg/util/util"
|
||||
)
|
||||
|
||||
@@ -41,21 +39,22 @@ const (
|
||||
)
|
||||
|
||||
var clientPluginOptionsTypeMap = map[string]reflect.Type{
|
||||
PluginHTTP2HTTPS: reflect.TypeOf(HTTP2HTTPSPluginOptions{}),
|
||||
PluginHTTP2HTTPSRedirect: reflect.TypeOf(HTTP2HTTPSRedirectPluginOptions{}),
|
||||
PluginHTTPProxy: reflect.TypeOf(HTTPProxyPluginOptions{}),
|
||||
PluginHTTPS2HTTP: reflect.TypeOf(HTTPS2HTTPPluginOptions{}),
|
||||
PluginHTTPS2HTTPS: reflect.TypeOf(HTTPS2HTTPSPluginOptions{}),
|
||||
PluginHTTP2HTTP: reflect.TypeOf(HTTP2HTTPPluginOptions{}),
|
||||
PluginSocks5: reflect.TypeOf(Socks5PluginOptions{}),
|
||||
PluginStaticFile: reflect.TypeOf(StaticFilePluginOptions{}),
|
||||
PluginUnixDomainSocket: reflect.TypeOf(UnixDomainSocketPluginOptions{}),
|
||||
PluginTLS2Raw: reflect.TypeOf(TLS2RawPluginOptions{}),
|
||||
PluginVirtualNet: reflect.TypeOf(VirtualNetPluginOptions{}),
|
||||
PluginHTTP2HTTPS: reflect.TypeFor[HTTP2HTTPSPluginOptions](),
|
||||
PluginHTTP2HTTPSRedirect: reflect.TypeFor[HTTP2HTTPSRedirectPluginOptions](),
|
||||
PluginHTTPProxy: reflect.TypeFor[HTTPProxyPluginOptions](),
|
||||
PluginHTTPS2HTTP: reflect.TypeFor[HTTPS2HTTPPluginOptions](),
|
||||
PluginHTTPS2HTTPS: reflect.TypeFor[HTTPS2HTTPSPluginOptions](),
|
||||
PluginHTTP2HTTP: reflect.TypeFor[HTTP2HTTPPluginOptions](),
|
||||
PluginSocks5: reflect.TypeFor[Socks5PluginOptions](),
|
||||
PluginStaticFile: reflect.TypeFor[StaticFilePluginOptions](),
|
||||
PluginUnixDomainSocket: reflect.TypeFor[UnixDomainSocketPluginOptions](),
|
||||
PluginTLS2Raw: reflect.TypeFor[TLS2RawPluginOptions](),
|
||||
PluginVirtualNet: reflect.TypeFor[VirtualNetPluginOptions](),
|
||||
}
|
||||
|
||||
type ClientPluginOptions interface {
|
||||
Complete()
|
||||
Clone() ClientPluginOptions
|
||||
}
|
||||
|
||||
type TypedClientPluginOptions struct {
|
||||
@@ -63,43 +62,48 @@ type TypedClientPluginOptions struct {
|
||||
ClientPluginOptions
|
||||
}
|
||||
|
||||
func (c *TypedClientPluginOptions) UnmarshalJSON(b []byte) error {
|
||||
if len(b) == 4 && string(b) == "null" {
|
||||
return nil
|
||||
func (c TypedClientPluginOptions) Clone() TypedClientPluginOptions {
|
||||
out := c
|
||||
if c.ClientPluginOptions != nil {
|
||||
out.ClientPluginOptions = c.ClientPluginOptions.Clone()
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
typeStruct := struct {
|
||||
Type string `json:"type"`
|
||||
}{}
|
||||
if err := json.Unmarshal(b, &typeStruct); err != nil {
|
||||
func (c *TypedClientPluginOptions) UnmarshalJSON(b []byte) error {
|
||||
decoded, err := DecodeClientPluginOptionsJSON(b, DecodeOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.Type = typeStruct.Type
|
||||
if c.Type == "" {
|
||||
return errors.New("plugin type is empty")
|
||||
}
|
||||
|
||||
v, ok := clientPluginOptionsTypeMap[typeStruct.Type]
|
||||
if !ok {
|
||||
return fmt.Errorf("unknown plugin type: %s", typeStruct.Type)
|
||||
}
|
||||
options := reflect.New(v).Interface().(ClientPluginOptions)
|
||||
|
||||
decoder := json.NewDecoder(bytes.NewBuffer(b))
|
||||
if DisallowUnknownFields {
|
||||
decoder.DisallowUnknownFields()
|
||||
}
|
||||
|
||||
if err := decoder.Decode(options); err != nil {
|
||||
return fmt.Errorf("unmarshal ClientPluginOptions error: %v", err)
|
||||
}
|
||||
c.ClientPluginOptions = options
|
||||
*c = decoded
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *TypedClientPluginOptions) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(c.ClientPluginOptions)
|
||||
return jsonx.Marshal(c.ClientPluginOptions)
|
||||
}
|
||||
|
||||
// AutoTLSOptions configures automatic certificate provisioning (ACME) for plugins
|
||||
// that terminate TLS locally.
|
||||
type AutoTLSOptions struct {
|
||||
Enable bool `json:"enable,omitempty"`
|
||||
// Contact email for certificate expiration and important notices.
|
||||
Email string `json:"email,omitempty"`
|
||||
// Directory used to cache ACME account and certificates.
|
||||
CacheDir string `json:"cacheDir,omitempty"`
|
||||
// ACME directory URL, e.g. Let's Encrypt staging/prod endpoint.
|
||||
CADirURL string `json:"caDirURL,omitempty"`
|
||||
// Restrict certificate issuance to the listed domains.
|
||||
HostAllowList []string `json:"hostAllowList,omitempty"`
|
||||
}
|
||||
|
||||
func (o *AutoTLSOptions) Clone() *AutoTLSOptions {
|
||||
if o == nil {
|
||||
return nil
|
||||
}
|
||||
out := *o
|
||||
out.HostAllowList = slices.Clone(o.HostAllowList)
|
||||
return &out
|
||||
}
|
||||
|
||||
type HTTP2HTTPSPluginOptions struct {
|
||||
@@ -111,6 +115,15 @@ type HTTP2HTTPSPluginOptions struct {
|
||||
|
||||
func (o *HTTP2HTTPSPluginOptions) Complete() {}
|
||||
|
||||
func (o *HTTP2HTTPSPluginOptions) Clone() ClientPluginOptions {
|
||||
if o == nil {
|
||||
return nil
|
||||
}
|
||||
out := *o
|
||||
out.RequestHeaders = o.RequestHeaders.Clone()
|
||||
return &out
|
||||
}
|
||||
|
||||
type HTTP2HTTPSRedirectPluginOptions struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
HTTPSPort int `json:"httpsPort,omitempty"`
|
||||
@@ -118,6 +131,14 @@ type HTTP2HTTPSRedirectPluginOptions struct {
|
||||
|
||||
func (o *HTTP2HTTPSRedirectPluginOptions) Complete() {}
|
||||
|
||||
func (o *HTTP2HTTPSRedirectPluginOptions) Clone() ClientPluginOptions {
|
||||
if o == nil {
|
||||
return nil
|
||||
}
|
||||
out := *o
|
||||
return &out
|
||||
}
|
||||
|
||||
type HTTPProxyPluginOptions struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
HTTPUser string `json:"httpUser,omitempty"`
|
||||
@@ -126,16 +147,12 @@ type HTTPProxyPluginOptions struct {
|
||||
|
||||
func (o *HTTPProxyPluginOptions) Complete() {}
|
||||
|
||||
type AutoTLSOptions struct {
|
||||
Enable bool `json:"enable,omitempty"`
|
||||
// Contact email for certificate expiration and important notices.
|
||||
Email string `json:"email,omitempty"`
|
||||
// Directory used to cache ACME account and certificates.
|
||||
CacheDir string `json:"cacheDir,omitempty"`
|
||||
// ACME directory URL, e.g. Let's Encrypt staging/prod endpoint.
|
||||
CADirURL string `json:"caDirURL,omitempty"`
|
||||
// Restrict certificate issuance to the listed domains.
|
||||
HostAllowList []string `json:"hostAllowList,omitempty"`
|
||||
func (o *HTTPProxyPluginOptions) Clone() ClientPluginOptions {
|
||||
if o == nil {
|
||||
return nil
|
||||
}
|
||||
out := *o
|
||||
return &out
|
||||
}
|
||||
|
||||
type HTTPS2HTTPPluginOptions struct {
|
||||
@@ -153,6 +170,17 @@ func (o *HTTPS2HTTPPluginOptions) Complete() {
|
||||
o.EnableHTTP2 = util.EmptyOr(o.EnableHTTP2, lo.ToPtr(true))
|
||||
}
|
||||
|
||||
func (o *HTTPS2HTTPPluginOptions) Clone() ClientPluginOptions {
|
||||
if o == nil {
|
||||
return nil
|
||||
}
|
||||
out := *o
|
||||
out.RequestHeaders = o.RequestHeaders.Clone()
|
||||
out.EnableHTTP2 = util.ClonePtr(o.EnableHTTP2)
|
||||
out.AutoTLS = o.AutoTLS.Clone()
|
||||
return &out
|
||||
}
|
||||
|
||||
type HTTPS2HTTPSPluginOptions struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
LocalAddr string `json:"localAddr,omitempty"`
|
||||
@@ -168,6 +196,17 @@ func (o *HTTPS2HTTPSPluginOptions) Complete() {
|
||||
o.EnableHTTP2 = util.EmptyOr(o.EnableHTTP2, lo.ToPtr(true))
|
||||
}
|
||||
|
||||
func (o *HTTPS2HTTPSPluginOptions) Clone() ClientPluginOptions {
|
||||
if o == nil {
|
||||
return nil
|
||||
}
|
||||
out := *o
|
||||
out.RequestHeaders = o.RequestHeaders.Clone()
|
||||
out.EnableHTTP2 = util.ClonePtr(o.EnableHTTP2)
|
||||
out.AutoTLS = o.AutoTLS.Clone()
|
||||
return &out
|
||||
}
|
||||
|
||||
type HTTP2HTTPPluginOptions struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
LocalAddr string `json:"localAddr,omitempty"`
|
||||
@@ -177,6 +216,15 @@ type HTTP2HTTPPluginOptions struct {
|
||||
|
||||
func (o *HTTP2HTTPPluginOptions) Complete() {}
|
||||
|
||||
func (o *HTTP2HTTPPluginOptions) Clone() ClientPluginOptions {
|
||||
if o == nil {
|
||||
return nil
|
||||
}
|
||||
out := *o
|
||||
out.RequestHeaders = o.RequestHeaders.Clone()
|
||||
return &out
|
||||
}
|
||||
|
||||
type Socks5PluginOptions struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
Username string `json:"username,omitempty"`
|
||||
@@ -185,6 +233,14 @@ type Socks5PluginOptions struct {
|
||||
|
||||
func (o *Socks5PluginOptions) Complete() {}
|
||||
|
||||
func (o *Socks5PluginOptions) Clone() ClientPluginOptions {
|
||||
if o == nil {
|
||||
return nil
|
||||
}
|
||||
out := *o
|
||||
return &out
|
||||
}
|
||||
|
||||
type StaticFilePluginOptions struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
LocalPath string `json:"localPath,omitempty"`
|
||||
@@ -195,6 +251,14 @@ type StaticFilePluginOptions struct {
|
||||
|
||||
func (o *StaticFilePluginOptions) Complete() {}
|
||||
|
||||
func (o *StaticFilePluginOptions) Clone() ClientPluginOptions {
|
||||
if o == nil {
|
||||
return nil
|
||||
}
|
||||
out := *o
|
||||
return &out
|
||||
}
|
||||
|
||||
type UnixDomainSocketPluginOptions struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
UnixPath string `json:"unixPath,omitempty"`
|
||||
@@ -202,6 +266,14 @@ type UnixDomainSocketPluginOptions struct {
|
||||
|
||||
func (o *UnixDomainSocketPluginOptions) Complete() {}
|
||||
|
||||
func (o *UnixDomainSocketPluginOptions) Clone() ClientPluginOptions {
|
||||
if o == nil {
|
||||
return nil
|
||||
}
|
||||
out := *o
|
||||
return &out
|
||||
}
|
||||
|
||||
type TLS2RawPluginOptions struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
LocalAddr string `json:"localAddr,omitempty"`
|
||||
@@ -212,8 +284,25 @@ type TLS2RawPluginOptions struct {
|
||||
|
||||
func (o *TLS2RawPluginOptions) Complete() {}
|
||||
|
||||
func (o *TLS2RawPluginOptions) Clone() ClientPluginOptions {
|
||||
if o == nil {
|
||||
return nil
|
||||
}
|
||||
out := *o
|
||||
out.AutoTLS = o.AutoTLS.Clone()
|
||||
return &out
|
||||
}
|
||||
|
||||
type VirtualNetPluginOptions struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
func (o *VirtualNetPluginOptions) Complete() {}
|
||||
|
||||
func (o *VirtualNetPluginOptions) Clone() ClientPluginOptions {
|
||||
if o == nil {
|
||||
return nil
|
||||
}
|
||||
out := *o
|
||||
return &out
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user