http: support setting headers

This commit is contained in:
fatedier 2018-05-20 23:22:07 +08:00
parent 0c35273759
commit db2d1fce76
6 changed files with 56 additions and 17 deletions

View File

@ -56,10 +56,10 @@ dns_server = 8.8.8.8
# heartbeat_interval = 30 # heartbeat_interval = 30
# heartbeat_timeout = 90 # heartbeat_timeout = 90
# ssh is the proxy name same as server's configuration # 'ssh' is the unique proxy name
# if user in [common] section is not empty, it will be changed to {user}.{proxy} such as your_name.ssh # if user in [common] section is not empty, it will be changed to {user}.{proxy} such as 'your_name.ssh'
[ssh] [ssh]
# tcp | udp | http | https, default is tcp # tcp | udp | http | https | stcp | xtcp, default is tcp
type = tcp type = tcp
local_ip = 127.0.0.1 local_ip = 127.0.0.1
local_port = 22 local_port = 22
@ -120,6 +120,8 @@ custom_domains = web02.yourdomain.com
# locations is only available for http type # locations is only available for http type
locations = /,/pic locations = /,/pic
host_header_rewrite = example.com host_header_rewrite = example.com
# params with prefix "header_" will be used to update http request headers
header_X-From-Where = frp
[web02] [web02]
type = https type = https
@ -136,7 +138,7 @@ remote_port = 6003
# if plugin is defined, local_ip and local_port is useless # if plugin is defined, local_ip and local_port is useless
# plugin will handle connections got from frps # plugin will handle connections got from frps
plugin = unix_domain_socket plugin = unix_domain_socket
# params set with prefix "plugin_" that plugin needed # params with prefix "plugin_" that plugin needed
plugin_unix_path = /var/run/docker.sock plugin_unix_path = /var/run/docker.sock
[plugin_http_proxy] [plugin_http_proxy]

View File

@ -430,9 +430,10 @@ type HttpProxyConf struct {
LocalSvrConf LocalSvrConf
Locations []string `json:"locations"` Locations []string `json:"locations"`
HostHeaderRewrite string `json:"host_header_rewrite"`
HttpUser string `json:"http_user"` HttpUser string `json:"http_user"`
HttpPwd string `json:"http_pwd"` HttpPwd string `json:"http_pwd"`
HostHeaderRewrite string `json:"host_header_rewrite"`
Headers map[string]string `json:"headers"`
} }
func (cfg *HttpProxyConf) Compare(cmp ProxyConf) bool { func (cfg *HttpProxyConf) Compare(cmp ProxyConf) bool {
@ -447,9 +448,20 @@ func (cfg *HttpProxyConf) Compare(cmp ProxyConf) bool {
strings.Join(cfg.Locations, " ") != strings.Join(cmpConf.Locations, " ") || strings.Join(cfg.Locations, " ") != strings.Join(cmpConf.Locations, " ") ||
cfg.HostHeaderRewrite != cmpConf.HostHeaderRewrite || cfg.HostHeaderRewrite != cmpConf.HostHeaderRewrite ||
cfg.HttpUser != cmpConf.HttpUser || cfg.HttpUser != cmpConf.HttpUser ||
cfg.HttpPwd != cmpConf.HttpPwd { cfg.HttpPwd != cmpConf.HttpPwd ||
len(cfg.Headers) != len(cmpConf.Headers) {
return false return false
} }
for k, v := range cfg.Headers {
if v2, ok := cmpConf.Headers[k]; !ok {
return false
} else {
if v != v2 {
return false
}
}
}
return true return true
} }
@ -461,6 +473,7 @@ func (cfg *HttpProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
cfg.HostHeaderRewrite = pMsg.HostHeaderRewrite cfg.HostHeaderRewrite = pMsg.HostHeaderRewrite
cfg.HttpUser = pMsg.HttpUser cfg.HttpUser = pMsg.HttpUser
cfg.HttpPwd = pMsg.HttpPwd cfg.HttpPwd = pMsg.HttpPwd
cfg.Headers = pMsg.Headers
} }
func (cfg *HttpProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) { func (cfg *HttpProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
@ -487,6 +500,13 @@ func (cfg *HttpProxyConf) UnmarshalFromIni(prefix string, name string, section i
cfg.HostHeaderRewrite = section["host_header_rewrite"] cfg.HostHeaderRewrite = section["host_header_rewrite"]
cfg.HttpUser = section["http_user"] cfg.HttpUser = section["http_user"]
cfg.HttpPwd = section["http_pwd"] cfg.HttpPwd = section["http_pwd"]
cfg.Headers = make(map[string]string)
for k, v := range section {
if strings.HasPrefix(k, "header_") {
cfg.Headers[strings.TrimPrefix(k, "header_")] = v
}
}
return return
} }
@ -498,6 +518,7 @@ func (cfg *HttpProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
pMsg.HostHeaderRewrite = cfg.HostHeaderRewrite pMsg.HostHeaderRewrite = cfg.HostHeaderRewrite
pMsg.HttpUser = cfg.HttpUser pMsg.HttpUser = cfg.HttpUser
pMsg.HttpPwd = cfg.HttpPwd pMsg.HttpPwd = cfg.HttpPwd
pMsg.Headers = cfg.Headers
} }
func (cfg *HttpProxyConf) CheckForCli() (err error) { func (cfg *HttpProxyConf) CheckForCli() (err error) {

View File

@ -94,9 +94,10 @@ type NewProxy struct {
CustomDomains []string `json:"custom_domains"` CustomDomains []string `json:"custom_domains"`
SubDomain string `json:"subdomain"` SubDomain string `json:"subdomain"`
Locations []string `json:"locations"` Locations []string `json:"locations"`
HostHeaderRewrite string `json:"host_header_rewrite"`
HttpUser string `json:"http_user"` HttpUser string `json:"http_user"`
HttpPwd string `json:"http_pwd"` HttpPwd string `json:"http_pwd"`
HostHeaderRewrite string `json:"host_header_rewrite"`
Headers map[string]string `json:"headers"`
// stcp // stcp
Sk string `json:"sk"` Sk string `json:"sk"`

View File

@ -225,6 +225,7 @@ type HttpProxy struct {
func (pxy *HttpProxy) Run() (remoteAddr string, err error) { func (pxy *HttpProxy) Run() (remoteAddr string, err error) {
routeConfig := vhost.VhostRouteConfig{ routeConfig := vhost.VhostRouteConfig{
RewriteHost: pxy.cfg.HostHeaderRewrite, RewriteHost: pxy.cfg.HostHeaderRewrite,
Headers: pxy.cfg.Headers,
Username: pxy.cfg.HttpUser, Username: pxy.cfg.HttpUser,
Password: pxy.cfg.HttpPwd, Password: pxy.cfg.HttpPwd,
CreateConnFn: pxy.GetRealConn, CreateConnFn: pxy.GetRealConn,

View File

@ -63,12 +63,17 @@ func NewHttpReverseProxy() *HttpReverseProxy {
Director: func(req *http.Request) { Director: func(req *http.Request) {
req.URL.Scheme = "http" req.URL.Scheme = "http"
url := req.Context().Value("url").(string) url := req.Context().Value("url").(string)
host := getHostFromAddr(req.Context().Value("host").(string)) oldHost := getHostFromAddr(req.Context().Value("host").(string))
host = rp.GetRealHost(host, url) host := rp.GetRealHost(oldHost, url)
if host != "" { if host != "" {
req.Host = host req.Host = host
} }
req.URL.Host = req.Host req.URL.Host = req.Host
headers := rp.GetHeaders(oldHost, url)
for k, v := range headers {
req.Header.Set(k, v)
}
}, },
Transport: &http.Transport{ Transport: &http.Transport{
ResponseHeaderTimeout: responseHeaderTimeout, ResponseHeaderTimeout: responseHeaderTimeout,
@ -117,6 +122,14 @@ func (rp *HttpReverseProxy) GetRealHost(domain string, location string) (host st
return return
} }
func (rp *HttpReverseProxy) GetHeaders(domain string, location string) (headers map[string]string) {
vr, ok := rp.getVhost(domain, location)
if ok {
headers = vr.payload.(*VhostRouteConfig).Headers
}
return
}
func (rp *HttpReverseProxy) CreateConnection(domain string, location string) (net.Conn, error) { func (rp *HttpReverseProxy) CreateConnection(domain string, location string) (net.Conn, error) {
vr, ok := rp.getVhost(domain, location) vr, ok := rp.getVhost(domain, location)
if ok { if ok {

View File

@ -59,6 +59,7 @@ type VhostRouteConfig struct {
RewriteHost string RewriteHost string
Username string Username string
Password string Password string
Headers map[string]string
CreateConnFn CreateConnFunc CreateConnFn CreateConnFunc
} }