mirror of
https://github.com/odin-lang/Odin.git
synced 2026-04-20 13:25:19 +00:00
Added support for URL fragments
Added support for a URL's fragment/anchor to `split_url` & `join_url` in `core:net` plus 4 new tests to cover it.
This commit is contained in:
@@ -21,7 +21,7 @@ import "core:strconv"
|
||||
import "core:unicode/utf8"
|
||||
import "core:encoding/hex"
|
||||
|
||||
split_url :: proc(url: string, allocator := context.allocator) -> (scheme, host, path: string, queries: map[string]string) {
|
||||
split_url :: proc(url: string, allocator := context.allocator) -> (scheme, host, path: string, queries: map[string]string, fragment: string) {
|
||||
s := url
|
||||
|
||||
i := strings.index(s, "://")
|
||||
@@ -30,6 +30,12 @@ split_url :: proc(url: string, allocator := context.allocator) -> (scheme, host,
|
||||
s = s[i+3:]
|
||||
}
|
||||
|
||||
i = strings.index_byte(s, '#')
|
||||
if i != -1 {
|
||||
fragment = s[i+1:]
|
||||
s = s[:i]
|
||||
}
|
||||
|
||||
i = strings.index(s, "?")
|
||||
if i != -1 {
|
||||
query_str := s[i+1:]
|
||||
@@ -62,7 +68,7 @@ split_url :: proc(url: string, allocator := context.allocator) -> (scheme, host,
|
||||
return
|
||||
}
|
||||
|
||||
join_url :: proc(scheme, host, path: string, queries: map[string]string, allocator := context.allocator) -> string {
|
||||
join_url :: proc(scheme, host, path: string, queries: map[string]string, fragment: string, allocator := context.allocator) -> string {
|
||||
b := strings.builder_make(allocator)
|
||||
strings.builder_grow(&b, len(scheme) + 3 + len(host) + 1 + len(path))
|
||||
|
||||
@@ -95,6 +101,13 @@ join_url :: proc(scheme, host, path: string, queries: map[string]string, allocat
|
||||
i += 1
|
||||
}
|
||||
|
||||
if fragment != "" {
|
||||
if fragment[0] != '#' {
|
||||
strings.write_byte(&b, '#')
|
||||
}
|
||||
strings.write_string(&b, strings.trim_space(fragment))
|
||||
}
|
||||
|
||||
return strings.to_string(b)
|
||||
}
|
||||
|
||||
|
||||
@@ -473,6 +473,7 @@ client_sends_server_data :: proc(t: ^testing.T) {
|
||||
URL_Test :: struct {
|
||||
scheme, host, path: string,
|
||||
queries: map[string]string,
|
||||
fragment: string,
|
||||
url: []string,
|
||||
}
|
||||
|
||||
@@ -481,58 +482,78 @@ split_url_test :: proc(t: ^testing.T) {
|
||||
test_cases := []URL_Test{
|
||||
{
|
||||
"http", "example.com", "/",
|
||||
{},
|
||||
{}, "",
|
||||
{"http://example.com"},
|
||||
},
|
||||
{
|
||||
"https", "odin-lang.org", "/",
|
||||
{},
|
||||
{}, "",
|
||||
{"https://odin-lang.org"},
|
||||
},
|
||||
{
|
||||
"https", "odin-lang.org", "/docs/",
|
||||
{},
|
||||
{}, "",
|
||||
{"https://odin-lang.org/docs/"},
|
||||
},
|
||||
{
|
||||
"https", "odin-lang.org", "/docs/overview",
|
||||
{},
|
||||
{}, "",
|
||||
{"https://odin-lang.org/docs/overview"},
|
||||
},
|
||||
{
|
||||
"http", "example.com", "/",
|
||||
{"a" = "b"},
|
||||
{"a" = "b"}, "",
|
||||
{"http://example.com?a=b"},
|
||||
},
|
||||
{
|
||||
"http", "example.com", "/",
|
||||
{"a" = ""},
|
||||
{"a" = ""}, "",
|
||||
{"http://example.com?a"},
|
||||
},
|
||||
{
|
||||
"http", "example.com", "/",
|
||||
{"a" = "b", "c" = "d"},
|
||||
{"a" = "b", "c" = "d"}, "",
|
||||
{"http://example.com?a=b&c=d"},
|
||||
},
|
||||
{
|
||||
"http", "example.com", "/",
|
||||
{"a" = "", "c" = "d"},
|
||||
{"a" = "", "c" = "d"}, "",
|
||||
{"http://example.com?a&c=d"},
|
||||
},
|
||||
{
|
||||
"http", "example.com", "/example",
|
||||
{"a" = "", "b" = ""},
|
||||
{"a" = "", "b" = ""}, "",
|
||||
{"http://example.com/example?a&b"},
|
||||
},
|
||||
{
|
||||
"https", "example.com", "/callback",
|
||||
{"redirect" = "https://other.com/login"},
|
||||
{"redirect" = "https://other.com/login"}, "",
|
||||
{"https://example.com/callback?redirect=https://other.com/login"},
|
||||
},
|
||||
{
|
||||
"http", "odin-lang.org", "/",
|
||||
{}, "Hellope",
|
||||
{"http://odin-lang.org#Hellope"}
|
||||
},
|
||||
{
|
||||
"https", "odin-lang.org", "/",
|
||||
{"a" = ""}, "Hellope",
|
||||
{"https://odin-lang.org?a#Hellope"}
|
||||
},
|
||||
{
|
||||
"http", "example.com", "/",
|
||||
{"a" = "b"}, "Hellope",
|
||||
{"http://example.com?a=b#Hellope"}
|
||||
},
|
||||
{
|
||||
"https", "example.com", "/example",
|
||||
{}, "Hellope",
|
||||
{"https://example.com/example#Hellope"}
|
||||
},
|
||||
}
|
||||
|
||||
for test in test_cases {
|
||||
scheme, host, path, queries := net.split_url(test.url[0])
|
||||
scheme, host, path, queries, fragment := net.split_url(test.url[0])
|
||||
defer {
|
||||
delete(queries)
|
||||
delete(test.queries)
|
||||
@@ -551,6 +572,9 @@ split_url_test :: proc(t: ^testing.T) {
|
||||
msg = fmt.tprintf("Expected `net.split_url` to return %s, got %s", expected, v)
|
||||
expect(t, v == expected, msg)
|
||||
}
|
||||
msg = fmt.tprintf("Expected `net.split_url` to return %s, got %s", test.fragment, fragment)
|
||||
expect(t, fragment == test.fragment, msg)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -560,53 +584,73 @@ join_url_test :: proc(t: ^testing.T) {
|
||||
test_cases := []URL_Test{
|
||||
{
|
||||
"http", "example.com", "/",
|
||||
{},
|
||||
{}, "",
|
||||
{"http://example.com/"},
|
||||
},
|
||||
{
|
||||
"https", "odin-lang.org", "/",
|
||||
{},
|
||||
{}, "",
|
||||
{"https://odin-lang.org/"},
|
||||
},
|
||||
{
|
||||
"https", "odin-lang.org", "/docs/",
|
||||
{},
|
||||
{}, "",
|
||||
{"https://odin-lang.org/docs/"},
|
||||
},
|
||||
{
|
||||
"https", "odin-lang.org", "/docs/overview",
|
||||
{},
|
||||
{}, "",
|
||||
{"https://odin-lang.org/docs/overview"},
|
||||
},
|
||||
{
|
||||
"http", "example.com", "/",
|
||||
{"a" = "b"},
|
||||
{"a" = "b"}, "",
|
||||
{"http://example.com/?a=b"},
|
||||
},
|
||||
{
|
||||
"http", "example.com", "/",
|
||||
{"a" = ""},
|
||||
{"a" = ""}, "",
|
||||
{"http://example.com/?a"},
|
||||
},
|
||||
{
|
||||
"http", "example.com", "/",
|
||||
{"a" = "b", "c" = "d"},
|
||||
{"a" = "b", "c" = "d"}, "",
|
||||
{"http://example.com/?a=b&c=d", "http://example.com/?c=d&a=b"},
|
||||
},
|
||||
{
|
||||
"http", "example.com", "/",
|
||||
{"a" = "", "c" = "d"},
|
||||
{"a" = "", "c" = "d"}, "",
|
||||
{"http://example.com/?a&c=d", "http://example.com/?c=d&a"},
|
||||
},
|
||||
{
|
||||
"http", "example.com", "/example",
|
||||
{"a" = "", "b" = ""},
|
||||
{"a" = "", "b" = ""}, "",
|
||||
{"http://example.com/example?a&b", "http://example.com/example?b&a"},
|
||||
},
|
||||
{
|
||||
"http", "odin-lang.org", "",
|
||||
{}, "Hellope",
|
||||
{"http://odin-lang.org#Hellope"}
|
||||
},
|
||||
{
|
||||
"https", "odin-lang.org", "",
|
||||
{"a" = ""}, "Hellope",
|
||||
{"https://odin-lang.org?a#Hellope"}
|
||||
},
|
||||
{
|
||||
"http", "example.com", "",
|
||||
{"a" = "b"}, "Hellope",
|
||||
{"http://example.com?a=b#Hellope"}
|
||||
},
|
||||
{
|
||||
"https", "example.com", "/example",
|
||||
{}, "Hellope",
|
||||
{"https://example.com/example#Hellope"}
|
||||
},
|
||||
}
|
||||
|
||||
for test in test_cases {
|
||||
url := net.join_url(test.scheme, test.host, test.path, test.queries)
|
||||
url := net.join_url(test.scheme, test.host, test.path, test.queries, test.fragment)
|
||||
defer {
|
||||
delete(url)
|
||||
delete(test.queries)
|
||||
|
||||
Reference in New Issue
Block a user