github.com/hellofresh/janus@v0.0.0-20230925145208-ce8de8183c67/pkg/plugin/requesttransformer/middleware.go (about) 1 package requesttransformer 2 3 import ( 4 "net/http" 5 "net/url" 6 ) 7 8 type headerFn func(headerName string, headerValue string) 9 10 // Options represents the available options to transform 11 type Options struct { 12 Headers map[string]string `json:"headers"` 13 QueryString map[string]string `json:"querystring"` 14 } 15 16 // Config represent the configuration of the modify headers middleware 17 type Config struct { 18 Add Options `json:"add"` 19 Append Options `json:"append"` 20 Remove Options `json:"remove"` 21 Replace Options `json:"replace"` 22 } 23 24 // NewRequestTransformer creates a new instance of RequestTransformer 25 func NewRequestTransformer(config Config) func(http.Handler) http.Handler { 26 return func(next http.Handler) http.Handler { 27 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 28 query := r.URL.Query() 29 30 transform(config.Remove.Headers, removeHeaders(r)) 31 transform(config.Remove.QueryString, removeQueryString(query)) 32 33 transform(config.Replace.Headers, replaceHeaders(r)) 34 transform(config.Replace.QueryString, replaceQueryString(query)) 35 36 transform(config.Add.Headers, addHeaders(r)) 37 transform(config.Add.QueryString, addQueryString(query)) 38 39 transform(config.Append.Headers, appendHeaders(r)) 40 transform(config.Append.QueryString, appendQueryString(query)) 41 42 r.URL.RawQuery = query.Encode() 43 44 next.ServeHTTP(w, r) 45 }) 46 } 47 } 48 49 // If and only if the header is not already set, set a new header with the given value. Ignored if the header is already set. 50 func addHeaders(r *http.Request) headerFn { 51 return func(headerName string, headerValue string) { 52 if r.Header.Get(headerName) == "" { 53 r.Header.Add(headerName, headerValue) 54 } 55 } 56 } 57 58 // If the header is not set, set it with the given value. If it is already set, a new header with the same name and the new value will be set. 59 func appendHeaders(r *http.Request) headerFn { 60 return func(headerName string, headerValue string) { 61 r.Header.Add(headerName, headerValue) 62 } 63 } 64 65 // Unset the headers with the given name. 66 func removeHeaders(r *http.Request) headerFn { 67 return func(headerName string, headerValue string) { 68 r.Header.Del(headerName) 69 } 70 } 71 72 // If and only if the header is already set, replace its old value with the new one. Ignored if the header is not already set. 73 func replaceHeaders(r *http.Request) headerFn { 74 return func(headerName string, headerValue string) { 75 if r.Header.Get(headerName) != "" { 76 r.Header.Set(headerName, headerValue) 77 } 78 } 79 } 80 81 func transform(values map[string]string, fn headerFn) { 82 if len(values) <= 0 { 83 return 84 } 85 86 for name, value := range values { 87 fn(name, value) 88 } 89 } 90 91 func addQueryString(query url.Values) headerFn { 92 return func(name string, value string) { 93 if query.Get(name) == "" { 94 query.Add(name, value) 95 } 96 } 97 } 98 99 func appendQueryString(query url.Values) headerFn { 100 return func(name string, value string) { 101 query.Add(name, value) 102 } 103 } 104 105 func removeQueryString(query url.Values) headerFn { 106 return func(name string, value string) { 107 query.Del(name) 108 } 109 } 110 111 func replaceQueryString(query url.Values) headerFn { 112 return func(name string, value string) { 113 if query.Get(name) != "" { 114 query.Set(name, value) 115 } 116 } 117 }