1
0

proxy_plugin.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. // Copyright 2023 The frp Authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package v1
  15. import (
  16. "bytes"
  17. "encoding/json"
  18. "errors"
  19. "fmt"
  20. "reflect"
  21. "github.com/samber/lo"
  22. "github.com/fatedier/frp/pkg/util/util"
  23. )
  24. const (
  25. PluginHTTP2HTTPS = "http2https"
  26. PluginHTTPProxy = "http_proxy"
  27. PluginHTTPS2HTTP = "https2http"
  28. PluginHTTPS2HTTPS = "https2https"
  29. PluginHTTP2HTTP = "http2http"
  30. PluginSocks5 = "socks5"
  31. PluginStaticFile = "static_file"
  32. PluginUnixDomainSocket = "unix_domain_socket"
  33. PluginTLS2Raw = "tls2raw"
  34. PluginVirtualNet = "virtual_net"
  35. )
  36. var clientPluginOptionsTypeMap = map[string]reflect.Type{
  37. PluginHTTP2HTTPS: reflect.TypeOf(HTTP2HTTPSPluginOptions{}),
  38. PluginHTTPProxy: reflect.TypeOf(HTTPProxyPluginOptions{}),
  39. PluginHTTPS2HTTP: reflect.TypeOf(HTTPS2HTTPPluginOptions{}),
  40. PluginHTTPS2HTTPS: reflect.TypeOf(HTTPS2HTTPSPluginOptions{}),
  41. PluginHTTP2HTTP: reflect.TypeOf(HTTP2HTTPPluginOptions{}),
  42. PluginSocks5: reflect.TypeOf(Socks5PluginOptions{}),
  43. PluginStaticFile: reflect.TypeOf(StaticFilePluginOptions{}),
  44. PluginUnixDomainSocket: reflect.TypeOf(UnixDomainSocketPluginOptions{}),
  45. PluginTLS2Raw: reflect.TypeOf(TLS2RawPluginOptions{}),
  46. PluginVirtualNet: reflect.TypeOf(VirtualNetPluginOptions{}),
  47. }
  48. type ClientPluginOptions interface {
  49. Complete()
  50. }
  51. type TypedClientPluginOptions struct {
  52. Type string `json:"type"`
  53. ClientPluginOptions
  54. }
  55. func (c *TypedClientPluginOptions) UnmarshalJSON(b []byte) error {
  56. if len(b) == 4 && string(b) == "null" {
  57. return nil
  58. }
  59. typeStruct := struct {
  60. Type string `json:"type"`
  61. }{}
  62. if err := json.Unmarshal(b, &typeStruct); err != nil {
  63. return err
  64. }
  65. c.Type = typeStruct.Type
  66. if c.Type == "" {
  67. return errors.New("plugin type is empty")
  68. }
  69. v, ok := clientPluginOptionsTypeMap[typeStruct.Type]
  70. if !ok {
  71. return fmt.Errorf("unknown plugin type: %s", typeStruct.Type)
  72. }
  73. options := reflect.New(v).Interface().(ClientPluginOptions)
  74. decoder := json.NewDecoder(bytes.NewBuffer(b))
  75. if DisallowUnknownFields {
  76. decoder.DisallowUnknownFields()
  77. }
  78. if err := decoder.Decode(options); err != nil {
  79. return fmt.Errorf("unmarshal ClientPluginOptions error: %v", err)
  80. }
  81. c.ClientPluginOptions = options
  82. return nil
  83. }
  84. func (c *TypedClientPluginOptions) MarshalJSON() ([]byte, error) {
  85. return json.Marshal(c.ClientPluginOptions)
  86. }
  87. type HTTP2HTTPSPluginOptions struct {
  88. Type string `json:"type,omitempty"`
  89. LocalAddr string `json:"localAddr,omitempty"`
  90. HostHeaderRewrite string `json:"hostHeaderRewrite,omitempty"`
  91. RequestHeaders HeaderOperations `json:"requestHeaders,omitempty"`
  92. }
  93. func (o *HTTP2HTTPSPluginOptions) Complete() {}
  94. type HTTPProxyPluginOptions struct {
  95. Type string `json:"type,omitempty"`
  96. HTTPUser string `json:"httpUser,omitempty"`
  97. HTTPPassword string `json:"httpPassword,omitempty"`
  98. }
  99. func (o *HTTPProxyPluginOptions) Complete() {}
  100. type HTTPS2HTTPPluginOptions struct {
  101. Type string `json:"type,omitempty"`
  102. LocalAddr string `json:"localAddr,omitempty"`
  103. HostHeaderRewrite string `json:"hostHeaderRewrite,omitempty"`
  104. RequestHeaders HeaderOperations `json:"requestHeaders,omitempty"`
  105. EnableHTTP2 *bool `json:"enableHTTP2,omitempty"`
  106. CrtPath string `json:"crtPath,omitempty"`
  107. KeyPath string `json:"keyPath,omitempty"`
  108. }
  109. func (o *HTTPS2HTTPPluginOptions) Complete() {
  110. o.EnableHTTP2 = util.EmptyOr(o.EnableHTTP2, lo.ToPtr(true))
  111. }
  112. type HTTPS2HTTPSPluginOptions struct {
  113. Type string `json:"type,omitempty"`
  114. LocalAddr string `json:"localAddr,omitempty"`
  115. HostHeaderRewrite string `json:"hostHeaderRewrite,omitempty"`
  116. RequestHeaders HeaderOperations `json:"requestHeaders,omitempty"`
  117. EnableHTTP2 *bool `json:"enableHTTP2,omitempty"`
  118. CrtPath string `json:"crtPath,omitempty"`
  119. KeyPath string `json:"keyPath,omitempty"`
  120. }
  121. func (o *HTTPS2HTTPSPluginOptions) Complete() {
  122. o.EnableHTTP2 = util.EmptyOr(o.EnableHTTP2, lo.ToPtr(true))
  123. }
  124. type HTTP2HTTPPluginOptions struct {
  125. Type string `json:"type,omitempty"`
  126. LocalAddr string `json:"localAddr,omitempty"`
  127. HostHeaderRewrite string `json:"hostHeaderRewrite,omitempty"`
  128. RequestHeaders HeaderOperations `json:"requestHeaders,omitempty"`
  129. }
  130. func (o *HTTP2HTTPPluginOptions) Complete() {}
  131. type Socks5PluginOptions struct {
  132. Type string `json:"type,omitempty"`
  133. Username string `json:"username,omitempty"`
  134. Password string `json:"password,omitempty"`
  135. }
  136. func (o *Socks5PluginOptions) Complete() {}
  137. type StaticFilePluginOptions struct {
  138. Type string `json:"type,omitempty"`
  139. LocalPath string `json:"localPath,omitempty"`
  140. StripPrefix string `json:"stripPrefix,omitempty"`
  141. HTTPUser string `json:"httpUser,omitempty"`
  142. HTTPPassword string `json:"httpPassword,omitempty"`
  143. }
  144. func (o *StaticFilePluginOptions) Complete() {}
  145. type UnixDomainSocketPluginOptions struct {
  146. Type string `json:"type,omitempty"`
  147. UnixPath string `json:"unixPath,omitempty"`
  148. }
  149. func (o *UnixDomainSocketPluginOptions) Complete() {}
  150. type TLS2RawPluginOptions struct {
  151. Type string `json:"type,omitempty"`
  152. LocalAddr string `json:"localAddr,omitempty"`
  153. CrtPath string `json:"crtPath,omitempty"`
  154. KeyPath string `json:"keyPath,omitempty"`
  155. }
  156. func (o *TLS2RawPluginOptions) Complete() {}
  157. type VirtualNetPluginOptions struct {
  158. Type string `json:"type,omitempty"`
  159. }
  160. func (o *VirtualNetPluginOptions) Complete() {}