Allow deleting headers

pull/4838/head
Jack Pordi 2025-06-16 14:57:35 +01:00
parent 3920a788b4
commit 8c00ba7c79
No known key found for this signature in database
GPG Key ID: 8C30C468C3A8AD0B
12 changed files with 78 additions and 63 deletions

View File

@ -218,7 +218,9 @@ locations = ["/", "/pic"]
# routeByHTTPUser = abc # routeByHTTPUser = abc
hostHeaderRewrite = "example.com" hostHeaderRewrite = "example.com"
requestHeaders.set.x-from-where = "frp" requestHeaders.set.x-from-where = "frp"
requestHeaders.delete = [ "foo" ]
responseHeaders.set.foo = "bar" responseHeaders.set.foo = "bar"
requestHeaders.delete = [ "foo" ]
healthCheck.type = "http" healthCheck.type = "http"
# frpc will send a GET http request '/status' to local http service # frpc will send a GET http request '/status' to local http service
# http service is alive when it return 2xx http response code # http service is alive when it return 2xx http response code

View File

@ -21,6 +21,7 @@ import (
"github.com/fatedier/frp/pkg/config/types" "github.com/fatedier/frp/pkg/config/types"
v1 "github.com/fatedier/frp/pkg/config/v1" v1 "github.com/fatedier/frp/pkg/config/v1"
"github.com/fatedier/frp/pkg/msg"
) )
func Convert_ClientCommonConf_To_v1(conf *ClientCommonConf) *v1.ClientCommonConfig { func Convert_ClientCommonConf_To_v1(conf *ClientCommonConf) *v1.ClientCommonConfig {
@ -168,8 +169,8 @@ func Convert_ServerCommonConf_To_v1(conf *ServerCommonConf) *v1.ServerConfig {
return out return out
} }
func transformHeadersFromPluginParams(params map[string]string) v1.HeaderOperations { func transformHeadersFromPluginParams(params map[string]string) msg.HeaderOperations {
out := v1.HeaderOperations{} out := msg.HeaderOperations{}
for k, v := range params { for k, v := range params {
if !strings.HasPrefix(k, "plugin_header_") { if !strings.HasPrefix(k, "plugin_header_") {
continue continue
@ -179,11 +180,6 @@ func transformHeadersFromPluginParams(params map[string]string) v1.HeaderOperati
out.Set = make(map[string]string) out.Set = make(map[string]string)
} }
out.Set[k] = v out.Set[k] = v
if out.Delete == nil {
out.Delete = make(map[string]bool)
}
out.Delete[k] = true
} }
} }
return out return out

View File

@ -294,13 +294,13 @@ type HTTPProxyConfig struct {
ProxyBaseConfig ProxyBaseConfig
DomainConfig DomainConfig
Locations []string `json:"locations,omitempty"` Locations []string `json:"locations,omitempty"`
HTTPUser string `json:"httpUser,omitempty"` HTTPUser string `json:"httpUser,omitempty"`
HTTPPassword string `json:"httpPassword,omitempty"` HTTPPassword string `json:"httpPassword,omitempty"`
HostHeaderRewrite string `json:"hostHeaderRewrite,omitempty"` HostHeaderRewrite string `json:"hostHeaderRewrite,omitempty"`
RequestHeaders HeaderOperations `json:"requestHeaders,omitempty"` RequestHeaders msg.HeaderOperations `json:"requestHeaders,omitempty"`
ResponseHeaders HeaderOperations `json:"responseHeaders,omitempty"` ResponseHeaders msg.HeaderOperations `json:"responseHeaders,omitempty"`
RouteByHTTPUser string `json:"routeByHTTPUser,omitempty"` RouteByHTTPUser string `json:"routeByHTTPUser,omitempty"`
} }
func (c *HTTPProxyConfig) MarshalToMsg(m *msg.NewProxy) { func (c *HTTPProxyConfig) MarshalToMsg(m *msg.NewProxy) {
@ -312,8 +312,8 @@ func (c *HTTPProxyConfig) MarshalToMsg(m *msg.NewProxy) {
m.HostHeaderRewrite = c.HostHeaderRewrite m.HostHeaderRewrite = c.HostHeaderRewrite
m.HTTPUser = c.HTTPUser m.HTTPUser = c.HTTPUser
m.HTTPPwd = c.HTTPPassword m.HTTPPwd = c.HTTPPassword
m.Headers = c.RequestHeaders.Set m.RequestHeaders = c.RequestHeaders
m.ResponseHeaders = c.ResponseHeaders.Set m.ResponseHeaders = c.ResponseHeaders
m.RouteByHTTPUser = c.RouteByHTTPUser m.RouteByHTTPUser = c.RouteByHTTPUser
} }
@ -326,8 +326,8 @@ func (c *HTTPProxyConfig) UnmarshalFromMsg(m *msg.NewProxy) {
c.HostHeaderRewrite = m.HostHeaderRewrite c.HostHeaderRewrite = m.HostHeaderRewrite
c.HTTPUser = m.HTTPUser c.HTTPUser = m.HTTPUser
c.HTTPPassword = m.HTTPPwd c.HTTPPassword = m.HTTPPwd
c.RequestHeaders.Set = m.Headers c.RequestHeaders = m.RequestHeaders
c.ResponseHeaders.Set = m.ResponseHeaders c.ResponseHeaders = m.ResponseHeaders
c.RouteByHTTPUser = m.RouteByHTTPUser c.RouteByHTTPUser = m.RouteByHTTPUser
} }

View File

@ -23,6 +23,7 @@ import (
"github.com/samber/lo" "github.com/samber/lo"
"github.com/fatedier/frp/pkg/msg"
"github.com/fatedier/frp/pkg/util/util" "github.com/fatedier/frp/pkg/util/util"
) )
@ -101,10 +102,10 @@ func (c *TypedClientPluginOptions) MarshalJSON() ([]byte, error) {
} }
type HTTP2HTTPSPluginOptions struct { type HTTP2HTTPSPluginOptions struct {
Type string `json:"type,omitempty"` Type string `json:"type,omitempty"`
LocalAddr string `json:"localAddr,omitempty"` LocalAddr string `json:"localAddr,omitempty"`
HostHeaderRewrite string `json:"hostHeaderRewrite,omitempty"` HostHeaderRewrite string `json:"hostHeaderRewrite,omitempty"`
RequestHeaders HeaderOperations `json:"requestHeaders,omitempty"` RequestHeaders msg.HeaderOperations `json:"requestHeaders,omitempty"`
} }
func (o *HTTP2HTTPSPluginOptions) Complete() {} func (o *HTTP2HTTPSPluginOptions) Complete() {}
@ -118,13 +119,13 @@ type HTTPProxyPluginOptions struct {
func (o *HTTPProxyPluginOptions) Complete() {} func (o *HTTPProxyPluginOptions) Complete() {}
type HTTPS2HTTPPluginOptions struct { type HTTPS2HTTPPluginOptions struct {
Type string `json:"type,omitempty"` Type string `json:"type,omitempty"`
LocalAddr string `json:"localAddr,omitempty"` LocalAddr string `json:"localAddr,omitempty"`
HostHeaderRewrite string `json:"hostHeaderRewrite,omitempty"` HostHeaderRewrite string `json:"hostHeaderRewrite,omitempty"`
RequestHeaders HeaderOperations `json:"requestHeaders,omitempty"` RequestHeaders msg.HeaderOperations `json:"requestHeaders,omitempty"`
EnableHTTP2 *bool `json:"enableHTTP2,omitempty"` EnableHTTP2 *bool `json:"enableHTTP2,omitempty"`
CrtPath string `json:"crtPath,omitempty"` CrtPath string `json:"crtPath,omitempty"`
KeyPath string `json:"keyPath,omitempty"` KeyPath string `json:"keyPath,omitempty"`
} }
func (o *HTTPS2HTTPPluginOptions) Complete() { func (o *HTTPS2HTTPPluginOptions) Complete() {
@ -132,13 +133,13 @@ func (o *HTTPS2HTTPPluginOptions) Complete() {
} }
type HTTPS2HTTPSPluginOptions struct { type HTTPS2HTTPSPluginOptions struct {
Type string `json:"type,omitempty"` Type string `json:"type,omitempty"`
LocalAddr string `json:"localAddr,omitempty"` LocalAddr string `json:"localAddr,omitempty"`
HostHeaderRewrite string `json:"hostHeaderRewrite,omitempty"` HostHeaderRewrite string `json:"hostHeaderRewrite,omitempty"`
RequestHeaders HeaderOperations `json:"requestHeaders,omitempty"` RequestHeaders msg.HeaderOperations `json:"requestHeaders,omitempty"`
EnableHTTP2 *bool `json:"enableHTTP2,omitempty"` EnableHTTP2 *bool `json:"enableHTTP2,omitempty"`
CrtPath string `json:"crtPath,omitempty"` CrtPath string `json:"crtPath,omitempty"`
KeyPath string `json:"keyPath,omitempty"` KeyPath string `json:"keyPath,omitempty"`
} }
func (o *HTTPS2HTTPSPluginOptions) Complete() { func (o *HTTPS2HTTPSPluginOptions) Complete() {
@ -146,10 +147,10 @@ func (o *HTTPS2HTTPSPluginOptions) Complete() {
} }
type HTTP2HTTPPluginOptions struct { type HTTP2HTTPPluginOptions struct {
Type string `json:"type,omitempty"` Type string `json:"type,omitempty"`
LocalAddr string `json:"localAddr,omitempty"` LocalAddr string `json:"localAddr,omitempty"`
HostHeaderRewrite string `json:"hostHeaderRewrite,omitempty"` HostHeaderRewrite string `json:"hostHeaderRewrite,omitempty"`
RequestHeaders HeaderOperations `json:"requestHeaders,omitempty"` RequestHeaders msg.HeaderOperations `json:"requestHeaders,omitempty"`
} }
func (o *HTTP2HTTPPluginOptions) Complete() {} func (o *HTTP2HTTPPluginOptions) Complete() {}

View File

@ -19,6 +19,12 @@ import (
"reflect" "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 ( const (
TypeLogin = 'o' TypeLogin = 'o'
TypeLoginResp = '1' TypeLoginResp = '1'
@ -114,15 +120,15 @@ type NewProxy struct {
RemotePort int `json:"remote_port,omitempty"` RemotePort int `json:"remote_port,omitempty"`
// http and https only // http and https only
CustomDomains []string `json:"custom_domains,omitempty"` CustomDomains []string `json:"custom_domains,omitempty"`
SubDomain string `json:"subdomain,omitempty"` SubDomain string `json:"subdomain,omitempty"`
Locations []string `json:"locations,omitempty"` Locations []string `json:"locations,omitempty"`
HTTPUser string `json:"http_user,omitempty"` HTTPUser string `json:"http_user,omitempty"`
HTTPPwd string `json:"http_pwd,omitempty"` HTTPPwd string `json:"http_pwd,omitempty"`
HostHeaderRewrite string `json:"host_header_rewrite,omitempty"` HostHeaderRewrite string `json:"host_header_rewrite,omitempty"`
Headers map[string]string `json:"headers,omitempty"` RequestHeaders HeaderOperations `json:"request_headers,omitempty"`
ResponseHeaders map[string]string `json:"response_headers,omitempty"` ResponseHeaders HeaderOperations `json:"response_headers,omitempty"`
RouteByHTTPUser string `json:"route_by_http_user,omitempty"` RouteByHTTPUser string `json:"route_by_http_user,omitempty"`
// stcp, sudp, xtcp // stcp, sudp, xtcp
Sk string `json:"sk,omitempty"` Sk string `json:"sk,omitempty"`

View File

@ -61,8 +61,8 @@ func NewHTTP2HTTPPlugin(_ PluginContext, options v1.ClientPluginOptions) (Plugin
for k, v := range p.opts.RequestHeaders.Set { for k, v := range p.opts.RequestHeaders.Set {
req.Header.Set(k, v) req.Header.Set(k, v)
} }
for k, _ := range p.opts.RequestHeaders.Delete { for _, v := range p.opts.RequestHeaders.Delete {
req.Header.Del(k) req.Header.Del(v)
} }
}, },
BufferPool: pool.NewBuffer(32 * 1024), BufferPool: pool.NewBuffer(32 * 1024),

View File

@ -69,8 +69,8 @@ func NewHTTP2HTTPSPlugin(_ PluginContext, options v1.ClientPluginOptions) (Plugi
for k, v := range p.opts.RequestHeaders.Set { for k, v := range p.opts.RequestHeaders.Set {
req.Header.Set(k, v) req.Header.Set(k, v)
} }
for k, _ := range p.opts.RequestHeaders.Delete { for _, v := range p.opts.RequestHeaders.Delete {
req.Header.Del(k) req.Header.Del(v)
} }
}, },
Transport: tr, Transport: tr,

View File

@ -68,8 +68,8 @@ func NewHTTPS2HTTPPlugin(_ PluginContext, options v1.ClientPluginOptions) (Plugi
for k, v := range p.opts.RequestHeaders.Set { for k, v := range p.opts.RequestHeaders.Set {
req.Header.Set(k, v) req.Header.Set(k, v)
} }
for k, _ := range p.opts.RequestHeaders.Delete { for _, v := range p.opts.RequestHeaders.Delete {
req.Header.Del(k) req.Header.Del(v)
} }
}, },
BufferPool: pool.NewBuffer(32 * 1024), BufferPool: pool.NewBuffer(32 * 1024),

View File

@ -73,8 +73,8 @@ func NewHTTPS2HTTPSPlugin(_ PluginContext, options v1.ClientPluginOptions) (Plug
for k, v := range p.opts.RequestHeaders.Set { for k, v := range p.opts.RequestHeaders.Set {
req.Header.Set(k, v) req.Header.Set(k, v)
} }
for k, _ := range p.opts.RequestHeaders.Delete { for _, v := range p.opts.RequestHeaders.Delete {
req.Header.Del(k) req.Header.Del(v)
} }
}, },
Transport: tr, Transport: tr,

View File

@ -87,9 +87,14 @@ func NewHTTPReverseProxy(option HTTPReverseProxyOptions, vhostRouter *Routers) *
base64.StdEncoding.EncodeToString([]byte(rc.RouteByHTTPUser)) + "." + base64.StdEncoding.EncodeToString([]byte(rc.RouteByHTTPUser)) + "." +
base64.StdEncoding.EncodeToString([]byte(endpoint)) base64.StdEncoding.EncodeToString([]byte(endpoint))
for k, v := range rc.Headers { for k, v := range rc.RequestHeaders.Set {
req.Header.Set(k, v) req.Header.Set(k, v)
} }
for _, v := range rc.RequestHeaders.Delete {
req.Header.Del(v)
}
} else { } else {
req.URL.Host = req.Host req.URL.Host = req.Host
} }
@ -97,9 +102,13 @@ func NewHTTPReverseProxy(option HTTPReverseProxyOptions, vhostRouter *Routers) *
ModifyResponse: func(r *http.Response) error { ModifyResponse: func(r *http.Response) error {
rc := r.Request.Context().Value(RouteConfigKey).(*RouteConfig) rc := r.Request.Context().Value(RouteConfigKey).(*RouteConfig)
if rc != nil { if rc != nil {
for k, v := range rc.ResponseHeaders { for k, v := range rc.ResponseHeaders.Set {
r.Header.Set(k, v) r.Header.Set(k, v)
} }
for _, v := range rc.ResponseHeaders.Delete {
r.Header.Del(v)
}
} }
return nil return nil
}, },

View File

@ -21,6 +21,7 @@ import (
"github.com/fatedier/golib/errors" "github.com/fatedier/golib/errors"
"github.com/fatedier/frp/pkg/msg"
"github.com/fatedier/frp/pkg/util/log" "github.com/fatedier/frp/pkg/util/log"
netpkg "github.com/fatedier/frp/pkg/util/net" netpkg "github.com/fatedier/frp/pkg/util/net"
"github.com/fatedier/frp/pkg/util/xlog" "github.com/fatedier/frp/pkg/util/xlog"
@ -117,8 +118,8 @@ type RouteConfig struct {
RewriteHost string RewriteHost string
Username string Username string
Password string Password string
Headers map[string]string RequestHeaders msg.HeaderOperations
ResponseHeaders map[string]string ResponseHeaders msg.HeaderOperations
RouteByHTTPUser string RouteByHTTPUser string
CreateConnFn CreateConnFunc CreateConnFn CreateConnFunc

View File

@ -57,8 +57,8 @@ func (pxy *HTTPProxy) Run() (remoteAddr string, err error) {
routeConfig := vhost.RouteConfig{ routeConfig := vhost.RouteConfig{
RewriteHost: pxy.cfg.HostHeaderRewrite, RewriteHost: pxy.cfg.HostHeaderRewrite,
RouteByHTTPUser: pxy.cfg.RouteByHTTPUser, RouteByHTTPUser: pxy.cfg.RouteByHTTPUser,
Headers: pxy.cfg.RequestHeaders.Set, RequestHeaders: pxy.cfg.RequestHeaders,
ResponseHeaders: pxy.cfg.ResponseHeaders.Set, ResponseHeaders: pxy.cfg.ResponseHeaders,
Username: pxy.cfg.HTTPUser, Username: pxy.cfg.HTTPUser,
Password: pxy.cfg.HTTPPassword, Password: pxy.cfg.HTTPPassword,
CreateConnFn: pxy.GetRealConn, CreateConnFn: pxy.GetRealConn,