summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorDominik Picheta <dominikpicheta@googlemail.com>2015-08-23 18:22:37 +0100
committerDominik Picheta <dominikpicheta@googlemail.com>2015-08-23 18:22:37 +0100
commit193f248ea0d510171b69e8e690eaaa05509be47f (patch)
treecbc6b33c7daffca3eb7bb56f074dfc926e78b793
parentdd2a0ec431c17f165c18b976d01195b93b69b5e8 (diff)
downloadNim-193f248ea0d510171b69e8e690eaaa05509be47f.tar.gz
Fixes parsing of URIs that begin with '//'.
-rw-r--r--lib/pure/uri.nim27
1 files changed, 20 insertions, 7 deletions
diff --git a/lib/pure/uri.nim b/lib/pure/uri.nim
index 1890a9bf4..492de3b46 100644
--- a/lib/pure/uri.nim
+++ b/lib/pure/uri.nim
@@ -14,7 +14,7 @@ type
   Url* = distinct string
 
   Uri* = object
-    scheme*, username*, password*: string 
+    scheme*, username*, password*: string
     hostname*, port*, path*, query*, anchor*: string
     opaque*: bool
 
@@ -69,7 +69,7 @@ proc parseAuthority(authority: string, result: var Uri) =
     i.inc
 
 proc parsePath(uri: string, i: var int, result: var Uri) =
-  
+
   i.inc parseUntil(uri, result.path, {'?', '#'}, i)
 
   # The 'mailto' scheme's PATH actually contains the hostname/username
@@ -104,19 +104,23 @@ proc parseUri*(uri: string, result: var Uri) =
   var i = 0
 
   # Check if this is a reference URI (relative URI)
+  let doubleSlash = uri.len > 1 and uri[1] == '/'
   if uri[i] == '/':
-    parsePath(uri, i, result)
-    return
+    # Make sure ``uri`` doesn't begin with '//'.
+    if not doubleSlash:
+      parsePath(uri, i, result)
+      return
 
   # Scheme
   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)
     i = 0
     result.scheme.setLen(0)
     parsePath(uri, i, result)
     return
-  i.inc # Skip ':'
+  if not doubleSlash:
+    i.inc # Skip ':'
 
   # Authority
   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"))
   ##   assert bar.path == "/foo/bar/baz"
-  
+
   template setAuthority(dest, src: expr): stmt =
     dest.hostname = src.hostname
     dest.username = src.username
@@ -369,6 +373,15 @@ when isMainModule:
     doAssert test.path == "test/no/slash"
     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
   block:
     doAssert removeDotSegments("/foo/bar/baz") == "/foo/bar/baz"