2020-05-07 09:36:32 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2021-10-22 16:08:06 +00:00
|
|
|
"fmt"
|
2020-05-07 09:36:32 +00:00
|
|
|
"net/url"
|
|
|
|
"testing"
|
|
|
|
)
|
|
|
|
|
2021-02-11 10:40:59 +00:00
|
|
|
func TestCreateTargetURLSuccess(t *testing.T) {
|
2021-10-22 16:08:06 +00:00
|
|
|
f := func(ui *UserInfo, requestURI, expectedTarget, expectedHeaders string) {
|
2020-05-07 09:36:32 +00:00
|
|
|
t.Helper()
|
|
|
|
u, err := url.Parse(requestURI)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("cannot parse %q: %s", requestURI, err)
|
|
|
|
}
|
2021-10-22 16:08:06 +00:00
|
|
|
target, headers, err := createTargetURL(ui, u)
|
2021-02-11 10:40:59 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error: %s", err)
|
|
|
|
}
|
2021-04-21 07:55:29 +00:00
|
|
|
if target.String() != expectedTarget {
|
2020-05-07 09:36:32 +00:00
|
|
|
t.Fatalf("unexpected target; got %q; want %q", target, expectedTarget)
|
|
|
|
}
|
2021-10-22 16:08:06 +00:00
|
|
|
headersStr := fmt.Sprintf("%q", headers)
|
|
|
|
if headersStr != expectedHeaders {
|
|
|
|
t.Fatalf("unexpected headers; got %s; want %s", headersStr, expectedHeaders)
|
|
|
|
}
|
2020-05-07 09:36:32 +00:00
|
|
|
}
|
2021-02-11 10:40:59 +00:00
|
|
|
// Simple routing with `url_prefix`
|
|
|
|
f(&UserInfo{
|
2021-04-21 07:55:29 +00:00
|
|
|
URLPrefix: mustParseURL("http://foo.bar"),
|
2021-10-22 16:08:06 +00:00
|
|
|
}, "", "http://foo.bar/.", "[]")
|
2021-02-11 10:40:59 +00:00
|
|
|
f(&UserInfo{
|
2021-04-21 07:55:29 +00:00
|
|
|
URLPrefix: mustParseURL("http://foo.bar"),
|
2021-10-22 16:08:06 +00:00
|
|
|
Headers: []Header{{
|
|
|
|
Name: "bb",
|
|
|
|
Value: "aaa",
|
|
|
|
}},
|
|
|
|
}, "/", "http://foo.bar", `[{"bb" "aaa"}]`)
|
2021-08-25 10:28:50 +00:00
|
|
|
f(&UserInfo{
|
|
|
|
URLPrefix: mustParseURL("http://foo.bar/federate"),
|
2021-10-22 16:08:06 +00:00
|
|
|
}, "/", "http://foo.bar/federate", "[]")
|
2021-02-11 10:40:59 +00:00
|
|
|
f(&UserInfo{
|
2021-04-21 07:55:29 +00:00
|
|
|
URLPrefix: mustParseURL("http://foo.bar"),
|
2021-10-22 16:08:06 +00:00
|
|
|
}, "a/b?c=d", "http://foo.bar/a/b?c=d", "[]")
|
2021-02-11 10:40:59 +00:00
|
|
|
f(&UserInfo{
|
2021-04-21 07:55:29 +00:00
|
|
|
URLPrefix: mustParseURL("https://sss:3894/x/y"),
|
2021-10-22 16:08:06 +00:00
|
|
|
}, "/z", "https://sss:3894/x/y/z", "[]")
|
2021-02-11 10:40:59 +00:00
|
|
|
f(&UserInfo{
|
2021-04-21 07:55:29 +00:00
|
|
|
URLPrefix: mustParseURL("https://sss:3894/x/y"),
|
2021-10-22 16:08:06 +00:00
|
|
|
}, "/../../aaa", "https://sss:3894/x/y/aaa", "[]")
|
2021-02-11 10:40:59 +00:00
|
|
|
f(&UserInfo{
|
2021-04-21 07:55:29 +00:00
|
|
|
URLPrefix: mustParseURL("https://sss:3894/x/y"),
|
2021-10-22 16:08:06 +00:00
|
|
|
}, "/./asd/../../aaa?a=d&s=s/../d", "https://sss:3894/x/y/aaa?a=d&s=s%2F..%2Fd", "[]")
|
2021-02-11 10:40:59 +00:00
|
|
|
|
|
|
|
// Complex routing with `url_map`
|
|
|
|
ui := &UserInfo{
|
|
|
|
URLMap: []URLMap{
|
|
|
|
{
|
2021-03-05 16:21:11 +00:00
|
|
|
SrcPaths: getSrcPaths([]string{"/api/v1/query"}),
|
2021-04-21 07:55:29 +00:00
|
|
|
URLPrefix: mustParseURL("http://vmselect/0/prometheus"),
|
2021-10-22 16:08:06 +00:00
|
|
|
Headers: []Header{
|
|
|
|
{
|
|
|
|
Name: "xx",
|
|
|
|
Value: "aa",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "yy",
|
|
|
|
Value: "asdf",
|
|
|
|
},
|
|
|
|
},
|
2021-02-11 10:40:59 +00:00
|
|
|
},
|
|
|
|
{
|
2021-03-05 16:21:11 +00:00
|
|
|
SrcPaths: getSrcPaths([]string{"/api/v1/write"}),
|
2021-04-21 07:55:29 +00:00
|
|
|
URLPrefix: mustParseURL("http://vminsert/0/prometheus"),
|
2021-02-11 10:40:59 +00:00
|
|
|
},
|
|
|
|
},
|
2021-04-21 07:55:29 +00:00
|
|
|
URLPrefix: mustParseURL("http://default-server"),
|
2021-10-22 16:08:06 +00:00
|
|
|
Headers: []Header{{
|
|
|
|
Name: "bb",
|
|
|
|
Value: "aaa",
|
|
|
|
}},
|
2021-02-11 10:40:59 +00:00
|
|
|
}
|
2021-10-22 16:08:06 +00:00
|
|
|
f(ui, "/api/v1/query?query=up", "http://vmselect/0/prometheus/api/v1/query?query=up", `[{"xx" "aa"} {"yy" "asdf"}]`)
|
|
|
|
f(ui, "/api/v1/write", "http://vminsert/0/prometheus/api/v1/write", "[]")
|
|
|
|
f(ui, "/api/v1/query_range", "http://default-server/api/v1/query_range", `[{"bb" "aaa"}]`)
|
2021-03-05 16:21:11 +00:00
|
|
|
|
|
|
|
// Complex routing regexp paths in `url_map`
|
|
|
|
ui = &UserInfo{
|
|
|
|
URLMap: []URLMap{
|
|
|
|
{
|
|
|
|
SrcPaths: getSrcPaths([]string{"/api/v1/query(_range)?", "/api/v1/label/[^/]+/values"}),
|
2021-04-21 07:55:29 +00:00
|
|
|
URLPrefix: mustParseURL("http://vmselect/0/prometheus"),
|
2021-03-05 16:21:11 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
SrcPaths: getSrcPaths([]string{"/api/v1/write"}),
|
2021-04-21 07:55:29 +00:00
|
|
|
URLPrefix: mustParseURL("http://vminsert/0/prometheus"),
|
2021-03-05 16:21:11 +00:00
|
|
|
},
|
|
|
|
},
|
2021-04-21 07:55:29 +00:00
|
|
|
URLPrefix: mustParseURL("http://default-server"),
|
2021-03-05 16:21:11 +00:00
|
|
|
}
|
2021-10-22 16:08:06 +00:00
|
|
|
f(ui, "/api/v1/query?query=up", "http://vmselect/0/prometheus/api/v1/query?query=up", "[]")
|
|
|
|
f(ui, "/api/v1/query_range?query=up", "http://vmselect/0/prometheus/api/v1/query_range?query=up", "[]")
|
|
|
|
f(ui, "/api/v1/label/foo/values", "http://vmselect/0/prometheus/api/v1/label/foo/values", "[]")
|
|
|
|
f(ui, "/api/v1/write", "http://vminsert/0/prometheus/api/v1/write", "[]")
|
|
|
|
f(ui, "/api/v1/foo/bar", "http://default-server/api/v1/foo/bar", "[]")
|
2021-04-20 07:51:03 +00:00
|
|
|
f(&UserInfo{
|
2021-04-21 07:55:29 +00:00
|
|
|
URLPrefix: mustParseURL("http://foo.bar?extra_label=team=dev"),
|
2021-10-22 16:08:06 +00:00
|
|
|
}, "/api/v1/query", "http://foo.bar/api/v1/query?extra_label=team=dev", "[]")
|
2021-04-20 07:51:03 +00:00
|
|
|
f(&UserInfo{
|
2021-04-21 07:55:29 +00:00
|
|
|
URLPrefix: mustParseURL("http://foo.bar?extra_label=team=mobile"),
|
2021-10-22 16:08:06 +00:00
|
|
|
}, "/api/v1/query?extra_label=team=dev", "http://foo.bar/api/v1/query?extra_label=team%3Dmobile", "[]")
|
2021-04-20 07:51:03 +00:00
|
|
|
|
2021-02-11 10:40:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestCreateTargetURLFailure(t *testing.T) {
|
|
|
|
f := func(ui *UserInfo, requestURI string) {
|
|
|
|
t.Helper()
|
|
|
|
u, err := url.Parse(requestURI)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("cannot parse %q: %s", requestURI, err)
|
|
|
|
}
|
2021-10-22 16:08:06 +00:00
|
|
|
target, headers, err := createTargetURL(ui, u)
|
2021-02-11 10:40:59 +00:00
|
|
|
if err == nil {
|
|
|
|
t.Fatalf("expecting non-nil error")
|
|
|
|
}
|
2021-04-21 07:55:29 +00:00
|
|
|
if target != nil {
|
2021-02-11 10:40:59 +00:00
|
|
|
t.Fatalf("unexpected target=%q; want empty string", target)
|
|
|
|
}
|
2021-10-22 16:08:06 +00:00
|
|
|
if headers != nil {
|
|
|
|
t.Fatalf("unexpected headers=%q; want empty string", headers)
|
|
|
|
}
|
2021-02-11 10:40:59 +00:00
|
|
|
}
|
|
|
|
f(&UserInfo{}, "/foo/bar")
|
|
|
|
f(&UserInfo{
|
|
|
|
URLMap: []URLMap{
|
|
|
|
{
|
2021-03-05 16:21:11 +00:00
|
|
|
SrcPaths: getSrcPaths([]string{"/api/v1/query"}),
|
2021-04-21 07:55:29 +00:00
|
|
|
URLPrefix: mustParseURL("http://foobar/baz"),
|
2021-02-11 10:40:59 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
}, "/api/v1/write")
|
2020-05-07 09:36:32 +00:00
|
|
|
}
|