VictoriaMetrics/app/vmauth/target_url.go

58 lines
1.4 KiB
Go
Raw Normal View History

package main
import (
"fmt"
"net/url"
"path"
"strings"
)
func mergeURLs(uiURL string, requestURI *url.URL) (string, error) {
prefixURL, err := url.Parse(uiURL)
if err != nil {
return "", fmt.Errorf("BUG - cannot parse userInfo url: %q, err: %w", uiURL, err)
}
prefixURL.Path += requestURI.Path
requestParams := requestURI.Query()
// fast path
if len(requestParams) == 0 {
return prefixURL.String(), nil
}
// merge query parameters from requests.
userInfoParams := prefixURL.Query()
for k, v := range requestParams {
// skip clashed query params from original request
if exist := userInfoParams.Get(k); len(exist) > 0 {
continue
}
for i := range v {
userInfoParams.Add(k, v[i])
}
}
prefixURL.RawQuery = userInfoParams.Encode()
return prefixURL.String(), nil
}
func createTargetURL(ui *UserInfo, uOrig *url.URL) (string, error) {
u, err := url.Parse(uOrig.String())
if err != nil {
return "", fmt.Errorf("cannot make a copy of %q: %w", u, err)
}
// Prevent from attacks with using `..` in r.URL.Path
u.Path = path.Clean(u.Path)
if !strings.HasPrefix(u.Path, "/") {
u.Path = "/" + u.Path
}
for _, e := range ui.URLMap {
for _, sp := range e.SrcPaths {
if sp.match(u.Path) {
return mergeURLs(e.URLPrefix, u)
}
}
}
if len(ui.URLPrefix) > 0 {
return mergeURLs(ui.URLPrefix, u)
}
return "", fmt.Errorf("missing route for %q", u)
}