r5331: *** empty log message ***
[puri.git] / uri.html
1 <html>
2
3 <head>
4 <title>URI support in Allegro CL</title>
5 </head>
6
7 <body>
8
9 <h1>URI support in Allegro CL</h1>
10
11 <p>This document contains the following sections:</p>
12 <a href="#uri-intro-1">
13
14 <p>1.0 Introduction</a><br>
15 <a href="#uri-api-1">2.0 The URI API definition</a><br>
16 <a href="#parsing-decoding-1">3.0 Parsing, escape decoding/encoding and the path</a><br>
17 <a href="#interning-uris-1">4.0 Interning URIs</a><br>
18 <a href="#acl-implementation-1">5.0 Allegro CL implementation notes</a><br>
19 <a href="#examples-1">6.0 Examples</a><br>
20 </p>
21
22 <p>This version of the Allegro CL URI support documentation is for distribution with the
23 Open Source version of the URI code. Links to Allegro CL documentation other than
24 URI-specific files have been supressed. To see Allegro CL documentation, see <a
25 href="http://www.franz.com/support/documentation/">http://www.franz.com/support/documentation/</a>,
26 which is the Allegro CL documentation page of the franz inc. website. Links to Allegro CL
27 documentation can be found on that page. </p>
28
29 <hr>
30
31 <hr>
32
33 <h2><a name="uri-intro-1">1.0 Introduction</a></h2>
34
35 <p><em>URI</em> stands for <em>Universal Resource Identifier</em>. For a description of
36 URIs, see RFC2396, which can be found in several places, including the IETF web site (<a
37 href="http://www.ietf.org/rfc/rfc2396.txt">http://www.ietf.org/rfc/rfc2396.txt</a>) and
38 the UCI/ICS web site (<a href="http://www.ics.uci.edu/pub/ietf/uri/rfc2396.txt">http://www.ics.uci.edu/pub/ietf/uri/rfc2396.txt</a>).
39 We prefer the UCI/ICS one as it has more examples. </p>
40
41 <p>URIs are a superset in functionality and syntax to URLs (Universal Resource Locators)
42 and URNs (Universal Resource Names). That is, RFC2396 updates and merges RFC1738 and
43 RFC1808 into a single syntax, called the URI. It does exclude some portions of RFC1738
44 that define specific syntax of individual URL schemes. </p>
45
46 <p>In URL slang, the <em>scheme</em> is usually called the `protocol', but it is called
47 scheme in RFC1738. A URL `host' corresponds to the URI `authority.' The URL slang
48 `bookmark' or `anchor' is `fragment' in URI lingo. </p>
49
50 <p>The URI facility was available as a patch to Allegro CL 5.0.1 and is included with
51 release 6.0. the URI facility might not be in an Allegro CL image. Evaluate <code>(require
52 :uri)</code> to ensure the facility is loaded (that form returns <code>nil</code> if the
53 URI module is already loaded). </p>
54
55 <p>Broadly, the URI facility creates a Lisp object that represents a URI, and provides
56 setters and accessors to fields in the URI object. The URI object can also be interned,
57 much like symbols in CL are. This document describes the facility and the related
58 operators. </p>
59
60 <p>Aside from the obvious slots which are called out in the RFC, URIs also have a property
61 list. With interning, this is another similarity between URIs and CL symbols. </p>
62
63 <hr>
64
65 <hr>
66
67 <h2><a name="uri-api-1">2.0 The URI API definition</a></h2>
68
69 <p>Symbols naming objects (functions, variables, etc.) in the <em>uri</em> module are
70 exported from the <code>net.uri</code> package. </p>
71
72 <p>URIs are represented by CLOS objects. Their slots are: </p>
73
74 <pre>
75 scheme 
76 host 
77 port 
78 path 
79 query
80 fragment 
81 plist 
82 </pre>
83
84 <p>The <code>host</code> and <code>port</code> slots together correspond to the <code>authority</code>
85 (see RFC2396). There is an accessor-like function, <a href="operators/uri-authority.htm"><b>uri-authority</b></a>,
86 that can be used to extract the authority from a URI. See the RFC2396 specifications
87 pointed to at the beginning of the <a href="#uri-intro-1">1.0 Introduction</a> for details
88 of all the slots except <code>plist</code>. The <code>plist</code> slot contains a
89 standard Common Lisp property list. </p>
90
91 <p>All symbols are external in the <code>net.uri</code> package, unless otherwise noted.
92 Brief descriptions are given in this document, with complete descriptions in the
93 individual pages. 
94
95 <ul>
96   <li><a href="classes/uri.htm"><code>uri</code></a>: the class of URI objects. </li>
97   <li><a href="classes/urn.htm"><code>urn</code></a>: the class of URN objects. </li>
98   <li><a href="operators/uri-p.htm"><b>uri-p</b></a> <p><b>Arguments: </b><i>object</i></p>
99     <p>Returns true if <i>object</i> is an instance of class <a href="classes/uri.htm"><code>uri</code></a>.
100     </p>
101   </li>
102   <li><a href="operators/copy-uri.htm"><b>copy-uri</b></a> <p><b>Arguments: </b><i>uri </i>&amp;key
103     <i>place scheme host port path query fragment plist </i></p>
104     <p>Copies the specified URI object. See the description page for information on the
105     keyword arguments. </p>
106   </li>
107   <li><a href="operators/uri-scheme.htm"><b>uri-scheme</b></a><br>
108     <a href="operators/uri-host.htm"><b>uri-host</b></a><br>
109     <a href="operators/uri-port.htm"><b>uri-port</b></a><br>
110     <a href="operators/uri-path.htm"><b>uri-path</b></a><br>
111     <a href="operators/uri-query.htm"><b>uri-query</b></a><br>
112     <a href="operators/uri-fragment.htm"><b>uri-fragment</b></a><br>
113     <a href="operators/uri-plist.htm"><b>uri-plist</b></a><br>
114     <p><b>Arguments: </b><i>uri-object </i></p>
115     <p>These accessors return the value of the associated slots of the <i>uri-object</i> </p>
116   </li>
117   <li><a href="operators/uri-authority.htm"><b>uri-authority</b></a> <p><b>Arguments: </b><i>uri-object
118     </i></p>
119     <p>Returns the authority of <i>uri-object</i>. The authority combines the host and port. </p>
120   </li>
121   <li><a href="operators/render-uri.htm"><b>render-uri</b></a> <p><b>Arguments: </b><i>uri
122     stream </i></p>
123     <p>Print to <i>stream</i> the printed representation of <i>uri</i>. </p>
124   </li>
125   <li><a href="operators/parse-uri.htm"><b>parse-uri</b></a> <p><b>Arguments: </b><i>string </i>&amp;key
126     (<i>class</i> 'uri)<i> </i></p>
127     <p>Parse <i>string</i> into a URI object. </p>
128   </li>
129   <li><a href="operators/merge-uris.htm"><b>merge-uris</b></a> <p><b>Arguments: </b><i>uri
130     base-uri </i>&amp;optional <i>place </i></p>
131     <p>Return an absolute URI, based on <i>uri</i>, which can be relative, and <i>base-uri</i>
132     which must be absolute. </p>
133   </li>
134   <li><a href="operators/enough-uri.htm"><b>enough-uri</b></a> <p><b>Arguments: </b><i>uri
135     base </i></p>
136     <p>Converts <i>uri</i> into a relative URI using <i>base</i> as the base URI. </p>
137   </li>
138   <li><a href="operators/uri-parsed-path.htm"><b>uri-parsed-path</b></a> <p><b>Arguments: </b><i>uri
139     </i></p>
140     <p>Return the parsed representation of the path. </p>
141   </li>
142   <li><a href="operators/uri.htm"><b>uri</b></a> <p><b>Arguments: </b><i>object </i></p>
143     <p>Defined methods: if argument is a uri object, return it; create a uri object if
144     possible and return it, or error if not possible. </p>
145   </li>
146 </ul>
147
148 <hr>
149
150 <hr>
151
152 <h2><a name="parsing-decoding-1">3.0 Parsing, escape decoding/encoding and the path</a></h2>
153
154 <p>The method <a href="operators/uri-path.htm"><b>uri-path</b></a> returns the path
155 portion of the URI, in string form. The method <a href="operators/uri-parsed-path.htm"><b>uri-parsed-path</b></a>
156 returns the path portion of the URI, in list form. This list form is discussed below,
157 after a discussion of decoding/encoding. </p>
158
159 <p>RFC2396 lays out a method for inserting into URIs <em>reserved characters</em>. You do
160 this by escaping the character. An <em>escaped</em> character is defined like this: </p>
161
162 <pre>
163 escaped = &quot;%&quot; hex hex 
164
165 hex = digit | &quot;A&quot; | &quot;B&quot; | &quot;C&quot; | &quot;D&quot; | &quot;E&quot; | &quot;F&quot; | &quot;a&quot; | &quot;b&quot; | &quot;c&quot; | &quot;d&quot; | &quot;e&quot; | &quot;f&quot; 
166 </pre>
167
168 <p>In addition, the RFC defines excluded characters: </p>
169
170 <pre>
171 &quot;&lt;&quot; | &quot;&gt;&quot; | &quot;#&quot; | &quot;%&quot; | &lt;&quot;&gt; | &quot;{&quot; | &quot;}&quot; | &quot;|&quot; | &quot;\&quot; | &quot;^&quot; | &quot;[&quot; | &quot;]&quot; | &quot;`&quot; 
172 </pre>
173
174 <p>The set of reserved characters are: </p>
175
176 <pre>
177 &quot;;&quot; | &quot;/&quot; | &quot;?&quot; | &quot;:&quot; | &quot;@&quot; | &quot;&amp;&quot; | &quot;=&quot; | &quot;+&quot; | &quot;$&quot; | &quot;,&quot; 
178 </pre>
179
180 <p>with the following exceptions: 
181
182 <ul>
183   <li>within the authority component, the characters &quot;;&quot;, &quot;:&quot;,
184     &quot;@&quot;, &quot;?&quot;, and &quot;/&quot; are reserved. </li>
185   <li>within a path segment, the characters &quot;/&quot;, &quot;;&quot;, &quot;=&quot;, and
186     &quot;?&quot; are reserved. </li>
187   <li>within a query component, the characters &quot;;&quot;, &quot;/&quot;, &quot;?&quot;,
188     &quot;:&quot;, &quot;@&quot;, &quot;&amp;&quot;, &quot;=&quot;, &quot;+&quot;,
189     &quot;,&quot;, and &quot;$&quot; are reserved. </li>
190 </ul>
191
192 <p>From the RFC, there are two important rules about escaping and unescaping (encoding and
193 decoding): 
194
195 <ul>
196   <li>decoding should only happen when the URI is parsed into component parts;</li>
197   <li>encoding can only occur when a URI is made from component parts (ie, rendered for
198     printing). </li>
199 </ul>
200
201 <p>The implication of this is that to decode the URI, it must be in a parsed state. That
202 is, you can't convert <font face="Courier New">%2f</font> (the escaped form of
203 &quot;/&quot;) until the path has been parsed into its component parts. Another important
204 desire is for the application viewing the component parts to see the decoded values of the
205 components. For example, consider: </p>
206
207 <pre>
208 http://www.franz.com/calculator/3%2f2 
209 </pre>
210
211 <p>This might be the implementation of a calculator, and how someone would execute 3/2.
212 Clearly, the application that implements this would want to see path components of
213 &quot;calculator&quot; and &quot;3/2&quot;. &quot;3%2f2&quot; would not be useful to the
214 calculator application. </p>
215
216 <p>For the reasons given above, a parsed version of the path is available and has the
217 following form: </p>
218
219 <pre>
220 ([:absolute | :relative] component1 [component2...]) 
221 </pre>
222
223 <p>where components are: </p>
224
225 <pre>
226 element | (element param1 [param2 ...]) 
227 </pre>
228
229 <p>and <em>element</em> is a path element, and the param's are path element parameters.
230 For example, the result of </p>
231
232 <pre>
233 (uri-parsed-path (parse-uri &quot;foo;10/bar:x;y;z/baz.htm&quot;)) 
234 </pre>
235
236 <p>is </p>
237
238 <pre>
239 (:relative (&quot;foo&quot; &quot;10&quot;) (&quot;bar:x&quot; &quot;y&quot; &quot;z&quot;) &quot;baz.htm&quot;) 
240 </pre>
241
242 <p>There is a certain amount of canonicalization that occurs when parsing: 
243
244 <ul>
245   <li>A path of <code>(:absolute)</code> or <code>(:absolute &quot;&quot;)</code> is
246     equivalent to a <code>nil</code> path. That is, <code>http://a/</code> is parsed with a <code>nil</code>
247     path and printed as <code>http://a</code>. </li>
248   <li>Escaped characters that are not reserved are not escaped upon printing. For example, <code>&quot;foob%61r&quot;</code>
249     is parsed into <code>&quot;foobar&quot;</code> and appears as <code>&quot;foobar&quot;</code>
250     when the URI is printed. </li>
251 </ul>
252
253 <hr>
254
255 <hr>
256
257 <h2><a name="interning-uris-1">4.0 Interning URIs</a></h2>
258
259 <p>This section describes how to intern URIs. Interning is not mandatory. URIs can be used
260 perfectly well without interning them. </p>
261
262 <p>Interned URIs in Allegro are like symbols. That is, a string representing a URI, when
263 parsed and interned, will always yield an <strong>eq</strong> object. For example: </p>
264
265 <pre>
266 (eq (intern-uri &quot;http://www.franz.com&quot;) 
267     (intern-uri &quot;http://www.franz.com&quot;)) 
268 </pre>
269
270 <p>is always true. (Two strings with identical contents may or may not be <strong>eq</strong>
271 in Common Lisp, note.) </p>
272
273 <p>The functions associated with interning are: 
274
275 <ul>
276   <li><a href="operators/make-uri-space.htm"><b>make-uri-space</b></a> <p><b>Arguments: </b>&amp;key
277     <i>size </i></p>
278     <p>Make a new hash-table object to contain interned URIs. </p>
279   </li>
280   <li><a href="operators/uri-space.htm"><b>uri-space</b></a> <p><b>Arguments: </b></p>
281     <p>Return the object into which URIs are currently being interned. </p>
282   </li>
283   <li><a href="operators/uri_eq.htm"><b>uri=</b></a> <p><b>Arguments: </b><i>uri1 uri2 </i></p>
284     <p>Returns true if <i>uri1</i> and <i>uri2</i> are equivalent. </p>
285   </li>
286   <li><a href="operators/intern-uri.htm"><b>intern-uri</b></a> <p><b>Arguments: </b><i>uri-name
287     </i>&amp;optional <i>uri-space </i></p>
288     <p>Intern the uri object specified in the uri-space specified. Methods exist for strings
289     and uri objects. </p>
290   </li>
291   <li><a href="operators/unintern-uri.htm"><b>unintern-uri</b></a> <p><b>Arguments: </b><i>uri
292     </i>&amp;optional <i>uri-space </i></p>
293     <p>Unintern the uri object specified or all uri objects (in <i>uri-space</i> if specified)
294     if <i>uri</i> is <code>t</code>. </p>
295   </li>
296   <li><a href="operators/do-all-uris.htm"><b>do-all-uris</b></a> <p><b>Arguments: </b><i>(var </i>&amp;optional
297     <i>uri-space result) </i>&amp;body <i>body </i></p>
298     <p>Bind <i>var</i> to all currently defined uris (in <i>uri-space</i> if specified) and
299     evaluate <i>body</i>. </p>
300   </li>
301 </ul>
302
303 <hr>
304
305 <hr>
306
307 <h2><a name="acl-implementation-1">5.0 Allegro CL implementation notes</a></h2>
308
309 <ol>
310   <li>The following are true: <br>
311     <code>(uri= (parse-uri &quot;http://www.franz.com/&quot;)</code> <br>
312     &nbsp; &nbsp; <code>(parse-uri &quot;http://www.franz.com&quot;))</code> <br>
313     <code>(eq (intern-uri &quot;http://www.franz.com/&quot;)</code> <br>
314     &nbsp;&nbsp; <code>(intern-uri &quot;http://www.franz.com&quot;))</code><br>
315   </li>
316   <li>The following is true: <br>
317     <code>(eq (intern-uri &quot;http://www.franz.com:80/foo/bar.htm&quot;)</code> <br>
318     &nbsp; &nbsp; <code>(intern-uri &quot;http://www.franz.com/foo/bar.htm&quot;))</code><br>
319     (I.e. specifying the default port is the same as specifying no port at all. This is
320     specific in RFC2396.) </li>
321   <li>The <em>scheme</em> and <em>authority</em> are case-insensitive. In Allegro CL, the
322     scheme is a keyword that appears in the normal case for the Lisp in which you are
323     executing. </li>
324   <li><code>#u&quot;...&quot;</code> is shorthand for <code>(parse-uri &quot;...&quot;)</code>
325     but if an existing <code>#u</code> dispatch macro definition exists, it will not be
326     overridden. </li>
327   <li>The interaction between setting the scheme, host, port, path, query, and fragment slots
328     of URI objects, in conjunction with interning URIs will have very bad and unpredictable
329     results. </li>
330   <li>The printable representation of URIs is cached, for efficiency. This caching is undone
331     when the above slots are changed. That is, when you create a URI the printed
332     representation is cached. When you change one of the above mentioned slots, the printed
333     representation is cleared and calculated when the URI is next printed. For example: </li>
334 </ol>
335
336 <pre>
337 user(10): (setq u #u&quot;http://foo.bar.com/foo/bar&quot;) 
338 #&lt;uri http://foo.bar.com/foo/bar&gt; 
339 user(11): (setf (net.uri:uri-host u) &quot;foo.com&quot;) 
340 &quot;foo.com&quot; 
341 user(12): u 
342 #&lt;uri http://foo.com/foo/bar&gt; 
343 user(13): 
344 </pre>
345
346 <p>This allows URIs behavior to follow the principle of least surprise. </p>
347
348 <hr>
349
350 <hr>
351
352 <h2><a name="examples-1">6.0 Examples</a></h2>
353
354 <pre>
355 uri(10): (use-package :net.uri)
356 t
357 uri(11): (parse-uri &quot;foo&quot;)
358 #&lt;uri foo&gt;
359 uri(12): #u&quot;foo&quot;
360 #&lt;uri foo&gt;
361 uri(13): (setq base (intern-uri &quot;http://www.franz.com/foo/bar/&quot;))
362 #&lt;uri http://www.franz.com/foo/bar/&gt;
363 uri(14): (merge-uris (parse-uri &quot;foo.htm&quot;) base)
364 #&lt;uri http://www.franz.com/foo/bar/foo.htm&gt;
365 uri(15): (merge-uris (parse-uri &quot;?foo&quot;) base)
366 #&lt;uri http://www.franz.com/foo/bar/?foo&gt;
367 uri(16): (setq base (intern-uri &quot;http://www.franz.com/foo/bar/baz.htm&quot;))
368 #&lt;uri http://www.franz.com/foo/bar/baz.htm&gt;
369 uri(17): (merge-uris (parse-uri &quot;foo.htm&quot;) base)
370 #&lt;uri http://www.franz.com/foo/bar/foo.htm&gt;
371 uri(18): (merge-uris #u&quot;?foo&quot; base)
372 #&lt;uri http://www.franz.com/foo/bar/?foo&gt;
373 uri(19): (describe #u&quot;http://www.franz.com&quot;)
374 #&lt;uri http://www.franz.com&gt; is an instance of #&lt;standard-class net.uri:uri&gt;:
375  The following slots have :instance allocation:
376   scheme        :http
377   host          &quot;www.franz.com&quot;
378   port          nil
379   path          nil
380   query         nil
381   fragment      nil
382   plist         nil
383   escaped       nil
384   string        &quot;http://www.franz.com&quot;
385   parsed-path   nil
386   hashcode      nil
387 uri(20): (describe #u&quot;http://www.franz.com/&quot;)
388 #&lt;uri http://www.franz.com&gt; is an instance of #&lt;standard-class net.uri:uri&gt;:
389  The following slots have :instance allocation:
390   scheme        :http
391   host          &quot;www.franz.com&quot;
392   port          nil
393   path          nil
394   query         nil
395   fragment      nil
396   plist         nil
397   escaped       nil
398   string        &quot;http://www.franz.com&quot;
399   parsed-path   nil
400   hashcode      nil
401 uri(21): #u&quot;foobar#baz%23xxx&quot;
402 #&lt;uri foobar#baz#xxx&gt;
403 </pre>
404
405 <p><small>Copyright (c) 1998-2001, Franz Inc. Berkeley, CA., USA. All rights reserved.
406 Created 2001.8.16.</small></p>
407 </body>
408 </html>