Skip to content

Commit

Permalink
net.urllib: fix parse of url relative address (fix vlang#21061) (vlan…
Browse files Browse the repository at this point in the history
  • Loading branch information
kbkpbot authored Dec 16, 2024
1 parent b1502d4 commit 03f3f7a
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 8 deletions.
21 changes: 13 additions & 8 deletions vlib/net/urllib/urllib.v
Original file line number Diff line number Diff line change
Expand Up @@ -436,11 +436,15 @@ fn split(s string, sep u8, cutc bool) (string, string) {
pub fn parse(rawurl string) !URL {
// Cut off #frag
u, frag := split(rawurl, `#`, true)
mut url := parse_url(u, false) or { return error(error_msg(err_msg_parse, u)) }
mut url := parse_url(u, false) or {
return error(error_msg(err_msg_parse + '[${err.msg()}]', u))
}
if frag == '' {
return url
}
f := unescape(frag, .encode_fragment) or { return error(error_msg(err_msg_parse, u)) }
f := unescape(frag, .encode_fragment) or {
return error(error_msg(err_msg_parse + '[${err.msg()}]', u))
}
url.fragment = f
return url
}
Expand Down Expand Up @@ -503,12 +507,13 @@ fn parse_url(rawurl string, via_request bool) !URL {
// RFC 3986, §3.3:
// In addition, a URI reference (Section 4.1) may be a relative-path reference,
// in which case the first path segment cannot contain a colon (':') character.
colon := rest.index(':') or { return error('there should be a : in the URL') }
slash := rest.index('/') or { return error('there should be a / in the URL') }
if colon >= 0 && (slash < 0 || colon < slash) {
// First path segment has colon. Not allowed in relative URL.
return error(error_msg('parse_url: first path segment in URL cannot contain colon',
''))
if colon := rest.index(':') {
slash := rest.index('/') or { return error('there should be a / in the URL') }
if colon >= 0 && (slash < 0 || colon < slash) {
// First path segment has colon. Not allowed in relative URL.
return error(error_msg('parse_url: first path segment in URL cannot contain colon',
''))
}
}
}
if ((url.scheme != '' || !via_request) && !rest.starts_with('///')) && rest.starts_with('//')
Expand Down
6 changes: 6 additions & 0 deletions vlib/net/urllib/urllib_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ fn test_parse() {
'foo://example.com:8042/over/there?name=ferret#nose',
'ftp://2001:0db8:85a3:0000:0000:8a2e:0370:7334/path/file.txt',
'ws://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:4000',
'/2000k/hls/mixed.m3u8',
'2000k/hls/mixed.m3u8',
'./2000k:hls/mixed.m3u8',
]
for url in urls {
urllib.parse(url)!
Expand All @@ -112,6 +115,9 @@ fn test_parse() {
assert u.scheme == 'https' && u.hostname() == 'www.mydomain.com' && u.port() == '8080'
&& u.path == '/som/url' && u.fragment == 'testfragment' && u.user.username == 'joe'
&& u.user.password == 'pass'

v := urllib.parse('https://vip.ffzy-online4.com/20230205/6094_d2720761/index.m3u8')!.resolve_reference(urllib.parse('2000k/hls/mixed.m3u8')!)!
assert v.str() == 'https://vip.ffzy-online4.com/20230205/6094_d2720761/2000k/hls/mixed.m3u8'
}

fn test_parse_authority() {
Expand Down

0 comments on commit 03f3f7a

Please sign in to comment.