Skip to content

Latest commit

 

History

105 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

uri

is a URI datatype and parser for Carp.

Installation

(load "git@github.com:carpentry-org/uri@0.5.1")

Usage

To get started, you’ll most probably want to parse a URI from a string. To do so, you use URI.parse. This function will return a URI datatype for you to work with, or an error type if the URI string was invalid.

If you have a a URI value the simplest operation is probably converting the URI back to a string using the str interface, which should be idempotent—i.e. you’ll get the original URI back.

You can also ask the URI for its properties, like the scheme, the port, or the URI parameters.

Query parameters

URI.query-map parses the query component into a Map String String. Since a map holds one value per key, repeated keys such as ?tag=a&tag=b keep only the last value. When repeated keys matter—checkbox lists, multi-select forms, ?id=1&id=2—use URI.query-multimap, which collects every value for a key into an Array, in the order it appeared:

(def u (Result.unsafe-from-success (URI.parse "http://x/?tag=a&tag=b&sort=asc")))
(URI.query-multimap &u)      ; => Success {"tag" ["a" "b"] "sort" ["asc"]}
(URI.query-values &u "tag")  ; => ["a" "b"]

URI.query-values returns just the values for one key (empty when it is absent), and URI.query-multimap-from-str does the same as query-multimap for a bare querystring.

Resolving relative references

URI.resolve resolves a relative URI reference against a base URI, following RFC 3986 section 5:

(def base (Result.unsafe-from-success (URI.parse "http://a/b/c/d;p?q")))
(URI.resolve &base "../g")   ; => Success http://a/b/g
(URI.resolve &base "/g")     ; => Success http://a/g
(URI.resolve &base "?y")     ; => Success http://a/b/c/d;p?y
(URI.resolve &base "//h/p")  ; => Success http://h/p

URI.remove-dot-segments is the underlying path normalizer (RFC 3986 section 5.2.4). It resolves . and .. segments in a path string:

(URI.remove-dot-segments "/a/b/c/./../../g") ; => "/a/g"

Normalizing URIs

URI.normalize brings a URI into the canonical form described by RFC 3986 section 6.2, so that two URIs denoting the same resource compare equal under URI.=:

(def u (Result.unsafe-from-success
         (URI.parse "HTTP://User@Example.COM:80/%7Ejoe/./index.html")))
(URI.str &(URI.normalize &u)) ; => "http://User@example.com/~joe/index.html"

It lower-cases the scheme and host, upper-cases the hex digits of retained percent-escapes, decodes percent-escaped unreserved characters, removes ./.. segments from the path, and drops a port that equals the scheme's default. The case of the userinfo, path, query, and fragment is preserved.

A more complete documentation can be found under https://veitheller.de/uri/!

Acknowledgements

This datatype and parser was heavily inspired by the one in the Crystal standard library. I cannot thank the people who worked on it enough; they saved me from going through a lot of pain and suffering!


Have fun!

About

A URI datatype and parser for Carp

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages