uri-old:   Web URI and URL
1 Introduction
2 Escaping and Unescaping
2.1 Escaping
uri-escape
uri-escape-i
uri-escape-nm
uri-plusescape
uri-plusescape-i
uri-plusescape-nm
2.2 Unescaping
uri-unescape
uri-unescape-i
uri-unescape-nm
uri-unplusescape
uri-unplusescape-i
uri-unplusescape-nm
char->uri-escaped-string
char->uri-escaped-string-i
3 URI Representation
uri?
uri-string?
3.1 Converting Strings to URI Objects
string->uri
string/  base->uri
substring->uri
substring/  base->uri
uri-string->uri
3.2 Writing URIs to Ports and Converting URIs to Strings
display-uri
display-uri/  nofragment
uri->string
uri->string/  nofragment
4 URI Schemes
urischeme?
ftp-urischeme
gopher-urischeme
http-urischeme
https-urischeme
imap-urischeme
ipp-urischeme
news-urischeme
nfs-urischeme
telnet-urischeme
uri-scheme
uri-with-scheme
string->urischeme
symbol->urischeme
urischeme->string
urischeme-hierarchical?
urischeme-default-portnum
5 URI Reference Fragment Identifiers
uri-fragment
uri-fragment/  escaped
uri-without-fragment
uri-with-fragment
uri-with-fragment/  escaped
uri-with-fragment
uri-with-fragment/  escaped
6 Hierarchical URIs
uri-hierarchical?
7 Server-Based Naming Authorities
uri-server-userinfo+  host+  portnum
uri-server-userinfo
uri-server-host
uri-server-portnum
uri-uriserver
uri-uriserver+  path+  query
uri-uriserver+  uripath+  uriquery
uri-userinfo+  host+  portnum
uri-portnum
make-uriserver
make-uriserver/  default-portnum
string->uriserver
string/  base->uriserver
string/  default-portnum->uriserver
string/  base/  default-portnum->uriserver
substring->uriserver
substring/  base->uriserver
substring/  default-portnum->uriserver
substring/  base/  default-portnum->uriserver
uriserver-userinfo
uriserver-host
uriserver-portnum
uriserver-userinfo+  host+  portnum
write-uriserver
uriserver-with-default-portnum
resolve-uriserver
resolve-uriserver/  default-portnum
8 Hierarchical Paths
uri-path-upcount+  segments
uri-path-upcount+  segments/  reverse
uri-path-upcount
uri-path-segments
uri-path-segments/  reverse
urisegment-name
urisegment-params
urisegment-name+  params
urisegment-has-params?
uri-path
uri-path/  noparams
uri-uripath
uri-uripath/  noparams
make-uripath
make-uripath/  reverse
make-uripath/  reverse/  shared-ok
uripath-with-upcount
string->uripath
string/  base->uripath
substring->uripath
substring/  base->uripath
uripath-upcount
uripath-segments
uripath-segments/  reverse
uripath-upcount+  segments
uripath-upcount+  segments/  reverse
uripath-has-params?
write-uripath
write-uripath/  leading-slash
uripath->string
uripath->string/  leading-slash
resolve-uripath
absolute-uripath
9 Attribute-Value Queries
uri-query
uri-query-value
uriquery-value
uri-uriquery
string->uriquery
substring->uriquery
write-uriquery
10 Resolution
absolute-uri?
resolve-uri
absolute-uri
11 Antiresolution
antiresolve-uripath
antiresolve-uriserver
antiresolve-uri
12 Known Issues
13 History
14 Legal
3:0

uri-old: Web URI and URL

Neil Van Dyke

 (require uri-old) package: uri-old

1 Introduction

Note: This package provides an old and incompletely-documented API that nevertheless is in use, and that does some neat things. So the package has been added to the Racket package catalog as package name uri-old.
The uri-old Racket package implements parsing, representation, and transforming of Web Uniform Resource Identifiers (URI), which includes Uniform Resource Locators (URL) and Uniform Resource Names (URN). It supports absolute and relative URIs and URI references. This library does not implement features for using URI to retrieve objects from the Web, such as making HTTP requests.
RFC 3305 was the principal reference used for this implementation. Earlier versions were informed by other RFCs, including RFC 2396 and RFC 2732.
Goals of this package are correctness, efficiency, and power.

2 Escaping and Unescaping

Several procedures to support escaping and unescaping of URI component strings, as described in [RFC2396 sec. 2.4], are provided. Also provided are escaping and unescaping procedures that also support + as an encoding of a space character, as is used in some HTTP encodings of HTML forms.
These procedures have multiple variants, concerning mutability and sharing of the strings they yield, with following the naming convention:
  • foo If the output would be equal to the input, might yield the identical input string rather than a copy. Output might or might not be mutable.

  • foo-i Always yields an immutable string.

  • foo-nm Always yields a new, mutable string.

Many applications will not call these procedures directly, since most of this library’s interface automatically escapes and unescapes strings as appropriate.

2.1 Escaping

procedure

(uri-escape str [start end])  string?

  str : string?
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (string-length str)
(uri-escape-i str [start end])  immutable-string?
  str : string?
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (string-length str)
(uri-escape-nm str [start end])  string?
  str : string?
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (string-length str)
Yields a URI-escaped encoding of string str. If start and end are given, then they designate the substring of str to use. All characters are escaped, except alphanumerics, minus, underscore, period, and tilde. For example.
> (uri-escape "a = b/c + d")
  "a%20%3D%20b%2Fc%20%2B%20d"

procedure

(uri-plusescape str [start end])  string?

  str : string?
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (string-length str)
(uri-plusescape-i str [start end])  immutable-string?
  str : string?
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (string-length str)
(uri-plusescape-nm str [start end])  string?
  str : string?
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (string-length str)
Like uri-escape, except encodes space characters as + instead of "%20". This should generally only be used to mimic the encoding some Web browsers do of HTML form values. For example:
> (uri-plusescape "a = b/c + d")
  "a+%3D+b%2Fc+%2B+d"

2.2 Unescaping

procedure

(uri-unescape str [start end])  string?

  str : string?
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (string-length str)
(uri-unescape-i str [start end])  immutable-string?
  str : string?
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (string-length str)
(uri-unescape-nm str [start end])  string?
  str : string?
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (string-length str)
Yields an URI-unescaped string from the encoding in string str. If start and end are given, then they designate the substring of str to use. For example:
> (uri-unescape "a%20b+c%20d")
  "a b+c d"

procedure

(uri-unplusescape str [start end])  string?

  str : string?
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (string-length str)
(uri-unplusescape-i str [start end])  immutable-string?
  str : string?
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (string-length str)
(uri-unplusescape-nm str [start end])  string?
  str : string?
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (string-length str)
Like uri-unescape, but also decodes the plus (+) character to space character. For example:
> (uri-unplusescape "a%20b+c%20d")
  "a b c d"

procedure

(char->uri-escaped-string chr)  string?

  chr : character?
(char->uri-escaped-string-i chr)  string?
  chr : character?
Yields a URI-escaped string of character chr. For example:
> (char->uri-escaped-string #\/)
  "%2F"

3 URI Representation

This package can deal with URI expressed in one of two forms: a special uri object, and a string. In this way, it is similar to the Racket path object and operations. The support for strings is as a convenience for programming. In general, procedures that return a URI will do so as a uri object, even if provided strings as arguments.

procedure

(uri? x)  boolean?

  x : any/c
Predicate for whether x is a uri object.

procedure

(uri-string? x)  boolean?

  x : any/c
Predicate for whether x is either a uri object or a string.

3.1 Converting Strings to URI Objects

procedure

(string->uri str)  uri?

  str : string?
(string/base->uri str base)  uri?
  str : string?
  base : uri-string?
!!!
Note that the value of (uri->string (string->uri S)) will not always be equal to S.

procedure

(substring->uri str start end)  uri?

  str : string?
  start : exact-nonnegative-integer?
  end : exact-nonnegative-integer?
(substring/base->uri str start end)  uri?
  str : string?
  start : exact-nonnegative-integer?
  end : exact-nonnegative-integer?
!!!

procedure

(uri-string->uri uri)  uri?

  uri : uri-string?
!!!

3.2 Writing URIs to Ports and Converting URIs to Strings

procedure

(display-uri uri [port])  void?

  uri : uri-string?
  port : output-port? = (current-output-port)
(display-uri/nofragment uri [port])  void?
  uri : uri-string?
  port : output-port? = (current-output-port)
Displays uri to output port port. For example:

> (display-uri "http://s/foo#bar")

http://s/foo#bar

> (display-uri/nofragment "http://s/foo#bar")

http://s/foo

procedure

(uri->string uri)  string?

  uri : uri-string?
(uri->string/nofragment uri)  string?
  uri : uri-string?
Yields the full string representation of URI uri. Of course this is not needed when using only the string representation of URI, but using this procedure in libraries permits the uri to also be used. For example:

> (define my-uri (string->uri "http://www/"))

> my-uri
  #uri"http://www/"
> (uri->string my-uri)
  "http://www/"

4 URI Schemes

URI schemes are currently represented as lowercase Racket symbols and associated data.

procedure

(urischeme? x)  boolean?

  x : any/c
Predicate for whether or not x is a urischeme.

value

ftp-urischeme : urischeme?

value

gopher-urischeme : urischeme?

value

http-urischeme : urischeme?

value

https-urischeme : urischeme?

value

imap-urischeme : urischeme?

value

ipp-urischeme : urischeme?

value

news-urischeme : urischeme?

value

nfs-urischeme : urischeme?

value

telnet-urischeme : urischeme?

Some common URI scheme symbols. (These are not so useful; they were in an earlier version of this library that needed to work with Scheme implementations with case-insensitive readers.)
> ftp-urischeme
  ftp

procedure

(uri-scheme uri)  (or/c urischeme? #f)

  uri : uri-string?
Yields the URI scheme of uri, or #f if none can be determined. For example:
> (uri-scheme "Http://www")
  http

procedure

(uri-with-scheme uri urischeme)  uri?

  uri : uri-string?
  urischeme : urischeme?
!!!

procedure

(string->urischeme str)  urischeme?

  str : string?
(symbol->urischeme sym)  urischeme?
  sym : symbol?
!!!

procedure

(urischeme->string urischeme)  string?

  urischeme : urischeme?
!!!

procedure

(urischeme-hierarchical? urischeme)  urischeme?

  urischeme : urischeme?
!!!

procedure

(urischeme-default-portnum urischeme)

  exact-nonnegative-integer?
  urischeme : urischeme
!!!

5 URI Reference Fragment Identifiers

procedure

(uri-fragment uri)  (or/c #f string?)

  uri : uri-string?
(uri-fragment/escaped uri)  (or/c #f string?)
  uri : uri-string?
Yields the fragment identifier component of URI (or URI reference) uri as a string, or #f if there is no fragment. uri-fragment yields the fragment in unescaped form, and uri-fragment/escaped yields an escaped form in the unusual case that is desired. For example:
> (uri-fragment         "foo#a%20b")
  "a b"
> (uri-fragment/escaped "foo#a%20b")
  "a%20b"

procedure

(uri-without-fragment uri)  uri?

  uri : uri-string?
Yields uri without the fragment component. For example:
> (uri-without-fragment "http://w/#bar")
  #uri"http://w/"

procedure

(uri-with-fragment uri fragment)  uri?

  uri : uri-string?
  fragment : (or/c #f string?)
(uri-with-fragment/escaped uri fragment)  uri?
  uri : uri-string?
  fragment : (or/c #f string?)
Yields a URI that is like uri except with the fragment fragment (or no fragment, if fragment is #f). For example:
> (uri-with-fragment "http://w/"     "foo")
  "http://w/#foo"
> (uri-with-fragment "http://w/#foo" "bar")
  "http://w/#bar"
> (uri-with-fragment "http://w/#bar" #f)
  "http://w/"
The uri-with-fragment/escaped variant can be used when the desired fragment string is already in uri-escaped form:
> (uri-with-fragment         "foo" "a b")
  "foo#a%20b"
> (uri-with-fragment/escaped "foo" "a%20b")
  "foo#a%20b"

procedure

(uri-with-fragment uri fragment)  uri?

  uri : uri-string?
  fragment : string?
(uri-with-fragment/escaped uri fragment)  uri?
  uri : uri-string?
  fragment : string?
!!!

6 Hierarchical URIs

This and some of the following sections concern “hierarchical” generic URI syntax as described in RFC2396, sec. 3.

procedure

(uri-hierarchical? uri)  boolean?

  uri : uri-string?
Yields a Boolean value for whether or not the URI scheme of URI uri is known to have a “hierarchical” generic URI layout. For example:
> (uri-hierarchical? "http://www/")
  #t
> (uri-hierarchical? "mailto://www/")
  #f
> (uri-hierarchical? "//www/")
  #f

7 Server-Based Naming Authorities

Several procedures extract the server authority values from URIs [RFC2396 sec. 3.2.2].

procedure

(uri-server-userinfo+host+portnum uri)

  
(or/c #f string?)
(or/c #f string?)
(or/c #f exact-nonnegative-integer?)
  uri : uri-string?
Yields three values for the server authority of URI uri: the userinfo as a string (or #f), the host as a string (or #f), and the effective port number as an integer (or #f). The effective port number of a server authority defaults to the default of the URI scheme unless overridden. For example (note the effective port number is 21, the default for the ftp scheme):
> (uri-server-userinfo+host+portnum "ftp://[email protected]@ftp.foo.bar/")
  "anon" "ftp.foo.bar" 21

procedure

(uri-server-userinfo uri)  (or/c #f string?)

  uri : uri-string?
(uri-server-host uri)  (or/c #f string?)
  uri : uri-string?
(uri-server-portnum uri)  (or/c #f exact-nonnegative-integer?)
  uri : uri-string?
Yield the respective part of the server authority of uri. See the discussion of uri-server-userinfo+host+portnum.

procedure

(uri-uriserver uri)  uriserver?

  uri : uri-string?
!!!

procedure

(uri-uriserver+path+query uri)  
uriserver? uripath? uriquery?
  uri : uristring?
!!!

procedure

(uri-uriserver+uripath+uriquery uri)

  
uriserver? uripath? uriquery?
  uri : uri-string?
!!!

procedure

(uri-userinfo+host+portnum uri)  !!!

  uri : uri-string?
!!!

procedure

(uri-portnum uri)  (or/c #f exact-nonnegative-integer?)

  uri : uri-string?
!!!

procedure

(make-uriserver userinfo host portnum)  uriserver?

  userinfo : (or/c #f string?)
  host : (or/c #f string?)
  portnum : (or/c #f exact-nonnegative-integer?)
(make-uriserver/default-portnum userinfo    
  host    
  portnum    
  default-portnum)  uriserver?
  userinfo : (or/c #f string?)
  host : (or/c #f string?)
  portnum : (or/c #f exact-nonnegative-integer?)
  default-portnum : (or/c #f exact-nonnegative-integer?)
!!!

procedure

(string->uriserver str)  uriserver?

  str : string?
(string/base->uriserver str base-uriserver)  uriserver?
  str : string?
  base-uriserver : uriserver?
(string/default-portnum->uriserver str 
  default-portnum) 
  uriserver?
  str : string?
  default-portnum : (or/c #f exact-nonnegative-integer?)
(string/base/default-portnum->uriserver str 
  base-uriserver 
  default-portnum) 
  uriserver?
  str : string?
  base-uriserver : uriserver?
  default-portnum : (or/c #f exact-nonnegative-integer?)
(substring->uriserver str start end)  uriserver?
  str : string?
  start : exact-nonnegative-integer?
  end : exact-nonnegative-integer?
(substring/base->uriserver str    
  start    
  end    
  base-uriserver)  uriserver?
  str : string?
  start : exact-nonnegative-integer?
  end : exact-nonnegative-integer?
  base-uriserver : uriserver?
(substring/default-portnum->uriserver str 
  start 
  end 
  default-portnum) 
  uriserver?
  str : string?
  start : exact-nonnegative-integer?
  end : exact-nonnegative-integer?
  default-portnum : (or/c #f exact-nonnegative-integer?)
(substring/base/default-portnum->uriserver str 
  start 
  end 
  base-uriserver 
  default-portnum) 
  uriserver?
  str : string?
  start : exact-nonnegative-integer?
  end : exact-nonnegative-integer?
  base-uriserver : uriserver?
  default-portnum : (or/c #f exact-nonnegative-integer?)
!!!

procedure

(uriserver-userinfo uriserver)  (or/c #f string?)

  uriserver : uriserver?
(uriserver-host uriserver)  (or/c #f string?)
  uriserver : uriserver?
(uriserver-portnum uriserver)
  (or/c #f exact-nonnegative-integer?)
  uriserver : uriserver?
(uriserver-userinfo+host+portnum uriserver)
  
(or/c #f string?)
(or/c #f string?)
(or/c #f exact-nonnegative-integer?)
  uriserver : uriserver?
!!!

procedure

(write-uriserver uriserver port)  void?

  uriserver : uriserver?
  port : output-port?
!!!

procedure

(uriserver-with-default-portnum uriserver    
  default-portnum)  uriserver?
  uriserver : uriserver?
  default-portnum : exact-nonnegative-integer?
!!!

procedure

(resolve-uriserver uriserver    
  base-uriserver)  uriserver?
  uriserver : uriserver?
  base-uriserver : uriserver?
(resolve-uriserver/default-portnum uriserver 
  base-uriserver 
  default-portnum) 
  uriserver?
  uriserver : uriserver?
  base-uriserver : uriserver?
  default-portnum : exact-nonnegative-integer?
!!!

8 Hierarchical Paths

A parsed hierarchical path [RFC2396 sec. 3] is represented in this package as a tuple of a list of path segments and an upcount. The list of path segments does not contain any “.” or “..” relative components, as those are removed during parsing. The upcount is either #f, meaning an absolute path, or an integer 0 or greater, meaning a relative path of that many levels “up.” A path segment without any parameters is represented as either a string or, if empty, #f. For example:
> (uri-path-upcount+segments "/a/b/")
  #f ("a" "b" #f)
> (uri-path-upcount+segments "/a/b/c")
  #f ("a" "b" "c")
> (uri-path-upcount+segments "/a/../../../b/c")
  2 ("b" "c")
and:
> (uri-path-upcount+segments "/.")
  #f ()
> (uri-path-upcount+segments "/")
  #f (#f)
> (uri-path-upcount+segments ".")
  0 (#f)
> (uri-path-upcount+segments "")
  0 ()
> (uri-path-upcount+segments "./")
  0 (#f)
> (uri-path-upcount+segments "..")
  1 ()
> (uri-path-upcount+segments "/..")
  1 ()
> (uri-path-upcount+segments "../")
  1 (#f)
A path segment with parameters is represented as a list, with the first element a string or #f for the path name, and the remaining elements strings for the parameters. For example:
> (uri-path-segments "../../a/b;p1/c/d;p2;p3/;p4")
  ("a" ("b" "p1") "c" ("d" "p2" "p3") (#f "p4"))
In the current version of this package, parsed paths are actually represented in reverse, which simplifies path resolution and permits list tails to be shared among potentially large numbers of long paths. For example:
> (let ((base (string->uripath "/a/b/c/index.html")))
    (map (lambda (n)
           (resolve-uripath (string->uripath n) base))
         '("x.html" "y/y.html" "../z/z.html")))

(("x.html" . #0=("c" . #1=("b" "a")))

 ("y.html" "y" . #0#)

 ("z.html" "z" . #1#)))))

 

procedure

(uri-path-upcount+segments uri)

  
(or/c #f exact-nonnegative-integer?)
(listof (or/c #f string?))
  uri : uri-string?
(uri-path-upcount+segments/reverse uri)
  
(or/c #f exact-nonnegative-integer?)
(listof (or/c #f string?))
  uri : uri-string?
Yields the path upcount and the segments of uri as two values. The segments list should be considered immutable, as it might be shared elsewhere. uri-path-upcount+segments/reverse yields the segments list in reverse order, and is the more efficient of the two procedures.
> (uri-path-upcount+segments/reverse "../a/../../b/./c")
  2 ("c" "b")
> (uri-path-upcount+segments         "../a/../../b/./c")
  2 ("b" "c")

procedure

(uri-path-upcount uri)  (or/c #f exact-nonnegative-integer?)

  uri : uri-string?
(uri-path-segments uri)  (listof (or/c #f string?))
  uri : uri-string?
(uri-path-segments/reverse uri)  (listof (or/c #f string?))
  uri : uri-string?
See the documentation for uri-path-upcount+segments.
> (uri-path-upcount          "../a/../../b/./c")
  2
> (uri-path-segments         "../a/../../b/./c")
  ("b" "c")
> (uri-path-segments/reverse "../a/../../b/./c")
  ("c" "b")

procedure

(urisegment-name urisegment)  (or/c #f string?)

  urisegment : urisegment?
(urisegment-params urisegment)  (listof (or/c #f string?))
  urisegment : urisegment?
(urisegment-name+params urisegment)
  
(or/c #f string?)
(listof (or/c #f string?))
  urisegment : urisegment?
(urisegment-has-params? urisegment)  boolean?
  urisegment : urisegment?
Yield the components of a parsed URI segment. The values should be considered immutable. For example:
> (urisegment-name+params "foo")
  "foo" ()
> (urisegment-name+params #f)
  #f ()
> (urisegment-name+params '("foo" "p1" "p2"))
  "foo" ("p1" "p2")
> (urisegment-name+params '(#f    "p1" "p2"))
  #f ("p1" "p2")

procedure

(uri-path uri)  uripath?

  uri : uri-string?
(uri-path/noparams uri)  uripath?
  uri : uri-string?
(uri-uripath uri)  uripath?
  uri : uri-string?
(uri-uripath/noparams uri)  uripath?
  uri : uri-string?
!!!

procedure

(make-uripath [upcount])  uripath?

  upcount : uriupcount? = (segments urisegments?)
(make-uripath/reverse [upcount])  uripath?
  upcount : uriupcount? = (segments urisegments?)
(make-uripath/reverse/shared-ok [upcount])  uripath?
  upcount : uriupcount? = (segments urisegments?)
!!!

procedure

(uripath-with-upcount uripath upcount)  (para "!!!")

  uripath : uripath?
  upcount : uriupcount?

procedure

(string->uripath str)  uripath?

  str : string?
(string/base->uripath str base-uripath)  uripath?
  str : string?
  base-uripath : uripath?
(substring->uripath str start end)  uripath?
  str : string?
  start : exact-nonnegative-integer?
  end : exact-nonnegative-integer?
(substring/base->uripath str    
  start    
  end    
  base-uripath)  uripath?
  str : string?
  start : exact-nonnegative-integer?
  end : exact-nonnegative-integer?
  base-uripath : uripath?
!!!
Note: Contrary to [RFC2396], we don’t require base to be absolute.

procedure

(uripath-upcount uripath)  uriupcount?

  uripath : uripath?
(uripath-segments uripath)  urisegments?
  uripath : uripath?
(uripath-segments/reverse uripath)  urisegments?
  uripath : uripath?
(uripath-upcount+segments uripath)  
uriupcount? urisegments?
  uripath : uripath?
(uripath-upcount+segments/reverse uripath)
  
uriupcount? urisegments?
  uripath : uripath?
!!!

procedure

(uripath-has-params? uripath)  boolean?

  uripath : uripath?
!!!

procedure

(write-uripath uripath port)  void?

  uripath : uripath?
  port : output-port?
(write-uripath/leading-slash uripath port)  void?
  uripath : uripath?
  port : output-port?
!!!

procedure

(uripath->string uripath)  string?

  uripath : uripath?
(uripath->string/leading-slash uripath)  string?
  uripath : uripath?
!!!
> (uri-path-segments "//a/b")
  ("b")
> (uri-path-segments "/.//a/b")
  (#f "a" "b")
!!!
> (uripath->string               (string->uripath "//b"))
  "//b"
> (uripath->string/leading-slash (string->uripath "//b"))
  "/.//b"
> (uripath->string/leading-slash (string->uripath "/a/b"))
  "/a/b"
> (uripath->string/leading-slash (string->uripath "/;p1/b"))
  "/;p1/b"

procedure

(resolve-uripath uripath base-uripath)  uripath?

  uripath : uripath?
  base-uripath : uripath?
!!!

procedure

(absolute-uripath uripath)  uripath?

  uripath : uripath?
!!!

9 Attribute-Value Queries

This library provides support for parsing the URI query component [RFC 2396 sec. 3.4], as attribute-value lists in the manner of 'http URI scheme queries. Parsed queries are represented as association lists, in which the car of each pair is the attribute name as a string, and the cdr is either the attribute value as a string or #t if no value given. All strings are uri-unescaped. For example:

> (uri-query "?q=fiendish+scheme&case&x=&y=1%2B2")

  (("q"    . "fiendish scheme")
   ("case" . #t)
   ("x"    . "")
   ("y"    . "1+2"))

procedure

(uri-query uri)  uriquery?

  uri : uri-string?
Yields the parsed attribute-value query of uri, or #f if no query. For example:
> (uri-query "?x=42&y=1%2B2")
  (("x" . "42") ("y" . "1+2"))

procedure

(uri-query-value uri attr)  (or/c #f #t string?)

  uri : uri-string?
  attr : string?
Yields the value of attribute attr in uri’s query, or #f if uri has no query component or no attr attribute. If the attribute appears multiple times in the query, the value of the first occurrence is used. For example:
> (uri-query-value "?x=42&y=1%2B2" "y")
  "1+2"

procedure

(uriquery-value uriquery attr)  (or/c #f #t string?)

  uriquery : uriquery?
  attr : string?
Yields the value of attribute attr in uriquery, or #f if there is no such attribute. If the attribute appears multiple times in the query, the value of the first occurrence is used.

procedure

(uri-uriquery uri)  uriquery?

  uri : uri-string?
!!!

procedure

(string->uriquery str)  uriquery?

  str : string?
(substring->uriquery str [start end])  uriquery?
  str : string?
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (string-length str)
!!!

procedure

(write-uriquery uriquery [port])  void?

  uriquery : uriquery?
  port : output-port? = (current-output-port)
!!!

10 Resolution

This subsection concerns resolving relative URI to absolute URI.

procedure

(absolute-uri? uri)  boolean?

  uri : uri-string?
Yields a Boolean value for whether or not URI uri is known by the library’s criteria to be absolute.

procedure

(resolve-uri uri base-uri)  uri?

  uri : uri-string?
  base-uri : uri-string
Yields a URI that is URI uri possibly resolved with respect to URI base-uri, but not necessarily absolute. As an extension to [RFC2396] rules for resolution, base-uri may be a relative URI.
> (resolve-uri "x.html" "http://w/a/b/c.html")
  #uri"http://w/a/b/x.html"
> (resolve-uri "//www:80/" "http:")
  #uri"http://www/"

procedure

(absolute-uri uri)  uri?

  uri : uri-string
Yields a URI that may be a variation on uri that has been forced to absolute (by, e.g., dropping relative path components, or supplying a missing path). The result might not be an absolute URI, however, due to limitations of the library or insufficient information in the URI. For example:
> (absolute-uri "http://w/../a")
  "http://w/a"
> (absolute-uri "http://w")
  "http://w/"

11 Antiresolution

!!!

procedure

(antiresolve-uripath uripath base-uripath)  uripath?

  uripath : uripath?
  base-uripath : uripath?
Antiresolves uripath with respect to base-uripath. For example:
!!!

procedure

(antiresolve-uriserver uriserver    
  base-uriserver)  uriserver?
  uriserver : uriserver?
  base-uriserver : uriserver?
Antiresolves uriserver with respect to base-uriserver. For example:
!!!

procedure

(antiresolve-uri uri base-uri)  uri?

  uri : uri-string?
  base-uri : uri-string?
Antiresolves uri with respect to base-uri. For example:
!!!

12 Known Issues

13 History

14 Legal

Copyright 2003, 2004, 2011, 2013, 2016 Neil Van Dyke. This program is Free Software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose. See http://www.gnu.org/licenses/ for details. For other licenses and consulting, please contact the author.