mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 07:38:48 +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:
+15
-2
@@ -21,7 +21,7 @@ import "core:strconv"
|
|||||||
import "core:unicode/utf8"
|
import "core:unicode/utf8"
|
||||||
import "core:encoding/hex"
|
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
|
s := url
|
||||||
|
|
||||||
i := strings.index(s, "://")
|
i := strings.index(s, "://")
|
||||||
@@ -30,6 +30,12 @@ split_url :: proc(url: string, allocator := context.allocator) -> (scheme, host,
|
|||||||
s = s[i+3:]
|
s = s[i+3:]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i = strings.index_byte(s, '#')
|
||||||
|
if i != -1 {
|
||||||
|
fragment = s[i+1:]
|
||||||
|
s = s[:i]
|
||||||
|
}
|
||||||
|
|
||||||
i = strings.index(s, "?")
|
i = strings.index(s, "?")
|
||||||
if i != -1 {
|
if i != -1 {
|
||||||
query_str := s[i+1:]
|
query_str := s[i+1:]
|
||||||
@@ -62,7 +68,7 @@ split_url :: proc(url: string, allocator := context.allocator) -> (scheme, host,
|
|||||||
return
|
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)
|
b := strings.builder_make(allocator)
|
||||||
strings.builder_grow(&b, len(scheme) + 3 + len(host) + 1 + len(path))
|
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
|
i += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if fragment != "" {
|
||||||
|
if fragment[0] != '#' {
|
||||||
|
strings.write_byte(&b, '#')
|
||||||
|
}
|
||||||
|
strings.write_string(&b, strings.trim_space(fragment))
|
||||||
|
}
|
||||||
|
|
||||||
return strings.to_string(b)
|
return strings.to_string(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -473,6 +473,7 @@ client_sends_server_data :: proc(t: ^testing.T) {
|
|||||||
URL_Test :: struct {
|
URL_Test :: struct {
|
||||||
scheme, host, path: string,
|
scheme, host, path: string,
|
||||||
queries: map[string]string,
|
queries: map[string]string,
|
||||||
|
fragment: string,
|
||||||
url: []string,
|
url: []string,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -481,58 +482,78 @@ split_url_test :: proc(t: ^testing.T) {
|
|||||||
test_cases := []URL_Test{
|
test_cases := []URL_Test{
|
||||||
{
|
{
|
||||||
"http", "example.com", "/",
|
"http", "example.com", "/",
|
||||||
{},
|
{}, "",
|
||||||
{"http://example.com"},
|
{"http://example.com"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"https", "odin-lang.org", "/",
|
"https", "odin-lang.org", "/",
|
||||||
{},
|
{}, "",
|
||||||
{"https://odin-lang.org"},
|
{"https://odin-lang.org"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"https", "odin-lang.org", "/docs/",
|
"https", "odin-lang.org", "/docs/",
|
||||||
{},
|
{}, "",
|
||||||
{"https://odin-lang.org/docs/"},
|
{"https://odin-lang.org/docs/"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"https", "odin-lang.org", "/docs/overview",
|
"https", "odin-lang.org", "/docs/overview",
|
||||||
{},
|
{}, "",
|
||||||
{"https://odin-lang.org/docs/overview"},
|
{"https://odin-lang.org/docs/overview"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"http", "example.com", "/",
|
"http", "example.com", "/",
|
||||||
{"a" = "b"},
|
{"a" = "b"}, "",
|
||||||
{"http://example.com?a=b"},
|
{"http://example.com?a=b"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"http", "example.com", "/",
|
"http", "example.com", "/",
|
||||||
{"a" = ""},
|
{"a" = ""}, "",
|
||||||
{"http://example.com?a"},
|
{"http://example.com?a"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"http", "example.com", "/",
|
"http", "example.com", "/",
|
||||||
{"a" = "b", "c" = "d"},
|
{"a" = "b", "c" = "d"}, "",
|
||||||
{"http://example.com?a=b&c=d"},
|
{"http://example.com?a=b&c=d"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"http", "example.com", "/",
|
"http", "example.com", "/",
|
||||||
{"a" = "", "c" = "d"},
|
{"a" = "", "c" = "d"}, "",
|
||||||
{"http://example.com?a&c=d"},
|
{"http://example.com?a&c=d"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"http", "example.com", "/example",
|
"http", "example.com", "/example",
|
||||||
{"a" = "", "b" = ""},
|
{"a" = "", "b" = ""}, "",
|
||||||
{"http://example.com/example?a&b"},
|
{"http://example.com/example?a&b"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"https", "example.com", "/callback",
|
"https", "example.com", "/callback",
|
||||||
{"redirect" = "https://other.com/login"},
|
{"redirect" = "https://other.com/login"}, "",
|
||||||
{"https://example.com/callback?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 {
|
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 {
|
defer {
|
||||||
delete(queries)
|
delete(queries)
|
||||||
delete(test.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)
|
msg = fmt.tprintf("Expected `net.split_url` to return %s, got %s", expected, v)
|
||||||
expect(t, v == expected, msg)
|
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{
|
test_cases := []URL_Test{
|
||||||
{
|
{
|
||||||
"http", "example.com", "/",
|
"http", "example.com", "/",
|
||||||
{},
|
{}, "",
|
||||||
{"http://example.com/"},
|
{"http://example.com/"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"https", "odin-lang.org", "/",
|
"https", "odin-lang.org", "/",
|
||||||
{},
|
{}, "",
|
||||||
{"https://odin-lang.org/"},
|
{"https://odin-lang.org/"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"https", "odin-lang.org", "/docs/",
|
"https", "odin-lang.org", "/docs/",
|
||||||
{},
|
{}, "",
|
||||||
{"https://odin-lang.org/docs/"},
|
{"https://odin-lang.org/docs/"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"https", "odin-lang.org", "/docs/overview",
|
"https", "odin-lang.org", "/docs/overview",
|
||||||
{},
|
{}, "",
|
||||||
{"https://odin-lang.org/docs/overview"},
|
{"https://odin-lang.org/docs/overview"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"http", "example.com", "/",
|
"http", "example.com", "/",
|
||||||
{"a" = "b"},
|
{"a" = "b"}, "",
|
||||||
{"http://example.com/?a=b"},
|
{"http://example.com/?a=b"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"http", "example.com", "/",
|
"http", "example.com", "/",
|
||||||
{"a" = ""},
|
{"a" = ""}, "",
|
||||||
{"http://example.com/?a"},
|
{"http://example.com/?a"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"http", "example.com", "/",
|
"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=b&c=d", "http://example.com/?c=d&a=b"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"http", "example.com", "/",
|
"http", "example.com", "/",
|
||||||
{"a" = "", "c" = "d"},
|
{"a" = "", "c" = "d"}, "",
|
||||||
{"http://example.com/?a&c=d", "http://example.com/?c=d&a"},
|
{"http://example.com/?a&c=d", "http://example.com/?c=d&a"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"http", "example.com", "/example",
|
"http", "example.com", "/example",
|
||||||
{"a" = "", "b" = ""},
|
{"a" = "", "b" = ""}, "",
|
||||||
{"http://example.com/example?a&b", "http://example.com/example?b&a"},
|
{"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 {
|
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 {
|
defer {
|
||||||
delete(url)
|
delete(url)
|
||||||
delete(test.queries)
|
delete(test.queries)
|
||||||
|
|||||||
Reference in New Issue
Block a user