github.com/msales/pkg/v3@v3.24.0/httpx/middleware/query_transformer.go (about)

     1  package middleware
     2  
     3  import (
     4  	"net/http"
     5  	"net/url"
     6  )
     7  
     8  // StringTransformerFunc represents a function that transforms a string into another string.
     9  type StringTransformerFunc func(string) string
    10  
    11  type transformationRule struct {
    12  	keys []string
    13  	fn   StringTransformerFunc
    14  }
    15  
    16  // QueryTransformer transforms query parameters with the registered functions.
    17  type QueryTransformer struct {
    18  	rules []transformationRule
    19  }
    20  
    21  // Register registers a function as a transformer for the given set of keys.
    22  func (t *QueryTransformer) Register(keys []string, fn StringTransformerFunc) {
    23  	t.rules = append(t.rules, transformationRule{keys: keys, fn: fn})
    24  }
    25  
    26  // WithQueryTransformer returns an http handler that transforms query parameters using the passed transformer.
    27  func WithQueryTransformer(h http.Handler, t QueryTransformer) http.HandlerFunc {
    28  	return func(w http.ResponseWriter, req *http.Request) {
    29  		values := req.URL.Query()
    30  
    31  		for _, rule := range t.rules {
    32  			transformKeys(values, rule.keys, rule.fn)
    33  		}
    34  
    35  		req.URL.RawQuery = values.Encode()
    36  
    37  		h.ServeHTTP(w, req)
    38  	}
    39  }
    40  
    41  // WithQueryTransformerFunc returns an http handler that transforms query parameters using the passed function.
    42  func WithQueryTransformerFunc(h http.Handler, keys []string, fn StringTransformerFunc) http.Handler {
    43  	if len(keys) == 0 {
    44  		return h
    45  	}
    46  
    47  	return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
    48  		values := req.URL.Query()
    49  
    50  		transformKeys(values, keys, fn)
    51  
    52  		req.URL.RawQuery = values.Encode()
    53  
    54  		h.ServeHTTP(w, req)
    55  	})
    56  }
    57  
    58  func transformKeys(values url.Values, keys []string, fn StringTransformerFunc) {
    59  	for _, key := range keys {
    60  		vs := values[key]
    61  		transformed := make([]string, len(vs))
    62  
    63  		for j, v := range vs {
    64  			transformed[j] = fn(v)
    65  		}
    66  
    67  		values[key] = transformed
    68  	}
    69  }