769 lines
19 KiB
Go
769 lines
19 KiB
Go
|
package purell
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"net/url"
|
||
|
"testing"
|
||
|
)
|
||
|
|
||
|
type testCase struct {
|
||
|
nm string
|
||
|
src string
|
||
|
flgs NormalizationFlags
|
||
|
res string
|
||
|
parsed bool
|
||
|
}
|
||
|
|
||
|
var (
|
||
|
cases = [...]*testCase{
|
||
|
&testCase{
|
||
|
"LowerScheme",
|
||
|
"HTTP://www.SRC.ca",
|
||
|
FlagLowercaseScheme,
|
||
|
"http://www.SRC.ca",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"LowerScheme2",
|
||
|
"http://www.SRC.ca",
|
||
|
FlagLowercaseScheme,
|
||
|
"http://www.SRC.ca",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"LowerHost",
|
||
|
"HTTP://www.SRC.ca/",
|
||
|
FlagLowercaseHost,
|
||
|
"http://www.src.ca/", // Since Go1.1, scheme is automatically lowercased
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"UpperEscapes",
|
||
|
`http://www.whatever.com/Some%aa%20Special%8Ecases/`,
|
||
|
FlagUppercaseEscapes,
|
||
|
"http://www.whatever.com/Some%AA%20Special%8Ecases/",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"UnnecessaryEscapes",
|
||
|
`http://www.toto.com/%41%42%2E%44/%32%33%52%2D/%5f%7E`,
|
||
|
FlagDecodeUnnecessaryEscapes,
|
||
|
"http://www.toto.com/AB.D/23R-/_~",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"RemoveDefaultPort",
|
||
|
"HTTP://www.SRC.ca:80/",
|
||
|
FlagRemoveDefaultPort,
|
||
|
"http://www.SRC.ca/", // Since Go1.1, scheme is automatically lowercased
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"RemoveDefaultPort2",
|
||
|
"HTTP://www.SRC.ca:80",
|
||
|
FlagRemoveDefaultPort,
|
||
|
"http://www.SRC.ca", // Since Go1.1, scheme is automatically lowercased
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"RemoveDefaultPort3",
|
||
|
"HTTP://www.SRC.ca:8080",
|
||
|
FlagRemoveDefaultPort,
|
||
|
"http://www.SRC.ca:8080", // Since Go1.1, scheme is automatically lowercased
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Safe",
|
||
|
"HTTP://www.SRC.ca:80/to%1ato%8b%ee/OKnow%41%42%43%7e",
|
||
|
FlagsSafe,
|
||
|
"http://www.src.ca/to%1Ato%8B%EE/OKnowABC~",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"BothLower",
|
||
|
"HTTP://www.SRC.ca:80/to%1ato%8b%ee/OKnow%41%42%43%7e",
|
||
|
FlagLowercaseHost | FlagLowercaseScheme,
|
||
|
"http://www.src.ca:80/to%1Ato%8B%EE/OKnowABC~",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"RemoveTrailingSlash",
|
||
|
"HTTP://www.SRC.ca:80/",
|
||
|
FlagRemoveTrailingSlash,
|
||
|
"http://www.SRC.ca:80", // Since Go1.1, scheme is automatically lowercased
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"RemoveTrailingSlash2",
|
||
|
"HTTP://www.SRC.ca:80/toto/titi/",
|
||
|
FlagRemoveTrailingSlash,
|
||
|
"http://www.SRC.ca:80/toto/titi", // Since Go1.1, scheme is automatically lowercased
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"RemoveTrailingSlash3",
|
||
|
"HTTP://www.SRC.ca:80/toto/titi/fin/?a=1",
|
||
|
FlagRemoveTrailingSlash,
|
||
|
"http://www.SRC.ca:80/toto/titi/fin?a=1", // Since Go1.1, scheme is automatically lowercased
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"AddTrailingSlash",
|
||
|
"HTTP://www.SRC.ca:80",
|
||
|
FlagAddTrailingSlash,
|
||
|
"http://www.SRC.ca:80/", // Since Go1.1, scheme is automatically lowercased
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"AddTrailingSlash2",
|
||
|
"HTTP://www.SRC.ca:80/toto/titi.html",
|
||
|
FlagAddTrailingSlash,
|
||
|
"http://www.SRC.ca:80/toto/titi.html/", // Since Go1.1, scheme is automatically lowercased
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"AddTrailingSlash3",
|
||
|
"HTTP://www.SRC.ca:80/toto/titi/fin?a=1",
|
||
|
FlagAddTrailingSlash,
|
||
|
"http://www.SRC.ca:80/toto/titi/fin/?a=1", // Since Go1.1, scheme is automatically lowercased
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"RemoveDotSegments",
|
||
|
"HTTP://root/a/b/./../../c/",
|
||
|
FlagRemoveDotSegments,
|
||
|
"http://root/c/", // Since Go1.1, scheme is automatically lowercased
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"RemoveDotSegments2",
|
||
|
"HTTP://root/../a/b/./../c/../d",
|
||
|
FlagRemoveDotSegments,
|
||
|
"http://root/a/d", // Since Go1.1, scheme is automatically lowercased
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"UsuallySafe",
|
||
|
"HTTP://www.SRC.ca:80/to%1ato%8b%ee/./c/d/../OKnow%41%42%43%7e/?a=b#test",
|
||
|
FlagsUsuallySafeGreedy,
|
||
|
"http://www.src.ca/to%1Ato%8B%EE/c/OKnowABC~?a=b#test",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"RemoveDirectoryIndex",
|
||
|
"HTTP://root/a/b/c/default.aspx",
|
||
|
FlagRemoveDirectoryIndex,
|
||
|
"http://root/a/b/c/", // Since Go1.1, scheme is automatically lowercased
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"RemoveDirectoryIndex2",
|
||
|
"HTTP://root/a/b/c/default#a=b",
|
||
|
FlagRemoveDirectoryIndex,
|
||
|
"http://root/a/b/c/default#a=b", // Since Go1.1, scheme is automatically lowercased
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"RemoveFragment",
|
||
|
"HTTP://root/a/b/c/default#toto=tata",
|
||
|
FlagRemoveFragment,
|
||
|
"http://root/a/b/c/default", // Since Go1.1, scheme is automatically lowercased
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"ForceHTTP",
|
||
|
"https://root/a/b/c/default#toto=tata",
|
||
|
FlagForceHTTP,
|
||
|
"http://root/a/b/c/default#toto=tata",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"RemoveDuplicateSlashes",
|
||
|
"https://root/a//b///c////default#toto=tata",
|
||
|
FlagRemoveDuplicateSlashes,
|
||
|
"https://root/a/b/c/default#toto=tata",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"RemoveDuplicateSlashes2",
|
||
|
"https://root//a//b///c////default#toto=tata",
|
||
|
FlagRemoveDuplicateSlashes,
|
||
|
"https://root/a/b/c/default#toto=tata",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"RemoveWWW",
|
||
|
"https://www.root/a/b/c/",
|
||
|
FlagRemoveWWW,
|
||
|
"https://root/a/b/c/",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"RemoveWWW2",
|
||
|
"https://WwW.Root/a/b/c/",
|
||
|
FlagRemoveWWW,
|
||
|
"https://Root/a/b/c/",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"AddWWW",
|
||
|
"https://Root/a/b/c/",
|
||
|
FlagAddWWW,
|
||
|
"https://www.Root/a/b/c/",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"SortQuery",
|
||
|
"http://root/toto/?b=4&a=1&c=3&b=2&a=5",
|
||
|
FlagSortQuery,
|
||
|
"http://root/toto/?a=1&a=5&b=2&b=4&c=3",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"RemoveEmptyQuerySeparator",
|
||
|
"http://root/toto/?",
|
||
|
FlagRemoveEmptyQuerySeparator,
|
||
|
"http://root/toto/",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Unsafe",
|
||
|
"HTTPS://www.RooT.com/toto/t%45%1f///a/./b/../c/?z=3&w=2&a=4&w=1#invalid",
|
||
|
FlagsUnsafeGreedy,
|
||
|
"http://root.com/toto/tE%1F/a/c?a=4&w=1&w=2&z=3",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Safe2",
|
||
|
"HTTPS://www.RooT.com/toto/t%45%1f///a/./b/../c/?z=3&w=2&a=4&w=1#invalid",
|
||
|
FlagsSafe,
|
||
|
"https://www.root.com/toto/tE%1F///a/./b/../c/?z=3&w=2&a=4&w=1#invalid",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"UsuallySafe2",
|
||
|
"HTTPS://www.RooT.com/toto/t%45%1f///a/./b/../c/?z=3&w=2&a=4&w=1#invalid",
|
||
|
FlagsUsuallySafeGreedy,
|
||
|
"https://www.root.com/toto/tE%1F///a/c?z=3&w=2&a=4&w=1#invalid",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"AddTrailingSlashBug",
|
||
|
"http://src.ca/",
|
||
|
FlagsAllNonGreedy,
|
||
|
"http://www.src.ca/",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"SourceModified",
|
||
|
"HTTPS://www.RooT.com/toto/t%45%1f///a/./b/../c/?z=3&w=2&a=4&w=1#invalid",
|
||
|
FlagsUnsafeGreedy,
|
||
|
"http://root.com/toto/tE%1F/a/c?a=4&w=1&w=2&z=3",
|
||
|
true,
|
||
|
},
|
||
|
&testCase{
|
||
|
"IPv6-1",
|
||
|
"http://[2001:db8:1f70::999:de8:7648:6e8]/test",
|
||
|
FlagsSafe | FlagRemoveDotSegments,
|
||
|
"http://[2001:db8:1f70::999:de8:7648:6e8]/test",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"IPv6-2",
|
||
|
"http://[::ffff:192.168.1.1]/test",
|
||
|
FlagsSafe | FlagRemoveDotSegments,
|
||
|
"http://[::ffff:192.168.1.1]/test",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"IPv6-3",
|
||
|
"http://[::ffff:192.168.1.1]:80/test",
|
||
|
FlagsSafe | FlagRemoveDotSegments,
|
||
|
"http://[::ffff:192.168.1.1]/test",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"IPv6-4",
|
||
|
"htTps://[::fFff:192.168.1.1]:443/test",
|
||
|
FlagsSafe | FlagRemoveDotSegments,
|
||
|
"https://[::ffff:192.168.1.1]/test",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"FTP",
|
||
|
"ftp://user:pass@ftp.foo.net/foo/bar",
|
||
|
FlagsSafe | FlagRemoveDotSegments,
|
||
|
"ftp://user:pass@ftp.foo.net/foo/bar",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Standard-1",
|
||
|
"http://www.foo.com:80/foo",
|
||
|
FlagsSafe | FlagRemoveDotSegments,
|
||
|
"http://www.foo.com/foo",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Standard-2",
|
||
|
"http://www.foo.com:8000/foo",
|
||
|
FlagsSafe | FlagRemoveDotSegments,
|
||
|
"http://www.foo.com:8000/foo",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Standard-3",
|
||
|
"http://www.foo.com/%7ebar",
|
||
|
FlagsSafe | FlagRemoveDotSegments,
|
||
|
"http://www.foo.com/~bar",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Standard-4",
|
||
|
"http://www.foo.com/%7Ebar",
|
||
|
FlagsSafe | FlagRemoveDotSegments,
|
||
|
"http://www.foo.com/~bar",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Standard-5",
|
||
|
"http://USER:pass@www.Example.COM/foo/bar",
|
||
|
FlagsSafe | FlagRemoveDotSegments,
|
||
|
"http://USER:pass@www.example.com/foo/bar",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Standard-6",
|
||
|
"http://test.example/?a=%26&b=1",
|
||
|
FlagsSafe | FlagRemoveDotSegments,
|
||
|
"http://test.example/?a=%26&b=1",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Standard-7",
|
||
|
"http://test.example/%25/?p=%20val%20%25",
|
||
|
FlagsSafe | FlagRemoveDotSegments,
|
||
|
"http://test.example/%25/?p=%20val%20%25",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Standard-8",
|
||
|
"http://test.example/path/with a%20space+/",
|
||
|
FlagsSafe | FlagRemoveDotSegments,
|
||
|
"http://test.example/path/with%20a%20space+/",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Standard-9",
|
||
|
"http://test.example/?",
|
||
|
FlagsSafe | FlagRemoveDotSegments,
|
||
|
"http://test.example/",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Standard-10",
|
||
|
"http://a.COM/path/?b&a",
|
||
|
FlagsSafe | FlagRemoveDotSegments,
|
||
|
"http://a.com/path/?b&a",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"StandardCasesAddTrailingSlash",
|
||
|
"http://test.example?",
|
||
|
FlagsSafe | FlagAddTrailingSlash,
|
||
|
"http://test.example/",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"OctalIP-1",
|
||
|
"http://0123.011.0.4/",
|
||
|
FlagsSafe | FlagDecodeOctalHost,
|
||
|
"http://0123.011.0.4/",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"OctalIP-2",
|
||
|
"http://0102.0146.07.0223/",
|
||
|
FlagsSafe | FlagDecodeOctalHost,
|
||
|
"http://66.102.7.147/",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"OctalIP-3",
|
||
|
"http://0102.0146.07.0223.:23/",
|
||
|
FlagsSafe | FlagDecodeOctalHost,
|
||
|
"http://66.102.7.147.:23/",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"OctalIP-4",
|
||
|
"http://USER:pass@0102.0146.07.0223../",
|
||
|
FlagsSafe | FlagDecodeOctalHost,
|
||
|
"http://USER:pass@66.102.7.147../",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"DWORDIP-1",
|
||
|
"http://123.1113982867/",
|
||
|
FlagsSafe | FlagDecodeDWORDHost,
|
||
|
"http://123.1113982867/",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"DWORDIP-2",
|
||
|
"http://1113982867/",
|
||
|
FlagsSafe | FlagDecodeDWORDHost,
|
||
|
"http://66.102.7.147/",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"DWORDIP-3",
|
||
|
"http://1113982867.:23/",
|
||
|
FlagsSafe | FlagDecodeDWORDHost,
|
||
|
"http://66.102.7.147.:23/",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"DWORDIP-4",
|
||
|
"http://USER:pass@1113982867../",
|
||
|
FlagsSafe | FlagDecodeDWORDHost,
|
||
|
"http://USER:pass@66.102.7.147../",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"HexIP-1",
|
||
|
"http://0x123.1113982867/",
|
||
|
FlagsSafe | FlagDecodeHexHost,
|
||
|
"http://0x123.1113982867/",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"HexIP-2",
|
||
|
"http://0x42660793/",
|
||
|
FlagsSafe | FlagDecodeHexHost,
|
||
|
"http://66.102.7.147/",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"HexIP-3",
|
||
|
"http://0x42660793.:23/",
|
||
|
FlagsSafe | FlagDecodeHexHost,
|
||
|
"http://66.102.7.147.:23/",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"HexIP-4",
|
||
|
"http://USER:pass@0x42660793../",
|
||
|
FlagsSafe | FlagDecodeHexHost,
|
||
|
"http://USER:pass@66.102.7.147../",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"UnnecessaryHostDots-1",
|
||
|
"http://.www.foo.com../foo/bar.html",
|
||
|
FlagsSafe | FlagRemoveUnnecessaryHostDots,
|
||
|
"http://www.foo.com/foo/bar.html",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"UnnecessaryHostDots-2",
|
||
|
"http://www.foo.com./foo/bar.html",
|
||
|
FlagsSafe | FlagRemoveUnnecessaryHostDots,
|
||
|
"http://www.foo.com/foo/bar.html",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"UnnecessaryHostDots-3",
|
||
|
"http://www.foo.com.:81/foo",
|
||
|
FlagsSafe | FlagRemoveUnnecessaryHostDots,
|
||
|
"http://www.foo.com:81/foo",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"UnnecessaryHostDots-4",
|
||
|
"http://www.example.com./",
|
||
|
FlagsSafe | FlagRemoveUnnecessaryHostDots,
|
||
|
"http://www.example.com/",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"EmptyPort-1",
|
||
|
"http://www.thedraymin.co.uk:/main/?p=308",
|
||
|
FlagsSafe | FlagRemoveEmptyPortSeparator,
|
||
|
"http://www.thedraymin.co.uk/main/?p=308",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"EmptyPort-2",
|
||
|
"http://www.src.ca:",
|
||
|
FlagsSafe | FlagRemoveEmptyPortSeparator,
|
||
|
"http://www.src.ca",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Slashes-1",
|
||
|
"http://test.example/foo/bar/.",
|
||
|
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||
|
"http://test.example/foo/bar/",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Slashes-2",
|
||
|
"http://test.example/foo/bar/./",
|
||
|
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||
|
"http://test.example/foo/bar/",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Slashes-3",
|
||
|
"http://test.example/foo/bar/..",
|
||
|
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||
|
"http://test.example/foo/",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Slashes-4",
|
||
|
"http://test.example/foo/bar/../",
|
||
|
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||
|
"http://test.example/foo/",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Slashes-5",
|
||
|
"http://test.example/foo/bar/../baz",
|
||
|
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||
|
"http://test.example/foo/baz",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Slashes-6",
|
||
|
"http://test.example/foo/bar/../..",
|
||
|
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||
|
"http://test.example/",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Slashes-7",
|
||
|
"http://test.example/foo/bar/../../",
|
||
|
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||
|
"http://test.example/",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Slashes-8",
|
||
|
"http://test.example/foo/bar/../../baz",
|
||
|
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||
|
"http://test.example/baz",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Slashes-9",
|
||
|
"http://test.example/foo/bar/../../../baz",
|
||
|
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||
|
"http://test.example/baz",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Slashes-10",
|
||
|
"http://test.example/foo/bar/../../../../baz",
|
||
|
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||
|
"http://test.example/baz",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Slashes-11",
|
||
|
"http://test.example/./foo",
|
||
|
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||
|
"http://test.example/foo",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Slashes-12",
|
||
|
"http://test.example/../foo",
|
||
|
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||
|
"http://test.example/foo",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Slashes-13",
|
||
|
"http://test.example/foo.",
|
||
|
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||
|
"http://test.example/foo.",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Slashes-14",
|
||
|
"http://test.example/.foo",
|
||
|
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||
|
"http://test.example/.foo",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Slashes-15",
|
||
|
"http://test.example/foo..",
|
||
|
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||
|
"http://test.example/foo..",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Slashes-16",
|
||
|
"http://test.example/..foo",
|
||
|
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||
|
"http://test.example/..foo",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Slashes-17",
|
||
|
"http://test.example/./../foo",
|
||
|
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||
|
"http://test.example/foo",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Slashes-18",
|
||
|
"http://test.example/./foo/.",
|
||
|
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||
|
"http://test.example/foo/",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Slashes-19",
|
||
|
"http://test.example/foo/./bar",
|
||
|
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||
|
"http://test.example/foo/bar",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Slashes-20",
|
||
|
"http://test.example/foo/../bar",
|
||
|
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||
|
"http://test.example/bar",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Slashes-21",
|
||
|
"http://test.example/foo//",
|
||
|
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||
|
"http://test.example/foo/",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Slashes-22",
|
||
|
"http://test.example/foo///bar//",
|
||
|
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||
|
"http://test.example/foo/bar/",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Relative",
|
||
|
"foo/bar",
|
||
|
FlagsAllGreedy,
|
||
|
"foo/bar",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Relative-1",
|
||
|
"./../foo",
|
||
|
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||
|
"foo",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Relative-2",
|
||
|
"./foo/bar/../baz/../bang/..",
|
||
|
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||
|
"foo/",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Relative-3",
|
||
|
"foo///bar//",
|
||
|
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||
|
"foo/bar/",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"Relative-4",
|
||
|
"www.youtube.com",
|
||
|
FlagsUsuallySafeGreedy,
|
||
|
"www.youtube.com",
|
||
|
false,
|
||
|
},
|
||
|
/*&testCase{
|
||
|
"UrlNorm-5",
|
||
|
"http://ja.wikipedia.org/wiki/%E3%82%AD%E3%83%A3%E3%82%BF%E3%83%94%E3%83%A9%E3%83%BC%E3%82%B8%E3%83%A3%E3%83%91%E3%83%B3",
|
||
|
FlagsSafe | FlagRemoveDotSegments,
|
||
|
"http://ja.wikipedia.org/wiki/\xe3\x82\xad\xe3\x83\xa3\xe3\x82\xbf\xe3\x83\x94\xe3\x83\xa9\xe3\x83\xbc\xe3\x82\xb8\xe3\x83\xa3\xe3\x83\x91\xe3\x83\xb3",
|
||
|
false,
|
||
|
},
|
||
|
&testCase{
|
||
|
"UrlNorm-1",
|
||
|
"http://test.example/?a=%e3%82%82%26",
|
||
|
FlagsAllGreedy,
|
||
|
"http://test.example/?a=\xe3\x82\x82%26",
|
||
|
false,
|
||
|
},*/
|
||
|
}
|
||
|
)
|
||
|
|
||
|
func TestRunner(t *testing.T) {
|
||
|
for _, tc := range cases {
|
||
|
runCase(tc, t)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func runCase(tc *testCase, t *testing.T) {
|
||
|
t.Logf("running %s...", tc.nm)
|
||
|
if tc.parsed {
|
||
|
u, e := url.Parse(tc.src)
|
||
|
if e != nil {
|
||
|
t.Errorf("%s - FAIL : %s", tc.nm, e)
|
||
|
return
|
||
|
} else {
|
||
|
NormalizeURL(u, tc.flgs)
|
||
|
if s := u.String(); s != tc.res {
|
||
|
t.Errorf("%s - FAIL expected '%s', got '%s'", tc.nm, tc.res, s)
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
if s, e := NormalizeURLString(tc.src, tc.flgs); e != nil {
|
||
|
t.Errorf("%s - FAIL : %s", tc.nm, e)
|
||
|
} else if s != tc.res {
|
||
|
t.Errorf("%s - FAIL expected '%s', got '%s'", tc.nm, tc.res, s)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestDecodeUnnecessaryEscapesAll(t *testing.T) {
|
||
|
var url = "http://host/"
|
||
|
|
||
|
for i := 0; i < 256; i++ {
|
||
|
url += fmt.Sprintf("%%%02x", i)
|
||
|
}
|
||
|
if s, e := NormalizeURLString(url, FlagDecodeUnnecessaryEscapes); e != nil {
|
||
|
t.Fatalf("Got error %s", e.Error())
|
||
|
} else {
|
||
|
const want = "http://host/%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%20!%22%23$%25&'()*+,-./0123456789:;%3C=%3E%3F@ABCDEFGHIJKLMNOPQRSTUVWXYZ[%5C]%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~%7F%80%81%82%83%84%85%86%87%88%89%8A%8B%8C%8D%8E%8F%90%91%92%93%94%95%96%97%98%99%9A%9B%9C%9D%9E%9F%A0%A1%A2%A3%A4%A5%A6%A7%A8%A9%AA%AB%AC%AD%AE%AF%B0%B1%B2%B3%B4%B5%B6%B7%B8%B9%BA%BB%BC%BD%BE%BF%C0%C1%C2%C3%C4%C5%C6%C7%C8%C9%CA%CB%CC%CD%CE%CF%D0%D1%D2%D3%D4%D5%D6%D7%D8%D9%DA%DB%DC%DD%DE%DF%E0%E1%E2%E3%E4%E5%E6%E7%E8%E9%EA%EB%EC%ED%EE%EF%F0%F1%F2%F3%F4%F5%F6%F7%F8%F9%FA%FB%FC%FD%FE%FF"
|
||
|
if s != want {
|
||
|
t.Errorf("DecodeUnnecessaryEscapesAll:\nwant\n%s\ngot\n%s", want, s)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestEncodeNecessaryEscapesAll(t *testing.T) {
|
||
|
var url = "http://host/"
|
||
|
|
||
|
for i := 0; i < 256; i++ {
|
||
|
if i != 0x25 {
|
||
|
url += string(i)
|
||
|
}
|
||
|
}
|
||
|
if s, e := NormalizeURLString(url, FlagEncodeNecessaryEscapes); e != nil {
|
||
|
t.Fatalf("Got error %s", e.Error())
|
||
|
} else {
|
||
|
const want = "http://host/%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%20!%22#$&'()*+,-./0123456789:;%3C=%3E?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[%5C]%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~%7F%C2%80%C2%81%C2%82%C2%83%C2%84%C2%85%C2%86%C2%87%C2%88%C2%89%C2%8A%C2%8B%C2%8C%C2%8D%C2%8E%C2%8F%C2%90%C2%91%C2%92%C2%93%C2%94%C2%95%C2%96%C2%97%C2%98%C2%99%C2%9A%C2%9B%C2%9C%C2%9D%C2%9E%C2%9F%C2%A0%C2%A1%C2%A2%C2%A3%C2%A4%C2%A5%C2%A6%C2%A7%C2%A8%C2%A9%C2%AA%C2%AB%C2%AC%C2%AD%C2%AE%C2%AF%C2%B0%C2%B1%C2%B2%C2%B3%C2%B4%C2%B5%C2%B6%C2%B7%C2%B8%C2%B9%C2%BA%C2%BB%C2%BC%C2%BD%C2%BE%C2%BF%C3%80%C3%81%C3%82%C3%83%C3%84%C3%85%C3%86%C3%87%C3%88%C3%89%C3%8A%C3%8B%C3%8C%C3%8D%C3%8E%C3%8F%C3%90%C3%91%C3%92%C3%93%C3%94%C3%95%C3%96%C3%97%C3%98%C3%99%C3%9A%C3%9B%C3%9C%C3%9D%C3%9E%C3%9F%C3%A0%C3%A1%C3%A2%C3%A3%C3%A4%C3%A5%C3%A6%C3%A7%C3%A8%C3%A9%C3%AA%C3%AB%C3%AC%C3%AD%C3%AE%C3%AF%C3%B0%C3%B1%C3%B2%C3%B3%C3%B4%C3%B5%C3%B6%C3%B7%C3%B8%C3%B9%C3%BA%C3%BB%C3%BC%C3%BD%C3%BE%C3%BF"
|
||
|
if s != want {
|
||
|
t.Errorf("EncodeNecessaryEscapesAll:\nwant\n%s\ngot\n%s", want, s)
|
||
|
}
|
||
|
}
|
||
|
}
|