Skip to content

Commit c635c10

Browse files
authored
Url: Support URIs in query parameters (#344)
Align with `basic-webserver`: roc-lang/basic-webserver#115 Query parameters should generally be percent-encoded but it's not required. Google's OAuth doesn't percent-encode their redirect URIs which prompted this PR.
1 parent 62363cd commit c635c10

File tree

1 file changed

+26
-10
lines changed

1 file changed

+26
-10
lines changed

platform/Url.roc

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -482,16 +482,19 @@ query_params = |url|
482482
path : Url -> Str
483483
path = |@Url(url_str)|
484484
without_authority =
485-
when Str.split_first(url_str, ":") is
486-
Ok({ after }) ->
487-
when Str.split_first(after, "//") is
488-
# Only drop the `//` if it's right after the `://` like in `https://`
489-
# (so, `before` is empty) - otherwise, the `//` is part of the path!
490-
Ok({ before, after: after_slashes }) if Str.is_empty(before) -> after_slashes
491-
_ -> after
492-
493-
# There's no `//` and also no `:` so this must be a path-only URL, e.g. "/foo?bar=baz#blah"
494-
Err(NotFound) -> url_str
485+
if Str.starts_with(url_str, "/") then
486+
url_str
487+
else
488+
when Str.split_first(url_str, ":") is
489+
Ok({ after }) ->
490+
when Str.split_first(after, "//") is
491+
# Only drop the `//` if it's right after the `://` like in `https://`
492+
# (so, `before` is empty) - otherwise, the `//` is part of the path!
493+
Ok({ before, after: after_slashes }) if Str.is_empty(before) -> after_slashes
494+
_ -> after
495+
496+
# There's no `//` and also no `:` so this must be a path-only URL, e.g. "/foo?bar=baz#blah"
497+
Err(NotFound) -> url_str
495498

496499
# Drop the query and/or fragment
497500
when Str.split_last(without_authority, "?") is
@@ -500,3 +503,16 @@ path = |@Url(url_str)|
500503
when Str.split_last(without_authority, "#") is
501504
Ok({ before }) -> before
502505
Err(NotFound) -> without_authority
506+
507+
# `Url.path` supports non-encoded URIs in query parameters (https://datatracker.ietf.org/doc/html/rfc3986#section-3.4)
508+
expect
509+
input = Url.from_str("https://example.com/foo/bar?key1=https://www.baz.com/some-path#stuff")
510+
expected = "example.com/foo/bar"
511+
path(input) == expected
512+
513+
# `Url.path` supports non-encoded URIs in query parameters (https://datatracker.ietf.org/doc/html/rfc3986#section-3.4)
514+
expect
515+
input = Url.from_str("/foo/bar?key1=https://www.baz.com/some-path#stuff")
516+
output = Url.path(input)
517+
expected = "/foo/bar"
518+
output == expected

0 commit comments

Comments
 (0)