mirror of
https://github.com/tobychui/zoraxy.git
synced 2025-08-07 05:38:30 +02:00
Added support for custom header variables
- Added support for using nginx-like variables in custom headers - Supported variables includes: $host, $remote_addr, $request_uri, $request_method, $content_length, $content_type, $uri, $args, $scheme, $query_string, $http_user_agent and $http_referer - Added test case for custom header variable rewriter
This commit is contained in:
63
src/mod/dynamicproxy/rewrite/headervars.go
Normal file
63
src/mod/dynamicproxy/rewrite/headervars.go
Normal file
@@ -0,0 +1,63 @@
|
||||
package rewrite
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// GetHeaderVariableValuesFromRequest returns a map of header variables and their values
|
||||
// note that variables behavior is not exactly identical to nginx variables
|
||||
func GetHeaderVariableValuesFromRequest(r *http.Request) map[string]string {
|
||||
vars := make(map[string]string)
|
||||
|
||||
// Request-specific variables
|
||||
vars["$host"] = r.Host
|
||||
vars["$remote_addr"] = r.RemoteAddr
|
||||
vars["$request_uri"] = r.RequestURI
|
||||
vars["$request_method"] = r.Method
|
||||
vars["$content_length"] = fmt.Sprintf("%d", r.ContentLength)
|
||||
vars["$content_type"] = r.Header.Get("Content-Type")
|
||||
|
||||
// Parsed URI elements
|
||||
vars["$uri"] = r.URL.Path
|
||||
vars["$args"] = r.URL.RawQuery
|
||||
vars["$scheme"] = r.URL.Scheme
|
||||
vars["$query_string"] = r.URL.RawQuery
|
||||
|
||||
// User agent and referer
|
||||
vars["$http_user_agent"] = r.UserAgent()
|
||||
vars["$http_referer"] = r.Referer()
|
||||
|
||||
return vars
|
||||
}
|
||||
|
||||
// CustomHeadersIncludeDynamicVariables checks if the user-defined headers contain dynamic variables
|
||||
// use for early exit when processing the headers
|
||||
func CustomHeadersIncludeDynamicVariables(userDefinedHeaders []*UserDefinedHeader) bool {
|
||||
for _, header := range userDefinedHeaders {
|
||||
if strings.Contains(header.Value, "$") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// PopulateRequestHeaderVariables populates the user-defined headers with the values from the request
|
||||
func PopulateRequestHeaderVariables(r *http.Request, userDefinedHeaders []*UserDefinedHeader) []*UserDefinedHeader {
|
||||
if !CustomHeadersIncludeDynamicVariables(userDefinedHeaders) {
|
||||
// Early exit if there are no dynamic variables
|
||||
return userDefinedHeaders
|
||||
}
|
||||
vars := GetHeaderVariableValuesFromRequest(r)
|
||||
populatedHeaders := []*UserDefinedHeader{}
|
||||
// Populate the user-defined headers with the values from the request
|
||||
for _, header := range userDefinedHeaders {
|
||||
thisHeader := header.Copy()
|
||||
for key, value := range vars {
|
||||
thisHeader.Value = strings.ReplaceAll(thisHeader.Value, key, value)
|
||||
}
|
||||
populatedHeaders = append(populatedHeaders, thisHeader)
|
||||
}
|
||||
return populatedHeaders
|
||||
}
|
Reference in New Issue
Block a user