URLs

URLs are CLOS objects after the pattern of PATHNAMEs in ANSI CL. There is theoretically a class per URL scheme, but only HTTP-URL and HTTPS-URL are currently defined. They behave very very similarly

Creating URLs

(make-instance 'http-url :host "foo.com" :port "8000" :scheme "HTTP"
	:path "/bar")
=> url

(parse-urlstring "http://foo.com:8000/")
=> url

(merge-url an-existing-url "/relative?url")
=> url

Accessors

url-scheme url-endpoint url-path url-query url-fragment

also url-host url-port ( url-endpoint = url-host ":" url-port )

These also have SETF methods. The behaviour of (setf url-scheme) is undefined, however, and it will probably go away unless somebody suggests a sensible one.

Relative URLs

Relative URLs are not implemented as objects - if we don't know what scheme they have, we don't know how to parse them. We do have a procedure merge-url that merges a base url with a string, though, which caters for most uses.

(merge-url url string)

will create and return a new URL from STRING according to the rules for creating relative URLs. Note that this is a complex operation which takes a whole RFC to describe, and it's unlikey that we do it correctly in weird cases. Relative URLs with authority components containing non-standard hosts are currently known to be broken.

In addition, there is also append-url which is very crude. It functions similarly to merge-url, but it is not recommended that you use it. The ONE time it is recommended is when you want to concatenate a URL with a string that begins with a slash.

(let ((url (parse-urlstring "http://example.com/my/example")))
  (format t "merge: ~A~%" (merge-url url "/is/here"))
  (format t "append: ~A~%" (append-url url "/is/here")))

merge: #<HTTP-URL "http://example.com/is/here" {9506011}>
append: #<HTTP-URL "http://example.com/my/example/is/here" {95073B9}>