Fixes parsing of URIs that begin with '//'.
This commit is contained in:
parent
dd2a0ec431
commit
193f248ea0
1 changed files with 20 additions and 7 deletions
|
|
@ -14,7 +14,7 @@ type
|
||||||
Url* = distinct string
|
Url* = distinct string
|
||||||
|
|
||||||
Uri* = object
|
Uri* = object
|
||||||
scheme*, username*, password*: string
|
scheme*, username*, password*: string
|
||||||
hostname*, port*, path*, query*, anchor*: string
|
hostname*, port*, path*, query*, anchor*: string
|
||||||
opaque*: bool
|
opaque*: bool
|
||||||
|
|
||||||
|
|
@ -69,7 +69,7 @@ proc parseAuthority(authority: string, result: var Uri) =
|
||||||
i.inc
|
i.inc
|
||||||
|
|
||||||
proc parsePath(uri: string, i: var int, result: var Uri) =
|
proc parsePath(uri: string, i: var int, result: var Uri) =
|
||||||
|
|
||||||
i.inc parseUntil(uri, result.path, {'?', '#'}, i)
|
i.inc parseUntil(uri, result.path, {'?', '#'}, i)
|
||||||
|
|
||||||
# The 'mailto' scheme's PATH actually contains the hostname/username
|
# The 'mailto' scheme's PATH actually contains the hostname/username
|
||||||
|
|
@ -104,19 +104,23 @@ proc parseUri*(uri: string, result: var Uri) =
|
||||||
var i = 0
|
var i = 0
|
||||||
|
|
||||||
# Check if this is a reference URI (relative URI)
|
# Check if this is a reference URI (relative URI)
|
||||||
|
let doubleSlash = uri.len > 1 and uri[1] == '/'
|
||||||
if uri[i] == '/':
|
if uri[i] == '/':
|
||||||
parsePath(uri, i, result)
|
# Make sure ``uri`` doesn't begin with '//'.
|
||||||
return
|
if not doubleSlash:
|
||||||
|
parsePath(uri, i, result)
|
||||||
|
return
|
||||||
|
|
||||||
# Scheme
|
# Scheme
|
||||||
i.inc parseWhile(uri, result.scheme, Letters + Digits + {'+', '-', '.'}, i)
|
i.inc parseWhile(uri, result.scheme, Letters + Digits + {'+', '-', '.'}, i)
|
||||||
if uri[i] != ':':
|
if uri[i] != ':' and not doubleSlash:
|
||||||
# Assume this is a reference URI (relative URI)
|
# Assume this is a reference URI (relative URI)
|
||||||
i = 0
|
i = 0
|
||||||
result.scheme.setLen(0)
|
result.scheme.setLen(0)
|
||||||
parsePath(uri, i, result)
|
parsePath(uri, i, result)
|
||||||
return
|
return
|
||||||
i.inc # Skip ':'
|
if not doubleSlash:
|
||||||
|
i.inc # Skip ':'
|
||||||
|
|
||||||
# Authority
|
# Authority
|
||||||
if uri[i] == '/' and uri[i+1] == '/':
|
if uri[i] == '/' and uri[i+1] == '/':
|
||||||
|
|
@ -201,7 +205,7 @@ proc combine*(base: Uri, reference: Uri): Uri =
|
||||||
##
|
##
|
||||||
## let bar = combine(parseUri("http://example.com/foo/bar/"), parseUri("baz"))
|
## let bar = combine(parseUri("http://example.com/foo/bar/"), parseUri("baz"))
|
||||||
## assert bar.path == "/foo/bar/baz"
|
## assert bar.path == "/foo/bar/baz"
|
||||||
|
|
||||||
template setAuthority(dest, src: expr): stmt =
|
template setAuthority(dest, src: expr): stmt =
|
||||||
dest.hostname = src.hostname
|
dest.hostname = src.hostname
|
||||||
dest.username = src.username
|
dest.username = src.username
|
||||||
|
|
@ -369,6 +373,15 @@ when isMainModule:
|
||||||
doAssert test.path == "test/no/slash"
|
doAssert test.path == "test/no/slash"
|
||||||
doAssert($test == str)
|
doAssert($test == str)
|
||||||
|
|
||||||
|
block:
|
||||||
|
let str = "//git@github.com:dom96/packages"
|
||||||
|
let test = parseUri(str)
|
||||||
|
doAssert test.scheme == ""
|
||||||
|
doAssert test.username == "git"
|
||||||
|
doAssert test.hostname == "github.com"
|
||||||
|
doAssert test.port == "dom96"
|
||||||
|
doAssert test.path == "/packages"
|
||||||
|
|
||||||
# Remove dot segments tests
|
# Remove dot segments tests
|
||||||
block:
|
block:
|
||||||
doAssert removeDotSegments("/foo/bar/baz") == "/foo/bar/baz"
|
doAssert removeDotSegments("/foo/bar/baz") == "/foo/bar/baz"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue