1
0

headervars.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. package rewrite
  2. import (
  3. "fmt"
  4. "net/http"
  5. "strings"
  6. )
  7. // GetHeaderVariableValuesFromRequest returns a map of header variables and their values
  8. // note that variables behavior is not exactly identical to nginx variables
  9. func GetHeaderVariableValuesFromRequest(r *http.Request) map[string]string {
  10. vars := make(map[string]string)
  11. // Request-specific variables
  12. vars["$host"] = r.Host
  13. vars["$remote_addr"] = r.RemoteAddr
  14. vars["$request_uri"] = r.RequestURI
  15. vars["$request_method"] = r.Method
  16. vars["$content_length"] = fmt.Sprintf("%d", r.ContentLength)
  17. vars["$content_type"] = r.Header.Get("Content-Type")
  18. // Parsed URI elements
  19. vars["$uri"] = r.URL.Path
  20. vars["$args"] = r.URL.RawQuery
  21. vars["$scheme"] = r.URL.Scheme
  22. vars["$query_string"] = r.URL.RawQuery
  23. // User agent and referer
  24. vars["$http_user_agent"] = r.UserAgent()
  25. vars["$http_referer"] = r.Referer()
  26. return vars
  27. }
  28. // CustomHeadersIncludeDynamicVariables checks if the user-defined headers contain dynamic variables
  29. // use for early exit when processing the headers
  30. func CustomHeadersIncludeDynamicVariables(userDefinedHeaders []*UserDefinedHeader) bool {
  31. for _, header := range userDefinedHeaders {
  32. if strings.Contains(header.Value, "$") {
  33. return true
  34. }
  35. }
  36. return false
  37. }
  38. // PopulateRequestHeaderVariables populates the user-defined headers with the values from the request
  39. func PopulateRequestHeaderVariables(r *http.Request, userDefinedHeaders []*UserDefinedHeader) []*UserDefinedHeader {
  40. if !CustomHeadersIncludeDynamicVariables(userDefinedHeaders) {
  41. // Early exit if there are no dynamic variables
  42. return userDefinedHeaders
  43. }
  44. vars := GetHeaderVariableValuesFromRequest(r)
  45. populatedHeaders := []*UserDefinedHeader{}
  46. // Populate the user-defined headers with the values from the request
  47. for _, header := range userDefinedHeaders {
  48. thisHeader := header.Copy()
  49. for key, value := range vars {
  50. thisHeader.Value = strings.ReplaceAll(thisHeader.Value, key, value)
  51. }
  52. populatedHeaders = append(populatedHeaders, thisHeader)
  53. }
  54. return populatedHeaders
  55. }