mirror of
https://github.com/hanzoai/ingress.git
synced 2026-11-02 09:23:31 +00:00
84 lines
2.3 KiB
Go
84 lines
2.3 KiB
Go
package ingressnginx
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"net/url"
|
|
"regexp"
|
|
"strings"
|
|
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
// This the list of supported NGINX variables for interpolation.
|
|
// It is not exhaustive, but covers the most commonly used ones in Ingress NGINX annotations.
|
|
const (
|
|
scheme = "$scheme"
|
|
host = "$host"
|
|
httpHeaders = "$http_"
|
|
hostname = "$hostname"
|
|
requestURI = "$request_uri"
|
|
queryString = "$query_string"
|
|
args = "$args"
|
|
arg = "$arg_"
|
|
remoteAddress = "$remote_addr"
|
|
|
|
// Variables set by ingress-nginx template.
|
|
bestHTTPHost = "$best_http_host"
|
|
escapedRequestURI = "$escaped_request_uri"
|
|
)
|
|
|
|
// varRegexp is a regular expression to match NGINX variables in the form of $variable or $variable_name.
|
|
var varRegexp = regexp.MustCompile(`\$[a-zA-Z_][a-zA-Z0-9_]*`)
|
|
|
|
// ReplaceVariables replaces NGINX variables in the given string with their corresponding values from the HTTP request.
|
|
func ReplaceVariables(str string, req *http.Request) string {
|
|
return varRegexp.ReplaceAllStringFunc(str, func(variable string) string {
|
|
val, err := variableValue(variable, req)
|
|
if err != nil {
|
|
log.Ctx(req.Context()).Debug().Err(err).Msgf("Error replacing variable: %s", variable)
|
|
return variable
|
|
}
|
|
return val
|
|
})
|
|
}
|
|
|
|
// variableValue returns the value of the given NGINX variable based on the HTTP request.
|
|
func variableValue(variable string, req *http.Request) (string, error) {
|
|
// $http_name variables are used to access HTTP headers in the request.
|
|
if header, ok := strings.CutPrefix(variable, httpHeaders); ok {
|
|
return strings.Join(req.Header.Values(strings.ReplaceAll(header, "_", "-")), ","), nil
|
|
}
|
|
|
|
// $arg_name variables are used to access query parameters in the request URL.
|
|
if arg, ok := strings.CutPrefix(variable, arg); ok {
|
|
return req.URL.Query().Get(arg), nil
|
|
}
|
|
|
|
switch variable {
|
|
case host, hostname, bestHTTPHost:
|
|
return req.Host, nil
|
|
|
|
case requestURI:
|
|
return req.URL.RequestURI(), nil
|
|
|
|
case escapedRequestURI:
|
|
return url.QueryEscape(req.URL.RequestURI()), nil
|
|
|
|
case scheme:
|
|
if req.TLS != nil {
|
|
return "https", nil
|
|
}
|
|
return "http", nil
|
|
|
|
case args, queryString:
|
|
return req.URL.Query().Encode(), nil
|
|
|
|
case remoteAddress:
|
|
return req.RemoteAddr, nil
|
|
|
|
default:
|
|
return "", fmt.Errorf("unsupported variable: %s", variable)
|
|
}
|
|
}
|