Docs/Networking

URLs

Parse, build, and encode URLs.

On this page

valk.url splits URLs into their parts, resolves links, and encodes query strings and other components.

Parse a URL#

Valk
use valk.url

fn main() {
    let u = url.parse("https://ada:secret@example.com:8443/docs/intro.html?lang=en#install")
    println(u.scheme)            // https
    println(u.user)              // ada
    println(u.host)              // example.com
    println(u.port ?? 0)         // 8443
    println(u.path)              // /docs/intro.html
    println(u.query)             // lang=en
    println(u.fragment)          // install
    println(u.host_with_port())  // example.com:8443
}

parse never fails: missing parts are empty and port is null. The parts stay percent-encoded. Change any field and to_string() (or printing) puts the URL back together.

resolve reads a link against the page it was found on, the way a browser does:

Valk
use valk.url

fn main() {
    let page = url.parse("https://example.com/docs/guide/intro.html")
    println(page.resolve("../img/logo.png"))     // https://example.com/docs/img/logo.png
    println(page.resolve("/about"))              // https://example.com/about
    println(page.resolve("//cdn.example.com/x")) // https://cdn.example.com/x
}

Query strings#

Valk
use valk.url

fn main() {
    let query = url.build_query(Map[String]{ "q" => "a b&c" })
    println(query) // q=a%20b%26c

    let params = url.parse_query("q=a%20b&page=2")
    println(params.get("q") !? "")    // a b
    println(params.get("page") !? "") // 2

    let tags = url.parse_query_grouped("tag=x&tag=y")
    let values = tags.get("tag") ! return
    println(values.join(", ")) // x, y
}

parse_query keeps the last value of a repeated key, parse_query_grouped keeps them all, and build_query_grouped writes them back.

Encode and decode a value#

Valk
use valk.url

fn main() {
    println(url.encode("a b/c"))                     // a%20b%2Fc
    println(url.encode("a b/c", url.Component.path)) // a%20b/c
    println(url.decode("a%20b+c"))                   // a b c
    println(url.decode_path("a%20b+c"))              // a b+c
}

encode escapes everything but letters, digits and -._~ by default; Component.path, query and fragment leave the characters that component allows. decode also turns + into a space, as forms do; decode_path does not, which is right for URL paths such as an HTTP request's path.