fix: address PR review for replacer — nil check, EscapedPath, scheme reuse, perf

- add req.URL nil guard
- use EscapedPath for {path} to avoid illegal header characters
- reuse reverseProxyRequestScheme for {scheme} consistency
- replace strings.NewReplacer with struct fields + strings.ReplaceAll
This commit is contained in:
wjqserver 2026-04-21 18:02:57 +08:00
parent fa925582d7
commit 1243d2d37a

View file

@ -264,32 +264,26 @@ func (ops *HeaderOps) Provision() error {
}
type reverseProxyReplacer struct {
req *http.Request
repl *strings.Replacer
method, host, path, query, scheme, uri, proto string
}
func newReverseProxyReplacer(req *http.Request) *reverseProxyReplacer {
r := &reverseProxyReplacer{req: req}
if req != nil {
uri := req.RequestURI
if uri == "" {
uri = req.URL.RequestURI()
}
scheme := "http"
if req.TLS != nil {
scheme = "https"
}
r.repl = strings.NewReplacer(
"{method}", req.Method,
"{host}", req.Host,
"{path}", req.URL.Path,
"{query}", req.URL.RawQuery,
"{scheme}", scheme,
"{uri}", uri,
"{proto}", req.Proto,
)
if req == nil || req.URL == nil {
return &reverseProxyReplacer{}
}
uri := req.RequestURI
if uri == "" {
uri = req.URL.RequestURI()
}
return &reverseProxyReplacer{
method: req.Method,
host: req.Host,
path: req.URL.EscapedPath(),
query: req.URL.RawQuery,
scheme: reverseProxyRequestScheme(req),
uri: uri,
proto: req.Proto,
}
return r
}
func newReverseProxyReplacerFromHeader(hdr http.Header) *reverseProxyReplacer {
@ -300,10 +294,28 @@ func (r *reverseProxyReplacer) Replace(s string) string {
if r == nil || s == "" {
return s
}
if r.repl == nil {
return s
if r.method != "" {
s = strings.ReplaceAll(s, "{method}", r.method)
}
return r.repl.Replace(s)
if r.host != "" {
s = strings.ReplaceAll(s, "{host}", r.host)
}
if r.path != "" {
s = strings.ReplaceAll(s, "{path}", r.path)
}
if r.query != "" {
s = strings.ReplaceAll(s, "{query}", r.query)
}
if r.scheme != "" {
s = strings.ReplaceAll(s, "{scheme}", r.scheme)
}
if r.uri != "" {
s = strings.ReplaceAll(s, "{uri}", r.uri)
}
if r.proto != "" {
s = strings.ReplaceAll(s, "{proto}", r.proto)
}
return s
}
type reverseProxyHandler struct {