1597 lines
49 KiB
Go
1597 lines
49 KiB
Go
package treerack
|
|
|
|
import (
|
|
"bytes"
|
|
"code.squareroundforest.org/arpio/notation"
|
|
"net/url"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
type urlCheck struct {
|
|
stdQuery func(u *url.URL) string
|
|
treerackQuery func(Node) string
|
|
expect string
|
|
}
|
|
|
|
type urlTestCase struct {
|
|
title string
|
|
input string
|
|
checks []urlCheck
|
|
bench int
|
|
skipSTD bool
|
|
skipSTDReq bool
|
|
}
|
|
|
|
func queryTreerack(p ...string) func(Node) string {
|
|
return func(a Node) string {
|
|
return astPath(a, p...)
|
|
}
|
|
}
|
|
|
|
func fakeSTDCheck(v string) func(*url.URL) string {
|
|
return func(*url.URL) string {
|
|
return v
|
|
}
|
|
}
|
|
|
|
func fakeTRCheck(v string) func(Node) string {
|
|
return func(Node) string {
|
|
return v
|
|
}
|
|
}
|
|
|
|
func printURLTree(t *testing.T, a Node) {
|
|
var trimTokens func(a Node) Node
|
|
trimTokens = func(a Node) Node {
|
|
for i := range a.Nodes {
|
|
a.Nodes[i] = trimTokens(a.Nodes[i])
|
|
}
|
|
|
|
a.tokens = nil
|
|
return a
|
|
}
|
|
|
|
a = trimTokens(a)
|
|
notation.Lprintw(t, a)
|
|
}
|
|
|
|
func urlParser(trace bool) func(string) (Node, error) {
|
|
b, err := os.ReadFile("doc/example/url.treerack")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
p := new(Syntax)
|
|
if trace {
|
|
p.MaxTraceLength = 180
|
|
}
|
|
|
|
if err = p.ReadSyntax(bytes.NewBuffer(b)); err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return func(s string) (a Node, err error) {
|
|
return p.Parse(bytes.NewBufferString(s))
|
|
}
|
|
}
|
|
|
|
func astPath(a Node, p ...string) string {
|
|
if len(p) == 0 {
|
|
return a.Text()
|
|
}
|
|
|
|
for _, ai := range a.Nodes {
|
|
if ai.Name == p[0] {
|
|
return astPath(ai, p[1:]...)
|
|
}
|
|
}
|
|
|
|
return ""
|
|
}
|
|
|
|
func TestURL(t *testing.T) {
|
|
for _, test := range []urlTestCase{{
|
|
|
|
title: "scheme only",
|
|
input: "http:",
|
|
bench: 3600,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme only with separator",
|
|
input: "http://",
|
|
bench: 3600,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url-rfc", "scheme"),
|
|
expect: "http",
|
|
}},
|
|
}, {
|
|
|
|
title: "user and passord only",
|
|
input: "//foo:bar@",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("relative-url-rfc", "userinfo"),
|
|
expect: "foo:bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "user only",
|
|
input: "//foo@",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("relative-url-rfc", "userinfo"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "host only",
|
|
input: "//foo.bar",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("relative-url", "hostname"),
|
|
expect: "foo.bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "host only with port",
|
|
input: "//foo.bar:8080",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: fakeTRCheck("foo.bar:8080"),
|
|
expect: "foo.bar:8080",
|
|
}, {
|
|
stdQuery: fakeSTDCheck("foo.bar"),
|
|
treerackQuery: queryTreerack("relative-url", "hostname"),
|
|
expect: "foo.bar",
|
|
}, {
|
|
stdQuery: fakeSTDCheck("8080"),
|
|
treerackQuery: queryTreerack("relative-url", "port"),
|
|
expect: "8080",
|
|
}},
|
|
}, {
|
|
|
|
title: "absolute path only",
|
|
input: "/foo/bar",
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("relative-url", "path-absolute"),
|
|
expect: "/foo/bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "relative path only",
|
|
input: "foo/bar",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("relative-url", "path-noscheme"),
|
|
expect: "foo/bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "relative path only with navigation segments",
|
|
input: "../foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("relative-url", "path-noscheme"),
|
|
expect: "../foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "query only",
|
|
input: "?foo=bar",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("relative-url", "query"),
|
|
expect: "foo=bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "query only empty",
|
|
input: "?",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("relative-url", "query"),
|
|
expect: "",
|
|
}},
|
|
}, {
|
|
|
|
title: "fragment only",
|
|
input: "#foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("relative-url", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "fragment only empty",
|
|
input: "#",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("relative-url", "fragment"),
|
|
expect: "",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and user",
|
|
input: "http://foo:bar@",
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url-rfc", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("absolute-url-rfc", "userinfo"),
|
|
expect: "foo:bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and user without password",
|
|
input: "http://foo@",
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url-rfc", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("absolute-url-rfc", "userinfo"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and host",
|
|
input: "http://foo.bar",
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("absolute-url", "hostname", "domain-name"),
|
|
expect: "foo.bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and host ipv4 as domain name because of numeric range",
|
|
input: "http://256.0.0.1",
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("absolute-url", "hostname", "domain-name"),
|
|
expect: "256.0.0.1",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and host ipv4 as domain name because of leading zero",
|
|
input: "http://128.0.0.01",
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("absolute-url", "hostname", "domain-name"),
|
|
expect: "128.0.0.01",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and host ipv4",
|
|
input: "http://128.0.0.1",
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("absolute-url", "hostname", "ipv4"),
|
|
expect: "128.0.0.1",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and host ipv6",
|
|
input: "http://[fe80::1]",
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: fakeTRCheck("[fe80::1]"),
|
|
expect: "[fe80::1]",
|
|
}, {
|
|
stdQuery: fakeSTDCheck("fe80::1"),
|
|
treerackQuery: queryTreerack("absolute-url", "hostname", "ipv6"),
|
|
expect: "fe80::1",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and host ipv6 with zone",
|
|
input: "http://[fe80::1%25eth0]",
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: fakeTRCheck("[fe80::1%eth0]"),
|
|
expect: "[fe80::1%eth0]",
|
|
}, {
|
|
stdQuery: fakeSTDCheck("fe80::1%25eth0"),
|
|
treerackQuery: queryTreerack("absolute-url", "hostname", "ipv6-zone"),
|
|
expect: "fe80::1%25eth0",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and host with port",
|
|
input: "http://foo.bar:8080",
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: fakeTRCheck("foo.bar:8080"),
|
|
expect: "foo.bar:8080",
|
|
}, {
|
|
stdQuery: fakeSTDCheck("foo.bar"),
|
|
treerackQuery: queryTreerack("absolute-url", "hostname"),
|
|
expect: "foo.bar",
|
|
}, {
|
|
stdQuery: fakeSTDCheck("8080"),
|
|
treerackQuery: queryTreerack("absolute-url", "port"),
|
|
expect: "8080",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and path",
|
|
input: "http:/foo/bar",
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("absolute-url", "path-absolute"),
|
|
expect: "/foo/bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and relative path",
|
|
input: "http:foo/bar",
|
|
skipSTD: true,
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("absolute-url", "path-rootless"),
|
|
expect: "foo/bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and query",
|
|
input: "http:?foo=bar",
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("absolute-url", "query"),
|
|
expect: "foo=bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and query empty",
|
|
input: "http:?",
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("absolute-url", "query"),
|
|
expect: "",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and fragment",
|
|
input: "http:#foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("absolute-url", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and fragment",
|
|
input: "http:#",
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("absolute-url", "fragment"),
|
|
expect: "",
|
|
}},
|
|
}, {
|
|
|
|
title: "user and host",
|
|
input: "//foo:bar@foo.bar",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("relative-url", "userinfo"),
|
|
expect: "foo:bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("relative-url", "hostname"),
|
|
expect: "foo.bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "user and path",
|
|
input: "//foo:bar@/foo/bar",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("relative-url-rfc", "userinfo"),
|
|
expect: "foo:bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("relative-url-rfc", "path-absolute-or-empty"),
|
|
expect: "/foo/bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "user and query",
|
|
input: "//foo:bar@?foo=bar",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("relative-url-rfc", "userinfo"),
|
|
expect: "foo:bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("relative-url-rfc", "query"),
|
|
expect: "foo=bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "user and fragment",
|
|
input: "//foo:bar@#foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("relative-url-rfc", "userinfo"),
|
|
expect: "foo:bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("relative-url-rfc", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "host and path",
|
|
input: "//foo.bar/foo/bar",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("relative-url", "hostname"),
|
|
expect: "foo.bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("relative-url", "path-absolute-or-empty"),
|
|
expect: "/foo/bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "host and query",
|
|
input: "//foo.bar?foo=bar",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("relative-url", "hostname"),
|
|
expect: "foo.bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("relative-url", "query"),
|
|
expect: "foo=bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "host and fragment",
|
|
input: "//foo.bar#foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("relative-url", "hostname"),
|
|
expect: "foo.bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("relative-url", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "path and query",
|
|
input: "/foo/bar?foo=bar",
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("relative-url", "path-absolute"),
|
|
expect: "/foo/bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("relative-url", "query"),
|
|
expect: "foo=bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "path and fragment",
|
|
input: "/foo/bar#foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("relative-url", "path-absolute"),
|
|
expect: "/foo/bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("relative-url", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "query and fragment",
|
|
input: "?foo=bar#foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("relative-url", "query"),
|
|
expect: "foo=bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("relative-url", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and user and host",
|
|
input: "http://foo:bar@foo.bar",
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("absolute-url", "userinfo"),
|
|
expect: "foo:bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("absolute-url", "hostname"),
|
|
expect: "foo.bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and user and path",
|
|
input: "http://foo:bar@/foo/bar",
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url-rfc", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("absolute-url-rfc", "userinfo"),
|
|
expect: "foo:bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("absolute-url-rfc", "path-absolute-or-empty"),
|
|
expect: "/foo/bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and user and query",
|
|
input: "http://foo:bar@?foo=bar",
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url-rfc", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("absolute-url-rfc", "userinfo"),
|
|
expect: "foo:bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("absolute-url-rfc", "query"),
|
|
expect: "foo=bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and user and fragment",
|
|
input: "http://foo:bar@#foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url-rfc", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("absolute-url-rfc", "userinfo"),
|
|
expect: "foo:bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("absolute-url-rfc", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and host and path",
|
|
input: "http://foo.bar/foo/bar",
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("absolute-url", "hostname"),
|
|
expect: "foo.bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("absolute-url", "path-absolute-or-empty"),
|
|
expect: "/foo/bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and host and query",
|
|
input: "http://foo.bar?foo=bar",
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("absolute-url", "hostname"),
|
|
expect: "foo.bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("absolute-url", "query"),
|
|
expect: "foo=bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and host and fragment",
|
|
input: "http://foo.bar#foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("absolute-url", "hostname"),
|
|
expect: "foo.bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("absolute-url", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and path and query",
|
|
input: "http:/foo/bar?foo=bar",
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("absolute-url", "path-absolute"),
|
|
expect: "/foo/bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("absolute-url", "query"),
|
|
expect: "foo=bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and path and fragment",
|
|
input: "http:/foo/bar#foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("absolute-url", "path-absolute"),
|
|
expect: "/foo/bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("absolute-url", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and query and fragment",
|
|
input: "http:?foo=bar#foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("absolute-url", "query"),
|
|
expect: "foo=bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("absolute-url", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "user and host and path",
|
|
input: "//foo:bar@foo.bar/foo/bar",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("relative-url", "userinfo"),
|
|
expect: "foo:bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("relative-url", "hostname"),
|
|
expect: "foo.bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("relative-url", "path-absolute-or-empty"),
|
|
expect: "/foo/bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "user and host and query",
|
|
input: "//foo:bar@foo.bar?foo=bar",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("relative-url", "userinfo"),
|
|
expect: "foo:bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("relative-url", "hostname"),
|
|
expect: "foo.bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("relative-url", "query"),
|
|
expect: "foo=bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "user and host and fragment",
|
|
input: "//foo:bar@foo.bar#foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("relative-url", "userinfo"),
|
|
expect: "foo:bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("relative-url", "hostname"),
|
|
expect: "foo.bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("relative-url", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "user and path and query",
|
|
input: "//foo:bar@/foo/bar?foo=bar",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("relative-url-rfc", "userinfo"),
|
|
expect: "foo:bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("relative-url-rfc", "path-absolute-or-empty"),
|
|
expect: "/foo/bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("relative-url-rfc", "query"),
|
|
expect: "foo=bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "user and path and fragment",
|
|
input: "//foo:bar@/foo/bar#foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("relative-url-rfc", "userinfo"),
|
|
expect: "foo:bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("relative-url-rfc", "path-absolute-or-empty"),
|
|
expect: "/foo/bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("relative-url-rfc", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "user and query and fragment",
|
|
input: "//foo:bar@?foo=bar#foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("relative-url-rfc", "userinfo"),
|
|
expect: "foo:bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("relative-url-rfc", "query"),
|
|
expect: "foo=bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("relative-url-rfc", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "host and path and query",
|
|
input: "//foo.bar/foo/bar?foo=bar",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("relative-url", "hostname"),
|
|
expect: "foo.bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("relative-url", "path-absolute-or-empty"),
|
|
expect: "/foo/bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("relative-url", "query"),
|
|
expect: "foo=bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "host and path and fragment",
|
|
input: "//foo.bar/foo/bar#foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("relative-url", "hostname"),
|
|
expect: "foo.bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("relative-url", "path-absolute-or-empty"),
|
|
expect: "/foo/bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("relative-url", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "host and query and fragment",
|
|
input: "//foo.bar?foo=bar#foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("relative-url", "hostname"),
|
|
expect: "foo.bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("relative-url", "query"),
|
|
expect: "foo=bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("relative-url", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "path and query and fragment",
|
|
input: "/foo/bar?foo=bar#foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("relative-url", "path-absolute"),
|
|
expect: "/foo/bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("relative-url", "query"),
|
|
expect: "foo=bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("relative-url", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "relative path and query and fragment",
|
|
input: "../foo/bar?foo=bar#foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("relative-url", "path-noscheme"),
|
|
expect: "../foo/bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("relative-url", "query"),
|
|
expect: "foo=bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("relative-url", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and user and host and path",
|
|
input: "http://foo:bar@foo.bar/foo/bar",
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("absolute-url", "userinfo"),
|
|
expect: "foo:bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("absolute-url", "hostname"),
|
|
expect: "foo.bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("absolute-url", "path-absolute-or-empty"),
|
|
expect: "/foo/bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and user and host and query",
|
|
input: "http://foo:bar@foo.bar?foo=bar",
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("absolute-url", "userinfo"),
|
|
expect: "foo:bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("absolute-url", "hostname"),
|
|
expect: "foo.bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("absolute-url", "query"),
|
|
expect: "foo=bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and user and host and fragment",
|
|
input: "http://foo:bar@foo.bar#foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("absolute-url", "userinfo"),
|
|
expect: "foo:bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("absolute-url", "hostname"),
|
|
expect: "foo.bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("absolute-url", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and user and path and query",
|
|
input: "http://foo:bar@/foo/bar?foo=bar",
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url-rfc", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("absolute-url-rfc", "userinfo"),
|
|
expect: "foo:bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("absolute-url-rfc", "path-absolute-or-empty"),
|
|
expect: "/foo/bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("absolute-url-rfc", "query"),
|
|
expect: "foo=bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and user and path and fragment",
|
|
input: "http://foo:bar@/foo/bar#foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url-rfc", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("absolute-url-rfc", "userinfo"),
|
|
expect: "foo:bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("absolute-url-rfc", "path-absolute-or-empty"),
|
|
expect: "/foo/bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("absolute-url-rfc", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and user and query and fragment",
|
|
input: "http://foo:bar@?foo=bar#foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url-rfc", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("absolute-url-rfc", "userinfo"),
|
|
expect: "foo:bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("absolute-url-rfc", "query"),
|
|
expect: "foo=bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("absolute-url-rfc", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and host and path and query",
|
|
input: "http://foo.bar/foo/bar?foo=bar",
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("absolute-url", "hostname"),
|
|
expect: "foo.bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("absolute-url", "path-absolute-or-empty"),
|
|
expect: "/foo/bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("absolute-url", "query"),
|
|
expect: "foo=bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and host and path and fragment",
|
|
input: "http://foo.bar/foo/bar#foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("absolute-url", "hostname"),
|
|
expect: "foo.bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("absolute-url", "path-absolute-or-empty"),
|
|
expect: "/foo/bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("absolute-url", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and host and query and fragment",
|
|
input: "http://foo.bar?foo=bar#foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("absolute-url", "hostname"),
|
|
expect: "foo.bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("absolute-url", "query"),
|
|
expect: "foo=bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("absolute-url", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and path and query and fragment",
|
|
input: "http:/foo/bar?foo=bar#foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("absolute-url", "path-absolute"),
|
|
expect: "/foo/bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("absolute-url", "query"),
|
|
expect: "foo=bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("absolute-url", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "user and host and path and query",
|
|
input: "//foo:bar@foo.bar/foo/bar?foo=bar",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("relative-url", "userinfo"),
|
|
expect: "foo:bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("relative-url", "hostname"),
|
|
expect: "foo.bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("relative-url", "path-absolute-or-empty"),
|
|
expect: "/foo/bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("relative-url", "query"),
|
|
expect: "foo=bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "user and host and path and fragment",
|
|
input: "//foo:bar@foo.bar/foo/bar#foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("relative-url", "userinfo"),
|
|
expect: "foo:bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("relative-url", "hostname"),
|
|
expect: "foo.bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("relative-url", "path-absolute-or-empty"),
|
|
expect: "/foo/bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("relative-url", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "user and path and query and fragment",
|
|
input: "//foo:bar@/foo/bar?foo=bar#foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("relative-url-rfc", "userinfo"),
|
|
expect: "foo:bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("relative-url-rfc", "path-absolute-or-empty"),
|
|
expect: "/foo/bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("relative-url-rfc", "query"),
|
|
expect: "foo=bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("relative-url-rfc", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "host and path and query and fragment",
|
|
input: "//foo.bar/foo/bar?foo=bar#foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("relative-url", "hostname"),
|
|
expect: "foo.bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("relative-url", "path-absolute-or-empty"),
|
|
expect: "/foo/bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("relative-url", "query"),
|
|
expect: "foo=bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("relative-url", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and user and host and path and query",
|
|
input: "http://foo:bar@foo.bar/foo/bar?foo=bar",
|
|
bench: 3600,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("absolute-url", "userinfo"),
|
|
expect: "foo:bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("absolute-url", "hostname", "domain-name"),
|
|
expect: "foo.bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("absolute-url", "path-absolute-or-empty"),
|
|
expect: "/foo/bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("absolute-url", "query"),
|
|
expect: "foo=bar",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and user and host and path and fragment",
|
|
input: "http://foo:bar@foo.bar/foo/bar#foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("absolute-url", "userinfo"),
|
|
expect: "foo:bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("absolute-url", "hostname", "domain-name"),
|
|
expect: "foo.bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("absolute-url", "path-absolute-or-empty"),
|
|
expect: "/foo/bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("absolute-url", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and user and host and query and fragment",
|
|
input: "http://foo:bar@foo.bar?foo=bar#foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("absolute-url", "userinfo"),
|
|
expect: "foo:bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("absolute-url", "hostname", "domain-name"),
|
|
expect: "foo.bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("absolute-url", "query"),
|
|
expect: "foo=bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("absolute-url", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and user and path and query and fragment",
|
|
input: "http://foo:bar@/foo/bar?foo=bar#foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url-rfc", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("absolute-url-rfc", "userinfo"),
|
|
expect: "foo:bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("absolute-url-rfc", "path-absolute-or-empty"),
|
|
expect: "/foo/bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("absolute-url-rfc", "query"),
|
|
expect: "foo=bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("absolute-url-rfc", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and host and path and query and fragment",
|
|
input: "http://foo.bar/foo/bar?foo=bar#foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("absolute-url", "hostname", "domain-name"),
|
|
expect: "foo.bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("absolute-url", "path-absolute-or-empty"),
|
|
expect: "/foo/bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("absolute-url", "query"),
|
|
expect: "foo=bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("absolute-url", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "user and host and path and query and fragment",
|
|
input: "//foo:bar@foo.bar/foo/bar?foo=bar#foo",
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("relative-url", "userinfo"),
|
|
expect: "foo:bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("relative-url", "hostname", "domain-name"),
|
|
expect: "foo.bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("relative-url", "path-absolute-or-empty"),
|
|
expect: "/foo/bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("relative-url", "query"),
|
|
expect: "foo=bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("relative-url", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}, {
|
|
|
|
title: "scheme and user and host and path and query and fragment",
|
|
input: "http://foo:bar@foo.bar/foo/bar?foo=bar#foo",
|
|
bench: 3600,
|
|
skipSTDReq: true,
|
|
checks: []urlCheck{{
|
|
stdQuery: func(u *url.URL) string { return u.Scheme },
|
|
treerackQuery: queryTreerack("absolute-url", "scheme"),
|
|
expect: "http",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.User.String() },
|
|
treerackQuery: queryTreerack("absolute-url", "userinfo"),
|
|
expect: "foo:bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Host },
|
|
treerackQuery: queryTreerack("absolute-url", "hostname", "domain-name"),
|
|
expect: "foo.bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Path },
|
|
treerackQuery: queryTreerack("absolute-url", "path-absolute-or-empty"),
|
|
expect: "/foo/bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.RawQuery },
|
|
treerackQuery: queryTreerack("absolute-url", "query"),
|
|
expect: "foo=bar",
|
|
}, {
|
|
stdQuery: func(u *url.URL) string { return u.Fragment },
|
|
treerackQuery: queryTreerack("absolute-url", "fragment"),
|
|
expect: "foo",
|
|
}},
|
|
}} {
|
|
t.Run(test.title, func(t *testing.T) {
|
|
t.Run("std", func(t *testing.T) {
|
|
if test.skipSTD {
|
|
t.Skip("!!!skipping standard library parser!!!")
|
|
}
|
|
|
|
n := test.bench
|
|
if n <= 0 {
|
|
n = 1
|
|
}
|
|
|
|
var d time.Duration
|
|
for i := 0; i < n && !t.Failed(); i++ {
|
|
start := time.Now()
|
|
u, err := url.Parse(test.input)
|
|
d += time.Since(start)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if i > 0 {
|
|
continue
|
|
}
|
|
|
|
for _, check := range test.checks {
|
|
v := check.stdQuery(u)
|
|
if v != check.expect {
|
|
notation.Lprintw(t, u)
|
|
t.Fatal("expecting:", check.expect, "got:", v)
|
|
}
|
|
}
|
|
}
|
|
|
|
if test.bench > 0 {
|
|
t.Log("average duration:", d/time.Duration(n))
|
|
}
|
|
})
|
|
|
|
t.Run("stdreq", func(t *testing.T) {
|
|
if test.skipSTDReq {
|
|
t.Skip("non-request URI")
|
|
}
|
|
|
|
n := test.bench
|
|
if n <= 0 {
|
|
n = 1
|
|
}
|
|
|
|
var d time.Duration
|
|
for i := 0; i < n && !t.Failed(); i++ {
|
|
start := time.Now()
|
|
u, err := url.ParseRequestURI(test.input)
|
|
d += time.Since(start)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if i > 0 {
|
|
continue
|
|
}
|
|
|
|
for _, check := range test.checks {
|
|
v := check.stdQuery(u)
|
|
if v != check.expect {
|
|
notation.Lprintw(t, u)
|
|
t.Fatal("expecting:", check.expect, "got:", v)
|
|
}
|
|
}
|
|
}
|
|
|
|
if test.bench > 0 {
|
|
t.Log("average duration:", d/time.Duration(n))
|
|
}
|
|
})
|
|
|
|
t.Run("treerack", func(t *testing.T) {
|
|
n := test.bench
|
|
if n <= 0 {
|
|
n = 1
|
|
}
|
|
|
|
var d time.Duration
|
|
p := urlParser(test.bench <= 0)
|
|
for i := 0; i < n && !t.Failed(); i++ {
|
|
start := time.Now()
|
|
a, err := p(test.input)
|
|
d += time.Since(start)
|
|
if err != nil {
|
|
Trace(t.Output(), err)
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if i > 0 {
|
|
continue
|
|
}
|
|
|
|
for _, check := range test.checks {
|
|
v := check.treerackQuery(a)
|
|
if v != check.expect {
|
|
printURLTree(t, a)
|
|
t.Fatal("expecting:", check.expect, "got:", v)
|
|
}
|
|
}
|
|
}
|
|
|
|
if test.bench > 0 {
|
|
t.Log("average duration:", d/time.Duration(n))
|
|
}
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestURLErrors(t *testing.T) {
|
|
for _, test := range []struct{ title, input string }{{
|
|
|
|
title: "scheme cannot start on a number",
|
|
input: "123http://foo.bar/foo/bar",
|
|
}, {
|
|
|
|
title: "scheme characters",
|
|
input: "http,unix://foo.bar/foo/bar",
|
|
}, {
|
|
|
|
title: "ipv4 in brackets",
|
|
input: "http://[128.0.0.1]",
|
|
}, {
|
|
|
|
title: "ipv6 without closing bracket",
|
|
input: "http://[fe80::1%25eth0",
|
|
}, {
|
|
|
|
title: "invalid port",
|
|
input: "http://foo.bar:99x99",
|
|
}, {
|
|
|
|
title: "invalid path",
|
|
input: "http://foo.bar/foo%xbar",
|
|
}} {
|
|
t.Run(test.title, func(t *testing.T) {
|
|
p := urlParser(false)
|
|
if a, err := p(test.input); err == nil {
|
|
printURLTree(t, a)
|
|
t.Fatal("failed to fail", test.input)
|
|
}
|
|
})
|
|
}
|
|
}
|