Skip to content

Commit

Permalink
Merge pull request #4324 from fatedier/dev
Browse files Browse the repository at this point in the history
bump version
  • Loading branch information
fatedier committed Jul 9, 2024
2 parents e649692 + b4d5d8c commit 243ca99
Show file tree
Hide file tree
Showing 17 changed files with 283 additions and 15 deletions.
17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,24 @@

<h3 align="center">Gold Sponsors</h3>
<!--gold sponsors start-->
<p align="center">
<a href="https://lokal.so/?utm_campaign=github_repo&utm_medium=referral&utm_content=frp&utm_source=github" target="_blank">
<img width="420px" src="https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/sponsor_lokal.png">
</a>
</p>
<p align="center">
<a href="https://workos.com/?utm_campaign=github_repo&utm_medium=referral&utm_content=frp&utm_source=github" target="_blank">
<img width="350px" src="https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/sponsor_workos.png">
<img width="420px" src="https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/sponsor_workos.png">
</a>
<a>&nbsp</a>
</p>
<p align="center">
<a href="https://github.com/daytonaio/daytona" target="_blank">
<img width="360px" src="https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/sponsor_daytona.png">
<img width="420px" src="https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/sponsor_daytona.png">
</a>
</p>
<p align="center">
<a href="https://github.com/beclab/terminus" target="_blank">
<img width="420px" src="https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/sponsor_terminusos.jpeg">
</a>
</p>
<!--gold sponsors end-->
Expand Down
17 changes: 14 additions & 3 deletions README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,24 @@ frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP

<h3 align="center">Gold Sponsors</h3>
<!--gold sponsors start-->
<p align="center">
<a href="https://lokal.so/?utm_campaign=github_repo&utm_medium=referral&utm_content=frp&utm_source=github" target="_blank">
<img width="420px" src="https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/sponsor_lokal.png">
</a>
</p>
<p align="center">
<a href="https://workos.com/?utm_campaign=github_repo&utm_medium=referral&utm_content=frp&utm_source=github" target="_blank">
<img width="350px" src="https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/sponsor_workos.png">
<img width="420px" src="https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/sponsor_workos.png">
</a>
<a>&nbsp</a>
</p>
<p align="center">
<a href="https://github.com/daytonaio/daytona" target="_blank">
<img width="360px" src="https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/sponsor_daytona.png">
<img width="420px" src="https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/sponsor_daytona.png">
</a>
</p>
<p align="center">
<a href="https://github.com/beclab/terminus" target="_blank">
<img width="420px" src="https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/sponsor_terminusos.jpeg">
</a>
</p>
<!--gold sponsors end-->
Expand Down
9 changes: 4 additions & 5 deletions Release.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
### Fixes
### Features

* Fixed an issue where HTTP/2 was not enabled for https2http and https2https plugins.
* Fixed the issue where the default values of INI configuration parameters are inconsistent with other configuration formats.
* Added a new plugin "http2http" which allows forwarding HTTP requests to another HTTP server, supporting options like local address binding, host header rewrite, and custom request headers.
* Added `enableHTTP2` option to control whether to enable HTTP/2 in plugin https2http and https2https, default is true.

### Changes

* Updated the default value of `transport.tcpMuxKeepaliveInterval` from 60 to 30.
* On the Android platform, the Google DNS server is used only when the default DNS server cannot be obtained.
* Plugin https2http & https2https: return 421 `Misdirected Request` if host not match sni.
10 changes: 10 additions & 0 deletions conf/frpc_full_example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,16 @@ localAddr = "127.0.0.1:443"
hostHeaderRewrite = "127.0.0.1"
requestHeaders.set.x-from-where = "frp"

[[proxies]]
name = "plugin_http2http"
type = "tcp"
remotePort = 6007
[proxies.plugin]
type = "http2http"
localAddr = "127.0.0.1:80"
hostHeaderRewrite = "127.0.0.1"
requestHeaders.set.x-from-where = "frp"

[[proxies]]
name = "secret_tcp"
# If the type is secret tcp, remotePort is useless
Expand Down
Binary file removed doc/pic/donate-wechatpay.png
Binary file not shown.
Binary file modified doc/pic/sponsor_daytona.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed doc/pic/sponsor_doppler.png
Binary file not shown.
Binary file added doc/pic/sponsor_lokal.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed doc/pic/sponsor_nango.png
Binary file not shown.
Binary file added doc/pic/sponsor_terminusos.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
39 changes: 38 additions & 1 deletion pkg/config/v1/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,15 @@ import (
"errors"
"fmt"
"reflect"

"github.com/samber/lo"

"github.com/fatedier/frp/pkg/util/util"
)

type ClientPluginOptions interface{}
type ClientPluginOptions interface {
Complete()
}

type TypedClientPluginOptions struct {
Type string `json:"type"`
Expand Down Expand Up @@ -73,6 +79,7 @@ const (
PluginHTTPProxy = "http_proxy"
PluginHTTPS2HTTP = "https2http"
PluginHTTPS2HTTPS = "https2https"
PluginHTTP2HTTP = "http2http"
PluginSocks5 = "socks5"
PluginStaticFile = "static_file"
PluginUnixDomainSocket = "unix_domain_socket"
Expand All @@ -83,6 +90,7 @@ var clientPluginOptionsTypeMap = map[string]reflect.Type{
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{}),
Expand All @@ -95,36 +103,61 @@ type HTTP2HTTPSPluginOptions struct {
RequestHeaders HeaderOperations `json:"requestHeaders,omitempty"`
}

func (o *HTTP2HTTPSPluginOptions) Complete() {}

type HTTPProxyPluginOptions struct {
Type string `json:"type,omitempty"`
HTTPUser string `json:"httpUser,omitempty"`
HTTPPassword string `json:"httpPassword,omitempty"`
}

func (o *HTTPProxyPluginOptions) Complete() {}

type HTTPS2HTTPPluginOptions struct {
Type string `json:"type,omitempty"`
LocalAddr string `json:"localAddr,omitempty"`
HostHeaderRewrite string `json:"hostHeaderRewrite,omitempty"`
RequestHeaders HeaderOperations `json:"requestHeaders,omitempty"`
EnableHTTP2 *bool `json:"enableHTTP2,omitempty"`
CrtPath string `json:"crtPath,omitempty"`
KeyPath string `json:"keyPath,omitempty"`
}

func (o *HTTPS2HTTPPluginOptions) Complete() {
o.EnableHTTP2 = util.EmptyOr(o.EnableHTTP2, lo.ToPtr(true))
}

type HTTPS2HTTPSPluginOptions struct {
Type string `json:"type,omitempty"`
LocalAddr string `json:"localAddr,omitempty"`
HostHeaderRewrite string `json:"hostHeaderRewrite,omitempty"`
RequestHeaders HeaderOperations `json:"requestHeaders,omitempty"`
EnableHTTP2 *bool `json:"enableHTTP2,omitempty"`
CrtPath string `json:"crtPath,omitempty"`
KeyPath string `json:"keyPath,omitempty"`
}

func (o *HTTPS2HTTPSPluginOptions) Complete() {
o.EnableHTTP2 = util.EmptyOr(o.EnableHTTP2, lo.ToPtr(true))
}

type HTTP2HTTPPluginOptions struct {
Type string `json:"type,omitempty"`
LocalAddr string `json:"localAddr,omitempty"`
HostHeaderRewrite string `json:"hostHeaderRewrite,omitempty"`
RequestHeaders HeaderOperations `json:"requestHeaders,omitempty"`
}

func (o *HTTP2HTTPPluginOptions) Complete() {}

type Socks5PluginOptions struct {
Type string `json:"type,omitempty"`
Username string `json:"username,omitempty"`
Password string `json:"password,omitempty"`
}

func (o *Socks5PluginOptions) Complete() {}

type StaticFilePluginOptions struct {
Type string `json:"type,omitempty"`
LocalPath string `json:"localPath,omitempty"`
Expand All @@ -133,7 +166,11 @@ type StaticFilePluginOptions struct {
HTTPPassword string `json:"httpPassword,omitempty"`
}

func (o *StaticFilePluginOptions) Complete() {}

type UnixDomainSocketPluginOptions struct {
Type string `json:"type,omitempty"`
UnixPath string `json:"unixPath,omitempty"`
}

func (o *UnixDomainSocketPluginOptions) Complete() {}
4 changes: 4 additions & 0 deletions pkg/config/v1/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ func (c *ProxyBaseConfig) Complete(namePrefix string) {
c.Name = lo.Ternary(namePrefix == "", "", namePrefix+".") + c.Name
c.LocalIP = util.EmptyOr(c.LocalIP, "127.0.0.1")
c.Transport.BandwidthLimitMode = util.EmptyOr(c.Transport.BandwidthLimitMode, types.BandwidthLimitModeClient)

if c.Plugin.ClientPluginOptions != nil {
c.Plugin.ClientPluginOptions.Complete()
}
}

func (c *ProxyBaseConfig) MarshalToMsg(m *msg.NewProxy) {
Expand Down
91 changes: 91 additions & 0 deletions pkg/plugin/client/http2http.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// Copyright 2024 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 plugin

import (
"io"
stdlog "log"
"net"
"net/http"
"net/http/httputil"

"github.com/fatedier/golib/pool"

v1 "github.com/fatedier/frp/pkg/config/v1"
"github.com/fatedier/frp/pkg/util/log"
netpkg "github.com/fatedier/frp/pkg/util/net"
)

func init() {
Register(v1.PluginHTTP2HTTP, NewHTTP2HTTPPlugin)
}

type HTTP2HTTPPlugin struct {
opts *v1.HTTP2HTTPPluginOptions

l *Listener
s *http.Server
}

func NewHTTP2HTTPPlugin(options v1.ClientPluginOptions) (Plugin, error) {
opts := options.(*v1.HTTP2HTTPPluginOptions)

listener := NewProxyListener()

p := &HTTP2HTTPPlugin{
opts: opts,
l: listener,
}

rp := &httputil.ReverseProxy{
Rewrite: func(r *httputil.ProxyRequest) {
req := r.Out
req.URL.Scheme = "http"
req.URL.Host = p.opts.LocalAddr
if p.opts.HostHeaderRewrite != "" {
req.Host = p.opts.HostHeaderRewrite
}
for k, v := range p.opts.RequestHeaders.Set {
req.Header.Set(k, v)
}
},
BufferPool: pool.NewBuffer(32 * 1024),
ErrorLog: stdlog.New(log.NewWriteLogger(log.WarnLevel, 2), "", 0),
}

p.s = &http.Server{
Handler: rp,
ReadHeaderTimeout: 0,
}

go func() {
_ = p.s.Serve(listener)
}()

return p, nil
}

func (p *HTTP2HTTPPlugin) Handle(conn io.ReadWriteCloser, realConn net.Conn, _ *ExtraInfo) {
wrapConn := netpkg.WrapReadWriteCloserToConn(conn, realConn)
_ = p.l.PutConn(wrapConn)
}

func (p *HTTP2HTTPPlugin) Name() string {
return v1.PluginHTTP2HTTP
}

func (p *HTTP2HTTPPlugin) Close() error {
return p.s.Close()
}
18 changes: 17 additions & 1 deletion pkg/plugin/client/https2http.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ import (
"time"

"github.com/fatedier/golib/pool"
"github.com/samber/lo"

v1 "github.com/fatedier/frp/pkg/config/v1"
"github.com/fatedier/frp/pkg/transport"
httppkg "github.com/fatedier/frp/pkg/util/http"
"github.com/fatedier/frp/pkg/util/log"
netpkg "github.com/fatedier/frp/pkg/util/net"
)
Expand Down Expand Up @@ -71,6 +73,17 @@ func NewHTTPS2HTTPPlugin(options v1.ClientPluginOptions) (Plugin, error) {
BufferPool: pool.NewBuffer(32 * 1024),
ErrorLog: stdlog.New(log.NewWriteLogger(log.WarnLevel, 2), "", 0),
}
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.TLS != nil {
tlsServerName, _ := httppkg.CanonicalHost(r.TLS.ServerName)
host, _ := httppkg.CanonicalHost(r.Host)
if tlsServerName != "" && tlsServerName != host {
w.WriteHeader(http.StatusMisdirectedRequest)
return
}
}
rp.ServeHTTP(w, r)
})

var (
tlsConfig *tls.Config
Expand All @@ -87,10 +100,13 @@ func NewHTTPS2HTTPPlugin(options v1.ClientPluginOptions) (Plugin, error) {
}

p.s = &http.Server{
Handler: rp,
Handler: handler,
ReadHeaderTimeout: 60 * time.Second,
TLSConfig: tlsConfig,
}
if !lo.FromPtr(opts.EnableHTTP2) {
p.s.TLSNextProto = make(map[string]func(*http.Server, *tls.Conn, http.Handler))
}

go func() {
_ = p.s.ServeTLS(listener, "", "")
Expand Down
18 changes: 17 additions & 1 deletion pkg/plugin/client/https2https.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ import (
"time"

"github.com/fatedier/golib/pool"
"github.com/samber/lo"

v1 "github.com/fatedier/frp/pkg/config/v1"
"github.com/fatedier/frp/pkg/transport"
httppkg "github.com/fatedier/frp/pkg/util/http"
"github.com/fatedier/frp/pkg/util/log"
netpkg "github.com/fatedier/frp/pkg/util/net"
)
Expand Down Expand Up @@ -77,6 +79,17 @@ func NewHTTPS2HTTPSPlugin(options v1.ClientPluginOptions) (Plugin, error) {
BufferPool: pool.NewBuffer(32 * 1024),
ErrorLog: stdlog.New(log.NewWriteLogger(log.WarnLevel, 2), "", 0),
}
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.TLS != nil {
tlsServerName, _ := httppkg.CanonicalHost(r.TLS.ServerName)
host, _ := httppkg.CanonicalHost(r.Host)
if tlsServerName != "" && tlsServerName != host {
w.WriteHeader(http.StatusMisdirectedRequest)
return
}
}
rp.ServeHTTP(w, r)
})

var (
tlsConfig *tls.Config
Expand All @@ -93,10 +106,13 @@ func NewHTTPS2HTTPSPlugin(options v1.ClientPluginOptions) (Plugin, error) {
}

p.s = &http.Server{
Handler: rp,
Handler: handler,
ReadHeaderTimeout: 60 * time.Second,
TLSConfig: tlsConfig,
}
if !lo.FromPtr(opts.EnableHTTP2) {
p.s.TLSNextProto = make(map[string]func(*http.Server, *tls.Conn, http.Handler))
}

go func() {
_ = p.s.ServeTLS(listener, "", "")
Expand Down
2 changes: 1 addition & 1 deletion pkg/util/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

package version

var version = "0.58.1"
var version = "0.59.0"

func Full() string {
return version
Expand Down
Loading

0 comments on commit 243ca99

Please sign in to comment.