hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 40f16febd26f41ab6978625f273349d2ea3a0306
parent c9fb75f584944c9e4a258fa1c2cffe2f3991681d
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Sat, 22 Jul 2023 06:37:39 +0200

net/uri: Always prefix path with a slash when there's a host

Diffstat:
Mnet/uri/+test.ha | 15+++++++++++++++
Mnet/uri/fmt.ha | 6++++++
2 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/net/uri/+test.ha b/net/uri/+test.ha @@ -91,6 +91,21 @@ use net::ip; )!; }; +@test fn edge_cases() void = { + const expected = "https://en.wiktionary.org/wiki/%E3%81%8A%E3%81%AF%E3%82%88%E3%81%86#Japanese"; + const u = uri { + scheme = "https", + host = "en.wiktionary.org", + path = "wiki/おはよう", + fragment = "Japanese", + ... + }; + let s = string(&u); + defer free(s); + + assert_str(s, expected); +}; + @test fn invalid() void = { // Scheme assert(parse(":") is invalid); diff --git a/net/uri/fmt.ha b/net/uri/fmt.ha @@ -27,6 +27,7 @@ def unres_path: str = "-._~!$&'()*+,;=:@/"; export fn fmt(out: io::handle, u: *const uri) (size | io::error) = { let n = 0z; let slashes_w = false; + let has_host = false; if (u.scheme != "") { n += fmt::fprintf(out, "{}:", u.scheme)?; }; @@ -39,6 +40,7 @@ export fn fmt(out: io::handle, u: *const uri) (size | io::error) = { case let host: str => // file scheme is allowed an empty host if (len(host) > 0 || u.scheme == "file") { + has_host = true; if (!slashes_w) { n += fmt::fprint(out, "//")?; }; @@ -50,6 +52,7 @@ export fn fmt(out: io::handle, u: *const uri) (size | io::error) = { n += percent_encode(out, host, unres)?; }; case let addr: ip::addr => + has_host = true; if (!slashes_w) { n += fmt::fprint(out, "//")?; }; @@ -58,6 +61,9 @@ export fn fmt(out: io::handle, u: *const uri) (size | io::error) = { if (u.port != 0) { n += fmt::fprintf(out, ":{}", u.port)?; }; + if (has_host && len(u.path) > 0 && !strings::hasprefix(u.path, '/')) { + n += fmt::fprint(out, "/")?; + }; n += percent_encode(out, u.path, unres_path)?; if (len(u.query) > 0) { // Always percent-encoded, see parse and encodequery/decodequery