#lang scribble/doc @; THIS FILE IS GENERATED @(require scribble/manual) @(require (for-label (planet neil/uri:1:=0))) @(require (for-label racket)) @title[#:version "0.2"]{@bold{uri}: Web Uniform Resource Identifiers (URI and URL) in Racket} @author{Neil Van Dyke} License: @seclink["Legal" #:underline? #f]{LGPL 3} @(hspace 1) Web: @link["http://www.neilvandyke.org/racket-uri/" #:underline? #f]{http://www.neilvandyke.org/racket-uri/} @defmodule[(planet neil/uri:1:=0)] @section{Introduction} @emph{WARNING: This package is being actively developed. A future version is expected to introduce some major non-backward-compatible changes.} @bold{uri} is a Racket code library for parsing, representing, and transforming 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. @link["http://www.ietf.org/rfc/rfc3305.txt"]{RFC2396} is the principal reference used for this implementation. Earlier versions were informed by other RFCs, including @link["http://www.ietf.org/rfc/rfc2396.txt"]{RFC2396} and @link["http://www.ietf.org/rfc/rfc2732.txt"]{RFC2732}. Goals of this package are correctness, efficiency, and power. @section{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 @tt{+} as an encoding of a space character, as is used in some HTTP encodings of HTML forms. These procedures have multiple variants, concerning mutability of the strings they yield, and following the naming convention: @itemize[ @item{@emph{foo}@tt{-i} Always yields an immutable string (or a new string, if the Scheme implementation does not support immutable string). } @item{@emph{foo}@tt{/new-mutable} Always yields a new, mutable string. } @item{@emph{foo}@tt{/shared-ok} If the output is equal to the input, might yield the input string rather than yielding a copy of it. } ] Many applications will not call these procedures directly, since most of this library's interface automatically escapes and unescapes strings as appropriate. @defproc[ (uri-escape (str any/c) (start any/c) (end any/c)) any/c]{} @defproc[ (uri-escape/new-mutable (str any/c) (start any/c) (end any/c)) any/c]{} @defproc[ (uri-escape/shared-ok (str any/c) (start any/c) (end any/c)) any/c]{ Yields a URI-escaped encoding of string @schemevarfont{str}. If @schemevarfont{start} and @schemevarfont{end} are given, then they designate the substring of @schemevarfont{str} to use. All characters are escaped, except alphanumerics, minus, underscore, period, and tilde. For example. @SCHEMEBLOCK[ (uri-escape "a = b/c + d") ==> "a%20%3D%20b%2Fc%20%2B%20d" ] } @defproc[ (uri-plusescape-i (str any/c) (start any/c) (end any/c)) any/c]{} @defproc[ (uri-plusescape/new-mutable (str any/c) (start any/c) (end any/c)) any/c]{} @defproc[ (uri-plusescape/shared-ok (str any/c) (start any/c) (end any/c)) any/c]{ Like @tt{uri-escape}, except encodes space characters as @tt{"+"} instead of @tt{"%20"}. This should generally only be used to mimic the encoding some Web browsers do of HTML form values. For example: @SCHEMEBLOCK[ (uri-plusescape "a = b/c + d") ==> "a+%3D+b%2Fc+%2B+d" ] } @defproc[ (uri-unescape-i (str any/c) (start any/c) (end any/c)) any/c]{} @defproc[ (uri-unescape/new-mutable (str any/c) (start any/c) (end any/c)) any/c]{} @defproc[ (uri-unescape/shared-ok (str any/c) (start any/c) (end any/c)) any/c]{ Yields an URI-unescaped string from the encoding in string @tt{str}. If @schemevarfont{start} and @schemevarfont{end} are given, then they designate the substring of @schemevarfont{str} to use. For example: @SCHEMEBLOCK[ (uri-unescape "a%20b+c%20d") ==> "a b+c d" ] } @defproc[ (uri-unplusescape-i (str any/c) (start any/c) (end any/c)) any/c]{} @defproc[ (uri-unplusescape/new-mutable (str any/c) (start any/c) (end any/c)) any/c]{} @defproc[ (uri-unplusescape/shared-ok (str any/c) (start any/c) (end any/c)) any/c]{ Like @tt{uri-unescape}, but also decodes the plus (@tt{+}) character as to space character. For example: @SCHEMEBLOCK[ (uri-unplusescape "a%20b+c%20d") ==> "a b c d" ] } @defproc[ (char->uri-escaped-string (chr any/c)) any/c]{} @defproc[ (char->uri-escaped-string-i (chr any/c)) any/c]{ Yields a URI-escaped string of character @schemevarfont{chr}. For example: @SCHEMEBLOCK[ (char->uri-escaped-string #\/) ==> "%2F" ] } @section{URI API} This section describes the ``URI string'' API, while the next section describes the ``URI object,'' (@tt{uri}) API. All procedures in this section yield URIs using immutable strings, and accept URIs as strings (immutable or mutable) or as the opaque objects described in the next section. @subsection{Predicate} @defproc[ (uri? (v any/c)) any/c]{ !!! } @subsection{Converting Strings to URI Objects} @defproc[ (string->uri (str any/c)) any/c]{} @defproc[ (string/base->uri (str any/c) (base-uri any/c)) any/c]{} @defproc[ (string/base-uri->uri (str any/c) (base-uri any/c)) any/c]{ !!! } @defproc[ (substring->uri (str any/c) (start any/c) (end any/c)) any/c]{} @defproc[ (substring/base-uri-or-string->uri (str any/c) (start any/c) (end any/c) (base-uri-or-string any/c)) any/c]{} @defproc[ (substring/base-uri->uri (str any/c) (start any/c) (end any/c) (base-uri any/c)) any/c]{ !!! } @defproc[ (uri-or-string->uri (uri-or-string any/c) (==> any/c) (uri any/c)) any/c]{ !!! convenience } @subsection{Writing URIs to Ports and Converting URIs to Strings} @defproc[ (display-uri (uri any/c) (port any/c)) any/c]{} @defproc[ (display-uri/nofragment (uri any/c) (port any/c)) any/c]{ Displays @schemevarfont{uri} to output port @schemevarfont{port}. For example: @SCHEMEBLOCK[ (display-uri "http://s/foo#bar" (current-output-port)) -| http://s/foo#bar (display-uri/nofragment "http://s/foo#bar" (current-output-port)) -| http://s/foo ] } @defproc[ (uri->string (uri any/c)) any/c]{ Yields the full string representation of URI @schemevarfont{uri}. Of course this is not needed when using only the string representation of URI, but using this procedure in libraries permits the @tt{uri} to also be used. For example: @SCHEMEBLOCK[ (define my-uri (string->uri "http://www/")) my-uri ==> (uri->string my-uri) ==> "http://www/" ] } @subsection{URI Schemes} URI schemes are currently represented as lowercase Racket symbols and associated data. @defthing[ftp-uri-scheme any/c]{} @defthing[gopher-uri-scheme any/c]{} @defthing[http-uri-scheme any/c]{} @defthing[https-uri-scheme any/c]{} @defthing[imap-uri-scheme any/c]{} @defthing[ipp-uri-scheme any/c]{} @defthing[news-uri-scheme any/c]{} @defthing[nfs-uri-scheme any/c]{} @defthing[telnet-uri-scheme any/c]{ Some common URI scheme symbols, as a convenience for Racket code that must be portable to Racket implementations with case-insensitive readers. For example, in some Racket implementations: @SCHEMEBLOCK[ 'ftp ==> FTP ftp-uri-scheme ==> ftp ] } @defproc[ (uri-scheme (uri any/c)) any/c]{ Yields the URI scheme of @schemevarfont{uri}, or @tt{#f} if none can be determined. For example: @SCHEMEBLOCK[ (uri-scheme "Http://www") ==> http ] } @defproc[ (register-uri-scheme-default-portnum (sym any/c) (portnum any/c)) any/c]{ Registers integer @schemevarfont{portnum} as the default port number for the server authority component of URI scheme @schemevarfont{sym}. @SCHEMEBLOCK[ (define x-foo-uri-scheme (string->symbol "x-foo")) (register-uri-scheme-default-portnum x-foo-uri-scheme 007) (register-uri-scheme-default-portnum x-foo-uri-scheme 666) error--> cannot change uri scheme default portnum: x-foo 7 666 ] } @defproc[ (register-uri-scheme-hierarchical (sym any/c)) any/c]{ Registers URI scheme @schemevarfont{sym} as having a ``hierarchical'' form as described in [RFC2396 sec. 3]. } @subsection{URI Reference Fragment Identifiers} @defproc[ (uri-fragment (uri any/c)) any/c]{} @defproc[ (uri-fragment/escaped (uri any/c)) any/c]{ Yields the fragment identifier component of URI (or URI reference) @schemevarfont{uri} as a string, or @tt{#f} if there is no fragment. @tt{uri-fragment} yields the fragment in unescaped form, and @tt{uri-fragment/escaped} yields an escaped form in the unusual case that is desired. For example: @SCHEMEBLOCK[ (uri-fragment "foo#a%20b") ==> "a b" (uri-fragment/escaped "foo#a%20b") ==> "a%20b" ] } @defproc[ (uri-without-fragment (uri any/c)) any/c]{ Yields @schemevarfont{uri} without the fragment component. For example: @SCHEMEBLOCK[ (uri-without-fragment "http://w/#bar") ==> "http://w/" ] } @defproc[ (uri-with-fragment (uri any/c) (fragment any/c)) any/c]{} @defproc[ (uri-with-fragment/escaped (uri any/c) (fragment any/c)) any/c]{ Yields a URI that is like @schemevarfont{uri} except with the fragment @schemevarfont{fragment} (or no fragment if @schemevarfont{fragment} is @tt{#f}). For example: @SCHEMEBLOCK[ (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 @tt{uri-with-fragment/escaped} variant can be used when the desired fragment string is already in uri-escaped form: @SCHEMEBLOCK[ (uri-with-fragment "foo" "a b") ==> "foo#a%20b" (uri-with-fragment/escaped "foo" "a%20b") ==> "foo#a%20b" ] } @subsection{Hierarchical URIs} This and some of the following subsections concern ``hierarchical'' generic URI syntax as described in @link["http://www.ietf.org/rfc/rfc3305.txt"]{RFC2396} sec. 3. @defproc[ (uri-hierarchical? (uri any/c)) any/c]{ Yields a Boolean value for whether or not the URI scheme of URI @schemevarfont{uri} is known to have a ``hierarchical'' generic URI layout. For example: @SCHEMEBLOCK[ (uri-hierarchical? "http://www/") ==> #t (uri-hierarchical? "mailto://www/") ==> #f (uri-hierarchical? "//www/") ==> #f ] } @subsection{Server-Based Naming Authorities} Several procedures extract the server authority values from URIs [RFC2396 sec. 3.2.2]. @defproc[ (uri-server-userinfo+host+portnum (uri any/c)) any/c]{ Yields three values for the server authority of URI @schemevarfont{uri}: the userinfo as a string (or @tt{#f}), the host as a string (or @tt{#f}), and the effective port number as an integer (or @tt{#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 @tt{ftp} scheme): @SCHEMEBLOCK[ (uri-server-userinfo+host+portnum "ftp://anon@ftp.foo.bar/") ==> "anon" "ftp.foo.bar" 21 ] } @defproc[ (uri-server-userinfo (uri any/c)) any/c]{} @defproc[ (uri-server-host (uri any/c)) any/c]{} @defproc[ (uri-server-portnum (uri any/c)) any/c]{ Yield the respective part of the server authority of @schemevarfont{uri}. See the discussion of @tt{uri-server-userinfo+host+portnum}. } @subsection{Hierarchical Paths} A parsed hierarchical path [RFC2396 sec. 3] is represented in @bold{uri} as a tuple of a list of path segments and an @italic{upcount}. The list of path segments does not contain any ``@tt{.}'' or ``@tt{..}'' relative components, as those are removed during parsing. The upcount is either @tt{#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, @tt{#f}. For example: @SCHEMEBLOCK[ (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: @SCHEMEBLOCK[ (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 @tt{#f} for the path name, and the remaining elements strings for the parameters. For example: @SCHEMEBLOCK[ (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 @bold{uri}, 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 (@tt{uripath} is a concept of the ``object URI'' API): @SCHEMEBLOCK[ (let ((base (string->uripath "/a/b/c/index.html"))) (map (lambda (n) (resolved-uripath (string->uripath n) base)) '("x.html" "y/y.html" "../z/z.html"))) ==> ] @verbatim["((\"x.html\" . #0=(\"c\" . #1=(\"b\" \"a\")))\n (\"y.html\" \"y\" . #0#)\n (\"z.html\" \"z\" . #1#))"] @defproc[ (uri-path-upcount+segments (uri any/c)) any/c]{} @defproc[ (uri-path-upcount+segments/reverse (uri any/c)) any/c]{ Yields the path upcount and the segments of @schemevarfont{uri} as two values. The segments list should be considered immutable, as it might be shared elsewhere. @tt{uri-path-upcount+segments/reverse} yields the segments list in reverse order, and is the more efficient of the two procedures. @SCHEMEBLOCK[ (uri-path-upcount+segments/reverse "../a/../../b/./c") ==> 2 ("c" "b") (uri-path-upcount+segments "../a/../../b/./c") ==> 2 ("b" "c") ] } @defproc[ (uri-path-upcount (uri any/c)) any/c]{} @defproc[ (uri-path-segments (uri any/c)) any/c]{} @defproc[ (uri-path-segments/reverse (uri any/c)) any/c]{ See the documentation for @tt{uri-path-upcount+segments}. @SCHEMEBLOCK[ (uri-path-upcount "../a/../../b/./c") ==> 2 (uri-path-segments "../a/../../b/./c") ==> ("b" "c") (uri-path-segments/reverse "../a/../../b/./c") ==> ("c" "b") ] } @defproc[ (urisegment-name (urisegment any/c)) any/c]{} @defproc[ (urisegment-params (urisegment any/c)) any/c]{} @defproc[ (urisegment-name+params (urisegment any/c)) any/c]{} @defproc[ (urisegment-has-params? (urisegment any/c)) any/c]{ Yield the components of a parsed URI segment. The values should be considered immutable. For example: @SCHEMEBLOCK[ (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") ] } @subsection{Attribute-Value Queries} This library provides support for parsing the URI query component [RFC2396 sec. 3.4], as attribute-value lists in the manner of @tt{http} URI scheme queries. Parsed queries are represented as association lists, in which the @italic{car} of each pair is the attribute name as a string, and the @italic{cdr} is either the attribute value as a string or @tt{#t} if no value given. All strings are uri-unescaped. For example: @SCHEMEBLOCK[ (uri-query "?q=fiendish+scheme&case&x=&y=1%2B2") ==> (("q" . "fiendish scheme") ("case" . #t) ("x" . "") ("y" . "1+2")) ] @defproc[ (uri-query (uri any/c)) any/c]{ Yields the parsed attribute-value query of @schemevarfont{uri}, or @tt{#f} if no query. For example: @SCHEMEBLOCK[ (uri-query "?x=42&y=1%2B2") ==> (("x" . "42") ("y" . "1+2")) ] } @defproc[ (uri-query-value (uri any/c) (attr any/c)) any/c]{ Yields the value of attribute @schemevarfont{attr} in @schemevarfont{uri}'s query, or @tt{#f} if @schemevarfont{uri} has no query component or no @schemevarfont{attr} attribute. If the attribute appears multiple times in the query, the value of the first occurrence is used. For example: @SCHEMEBLOCK[ (uri-query-value "?x=42&y=1%2B2" "y") ==> "1+2" ] } @defproc[ (uriquery-value (uriquery any/c) (attr any/c)) any/c]{ Yields the value of attribute @schemevarfont{attr} in @schemevarfont{uriquery}, or @tt{#f} if there is no such attribute. If the attribute appears multiple times in the query, the value of the first occurrence is used. } @subsection{Resolving Relative URI} This subsection concerns resolving relative URI. @defproc[ (absolute-uri? (uri any/c)) any/c]{ Yields a Boolean value for whether or not URI @schemevarfont{uri} is @emph{known} by the library's criteria to be absolute. } @defproc[ (resolved-uri (uri any/c) (base-uri any/c)) any/c]{ Yields a URI string that is URI @schemevarfont{uri} possibly resolved with respect to URI @schemevarfont{base-uri}, but not necessarily absolute. As an extension to [RFC2396] rules for resolution, @schemevarfont{base-uri} may be a relative URI. @SCHEMEBLOCK[ (resolved-uri "x.html" "http://w/a/b/c.html") ==> "http://w/a/b/x.html" (resolved-uri "//www:80/" "http:") ==> "http://www/" ] } @defproc[ (absolute-uri (uri any/c)) any/c]{ Yields a URI that may be a variation on @schemevarfont{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: @SCHEMEBLOCK[ (absolute-uri "http://w/../a") ==> "http://w/a" (absolute-uri "http://w") ==> "http://w/" ] } @section{URI Schemes} @defproc[ (uri-scheme (uri any/c)) any/c]{ !!! } @defproc[ (uri-with-scheme (uri any/c) (urischeme any/c)) any/c]{ !!! } @defproc[ (string->urischeme (str any/c)) any/c]{} @defproc[ (symbol->urischeme (sym any/c)) any/c]{ !!! } @defproc[ (urischeme->string) any/c]{ !!! } @defproc[ (urischeme-hierarchical? (urischeme any/c)) any/c]{ !!! } @defproc[ (urischeme-default-portnum (urischeme any/c)) any/c]{ !!! } @section{Hierarchical URIs} @defproc[ (uri-uriserver (uri any/c)) any/c]{ !!! } @defproc[ (uri-uriserver+path+query (uri any/c)) any/c]{ !!! } @defproc[ (uri-uriserver (uri any/c) (==> any/c) (uriserver any/c)) any/c]{ !!! } @defproc[ (uri-uriserver+uripath+uriquery (uri any/c)) any/c]{ !!! } @defproc[ (uri-userinfo+host+portnum (uri any/c)) any/c]{ !!! } @defproc[ (uri-portnum (uri any/c)) any/c]{ !!! } @defproc[ (make-uriserver (userinfo any/c) (host any/c) (portnum any/c)) any/c]{} @defproc[ (make-uriserver/default-portnum (userinfo any/c) (host any/c) (portnum any/c) (default-portnum any/c)) any/c]{ !!! } @defproc[ (make-or-reuse-uriserver (userinfo any/c) (host any/c) (portnum any/c) (base-uriserver any/c)) any/c]{} @defproc[ (make-or-reuse-uriserver/default-portnum (userinfo any/c) (host any/c) (portnum any/c) (base-uriserver any/c) (default-portnum any/c)) any/c]{ !!! } @defproc[ (string->uriserver (str any/c)) any/c]{} @defproc[ (string/base->uriserver (str any/c) (base-uriserver any/c)) any/c]{} @defproc[ (string/default-portnum->uriserver (str any/c) (default-portnum any/c)) any/c]{} @defproc[ (string/base/default-portnum->uriserver (str any/c) (base-uriserver any/c) (default-portnum any/c)) any/c]{} @defproc[ (substring->uriserver (str any/c) (start any/c) (end any/c)) any/c]{} @defproc[ (substring/base->uriserver (str any/c) (start any/c) (end any/c) (base-uriserver any/c)) any/c]{} @defproc[ (substring/default-portnum->uriserver (str any/c) (start any/c) (end any/c) (default-portnum any/c)) any/c]{} @defproc[ (substring/base/default-portnum->uriserver (str any/c) (start any/c) (end any/c) (base-uriserver any/c) (default-portnum any/c)) any/c]{ !!! } @defproc[ (uriserver-userinfo (uriserver any/c)) any/c]{} @defproc[ (uriserver-host (uriserver any/c)) any/c]{} @defproc[ (uriserver-portnum (uriserver any/c)) any/c]{} @defproc[ (uriserver-userinfo+host+portnum (uriserver any/c)) any/c]{ !!! } @defproc[ (write-uriserver (uriserver any/c) (port any/c)) any/c]{ !!! } @defproc[ (uriserver-with-default-portnum (uriserver any/c) (default-portnum any/c)) any/c]{ !!! } @defproc[ (resolved-uriserver (uriserver any/c) (base-uriserver any/c)) any/c]{} @defproc[ (resolved-uriserver/default-portnum (uriserver any/c) (base-uriserver any/c) (default-portnum any/c)) any/c]{ !!! } @subsection{Hierarchical Paths} @defproc[ (uri-path (uri any/c)) any/c]{} @defproc[ (uri-path/noparams (uri any/c)) any/c]{} @defproc[ (uri-uripath (uri any/c)) any/c]{} @defproc[ (uri-uripath/noparams (uri any/c)) any/c]{ !!! } @defproc[ (make-uripath (upcount any/c) (segments any/c)) any/c]{} @defproc[ (make-uripath/reverse (upcount any/c) (segments any/c)) any/c]{} @defproc[ (make-uripath/reverse/shared-ok (upcount any/c) (segments any/c)) any/c]{ !!! } @defproc[ (uripath-with-upcount (uripath any/c) (upcount any/c)) any/c]{ !!! } @defproc[ (string->uripath (str any/c)) any/c]{} @defproc[ (string/base->uripath (str any/c) (base-uripath any/c)) any/c]{} @defproc[ (substring->uripath (str any/c) (start any/c) (end any/c)) any/c]{} @defproc[ (substring/base->uripath (str any/c) (start any/c) (end any/c) (base-uripath any/c)) any/c]{ !!! Note: Contrary to [RFC2396], we don't require base to be absolute. } @defproc[ (uripath-upcount (uripath any/c)) any/c]{} @defproc[ (uripath-segments (uripath any/c)) any/c]{} @defproc[ (uripath-segments/reverse (uripath any/c)) any/c]{} @defproc[ (uripath-upcount+segments (uripath any/c)) any/c]{} @defproc[ (uripath-upcount+segments/reverse (uripath any/c)) any/c]{ !!! } @defproc[ (uripath-has-params? (uripath any/c)) any/c]{ !!! } @defproc[ (write-uripath (uripath any/c) (port any/c)) any/c]{} @defproc[ (write-uripath/leading-slash (uripath any/c) (port any/c)) any/c]{ !!! } @defproc[ (uripath->string (uripath any/c)) any/c]{} @defproc[ (uripath->string/leading-slash (uripath any/c)) any/c]{ !!! @SCHEMEBLOCK[ (uri-path-segments "//a/b") ==> ("b") (uri-path-segments "/.//a/b") ==> (#f "a" "b") ] !!! @SCHEMEBLOCK[ (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" ] } @defproc[ (resolved-uripath (uripath any/c) (base-uripath any/c)) any/c]{ !!! } @defproc[ (absolute-uripath (uripath any/c)) any/c]{ !!! } @subsection{Attribute-Value Queries} @defproc[ (uri-uriquery (uri any/c)) any/c]{ !!! } @defproc[ (string->uriquery (str any/c)) any/c]{} @defproc[ (substring->uriquery (str any/c) (start any/c) (end any/c)) any/c]{ !!! } @defproc[ (write-uriquery (uriquery any/c) (port any/c)) any/c]{ !!! } @section{Antiresolution (In-Progress)} @defproc[ (antiresolved-uripath (uripath any/c) (base-uripath any/c)) any/c]{ !!! } @defproc[ (antiresolved-uriserver (uriserver any/c) (base-uriserver any/c)) any/c]{} @defproc[ (antiresolved-uriserver/default-portnum (uriserver any/c) (base-uriserver any/c) (default-portnum any/c)) any/c]{ !!! } @section{History} @itemize[ @item{Version 0.2 --- 2011-08-23 --- PLaneT @tt{(1 0)} This is a release of some code-in-progress that has been sitting around unreleased for years. It has been changed heavily since the 2004, non-PLaneT release, including getting rid of the "uriobj"-specific operations, so that all operations work on both string and object forms. A few tests fail. Non-backward-compatible API changes are expected. } @item{Version 0.1 --- 2004-08-18 Initial release. Incorporates some code from UriFrame. } ] @section[#:tag "Legal"]{Legal} Copyright (c) 2003--2011 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 (LGPL 3), 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. @italic{@smaller{Standard Documentation Format Note: The API signatures in this documentation are likely incorrect in some regards, such as indicating type @tt{any/c} for things that are not, and not indicating when arguments are optional. This is due to a transitioning from the Texinfo documentation format to Scribble, which the author intends to finish someday.}}