From 8c00ba7c79e6a536eb4670cfabd2a56341e4295d Mon Sep 17 00:00:00 2001 From: Jack Pordi Date: Mon, 16 Jun 2025 14:57:35 +0100 Subject: [PATCH] Allow deleting headers --- conf/frpc_full_example.toml | 2 ++ pkg/config/legacy/conversion.go | 10 +++---- pkg/config/v1/proxy.go | 22 ++++++++-------- pkg/config/v1/proxy_plugin.go | 45 ++++++++++++++++---------------- pkg/msg/msg.go | 24 ++++++++++------- pkg/plugin/client/http2http.go | 4 +-- pkg/plugin/client/http2https.go | 4 +-- pkg/plugin/client/https2http.go | 4 +-- pkg/plugin/client/https2https.go | 4 +-- pkg/util/vhost/http.go | 13 +++++++-- pkg/util/vhost/vhost.go | 5 ++-- server/proxy/http.go | 4 +-- 12 files changed, 78 insertions(+), 63 deletions(-) diff --git a/conf/frpc_full_example.toml b/conf/frpc_full_example.toml index 7d4838cd..9bcd2fb7 100644 --- a/conf/frpc_full_example.toml +++ b/conf/frpc_full_example.toml @@ -218,7 +218,9 @@ locations = ["/", "/pic"] # routeByHTTPUser = abc hostHeaderRewrite = "example.com" requestHeaders.set.x-from-where = "frp" +requestHeaders.delete = [ "foo" ] responseHeaders.set.foo = "bar" +requestHeaders.delete = [ "foo" ] healthCheck.type = "http" # frpc will send a GET http request '/status' to local http service # http service is alive when it return 2xx http response code diff --git a/pkg/config/legacy/conversion.go b/pkg/config/legacy/conversion.go index 73859d26..5030e560 100644 --- a/pkg/config/legacy/conversion.go +++ b/pkg/config/legacy/conversion.go @@ -21,6 +21,7 @@ import ( "github.com/fatedier/frp/pkg/config/types" v1 "github.com/fatedier/frp/pkg/config/v1" + "github.com/fatedier/frp/pkg/msg" ) func Convert_ClientCommonConf_To_v1(conf *ClientCommonConf) *v1.ClientCommonConfig { @@ -168,8 +169,8 @@ func Convert_ServerCommonConf_To_v1(conf *ServerCommonConf) *v1.ServerConfig { return out } -func transformHeadersFromPluginParams(params map[string]string) v1.HeaderOperations { - out := v1.HeaderOperations{} +func transformHeadersFromPluginParams(params map[string]string) msg.HeaderOperations { + out := msg.HeaderOperations{} for k, v := range params { if !strings.HasPrefix(k, "plugin_header_") { continue @@ -179,11 +180,6 @@ func transformHeadersFromPluginParams(params map[string]string) v1.HeaderOperati out.Set = make(map[string]string) } out.Set[k] = v - - if out.Delete == nil { - out.Delete = make(map[string]bool) - } - out.Delete[k] = true } } return out diff --git a/pkg/config/v1/proxy.go b/pkg/config/v1/proxy.go index 34bd7125..a4bfe31e 100644 --- a/pkg/config/v1/proxy.go +++ b/pkg/config/v1/proxy.go @@ -294,13 +294,13 @@ type HTTPProxyConfig struct { ProxyBaseConfig DomainConfig - Locations []string `json:"locations,omitempty"` - HTTPUser string `json:"httpUser,omitempty"` - HTTPPassword string `json:"httpPassword,omitempty"` - HostHeaderRewrite string `json:"hostHeaderRewrite,omitempty"` - RequestHeaders HeaderOperations `json:"requestHeaders,omitempty"` - ResponseHeaders HeaderOperations `json:"responseHeaders,omitempty"` - RouteByHTTPUser string `json:"routeByHTTPUser,omitempty"` + Locations []string `json:"locations,omitempty"` + HTTPUser string `json:"httpUser,omitempty"` + HTTPPassword string `json:"httpPassword,omitempty"` + HostHeaderRewrite string `json:"hostHeaderRewrite,omitempty"` + RequestHeaders msg.HeaderOperations `json:"requestHeaders,omitempty"` + ResponseHeaders msg.HeaderOperations `json:"responseHeaders,omitempty"` + RouteByHTTPUser string `json:"routeByHTTPUser,omitempty"` } func (c *HTTPProxyConfig) MarshalToMsg(m *msg.NewProxy) { @@ -312,8 +312,8 @@ func (c *HTTPProxyConfig) MarshalToMsg(m *msg.NewProxy) { m.HostHeaderRewrite = c.HostHeaderRewrite m.HTTPUser = c.HTTPUser m.HTTPPwd = c.HTTPPassword - m.Headers = c.RequestHeaders.Set - m.ResponseHeaders = c.ResponseHeaders.Set + m.RequestHeaders = c.RequestHeaders + m.ResponseHeaders = c.ResponseHeaders m.RouteByHTTPUser = c.RouteByHTTPUser } @@ -326,8 +326,8 @@ func (c *HTTPProxyConfig) UnmarshalFromMsg(m *msg.NewProxy) { c.HostHeaderRewrite = m.HostHeaderRewrite c.HTTPUser = m.HTTPUser c.HTTPPassword = m.HTTPPwd - c.RequestHeaders.Set = m.Headers - c.ResponseHeaders.Set = m.ResponseHeaders + c.RequestHeaders = m.RequestHeaders + c.ResponseHeaders = m.ResponseHeaders c.RouteByHTTPUser = m.RouteByHTTPUser } diff --git a/pkg/config/v1/proxy_plugin.go b/pkg/config/v1/proxy_plugin.go index 128ccae6..f6967932 100644 --- a/pkg/config/v1/proxy_plugin.go +++ b/pkg/config/v1/proxy_plugin.go @@ -23,6 +23,7 @@ import ( "github.com/samber/lo" + "github.com/fatedier/frp/pkg/msg" "github.com/fatedier/frp/pkg/util/util" ) @@ -101,10 +102,10 @@ func (c *TypedClientPluginOptions) MarshalJSON() ([]byte, error) { } type HTTP2HTTPSPluginOptions struct { - Type string `json:"type,omitempty"` - LocalAddr string `json:"localAddr,omitempty"` - HostHeaderRewrite string `json:"hostHeaderRewrite,omitempty"` - RequestHeaders HeaderOperations `json:"requestHeaders,omitempty"` + Type string `json:"type,omitempty"` + LocalAddr string `json:"localAddr,omitempty"` + HostHeaderRewrite string `json:"hostHeaderRewrite,omitempty"` + RequestHeaders msg.HeaderOperations `json:"requestHeaders,omitempty"` } func (o *HTTP2HTTPSPluginOptions) Complete() {} @@ -118,13 +119,13 @@ type HTTPProxyPluginOptions struct { 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"` + Type string `json:"type,omitempty"` + LocalAddr string `json:"localAddr,omitempty"` + HostHeaderRewrite string `json:"hostHeaderRewrite,omitempty"` + RequestHeaders msg.HeaderOperations `json:"requestHeaders,omitempty"` + EnableHTTP2 *bool `json:"enableHTTP2,omitempty"` + CrtPath string `json:"crtPath,omitempty"` + KeyPath string `json:"keyPath,omitempty"` } func (o *HTTPS2HTTPPluginOptions) Complete() { @@ -132,13 +133,13 @@ func (o *HTTPS2HTTPPluginOptions) Complete() { } 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"` + Type string `json:"type,omitempty"` + LocalAddr string `json:"localAddr,omitempty"` + HostHeaderRewrite string `json:"hostHeaderRewrite,omitempty"` + RequestHeaders msg.HeaderOperations `json:"requestHeaders,omitempty"` + EnableHTTP2 *bool `json:"enableHTTP2,omitempty"` + CrtPath string `json:"crtPath,omitempty"` + KeyPath string `json:"keyPath,omitempty"` } func (o *HTTPS2HTTPSPluginOptions) Complete() { @@ -146,10 +147,10 @@ func (o *HTTPS2HTTPSPluginOptions) Complete() { } type HTTP2HTTPPluginOptions struct { - Type string `json:"type,omitempty"` - LocalAddr string `json:"localAddr,omitempty"` - HostHeaderRewrite string `json:"hostHeaderRewrite,omitempty"` - RequestHeaders HeaderOperations `json:"requestHeaders,omitempty"` + Type string `json:"type,omitempty"` + LocalAddr string `json:"localAddr,omitempty"` + HostHeaderRewrite string `json:"hostHeaderRewrite,omitempty"` + RequestHeaders msg.HeaderOperations `json:"requestHeaders,omitempty"` } func (o *HTTP2HTTPPluginOptions) Complete() {} diff --git a/pkg/msg/msg.go b/pkg/msg/msg.go index d466f231..325c9c3a 100644 --- a/pkg/msg/msg.go +++ b/pkg/msg/msg.go @@ -19,6 +19,12 @@ import ( "reflect" ) +// HeaderOperations represents operations to be performed on HTTP headers +type HeaderOperations struct { + Set map[string]string `json:"set,omitempty"` + Delete []string `json:"delete,omitempty"` +} + const ( TypeLogin = 'o' TypeLoginResp = '1' @@ -114,15 +120,15 @@ type NewProxy struct { RemotePort int `json:"remote_port,omitempty"` // http and https only - CustomDomains []string `json:"custom_domains,omitempty"` - SubDomain string `json:"subdomain,omitempty"` - Locations []string `json:"locations,omitempty"` - HTTPUser string `json:"http_user,omitempty"` - HTTPPwd string `json:"http_pwd,omitempty"` - HostHeaderRewrite string `json:"host_header_rewrite,omitempty"` - Headers map[string]string `json:"headers,omitempty"` - ResponseHeaders map[string]string `json:"response_headers,omitempty"` - RouteByHTTPUser string `json:"route_by_http_user,omitempty"` + CustomDomains []string `json:"custom_domains,omitempty"` + SubDomain string `json:"subdomain,omitempty"` + Locations []string `json:"locations,omitempty"` + HTTPUser string `json:"http_user,omitempty"` + HTTPPwd string `json:"http_pwd,omitempty"` + HostHeaderRewrite string `json:"host_header_rewrite,omitempty"` + RequestHeaders HeaderOperations `json:"request_headers,omitempty"` + ResponseHeaders HeaderOperations `json:"response_headers,omitempty"` + RouteByHTTPUser string `json:"route_by_http_user,omitempty"` // stcp, sudp, xtcp Sk string `json:"sk,omitempty"` diff --git a/pkg/plugin/client/http2http.go b/pkg/plugin/client/http2http.go index 807eece7..ed37a0ca 100644 --- a/pkg/plugin/client/http2http.go +++ b/pkg/plugin/client/http2http.go @@ -61,8 +61,8 @@ func NewHTTP2HTTPPlugin(_ PluginContext, options v1.ClientPluginOptions) (Plugin for k, v := range p.opts.RequestHeaders.Set { req.Header.Set(k, v) } - for k, _ := range p.opts.RequestHeaders.Delete { - req.Header.Del(k) + for _, v := range p.opts.RequestHeaders.Delete { + req.Header.Del(v) } }, BufferPool: pool.NewBuffer(32 * 1024), diff --git a/pkg/plugin/client/http2https.go b/pkg/plugin/client/http2https.go index 43163130..f035b980 100644 --- a/pkg/plugin/client/http2https.go +++ b/pkg/plugin/client/http2https.go @@ -69,8 +69,8 @@ func NewHTTP2HTTPSPlugin(_ PluginContext, options v1.ClientPluginOptions) (Plugi for k, v := range p.opts.RequestHeaders.Set { req.Header.Set(k, v) } - for k, _ := range p.opts.RequestHeaders.Delete { - req.Header.Del(k) + for _, v := range p.opts.RequestHeaders.Delete { + req.Header.Del(v) } }, Transport: tr, diff --git a/pkg/plugin/client/https2http.go b/pkg/plugin/client/https2http.go index 96459124..0c231cd8 100644 --- a/pkg/plugin/client/https2http.go +++ b/pkg/plugin/client/https2http.go @@ -68,8 +68,8 @@ func NewHTTPS2HTTPPlugin(_ PluginContext, options v1.ClientPluginOptions) (Plugi for k, v := range p.opts.RequestHeaders.Set { req.Header.Set(k, v) } - for k, _ := range p.opts.RequestHeaders.Delete { - req.Header.Del(k) + for _, v := range p.opts.RequestHeaders.Delete { + req.Header.Del(v) } }, BufferPool: pool.NewBuffer(32 * 1024), diff --git a/pkg/plugin/client/https2https.go b/pkg/plugin/client/https2https.go index c2c6ffd0..539c0564 100644 --- a/pkg/plugin/client/https2https.go +++ b/pkg/plugin/client/https2https.go @@ -73,8 +73,8 @@ func NewHTTPS2HTTPSPlugin(_ PluginContext, options v1.ClientPluginOptions) (Plug for k, v := range p.opts.RequestHeaders.Set { req.Header.Set(k, v) } - for k, _ := range p.opts.RequestHeaders.Delete { - req.Header.Del(k) + for _, v := range p.opts.RequestHeaders.Delete { + req.Header.Del(v) } }, Transport: tr, diff --git a/pkg/util/vhost/http.go b/pkg/util/vhost/http.go index 05ec174b..c72eed76 100644 --- a/pkg/util/vhost/http.go +++ b/pkg/util/vhost/http.go @@ -87,9 +87,14 @@ func NewHTTPReverseProxy(option HTTPReverseProxyOptions, vhostRouter *Routers) * base64.StdEncoding.EncodeToString([]byte(rc.RouteByHTTPUser)) + "." + base64.StdEncoding.EncodeToString([]byte(endpoint)) - for k, v := range rc.Headers { + for k, v := range rc.RequestHeaders.Set { req.Header.Set(k, v) } + + for _, v := range rc.RequestHeaders.Delete { + req.Header.Del(v) + } + } else { req.URL.Host = req.Host } @@ -97,9 +102,13 @@ func NewHTTPReverseProxy(option HTTPReverseProxyOptions, vhostRouter *Routers) * ModifyResponse: func(r *http.Response) error { rc := r.Request.Context().Value(RouteConfigKey).(*RouteConfig) if rc != nil { - for k, v := range rc.ResponseHeaders { + for k, v := range rc.ResponseHeaders.Set { r.Header.Set(k, v) } + + for _, v := range rc.ResponseHeaders.Delete { + r.Header.Del(v) + } } return nil }, diff --git a/pkg/util/vhost/vhost.go b/pkg/util/vhost/vhost.go index 007751d7..70261c90 100644 --- a/pkg/util/vhost/vhost.go +++ b/pkg/util/vhost/vhost.go @@ -21,6 +21,7 @@ import ( "github.com/fatedier/golib/errors" + "github.com/fatedier/frp/pkg/msg" "github.com/fatedier/frp/pkg/util/log" netpkg "github.com/fatedier/frp/pkg/util/net" "github.com/fatedier/frp/pkg/util/xlog" @@ -117,8 +118,8 @@ type RouteConfig struct { RewriteHost string Username string Password string - Headers map[string]string - ResponseHeaders map[string]string + RequestHeaders msg.HeaderOperations + ResponseHeaders msg.HeaderOperations RouteByHTTPUser string CreateConnFn CreateConnFunc diff --git a/server/proxy/http.go b/server/proxy/http.go index 9a02dcdd..966ff377 100644 --- a/server/proxy/http.go +++ b/server/proxy/http.go @@ -57,8 +57,8 @@ func (pxy *HTTPProxy) Run() (remoteAddr string, err error) { routeConfig := vhost.RouteConfig{ RewriteHost: pxy.cfg.HostHeaderRewrite, RouteByHTTPUser: pxy.cfg.RouteByHTTPUser, - Headers: pxy.cfg.RequestHeaders.Set, - ResponseHeaders: pxy.cfg.ResponseHeaders.Set, + RequestHeaders: pxy.cfg.RequestHeaders, + ResponseHeaders: pxy.cfg.ResponseHeaders, Username: pxy.cfg.HTTPUser, Password: pxy.cfg.HTTPPassword, CreateConnFn: pxy.GetRealConn,