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