URL and URI parsing for Nim for C/JS backends. Similar api to browsers's window.location
.
Nim's standard library uri
module does not parse the query string. And Nim's standard library cgi
module does not work in js
mode. This module works everywhere and parses everything! Including providing an easy way to work with the query key-value pairs.
foo://admin:[email protected]:8042/over/there?name=ferret#nose
\_/ \___/ \_____/ \_________/ \__/\_________/ \_________/ \__/
| | | | | | | |
scheme username password hostname port path query fragment
let test = "foo://admin:[email protected]:8042/over/there?name=ferret#nose"
let url = parseUrl(test)
url.scheme == "foo"
url.username == "admin"
url.password == "hunter1"
url.hostname == "example.com"
url.port == "8042"
url.authority == "admin:[email protected]:8042"
url.path == "/over/there"
url.search == "name=ferret"
url.query["name"] == "ferret"
url.fragment == "nose"
$url == test
You can always turn a Url
into a string
with the $
function.
var url = Url()
url.hostname = "example.com"
url.query["q"] = "foo"
url.fragment = "heading1"
assert $url == "example.com?q=foo#heading1"
The Url.query
is just a sequence of key value pairs (seq[(string, string)]
). This preserves their order and allows 100% exact reconstruction of the url string. This also allows you to walk through each pair looking for things you need:
let url = parseUrl("?name=ferret&age=12&leg=1&leg=2&leg=3&leg=4")
for (k, v) in url.query:
if k == "leg":
echo v
But for most use cases a special []
is provided. This is the most common use of the query.
url.query["name"] == "ferret"
If the key repeats multiple times only the first one is returned using the []
method. Use the for loop method if you need to support multiple keys or preserves special ordering.
url.query["leg"] == "1"
Missing keys are just empty strings, no need to check if its there or handle exceptions:
url.query["missing"] == ""
You can also modify the query string with []=
method:
url.query["missing"] = "no more!"
import urliy
Url = ref object
scheme*, username*, password*: string
hostname*, port*, path*, fragment*: string
query*: seq[(string, string)]
Get a key out of url.query. Use a for loop to get multiple keys.
func `[]`(query: seq[(string, string)]; key: string): string
Sets a key in the url.query. If key is not there appends a new key-value pair at the end.
func `[]=`(query: var seq[(string, string)]; key, value: string)
Takes a string and encodes it in the URl format.
func encodeUrlComponent(s: string): string
Takes a string and decodes it from the URl format.
func decodeUrlComponent(s: string): string {.raises: [ValueError].}
Parses a URl or a URL into the Url object.
func parseUrl(s: string): Url {.raises: [ValueError].}
Returns Host and port part of the URl as a string.
func host(url: Url): string
Returns the search part of the URl as a string.
func search(url: Url): string
Returns the authority part of URl as a string.
func authority(url: Url): string
Turns Url into a string. Preserves query string param ordering.
func `$`(url: Url): string