Initial checkin for github.
[zs3.git] / doc / index.html
blob4ac7e9115eb1e21cdb0bb0a43d6cff066967c0a5
1 <html>
2 <head>
3 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
4 <link rel='stylesheet' type='text/css' href='style.css'>
5 <title>ZS3 - Amazon S3 and CloudFront from Common Lisp</title>
6 </head>
7 <body>
9 <div id='content'>
10 <h2>ZS3 - Amazon S3 and CloudFront from Common Lisp</h2>
12 <p>ZS3 is a Common Lisp library for working with
13 Amazon's <a href="http://aws.amazon.com/s3/">Simple Storage
14 Service</a> (S3)
15 and <a href="http://aws.amazon.com/cloudfront/">CloudFront content
16 delivery service</a>. It is available under a BSD-style license;
17 see <a href='LICENSE'>LICENSE</a> for details. The latest version
18 is 1.1.4, released on September 16, 2010.
20 <p>Download shortcut: <a href='http://www.xach.com/lisp/zs3.tgz'>http://www.xach.com/lisp/zs3.tgz</a>
22 <h2>Contents</h2>
24 <ul>
25 <li> <a href='#installation'>Installation</a>
26 <li> <a href='#overview'>Overview</a>
27 <li> <a href='#example'>Example Use</a>
28 <li> <a href='#limitations'>Limitations</a>
29 <li> <a href='#dictionary'>The ZS3 Dictionary</a>
30 <ul>
31 <li> <a href='#credentials'>Credentials</a>
32 <li> <a href='#bucket-ops'>Operations on Buckets</a>
33 <li> <a href='#querying-buckets'>Querying Buckets</a>
34 <li> <a href='#object-ops'>Operations on Objects</a>
35 <li> <a href='#access-control'>Access Control</a>
36 <li> <a href='#access-logging'>Access Logging</a>
37 <li> <a href='#misc'>Miscellaneous Operations</a>
38 <li> <a href='#utility'>Utility Functions</a>
39 <li> <a href='#cloudfront'>CloudFront</a>
40 </ul>
41 <li> <a href='#references'>References</a>
42 <li> <a href='#acknowledgements'>Acknowledgements</a>
43 <li> <a href='#feedback'>Feedback</a>
44 </ul>
46 <a name='installation'><h2>Installation</h2></a>
48 <p>ZS3 depends on the following libraries:
50 <ul>
51 <li> <a href="http://common-lisp.net/project/cxml/">Closure XML</a> (<a href='http://cliki.net/cxml?download'>download</a>)
52 <li> <a href="http://weitz.de/drakma/">Drakma</a> <b>1.0.0 or newer</b> (<a href='http://cliki.net/Drakma?download'>download</a>)
53 <li> <a href="http://method-combination.net/lisp/ironclad/">Ironclad</a> (<a href='http://cliki.net/ironclad?download'>download</a>)
54 <li> <a href="http://files.b9.com/cl-base64/">cl-base64</a> (<a href='http://cliki.net/cl-base64?download'>download</a>)
55 <li> <a href="http://puri.b9.com/">Puri</a> (<a href='http://cliki.net/puri?download'>download</a>)
56 </ul>
58 <p>Those libraries additionally depend on:
59 <ul>
60 <li> <a href="http://common-lisp.net/project/alexandria/">Alexandria</a> (<a href='http://cliki.net/alexandria?download'>download</a>)
61 <li> <a href="http://common-lisp.net/project/babel/">Babel</a> (<a href='http://cliki.net/babel?download'>download</a>)
62 <li> <a href="http://common-lisp.net/project/cffi/">CFFI</a> (<a href='http://cliki.net/cffi?download'>download</a>)
63 <li> <a href="http://weitz.de/chunga/">Chunga</a> (<a href='http://cliki.net/chunga?download'>download</a>)
64 <li> <a href="http://common-lisp.net/project/cl-plus-ssl/">CL+SSL</a> (<a href='http://cliki.net/cl+ssl?download'>download</a>)
65 <li> <a href="http://www.cliki.net/closure-common">closure-common</a> (<a href='http://cliki.net/closure-common?download'>download</a>)
66 <li> <a href="http://weitz.de/flexi-streams/">FLEXI-STREAMS</a> (<a href='http://cliki.net/flexi-streams?download'>download</a>)
67 <li> <a href="http://www.cliki.net/trivial-features">trivial-features</a> (<a href='http://cliki.net/trivial-features?download'>download</a>)
68 <li> <a href="http://www.cliki.net/trivial-gray-streams">trivial-gray-streams</a> (<a href='http://cliki.net/trivial-gray-streams?download'>download</a>)
69 <li> <a href="http://www.cliki.net/usocket">usocket</a> (<a href='http://cliki.net/usocket?download'>download</a>)
70 </ul>
72 <p>If you
73 have <a href="http://cliki.net/asdf-install">asdf-install</a>, you
74 can use <code>(asdf-install:install 'zs3)</code>, which will fetch
75 and load all the dependencies listed above.
77 <p>For more information about incorporating ASDF-using libraries like
78 ZS3 into your own projects,
79 see <a href="http://xach.livejournal.com/130040.html">this short
80 tutorial</a>.
83 <a name='overview'><h2>Overview</h2></a>
85 <p>ZS3 provides an interface to two separate, but related, Amazon
86 services: <a href="http://aws.amazon.com/s3/">S3</a>
87 and <a href="http://aws.amazon.com/cloudfront/">CloudFront</a>
89 <p>Using Amazon S3 involves working with two kinds of resources:
90 buckets and objects.
92 <p>Buckets are containers, and are used to organize and manage
93 objects. Buckets are identified by their name, which must be unique
94 across all of S3. A user may have up to 100 buckets in S3.
96 <p>Objects are stored within buckets. Objects consist of arbitrary
97 binary data, from 1 byte to 5 gigabytes. They are identified by a
98 key, which must be unique within a bucket. Objects can also have
99 associated S3-specific metadata and HTTP metadata.
101 <p>For full documentation of the Amazon S3 system, see
102 the <a href="http://developer.amazonwebservices.com/connect/entry.jspa?externalID=123&categoryID=48">Amazon
103 S3 Technical Documentation</a>. ZS3 uses the REST
104 interface for all its operations.
106 <p>Using Amazon CloudFront involves working with
107 distributions. Distributions are objects that associate an S3
108 bucket with primary cloudfront.net hostname and zero or more
109 arbitrary CNAMEs. S3 objects requested through a CloudFront
110 distribution are distributed to and cached in multiple locations
111 throughout the world, reducing latency and improving throughput,
112 compared to direct S3 requests.
114 <p>For full documentation of the Amazon CloudFront system, see the
115 <a href="http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1876&categoryID=213">Amazon
116 CloudFront Technical Documentation</a>.
118 <p>For help with using ZS3, please see
119 the <a href="http://groups.google.com/group/zs3-devel">zs3-devel</a>
120 mailing list.
122 <a name='example'><h2>Example Use</h2></a>
125 <pre class='code'>
126 * <b>(asdf:oos 'asdf:load-op '#:zs3)</b>
127 => <i>lots of stuff</i>
129 * <b>(defpackage #:demo (:use #:cl #:zs3))</b>
130 => #&lt;PACKAGE "DEMO"&gt;
132 * <b>(in-package #:demo)</b>
133 => #&lt;PACKAGE "DEMO"&gt;
135 * <b>(setf <a href='#*credentials*'>*credentials*</a> (<a href='#file-credentials'>file-credentials</a> "~/.aws"))</b>
136 => #&lt;FILE-CREDENTIALS {100482AF91}>
138 * <b>(<a href='#bucket-exists-p'>bucket-exists-p</a> "zs3-demo")</b>
139 => NIL
141 * <b>(<a href='#create-bucket'>create-bucket</a> "zs3-demo")</b>
142 => #&lt;RESPONSE 200 "OK" {10040D3281}>
144 * <b>(<a href='#put-vector'>put-vector</a> (<a href='#octet-vector'>octet-vector</a> 8 6 7 5 3 0 9 ) "zs3-demo" "jenny")</b>
145 => #&lt;RESPONSE 200 "OK" {10033EC2E1}>
147 * <b>(create-bucket "zs3 demo")</b>
148 Error:
149 InvalidBucketName: The specified bucket is not valid.
150 For more information, see:
151 <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/BucketRestrictions.html">http://docs.amazonwebservices.com/AmazonS3/2006-03-01/BucketRestrictions.html</a>
152 [Condition of type INVALID-BUCKET-NAME]
154 * <b>(<a href='#copy-object'>copy-object</a> :from-bucket "zs3-demo" :from-key "jenny" :to-key "j2")</b>
155 => #&lt;RESPONSE 200 "OK" {10040E3EA1}>
157 * <b>(<a href='#get-vector'>get-vector</a> "zs3-demo" "j2")</b>
158 => #(8 6 7 5 3 0 9),
159 ((:X-AMZ-ID-2 . "Huwo...")
160 (:X-AMZ-REQUEST-ID . "304...")
161 (:DATE . "Sat, 27 Sep 2008 15:01:03 GMT")
162 (:LAST-MODIFIED . "Sat, 27 Sep 2008 14:57:31 GMT")
163 (:ETAG . "\"f9e71fe2c41a10c0a78218e98a025520\"")
164 (:CONTENT-TYPE . "binary/octet-stream")
165 (:CONTENT-LENGTH . "7")
166 (:CONNECTION . "close")
167 (:SERVER . "AmazonS3"))
169 * <b>(<a href='#put-string'>put-string</a> "N&auml;men" "zs3-demo" "bork")</b>
170 => #&lt;RESPONSE 200 "OK" {10047A3791}>
172 * <b>(values (get-vector "zs3-demo" "bork"))</b>
173 => #(78 195 164 109 101 110)
175 * <b>(values (<a href='#get-file'>get-file</a> "zs3-demo" "bork" "bork.txt"))</b>
176 => #P"bork.txt"
178 * <b>(setf *distribution* (<a href='#create-distribution'>create-distribution</a> "zs3-demo" :cnames "cdn.wigflip.com")</b>
179 => #&lt;DISTRIBUTION X2S94L4KLZK5G0 for "zs3-demo.s3.amazonaws.com" [InProgress]>
181 * <b>(progn (sleep 180) (<a href='#refresh'>refresh</a> *distribution*))</b>
182 => #&lt;DISTRIBUTION X2S94L4KLZK5G0 for "zs3-demo.s3.amazonaws.com" [Deployed]>
184 * <b>(<a href='#domain-name'>domain-name</a> *distribution*)</b>
185 => "x214g1hzpjm1zp.cloudfront.net"
187 * <b>(<a href='#cnames'>cnames</a> *distribution*)</b>
188 => ("cdn.wigflip.com")
190 * <b>(put-string "Hello, world" "zs3-demo" "cloudfront" :public t)</b>
191 #&lt;RESPONSE 200 "OK" {10042689F1}>
193 * <b>(drakma:http-request "http://x214g1hzpjm1zp.cloudfront.net/cloudfront")</b>
194 "Hello, world"
196 ((:X-AMZ-ID-2 . "NMc3IY3NzHGGEvV/KlzPgZMyDfPVT+ITtHo47Alqg00MboTxSX2f5XJzVTErfuHr")
197 (:X-AMZ-REQUEST-ID . "52B050DC18638A00")
198 (:DATE . "Thu, 05 Mar 2009 16:24:25 GMT")
199 (:LAST-MODIFIED . "Thu, 05 Mar 2009 16:24:10 GMT")
200 (:ETAG . "\"bc6e6f16b8a077ef5fbc8d59d0b931b9\"")
201 (:CONTENT-TYPE . "text/plain")
202 (:CONTENT-LENGTH . "12")
203 (:SERVER . "AmazonS3")
204 (:X-CACHE . "Miss from cloudfront")
205 (:VIA . "1.0 ad78cb56da368c171e069e4444b2cbf6.cloudfront.net:11180")
206 (:CONNECTION . "close"))
207 #&lt;PURI:URI http://x214g1hzpjm1zp.cloudfront.net/cloudfront>
208 #&lt;FLEXI-STREAMS:FLEXI-IO-STREAM {1002CE0781}>
210 "OK"
212 * <b>(drakma:http-request "http://x214g1hzpjm1zp.cloudfront.net/cloudfront")</b>
213 "Hello, world"
215 ((:X-AMZ-ID-2 . "NMc3IY3NzHGGEvV/KlzPgZMyDfPVT+ITtHo47Alqg00MboTxSX2f5XJzVTErfuHr")
216 (:X-AMZ-REQUEST-ID . "52B050DC18638A00")
217 (:DATE . "Thu, 05 Mar 2009 16:24:25 GMT")
218 (:LAST-MODIFIED . "Thu, 05 Mar 2009 16:24:10 GMT")
219 (:ETAG . "\"bc6e6f16b8a077ef5fbc8d59d0b931b9\"")
220 (:CONTENT-TYPE . "text/plain")
221 (:CONTENT-LENGTH . "12")
222 (:SERVER . "AmazonS3")
223 (:AGE . "311")
224 (:X-CACHE . "Hit from cloudfront")
225 (:VIA . "1.0 0d78cb56da368c171e069e4444b2cbf6.cloudfront.net:11180")
226 (:CONNECTION . "close"))
227 #&lt;PURI:URI http://x214g1hzpjm1zp.cloudfront.net/cloudfront>
228 #&lt;FLEXI-STREAMS:FLEXI-IO-STREAM {100360A781}>
230 "OK"
232 </pre>
235 <a name='limitations'><h2>Limitations</h2></a>
237 <p>ZS3 supports almost all of the features of Amazon's S3 REST
238 interface. Some features are unsupported or incompletely supported:
240 <ul>
241 <li> No direct support
242 for <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingDevPay.html">Amazon
243 DevPay</a>
245 <li> No support for checking the 100-Continue response to avoid
246 unnecessary large requests; this will hopefully be fixed with a
247 future <a href='http://weitz.de/drakma/'>Drakma</a> release
249 <li> If a character in a key is encoded with multiple bytes in
250 UTF-8, a bad interaction
251 between <a href="http://puri.b9.com/">PURI</a> and Amazon's web
252 servers will trigger a validation error.
254 </ul>
256 <a name='dictionary'><h2>The ZS3 Dictionary</h2></a>
258 <p>The following sections document the symbols that are exported from
259 ZS3.
262 <a name='credentials'><h3>Credentials</h3></a>
266 <div class='item'>
267 <div class='type'><a name='*credentials*'>[Special variable]</a></div>
268 <div class='signature'>
269 <code class='name'>*credentials*</code>
270 </div>
272 <blockquote class='description'>
273 <p><code>*CREDENTIALS*</code> is the source of the Amazon Access
274 Key and Secret Key for authenticated requests. Any object that has
275 methods for the <a href='#access-key'><tt>ACCESS-KEY</tt></a>
276 and <a href='#secret-key'><tt>SECRET-KEY</tt></a> generic
277 functions may be used.
279 <p>If <code>*CREDENTIALS*</code> is a cons, it is treated as a
280 list, and the first element of the list is taken as the access
281 key and the second element of the list is taken as the secret
282 key.
284 <p>The default value of <code>*CREDENTIALS*</code> is NIL, which
285 will signal an error. You must set <code>*CREDENTIALS*</code> to
286 something that follows the credentials generic function protocol
287 to use ZS3.
289 <p>All ZS3 functions that involve authenticated requests take an
290 optional <code class='kw'>:CREDENTIALS</code> keyword
291 parameter. This parameter is bound to <code>*CREDENTIALS*</code>
292 for the duration of the function call.
294 <p>The following illustrates how to implement a credentials object
295 that gets the access and secret key from external environment
296 variables.
298 <pre class='code'>
299 (defclass environment-credentials () ())
301 (defmethod access-key ((credentials environment-credentials))
302 (declare (ignore credentials))
303 (getenv "AWS_ACCESS_KEY"))
305 (defmethod secret-key ((credentials environment-credentials))
306 (declare (ignore credentials))
307 (getenv "AWS_SECRET_KEY"))
309 (setf *credentials* (make-instance 'environment-credentials))
310 </pre>
311 </blockquote>
312 </div>
315 <div class='item'>
316 <div class='type'><a name='access-key'>[Generic function]</a></div>
317 <div class='signature'>
318 <code class='name'>access-key</code>
319 <span class='args'>
320 <var>credentials</var>
321 </span>
322 <span class='result'>=> <var>access-key-string</var></span>
323 </div>
325 <blockquote class='description'>
326 <p>Returns the access key for <var>credentials</var>.
327 </blockquote>
328 </div>
331 <div class='item'>
332 <div class='type'><a name='secret-key'>[Generic function]</a></div>
333 <div class='signature'>
334 <code class='name'>secret-key</code>
335 <span class='args'>
336 <var>credentials</var>
337 </span>
338 <span class='result'>=> <var>secret-key-string</var></span>
339 </div>
341 <blockquote class='description'>
342 <p>Returns the secret key for <var>credentials</var>.
343 </blockquote>
344 </div>
346 <div class='item'>
347 <div class='type'><a name='file-credentials'>[Function]</a></div>
348 <div class='signature'>
349 <code class='name'>file-credentials</code>
350 <span class='args'>
351 <var>pathname</var>
352 </span>
353 <span class='result'>=> <var>credentials</var></span>
354 </div>
356 <blockquote class='description'>
357 <p>Loads credentials on demand from <var>pathname</var>. The file
358 named by <var>pathname</var> should be a text file with the
359 access key on the first line and the secret key on the second
360 line.
362 <p>It can be used like so:
364 <pre class='code'>
365 (setf *credentials* (file-credentials "/etc/s3.conf"))
366 </pre>
367 </blockquote>
368 </div>
372 <a name='bucket-ops'><h3>Operations on Buckets</h3></a>
374 <p>With ZS3, you can put, get, copy, and delete buckets. You can also
375 get information about the bucket.
377 <div class='item'>
378 <div class='type'><a name='all-buckets'>[Function]</a></div>
379 <div class='signature'>
380 <code class='name'>all-buckets</code>
381 <span class='args'>
382 <code class='llkw'>&amp;key</code> <var>credentials</var>
383 </span>
384 <span class='result'>=> <var>bucket-vector</var></span>
385 </div>
387 <blockquote class='description'>
388 <p>Returns a vector of all bucket objects. Bucket object
389 attributes are accessible via <a href='#name'><tt>NAME</tt></a>
390 and <a href='#creation-date'><tt>CREATION-DATE</tt></a>.
391 </blockquote>
392 </div>
394 <div class='item'>
395 <div class='type'><a name='creation-date'>[Function]</a></div>
396 <div class='signature'>
397 <code class='name'>creation-date</code>
398 <span class='args'>
399 <var>bucket-object</var>
400 </span>
401 <span class='result'>=> <var>creation-universal-time</var></span>
402 </div>
404 <blockquote class='description'>
405 <p>Returns the creation date of <var>bucket-object</var>, which
406 must be a bucket object, as a universal time.
407 </blockquote>
408 </div>
411 <div class='item'>
412 <div class='type'><a name='name'>[Function]</a></div>
413 <div class='signature'>
414 <code class='name'>name</code>
415 <span class='args'>
416 <var>object</var>
417 </span>
418 <span class='result'>=> <var>name-string</var></span>
419 </div>
421 <blockquote class='description'>
422 <p>Returns the string name of <var>object</var>, which must be a
423 key object or bucket object.
424 </blockquote>
425 </div>
428 <div class='item'>
429 <div class='type'><a name='all-keys'>[Function]</a></div>
430 <div class='signature'>
431 <code class='name'>all-keys</code>
432 <span class='args'>
433 <var>bucket</var>
434 <code class='llkw'>&amp;key</code>
435 <var>prefix</var>
436 <var>credentials</var>
437 </span>
438 <span class='result'>=> <var>key-vector</var></span>
439 </div>
441 <blockquote class='description'>
442 <p>Returns a vector of all key objects in <var>bucket</var> with names
443 that start with the string <var>prefix</var>. If no prefix is
444 specified, returns all keys. Keys in the vector are in
445 alphabetical order by name. Key
446 object attributes are accessible via
447 <a href='#name'><tt>NAME</tt></a>,
448 <a href='#size'><tt>SIZE</tt></a>,
449 <a href='#etag'><tt>ETAG</tt></a>,
450 <a href='#last-modified'><tt>LAST-MODIFIED</tt></a>,
451 and <a href='#owner'><tt>OWNER</tt></a>.
453 <p>This function is built
454 on <a href='#query-bucket'><tt>QUERY-BUCKET</tt></a> and may
455 involve multiple requests if a bucket has more than 1000 keys.
456 </blockquote>
457 </div>
460 <div class='item'>
461 <div class='type'><a name='bucket-exists-p'>[Function]</a></div>
462 <div class='signature'>
463 <code class='name'>bucket-exists-p</code>
464 <span class='args'>
465 <var>bucket</var>
466 <code class='llkw'>&amp;key</code>
467 <var>credentials</var>
468 </span>
469 <span class='result'>=> <var>boolean</var></span>
470 </div>
472 <blockquote class='description'>
473 <p>Returns <i>true</i> if <var>bucket</var> exists.
474 </blockquote>
475 </div>
478 <div class='item'>
479 <div class='type'><a name='create-bucket'>[Function]</a></div>
480 <div class='signature'>
481 <code class='name'>create-bucket</code>
482 <span class='args'>
483 <var>name</var>
484 <code class='llkw'>&amp;key</code>
485 <var>access-policy</var>
486 <var>public</var>
487 <var>location</var>
488 <var>credentials</var>
489 </span>
490 <span class='result'>=> |</span>
491 </div>
493 <blockquote class='description'>
494 <p>Creates a bucket named <var>name</var>.
496 <p>If provided, <var>access-policy</var> should be one of the
497 following:
499 <ul>
500 <li> <code class='kw'>:PRIVATE</code> - bucket owner is
501 granted <code class='kw'>:FULL-CONTROL</code>; this is the
502 default behavior if no access policy is provided
503 <li> <code class='kw'>:PUBLIC-READ</code> - all users,
504 regardless of authentication, can query the bucket's contents
505 <li> <code class='kw'>:PUBLIC-READ-WRITE</code> - all users,
506 regardless of authentication, can query the bucket's
507 contents and create new objects in the bucket
508 <li> <code class='kw'>:AUTHENTICATED-READ</code> -
509 authenticated Amazon AWS users can query the bucket
510 </ul>
512 <p>For more information about access policies,
513 see <a href='http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAccessPolicy.html'>Canned
514 Access Policies</a> in the Amazon S3 developer documentation.
516 <p>If <var>public</var> is <i>true</i>, it has the same effect as
517 providing an <var>access-policy</var>
518 of <code class='kw'>:PUBLIC-READ</code>. An error is signaled if
519 both <var>public</var> and
520 <var>access-policy</var> are provided.
522 <p>If <var>location</var> is "EU", the bucket will be created in
523 Europe. See <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/BucketConfiguration.html">Bucket
524 Configuration Options</a> in the Amazon S3 developer
525 documentation for more information about location constraints.
526 </blockquote>
527 </div>
530 <div class='item'>
531 <div class='type'><a name='delete-bucket'>[Function]</a></div>
532 <div class='signature'>
533 <code class='name'>delete-bucket</code>
534 <span class='args'>
535 <var>bucket</var> <code class='llkw'>&amp;key</code> <var>credentials</var>
536 </span>
537 <span class='result'>=> |</span>
538 </div>
540 <blockquote class='description'>
541 <p>Deletes <var>bucket</var>. Signals a BUCKET-NOT-EMPTY error if
542 the bucket is not empty, or a NO-SUCH-BUCKET error if there is no
543 bucket with the given name.
545 </blockquote>
546 </div>
549 <div class='item'>
550 <div class='type'><a name='bucket-location'>[Function]</a></div>
551 <div class='signature'>
552 <code class='name'>bucket-location</code>
553 <span class='args'>
554 <var>bucket</var> <code class='llkw'>&amp;key</code> <var>credentials</var>
555 </span>
556 <span class='result'>=> <var>location</var></span>
557 </div>
559 <blockquote class='description'>
560 <p>Returns the location specified when creating a bucket, or NIL if no
561 location was specified.
562 </blockquote>
563 </div>
566 <a name='querying-buckets'><h3>Querying Buckets</h3></a>
568 <p>S3 has a flexible interface for querying a bucket for information
569 about its contents. ZS3 supports this interface via
570 <a href='#query-bucket'><tt>QUERY-BUCKET</tt></a>,
571 <a href='#continue-bucket-query'><tt>CONTINUE-BUCKET-QUERY</tt></a>,
572 and related functions.
574 <div class='item'>
575 <div class='type'><a name='query-bucket'>[Function]</a></div>
576 <div class='signature'>
577 <code class='name'>query-bucket</code>
578 <span class='args'>
579 <var>bucket</var>
580 <code class='llkw'>&amp;key</code>
581 <var>prefix</var>
582 <var>marker</var>
583 <var>max-keys</var>
584 <var>delimiter</var>
585 <var>credentials</var>
586 </span>
587 <span class='result'>=> <var>response</var></span>
588 </div>
590 <blockquote class='description'>
591 <p>Query <var>bucket</var> for key information. Returns a response
592 object that has the result of the query. Response attributes are
593 accessible via
594 <a href='#bucket-name'><tt>BUCKET-NAME</tt></a>,
595 <a href='#prefix'><tt>PREFIX</tt></a>,
596 <a href='#marker'><tt>MARKER</tt></a>,
597 <a href='#delimiter'><tt>DELIMITER</tt></a>,
598 <a href='#truncatedp'><tt>TRUNCATEDP</tt></a>,
599 <a href='#keys'><tt>KEYS</tt></a>, and
600 <a href='#common-prefixes'><tt>COMMON-PREFIXES</tt></a>.
602 <p>Amazon might return fewer key objects than actually match the
603 query parameters, based on <var>max-keys</var> or the result
604 limit of 1000 key objects. In that
605 case, <a href='#truncatedp'><tt>TRUNCATEDP</tt></a>
606 for <var>response</var> is <i>true</i>, and
607 <a href='#continue-bucket-query'><tt>CONTINUE-BUCKET-QUERY</tt></a>
608 can be used with <var>response</var> be used to get successive
609 responses for the query parameters.
611 <p>When <var>prefix</var> is supplied, only key objects with names
612 that start with <var>prefix</var> will be returned
613 in <var>response</var>.
615 <p>When <var>marker</var> is supplied, only key objects with names
616 occurring lexically after <var>marker</var> will be returned in
617 <var>response</var>.
619 <p>When <var>max-keys</var> is supplied, it places an inclusive
620 upper limit on the number of key objects returned
621 in <var>response</var>. Note that Amazon currently limits
622 responses to at most 1000 key objects even
623 if <var>max-keys</var> is greater than 1000.
625 <p>When <var>delimiter</var> is supplied, key objects that have
626 the delimiter string after <var>prefix</var> in their names are
627 not returned in the <a href='#keys'><tt>KEYS</tt></a> attribute
628 of the response, but are instead accumulated into the
629 <a href='#common-prefixes'><tt>COMMON-PREFIXES</tt></a>
630 attribute of the response. For example:
631 <pre class='code'>
632 * <b>(all-keys "zs3-demo")</b>
633 => #(#&lt;KEY "a" 4>
634 #&lt;KEY "b/1" 4>
635 #&lt;KEY "b/2" 4>
636 #&lt;KEY "b/3" 4>
637 #&lt;KEY "c/10" 4>
638 #&lt;KEY "c/20" 4>
639 #&lt;KEY "c/30" 4>)
641 * <b>(setf *response* (query-bucket "zs3-demo" :delimiter "/"))</b>
642 => #&lt;BUCKET-LISTING "zs3-demo">
644 * <b>(values (keys *response*) (common-prefixes *response*))</b>
645 => #(#&lt;KEY "a" 4>),
646 #("b/"
647 "c/")
649 * <b>(setf *response* (query-bucket "zs3-demo" :delimiter "/" :prefix "b/"))</b>
650 => #&lt;BUCKET-LISTING "zs3-demo">
652 * <b>(values (keys *response*) (common-prefixes *response*))</b>
653 => #(#&lt;KEY "b/1" 4>
654 #&lt;KEY "b/2" 4>
655 #&lt;KEY "b/3" 4>),
656 #()</pre>
658 <p>For more information about bucket queries,
659 see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTBucketGET.html">GET
660 Bucket</a> in the Amazon S3 developer documentation.
662 </blockquote>
664 </div>
667 <div class='item'>
668 <div class='type'><a name='continue-bucket-query'>[Function]</a></div>
669 <div class='signature'>
670 <code class='name'>continue-bucket-query</code>
671 <span class='args'>
672 <var>response</var>
673 </span>
674 <span class='result'>=> <var>response</var></span>
675 </div>
677 <blockquote class='description'>
678 <p>If <var>response</var> is a truncated response from a previous
679 call to
680 <a href='#query-bucket'><tt>QUERY-BUCKET</tt></a>,
681 continue-bucket-query returns the result of resuming the query at the
682 truncation point. When there are no more results,
683 continue-bucket-query returns NIL.
684 </blockquote>
685 </div>
687 <div class='item'>
688 <div class='type'><a name='bucket-name'>[Function]</a></div>
689 <div class='signature'>
690 <code class='name'>bucket-name</code>
691 <span class='args'>
692 <var>response</var>
693 </span>
694 <span class='result'>=> <var>name</var></span>
695 </div>
697 <blockquote class='description'>
698 <p>Returns the name of the bucket used in the call
699 to <a href='#query-bucket'><tt>QUERY-BUCKET</tt></a> that
700 produced <var>response</var>.
701 </blockquote>
702 </div>
707 <div class='item'>
708 <div class='type'><a name='keys'>[Function]</a></div>
709 <div class='signature'>
710 <code class='name'>keys</code>
711 <span class='args'>
712 <var>response</var>
713 </span>
714 <span class='result'>=> <var>keys-vector</var></span>
715 </div>
717 <blockquote class='description'>
718 <p>Returns the vector of key objects in <var>response</var>. Key
719 object attributes are accessible via
720 <a href='#name'><tt>NAME</tt></a>,
721 <a href='#size'><tt>SIZE</tt></a>,
722 <a href='#etag'><tt>ETAG</tt></a>,
723 <a href='#last-modified'><tt>LAST-MODIFIED</tt></a>,
724 and <a href='#owner'><tt>OWNER</tt></a>.
725 </blockquote>
726 </div>
729 <div class='item'>
730 <div class='type'><a name='common-prefixes'>[Function]</a></div>
731 <div class='signature'>
732 <code class='name'>common-prefixes</code>
733 <span class='args'>
734 <var>response</var>
735 </span>
736 <span class='result'>=> <var>prefix-vector</var></span>
737 </div>
739 <blockquote class='description'>
740 <p>Returns a vector of common prefix strings, based on the
741 delimiter argument of
742 the <a href='#query-bucket'><tt>QUERY-BUCKET</tt></a> call that
743 produced <var>response</var>.
744 </blockquote>
745 </div>
748 <div class='item'>
749 <div class='type'><a name='prefix'>[Function]</a></div>
750 <div class='signature'>
751 <code class='name'>prefix</code>
752 <span class='args'>
753 <var>response</var>
754 </span>
755 <span class='result'>=> <var>prefix-string</var></span>
756 </div>
758 <blockquote class='description'>
759 <p>Returns the prefix given to
760 the <a href='#query-bucket'><tt>QUERY-BUCKET</tt></a> call that
761 produced <var>response</var>. If present, all keys
762 in <var>response</var> have <var>prefix-string</var> as a prefix.
763 </blockquote>
764 </div>
766 <div class='item'>
767 <div class='type'><a name='marker'>[Function]</a></div>
768 <div class='signature'>
769 <code class='name'>marker</code>
770 <span class='args'>
771 <var>response</var>
772 </span>
773 <span class='result'>=> <var>marker</var></span>
774 </div>
776 <blockquote class='description'>
777 <p>Returns the marker given to
778 the <a href='#query-bucket'><tt>QUERY-BUCKET</tt></a> call that
779 produced <var>response</var>. If present,
780 it lexically precedes all key names in the response.
781 </blockquote>
782 </div>
784 <div class='item'>
785 <div class='type'><a name='delimiter'>[Function]</a></div>
786 <div class='signature'>
787 <code class='name'>delimiter</code>
788 <span class='args'>
789 <var>response</var>
790 </span>
791 <span class='result'>=> <var>delimiter</var></span>
792 </div>
794 <blockquote class='description'>
795 <p>Returns the delimiter used in
796 the <a href='#query-bucket'><tt>QUERY-BUCKET</tt></a> call that
797 produced <var>response</var>.
798 </blockquote>
799 </div>
802 <div class='item'>
803 <div class='type'><a name='truncatedp'>[Function]</a></div>
804 <div class='signature'>
805 <code class='name'>truncatedp</code>
806 <span class='args'>
807 <var>response</var>
808 </span>
809 <span class='result'>=> <var>boolean</var></span>
810 </div>
812 <blockquote class='description'>
813 <p>Returns <i>true</i> if <var>response</var> is truncated; that
814 is, if there is more data to retrieve for a
815 given <a href='#query-bucket'><tt>QUERY-BUCKET</tt></a>
816 query. <a href='#continue-bucket-query'><tt>CONTINUE-BUCKET-QUERY</tt></a>
817 may be used to fetch more data.
818 </blockquote>
819 </div>
822 <div class='item'>
823 <div class='type'><a name='last-modified'>[Function]</a></div>
824 <div class='signature'>
825 <code class='name'>last-modified</code>
826 <span class='args'>
827 <var>key-object</var>
828 </span>
829 <span class='result'>=> <var>universal-time</var></span>
830 </div>
832 <blockquote class='description'>
833 <p>Returns a universal time representing the last modified time
834 of <var>key-object</var>.
835 </blockquote>
836 </div>
839 <div class='item'>
840 <div class='type'><a name='etag'>[Function]</a></div>
841 <div class='signature'>
842 <code class='name'>etag</code>
843 <span class='args'>
844 <var>key-object</var>
845 </span>
846 <span class='result'>=> <var>etag-string</var></span>
847 </div>
849 <blockquote class='description'>
850 <p>Returns the etag for <var>key-object</var>.
851 </blockquote>
852 </div>
855 <div class='item'>
856 <div class='type'><a name='size'>[Function]</a></div>
857 <div class='signature'>
858 <code class='name'>size</code>
859 <span class='args'>
860 <var>key-object</var>
861 </span>
862 <span class='result'>=> <var>size</var></span>
863 </div>
865 <blockquote class='description'>
866 <p>Returns the size, in octets, of <var>key-object</var>.
867 </blockquote>
868 </div>
871 <div class='item'>
872 <div class='type'><a name='owner'>[Function]</a></div>
873 <div class='signature'>
874 <code class='name'>owner</code>
875 <span class='args'>
876 <var>key-object</var>
877 </span>
878 <span class='result'>=> <var>owner</var></span>
879 </div>
881 <blockquote class='description'>
882 <p>Returns the owner of <var>key-object</var>, or NIL if no owner
883 information is available.
884 </blockquote>
885 </div>
890 <a name='object-ops'><h3>Operations on Objects</h3></a>
892 <p>Objects are the stored binary data in S3. Every object is uniquely
893 identified by a bucket/key pair. ZS3 has several functions for
894 storing and fetching objects, and querying object attributes.
896 <div class='item'>
897 <div class='type'><a name='get-object'>[Function]</a></div>
898 <div class='signature'>
899 <code class='name'>get-object</code>
900 <span class='args'>
901 <var>bucket</var>
902 <var>key</var>
903 <code class='llkw'>&amp;key</code>
904 <var>output</var> <br>
905 <var>start</var> <var>end</var> <br>
906 <var>when-modified-since</var> <var>unless-modified-since</var> <br>
907 <var>when-etag-matches</var> <var>unless-etag-matches</var> <br>
908 <var>if-exists</var> <var>string-external-format</var>
909 <var>credentials</var>
910 </span>
911 <span class='result'>=> <var>object</var></span>
912 </div>
914 <blockquote class='description'>
915 <p>Fetch the object referenced by <var>bucket</var>
916 and <var>key</var>. The secondary value of all successful requests
917 is an alist of <a href='http://weitz.de/drakma/'>Drakma</a>-style
918 response HTTP headers.
920 <p>If <var>output</var> is <code class='kw'>:VECTOR</code> (the
921 default), the object's octets are returned in a vector.
923 <p>If <var>output</var> is <code class='kw'>:STRING</code>, the
924 object's octets are converted to a string using the encoding
925 specified by <var>string-external-format</var>, which defaults
926 to <code class='kw'>:UTF-8</code>. See <a href="http://weitz.de/flexi-streams/#external-formats">External
927 formats</a> in the FLEXI-STREAMS documentation for supported
928 values for the string external format. Note that, even
929 when <var>output</var> is <code class='kw'>:STRING</code>, the
930 start and end arguments operate on the object's underlying octets,
931 not the string representation in a particular encoding. It's
932 possible to produce a subsequence of the object's octets that are
933 not valid in the desired encoding.
935 <p>If <var>output</var> is a string or pathname, the object's
936 octets are saved to a file identified by the string or
937 pathname. The <var>if-exists</var> argument is passed
938 to <code>WITH-OPEN-FILE</code> to control the behavior when the
939 output file already exists. It defaults
940 to <code class='kw'>:SUPERSEDE</code>.
942 <p><var>start</var> marks the first index fetched from the
943 object's data. <var>end</var> specifies the index after the last
944 octet fetched. If start is NIL, it defaults to 0. If end is nil,
945 it defaults to the total length of the object. If
946 both <var>start</var> and <var>end</var> are
947 provided, <var>start</var> must be less than or equal
948 to <var>end</var>.
950 <p><var>when-modified-since</var>
951 and <var>unless-modified-since</var> are optional. If
952 <var>when-modified-since</var> is provided, the result will be the normal
953 object value if the object has been modified since the provided
954 universal time, NIL otherwise. The logic is reversed for
955 <var>unless-modified-since</var>.
957 <p><var>when-etag-matches</var> and <var>unless-etag-matches</var> are optional. If
958 <var>when-etag-matches</var> is provided, the result will be the
959 normal object value if the object's etag matches the provided
960 string, NIL otherwise. The logic is reversed
961 for <var>unless-etag-matches</var>.
963 </blockquote>
964 </div>
966 <div class='item'>
967 <div class='type'><a name='get-vector'>[Function]</a></div>
968 <div class='signature'>
969 <code class='name'>get-vector</code>
970 <span class='args'>
971 <var>bucket</var> <var>key</var>
972 <code class='llkw'>&amp;key</code>
973 <var>start</var> <var>end</var>
974 <var>when-modified-since</var> <var>unless-modified-since</var>
975 <var>when-etag-matches</var> <var>unless-etag-matches</var>
976 <var>credentials</var>
977 </span>
978 <span class='result'>=> <var>vector</var></span>
979 </div>
981 <blockquote class='description'>
982 <p>get-vector is a convenience interface to <a href='#get-object'><tt>GET-OBJECT</tt></a>. It is equivalent
983 to calling:
985 <pre class='code'>
986 (get-object bucket key <b>:output :vector</b> ...)
987 </pre>
988 </blockquote>
989 </div>
991 <div class='item'>
992 <div class='type'><a name='get-string'>[Function]</a></div>
993 <div class='signature'>
994 <code class='name'>get-string</code>
995 <span class='args'>
996 <var>bucket</var> <var>key</var>
997 <code class='llkw'>&amp;key</code>
998 <var>external-format</var>
999 <var>start</var> <var>end</var>
1000 <var>when-modified-since</var>
1001 <var>unless-modified-since</var>
1002 <var>when-etag-matches</var>
1003 <var>unless-etag-matches</var>
1004 <var>credentials</var>
1005 </span>
1006 <span class='result'>=> <var>string</var></span>
1007 </div>
1009 <blockquote class='description'>
1010 get-string is a convenience interface
1011 to <a href='#get-object'><tt>GET-OBJECT</tt></a>. It is equivalent
1012 to calling:
1014 <pre class='code'>
1015 (get-object bucket key <b>:output :string</b> :string-external-format external-format ...)
1016 </pre>
1018 </blockquote>
1019 </div>
1021 <div class='item'>
1022 <div class='type'><a name='get-file'>[Function]</a></div>
1023 <div class='signature'>
1024 <code class='name'>get-file</code>
1025 <span class='args'>
1026 <var>bucket</var> <var>key</var> <var>file</var>
1027 <code class='llkw'>&amp;key</code>
1028 <var>start</var> <var>end</var>
1029 <var>when-modified-since</var>
1030 <var>unless-modified-since</var>
1031 <var>when-etag-matches</var>
1032 <var>unless-etag-matches</var>
1033 <var>credentials</var>
1034 </span>
1035 <span class='result'>=> <var>pathname</var></span>
1036 </div>
1038 <blockquote class='description'>
1039 <p>get-file is a convenience interface
1040 to <a href='#get-object'><tt>GET-OBJECT</tt></a>. It is
1041 equivalent to calling:
1043 <pre class='code'>
1044 (get-object bucket key <b>:output file</b> ...)
1045 </pre>
1047 </blockquote>
1048 </div>
1051 <div class='item'>
1052 <div class='type'><a name='put-object'>[Function]</a></div>
1053 <div class='signature'>
1054 <code class='name'>put-object</code>
1055 <span class='args'>
1056 <var>object</var> <var>bucket</var> <var>key</var>
1057 <code class='llkw'>&amp;key</code>
1058 <var>access-policy</var>
1059 <var>public</var>
1060 <var>metadata</var>
1061 <var>string-external-format</var>
1062 <var>cache-control</var>
1063 <var>content-encoding</var>
1064 <var>content-disposition</var>
1065 <var>content-type</var>
1066 <var>expires</var>
1067 <var>credentials</var>
1068 </span>
1069 <span class='result'>=> |</span>
1070 </div>
1072 <blockquote class='description'>
1073 <p>Stores the octets of <var>object</var> in the location
1074 identified by <var>bucket</var> and <var>key</var>.
1076 <p>If <i>object</i> is an octet vector, it is stored directly.
1078 <p>If <i>object</i> is a string, it is converted to an octet
1079 vector using <i>string-external-format</i>, which defaults
1080 to <code class='kw'>:UTF-8</code>, then
1081 stored. See <a href="http://weitz.de/flexi-streams/#external-formats">External
1082 formats</a> in the FLEXI-STREAMS documentation for supported
1083 values for the string external format.
1085 <p>If <i>object</i> is a pathname, its contents are loaded in
1086 memory as an octet vector and stored.
1088 <p>If provided, <var>access-policy</var> should be one of the
1089 following:
1091 <ul>
1092 <li> <code class='kw'>:PRIVATE</code> - object owner is
1093 granted <code class='kw'>:FULL-CONTROL</code>; this is the
1094 default behavior if no access policy is provided
1095 <li> <code class='kw'>:PUBLIC-READ</code> - all users,
1096 regardless of authentication, can read the object
1097 <li> <code class='kw'>:AUTHENTICATED-READ</code> -
1098 authenticated Amazon AWS users can read the object
1099 </ul>
1101 <p>For more information about access policies,
1102 see <a href='http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAccessPolicy.html'>Canned
1103 Access Policies</a> in the Amazon S3 developer documentation.
1105 <p>If <var>public</var> is <i>true</i>, it has the same effect as
1106 providing an <var>access-policy</var>
1107 of <code class='kw'>:PUBLIC-READ</code>. An error is signaled if
1108 both <var>public</var> and
1109 <var>access-policy</var> are provided.
1112 <p>If provided, <var>metadata</var> should be an alist of Amazon
1113 metadata to set on the object. When the object is fetched again,
1114 the metadata will be returned in HTTP headers prefixed with
1115 "x-amz-meta-".
1117 <p>The <i>cache-control</i>, <i>content-encoding</i>, <i>content-disposition</i>,
1118 <i>content-type</i>, and <i>expires</i> values are all used to set
1119 HTTP properties of the object that are returned with subsequent
1120 GET or HEAD requests. If <i>content-type</i> is not set, it
1121 defaults to "binary/octet-stream". The others default to
1122 NIL. If <i>expires</i> is provided, it should be a universal time.
1123 </blockquote>
1124 </div>
1126 <div class='item'>
1127 <div class='type'><a name='put-vector'>[Function]</a></div>
1128 <div class='signature'>
1129 <code class='name'>put-vector</code>
1130 <span class='args'>
1131 <var>vector</var>
1132 <var>bucket</var>
1133 <var>key</var> <code class='llkw'>&amp;key</code>
1134 <var>start</var> <var>end</var>
1135 <var>access-policy</var>
1136 <var>public</var> <var>metadata</var>
1137 <var>content-disposition</var>
1138 <var>content-encoding</var>
1139 <var>content-type</var>
1140 <var>expires</var>
1141 <var>credentials</var>
1142 </span>
1143 <span class='result'>=> |</span>
1144 </div>
1146 <blockquote class='description'>
1147 <p>put-vector is a convenience interface
1148 to <a href='#put-object'><tt>PUT-OBJECT</tt></a>. It is similar
1149 to calling:
1151 <pre class='code'>
1152 (put-object vector bucket key ...)
1153 </pre>
1154 </blockquote>
1156 <p>If one of <var>start</var> or <var>end</var> is provided, they
1157 are used as bounding index designators on the string, and only a
1158 subsequence is used.
1159 </div>
1161 <div class='item'>
1162 <div class='type'><a name='put-string'>[Function]</a></div>
1163 <div class='signature'>
1164 <code class='name'>put-string</code>
1165 <span class='args'>
1166 <var>string</var> <var>bucket</var> <var>key</var>
1167 <code class='llkw'>&amp;key</code>
1168 <var>start</var> <var>end</var>
1169 <var>external-format</var>
1170 <var>access-policy</var>
1171 <var>public</var> <var>metadata</var>
1172 <var>content-disposition</var>
1173 <var>content-encoding</var>
1174 <var>content-type</var>
1175 <var>expires</var>
1176 <var>credentials</var>
1177 </span>
1178 <span class='result'>=> |</span>
1179 </div>
1181 <blockquote class='description'>
1182 <p>put-string is a convenience interface
1183 to <a href='#put-object'><tt>PUT-OBJECT</tt></a>. It is similar to
1184 calling:
1186 <pre class='code'>
1187 (put-object string bucket key :string-external-format external-format ...)
1188 </pre>
1189 </blockquote>
1191 <p>If one of <var>start</var> or end is <var>supplied</var>, they
1192 are used as bounding index designators on the string, and only a
1193 substring is used.
1194 </div>
1196 <div class='item'>
1197 <div class='type'><a name='put-file'>[Function]</a></div>
1198 <div class='signature'>
1199 <code class='name'>put-file</code>
1200 <span class='args'>
1201 <var>file</var> <var>bucket</var> <var>key</var>
1202 <code class='llkw'>&amp;key</code>
1203 <var>start</var> <var>end</var>
1204 <var>access-policy</var>
1205 <var>public</var> <var>metadata</var>
1206 <var>content-disposition</var> <var>content-encoding</var> <var>content-type</var>
1207 <var>expires</var>
1208 <var>credentials</var>
1209 </span>
1210 <span class='result'>=> |</span>
1211 </div>
1213 <blockquote class='description'>
1214 <p>put-file is a convenience interface
1215 to <a href='#put-object'><tt>PUT-OBJECT</tt></a>. It is almost
1216 equivalent to calling:
1218 <pre class='code'>
1219 (put-object (pathname file) bucket key ...)
1220 </pre>
1222 <p>If <var>key</var> is T, the <code>FILE-NAMESTRING</code> of
1223 the file is used as the key instead of <i>key</i>.
1225 <p>If one of <var>start</var> or <var>end</var> is supplied, only
1226 a subset of the file is used. If <var>start</var> is not
1227 NIL, <var>start</var> octets starting from the beginning of the
1228 file are skipped. If <var>end</var> is not NIL, octets in the
1229 file at and after <var>end</var> are ignored. An error of type
1230 <tt>CL:END-OF-FILE</tt> is signaled if <var>end</var> is
1231 provided and the file size is less than <var>end</var>.
1232 </blockquote>
1233 </div>
1236 <div class='item'>
1237 <div class='type'><a name='put-stream'>[Function]</a></div>
1238 <div class='signature'>
1239 <code class='name'>put-stream</code>
1240 <span class='args'>
1241 <var>file</var> <var>bucket</var> <var>key</var>
1242 <code class='llkw'>&amp;key</code>
1243 <var>start</var> <var>end</var>
1244 <var>access-policy</var>
1245 <var>public</var> <var>metadata</var>
1246 <var>content-disposition</var> <var>content-encoding</var> <var>content-type</var>
1247 <var>expires</var>
1248 <var>credentials</var>
1249 </span>
1250 <span class='result'>=> |</span>
1251 </div>
1253 <blockquote class='description'>
1254 <p>put-stream is similar to
1255 to <a href='#put-object'><tt>PUT-OBJECT</tt></a>. It has the same
1256 effect as collecting octets from <var>stream</var> into a vector
1257 and using:
1259 <pre class='code'>
1260 (put-object vector bucket key ...)
1261 </pre>
1263 <p>If <var>start</var> is not NIL, <var>start</var> octets
1264 starting from the current position in the stream are skipped
1265 before collecting.
1267 <p>If <var>end</var> is NIL, octets are collected until the end of
1268 the stream is reached.
1270 <p>If <var>end</var> is not NIL, collecting octets stops just
1271 before reaching <var>end</var> in the stream. An error of type
1272 <tt>CL:END-OF-FILE</tt> is signaled if the stream ends
1273 prematurely.
1274 </blockquote>
1275 </div>
1278 <div class='item'>
1279 <div class='type'><a name='copy-object'>[Function]</a></div>
1280 <div class='signature'>
1281 <code class='name'>copy-object</code>
1282 <span class='args'>
1283 <code class='llkw'>&amp;key</code>
1284 <var>from-bucket</var>
1285 <var>from-key</var>
1286 <var>to-bucket</var>
1287 <var>to-key</var> <br>
1288 <var>access-policy</var>
1289 <var>public</var> <br>
1290 <var>when-etag-matches</var>
1291 <var>unless-etag-matches</var> <br>
1292 <var>when-modified-since</var>
1293 <var>unless-modified-since</var> <br>
1294 <var>metadata</var> <var>public</var> <var>precondition-errors</var>
1295 <var>credentials</var>
1296 </span>
1297 <span class='result'>=> |</span>
1298 </div>
1300 <blockquote class='description'>
1301 <p>Copies the object identified by <var>from-bucket</var>
1302 and <var>from-key</var> to a new location identified by
1303 <var>to-bucket</var> and <var>to-key</var>.
1305 If <var>to-bucket</var> is NIL, <var>from-bucket</var> is used as
1306 the target. If <var>to-key</var> is nil, <var>from-key</var> is
1307 used as the target. An error is signaled if both <var>to-bucket</var> and
1308 <var>to-key</var> are NIL.
1310 <p><var>access-policy</var> and <var>public</var> have the same
1311 effect on the target object as
1312 in <a href='#put-object'><tt>PUT-OBJECT</tt></a>.
1314 <p>The precondition arguments <var>when-etag-matches</var>, <var>unless-etag-matches</var>,
1315 <var>when-modified-since</var>, and <var>unless-modified-since</var> work the same way they
1316 do in <a href='#get-object'><tt>GET-OBJECT</tt></a>, but with one difference: if <var>precondition-errors</var> is
1317 <i>true</i>, an <code>PRECONDITION-FAILED</code> error is signaled
1318 when a precondition does not hold, instead of returning NIL.
1320 <p>If <var>metadata</var> is explicitly provided, it follows the
1321 same behavior as
1322 with <a href='#put-object'><tt>PUT-OBJECT</tt></a>. Passing NIL
1323 means that the new object has no metadata. Otherwise, the metadata
1324 is copied from the original object.
1325 </blockquote>
1326 </div>
1328 <div class='item'>
1329 <div class='type'><a name='delete-object'>[Function]</a></div>
1330 <div class='signature'>
1331 <code class='name'>delete-object</code>
1332 <span class='args'>
1333 <var>bucket</var>
1334 <var>key</var>
1335 <code class='llkw'>&amp;key</code>
1336 <var>credentials</var>
1337 </span>
1338 <span class='result'>=> |</span>
1339 </div>
1341 <blockquote class='description'>
1342 <p>Deletes the object identified by <var>bucket</var>
1343 and <var>key</var>.
1344 <p>If <var>bucket</var> is a valid bucket for
1345 which you have delete access granted, S3 will always return a success
1346 response, even if <var>key</var> does not reference an existing
1347 object.
1348 </blockquote>
1349 </div>
1351 <div class='item'>
1352 <div class='type'><a name='delete-objects'>[Function]</a></div>
1353 <div class='signature'>
1354 <code class='name'>delete-objects</code>
1355 <span class='args'>
1356 <var>bucket</var>
1357 <var>keys</var>
1358 <code class='llkw'>&amp;key</code>
1359 <var>credentials</var>
1360 </span>
1361 <span class='result'>=> |</span>
1362 </div>
1364 <blockquote class='description'>
1365 <p>Deletes <var>keys</var>, which should be a sequence of keys,
1366 from <var>bucket</var>.
1367 </blockquote>
1368 </div>
1370 <div class='item'>
1371 <div class='type'><a name='delete-all-objects'>[Function]</a></div>
1372 <div class='signature'>
1373 <code class='name'>delete-all-objects</code>
1374 <span class='args'>
1375 <var>bucket</var>
1376 <code class='llkw'>&amp;key</code>
1377 <var>credentials</var>
1378 </span>
1379 <span class='result'>=> <var>count</var></span>
1380 </div>
1382 <blockquote class='description'>
1383 <p>Deletes all objects in <var>bucket</var> and returns the count
1384 of objects deleted.
1385 </blockquote>
1386 </div>
1389 <div class='item'>
1390 <div class='type'><a name='object-metadata'>[Function]</a></div>
1391 <div class='signature'>
1392 <code class='name'>object-metadata</code>
1393 <span class='args'>
1394 <var>bucket</var>
1395 <var>key</var>
1396 <code class='llkw'>&amp;key</code>
1397 <var>credentials</var>
1398 </span>
1399 <span class='result'>=> <var>metadata-alist</var></span>
1400 </div>
1402 <blockquote class='description'>
1403 <p>Returns the metadata for the object identified by <var>bucket</var> and <var>key</var>, or
1404 NIL if there is no metadata. For example:
1406 <pre class='code'>
1407 * <b>(put-string "Hadjaha!" "zs3-demo" "hadjaha.txt" :metadata (parameters-alist :language "Swedish"))</b>
1408 => #&lt;RESPONSE 200 "OK" {1003BD2841}>
1410 * <b>(object-metadata "zs3-demo" "hadjaha.txt")</b>
1411 => ((:LANGUAGE . "Swedish"))
1412 </pre>
1414 </blockquote>
1415 </div>
1418 <a name='access-control'><h3>Access Control</h3></a>
1420 <p>Each S3 resource has an associated access control list that is
1421 created automatically when the resource is created. The access
1422 control list specifies the resource owner and a list of permission
1423 grants.
1425 <p>Grants consist of a permission and a grantee. The permission must
1426 be one of <code class='kw'>:READ</code>, <code class='kw'>:WRITE</code>,
1427 <code class='kw'>:READ-ACL</code>, <code class='kw'>:WRITE-ACL</code>,
1428 or <code class='kw'>:FULL-CONTROL</code>. The grantee should be a
1429 person object, an acl-group object, or an acl-email object.
1431 <p>ZS3 has several functions that assist in reading, modifying, and
1432 storing access control lists.
1435 <div class='item'>
1436 <div class='type'><a name='get-acl'>[Function]</a></div>
1437 <div class='signature'>
1438 <code class='name'>get-acl</code>
1439 <span class='args'>
1440 <code class='llkw'>&amp;key</code>
1441 <var>bucket</var>
1442 <var>key</var>
1443 <var>credentials</var>
1444 </span>
1445 <span class='result'>=> <var>owner</var>, <var>grants</var></span>
1446 </div>
1448 <blockquote class='description'>
1449 <p>Returns the owner and grant list for a resource as
1450 multiple values.
1451 </blockquote>
1452 </div>
1455 <div class='item'>
1456 <div class='type'><a name='put-acl'>[Function]</a></div>
1457 <div class='signature'>
1458 <code class='name'>put-acl</code>
1459 <span class='args'>
1460 <var>owner</var> <var>grants</var>
1461 <code class='llkw'>&amp;key</code>
1462 <var>bucket</var>
1463 <var>key</var>
1464 <var>credentials</var>
1465 </span>
1466 <span class='result'>=> |</span>
1467 </div>
1469 <blockquote class='description'>
1470 <p>Sets the owner and grant list of a resource.
1471 </blockquote>
1472 </div>
1475 <div class='item'>
1476 <div class='type'><a name='grant'>[Function]</a></div>
1477 <div class='signature'>
1478 <code class='name'>grant</code>
1479 <span class='args'>
1480 <var>permission</var>
1481 <code class='llkw'>&amp;key</code>
1482 <var>to</var>
1483 </span>
1484 <span class='result'>=> <var>grant</var></span>
1485 </div>
1487 <blockquote class='description'>
1488 <p>Returns a grant object that represents a permission (one of <code class='kw'>:READ</code>, <code class='kw'>:WRITE</code>,
1489 <code class='kw'>:READ-ACL</code>, <code class='kw'>:WRITE-ACL</code>,
1490 or <code class='kw'>:FULL-CONTROL</code>) for the
1491 grantee <var>to</var>. For example:
1493 <pre class='code'>
1494 * <b>(grant :full-control :to (<a href='#acl-email'>acl-email</a> "bob@example.com"))</b>
1495 => #&lt;GRANT :FULL-CONTROL to "bob@example.com">
1497 * <b>(grant :read :to <a href='#*all-users*'>*all-users*</a>)</b>
1498 => #&lt;GRANT :READ to "AllUsers">
1499 </pre>
1501 <p>It can be used to create or modify a grant list for use
1502 with <a href='#put-acl'><tt>PUT-ACL</tt></a>.
1503 </blockquote>
1504 </div>
1507 <div class='item'>
1508 <div class='type'><a name='acl-eqv'>[Function]</a></div>
1509 <div class='signature'>
1510 <code class='name'>acl-eqv</code>
1511 <span class='args'>
1512 <var>a</var> <var>b</var>
1513 </span>
1514 <span class='result'>=> <var>boolean</var></span>
1515 </div>
1517 <blockquote class='description'>
1518 <p>Returns <i>true</i> if <var>a</var> and <var>b</var> are equivalent
1519 ACL-related objects (person, group, email, or grant).
1520 </blockquote>
1521 </div>
1524 <div class='item'>
1525 <div class='type'><a name='*all-users*'>[Special variable]</a></div>
1526 <div class='signature'>
1527 <code class='name'>*all-users*</code>
1528 </div>
1530 <blockquote class='description'>
1531 <p>This acl-group includes all users, including unauthenticated
1532 clients.
1533 </blockquote>
1534 </div>
1537 <div class='item'>
1538 <div class='type'><a name='*aws-users*'>[Special variable]</a></div>
1539 <div class='signature'>
1540 <code class='name'>*aws-users*</code>
1541 </div>
1543 <blockquote class='description'>
1544 <p>This acl-group object includes only users that have an
1545 Amazon Web Services account.
1546 </blockquote>
1547 </div>
1550 <div class='item'>
1551 <div class='type'><a name='*log-delivery*'>[Special variable]</a></div>
1552 <div class='signature'>
1553 <code class='name'>*log-delivery*</code>
1554 </div>
1556 <blockquote class='description'>
1557 <p>This acl-group object includes the S3 system user that creates
1558 logfile objects. See
1559 also <a href='#enable-logging-to'><tt>ENABLE-LOGGING-TO</tt></a>.
1560 </blockquote>
1561 </div>
1564 <div class='item'>
1565 <div class='type'><a name='acl-email'>[Function]</a></div>
1566 <div class='signature'>
1567 <code class='name'>acl-email</code>
1568 <span class='args'>
1569 <var>email-address</var>
1570 </span>
1571 <span class='result'>=> <var>acl-email</var></span>
1572 </div>
1574 <blockquote class='description'>
1575 <p>Returns an acl-email object, which can be used as a grantee for
1576 <a href='#grant'><tt>GRANT</tt></a>.
1577 </blockquote>
1578 </div>
1581 <div class='item'>
1582 <div class='type'><a name='acl-person'>[Function]</a></div>
1583 <div class='signature'>
1584 <code class='name'>acl-person</code>
1585 <span class='args'>
1586 <var>id</var>
1587 <code class='llkw'>&amp;optional</code>
1588 <var>display-name</var>
1589 </span>
1590 <span class='result'>=> <var>acl-person</var></span>
1591 </div>
1593 <blockquote class='description'>
1594 <p>Returns an acl-person object for use as a resource owner (for
1595 <a href='#put-acl'><tt>PUT-ACL</tt></a>) or as a grantee
1596 (for <a href='#grant'><tt>GRANT</tt></a>). <var>id</var> must be
1597 a string representing the person's Amazon AWS canonical ID; for
1598 information about getting the canonical ID, see
1599 the <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/S3_ACLs.html">Access
1600 Control Lists</a> in the Amazon S3 developer
1601 documentation. If <var>display-name</var> is provided, it is
1602 used only for printing the object in Lisp; it is ignored when
1603 passed to S3.
1604 </blockquote>
1605 </div>
1608 <div class='item'>
1609 <div class='type'><a name='me'>[Function]</a></div>
1610 <div class='signature'>
1611 <code class='name'>me</code>
1612 <span class='args'>
1613 <code class='llkw'>&amp;key</code>
1614 <var>credentials</var>
1615 </span>
1616 <span class='result'>=> <var>acl-person</var></span>
1617 </div>
1619 <blockquote class='description'>
1620 <p>Returns the acl-person object associated with the current
1621 credentials.
1623 <p>This data requires a S3 request, but the result is always the
1624 same per credentials and is cached.
1625 </blockquote>
1626 </div>
1629 <div class='item'>
1630 <div class='type'><a name='make-public'>[Function]</a></div>
1631 <div class='signature'>
1632 <code class='name'>make-public</code>
1633 <span class='args'>
1634 <code class='llkw'>&amp;key</code>
1635 <var>bucket</var>
1636 <var>key</var>
1637 <var>credentials</var>
1638 </span>
1639 <span class='result'>=> |</span>
1640 </div>
1642 <blockquote class='description'>
1643 <p>Makes a resource publicly accessible, i.e. readable by
1644 the <a href='#*all-users*'><tt>*ALL-USERS*</tt></a> group.
1645 </blockquote>
1646 </div>
1649 <div class='item'>
1650 <div class='type'><a name='make-private'>[Function]</a></div>
1651 <div class='signature'>
1652 <code class='name'>make-private</code>
1653 <span class='args'>
1654 <code class='llkw'>&amp;key</code>
1655 <var>bucket</var>
1656 <var>key</var>
1657 <var>credentials</var>
1658 </span>
1659 <span class='result'>=> |</span>
1660 </div>
1662 <blockquote class='description'>
1663 <p>Removes public access to a resource, i.e. removes all
1664 access grants for
1665 the <a href='#*all-users*'><tt>*ALL-USERS*</tt></a> group.
1666 </blockquote>
1667 </div>
1671 <a name='access-logging'><h3>Access Logging</h3></a>
1673 <p>S3 offers support for logging information about client
1674 requests. Logfile objects are delivered by a system user in
1675 the <a href='#*log-delivery*'><tt>*LOG-DELIVERY*</tt></a> group to a
1676 bucket of your choosing. For more information about S3 access
1677 logging and the logfile format, see
1678 the <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/ServerLogs.html">Server
1679 Access Logging</a> in the Amazon S3
1680 developer documentation.
1682 <div class='item'>
1683 <div class='type'><a name='enable-logging-to'>[Function]</a></div>
1684 <div class='signature'>
1685 <code class='name'>enable-logging-to</code>
1686 <span class='args'>
1687 <var>bucket</var>
1688 <code class='llkw'>&amp;key</code>
1689 <var>credentials</var>
1690 </span>
1691 <span class='result'>=> |</span>
1692 </div>
1694 <blockquote class='description'>
1695 Adds the necessary permission grants to <var>bucket</var> to allow
1696 S3 to write logfile objects into it.
1697 </blockquote>
1698 </div>
1701 <div class='item'>
1702 <div class='type'><a name='disable-logging-to'>[Function]</a></div>
1703 <div class='signature'>
1704 <code class='name'>disable-logging-to</code>
1705 <span class='args'>
1706 <var>bucket</var>
1707 <code class='llkw'>&amp;key</code>
1708 <var>credentials</var>
1709 </span>
1710 <span class='result'>=> |</span>
1711 </div>
1713 <blockquote class='description'>
1714 <p>Changes the access control list of <var>bucket</var> to remove
1715 all grants for
1716 the <a href='#*log-delivery*'><tt>*LOG-DELIVERY*</tt></a> group.
1717 </blockquote>
1718 </div>
1721 <div class='item'>
1722 <div class='type'><a name='enable-logging'>[Function]</a></div>
1723 <div class='signature'>
1724 <code class='name'>enable-logging</code>
1725 <span class='args'>
1726 <var>bucket</var>
1727 <var>target-bucket</var>
1728 <var>target-prefix</var>
1729 <code class='llkw'>&amp;key</code>
1730 <var>target-grants</var>
1731 <var>credentials</var>
1732 </span>
1733 <span class='result'>=> |</span>
1734 </div>
1736 <blockquote class='description'>
1737 <p>Enables logging of all requests
1738 involving <var>bucket</var>. Logfile objects are created in
1739 <var>target-bucket</var> and each logfile's key starts with
1740 <var>target-prefix</var>.
1742 <p>When a new logfile is
1743 created, its list of access control grants is extended with
1744 <var>target-grants</var>, if any.
1746 <p>If <var>target-bucket</var> does not have the necessary grants
1747 to allow logging, the grants are implicitly added by
1748 calling <a href='#enable-logging-to'><tt>ENABLE-LOGGING-TO</tt></a>.
1749 </blockquote>
1750 </div>
1753 <div class='item'>
1754 <div class='type'><a name='disable-logging'>[Function]</a></div>
1755 <div class='signature'>
1756 <code class='name'>disable-logging</code>
1757 <span class='args'>
1758 <var>bucket</var> <code class='llkw'>&amp;key</code> <var>credentials</var>
1759 </span>
1760 <span class='result'>=> |</span>
1761 </div>
1763 <blockquote class='description'>
1764 Disables logging for <var>bucket</var>.
1765 </blockquote>
1766 </div>
1769 <div class='item'>
1770 <div class='type'><a name='logging-setup'>[Function]</a></div>
1771 <div class='signature'>
1772 <code class='name'>logging-setup</code>
1773 <span class='args'>
1774 <var>bucket</var>
1775 <code class='llkw'>&amp;key</code>
1776 <var>credentials</var>
1777 </span>
1778 <span class='result'>=> <var>target-bucket</var>,
1779 <var>target-prefix</var>,
1780 <var>target-grants</var></span>
1781 </div>
1783 <blockquote class='description'>
1784 <p>If logging is enabled for <var>bucket</var>, returns the target
1785 bucket, target prefix, and target grants as multiple values.
1786 </blockquote>
1787 </div>
1790 <a name='misc'><h3>Miscellaneous Operations</h3></a>
1794 <div class='item'>
1795 <div class='type'><a name='*use-ssl*'>[Special variable]</a></div>
1796 <div class='signature'>
1797 <code class='name'>*use-ssl*</code>
1798 </div>
1800 <blockquote class='description'>
1801 <p>When <i>true</i>, requests to S3 are sent via HTTPS. The
1802 default is NIL.
1803 </blockquote>
1804 </div>
1807 <div class='item'>
1808 <div class='type'><a name='make-post-policy'>[Function]</a></div>
1809 <div class='signature'>
1810 <code class='name'>make-post-policy</code>
1811 <span class='args'>
1812 <code class='llkw'>&amp;key</code>
1813 <var>expires</var>
1814 <var>conditions</var>
1815 <var>credentials</var>
1816 </span>
1817 <span class='result'>=> <var>policy</var>, <var>signature</var></span>
1818 </div>
1820 <blockquote class='description'>
1821 <p>Returns an encoded HTML POST form policy and its signature as
1822 multiple values. The policy can be used to conditionally allow any
1823 user to put objects into S3.
1825 <p><var>expires</var> must be a universal time after which
1826 the policy is no longer accepted.
1828 <p><var>conditions</var> must be a list of conditions that the
1829 posted form fields must satisfy. Each condition is a list of a
1830 condition keyword, a form field name, and the form field
1831 value. For example, the following are all valid conditions:
1834 <ul>
1835 <li> <code>(:starts-with "key" "uploads/")</code>
1836 <li> <code>(:eq "bucket" "user-uploads")</code>
1837 <li> <code>(:eq "acl" "public-read")</code>
1838 <li> <code>(:range "content-length-range" 1 10000)</code>
1839 </ul>
1841 <p>These conditions are converted into a post policy description,
1842 base64-encoded, and returned as <var>policy</var>. The signature
1843 is returned as <var>signature</var>. These values can then be
1844 embedded in an HTML form and used to allow direct browser uploads.
1846 <p>For example, if <var>policy</var> is
1847 "YSBwYXRlbnRseSBmYWtlIHBvbGljeQ==" and the policy signature is
1848 "ZmFrZSBzaWduYXR1cmU=", you could construct a form like this:
1850 <p class='html'>
1851 &lt;form action="http://user-uploads.s3.amazonaws.com/" method="post" enctype="multipart/form-data"><br>
1852 &lt;input type="input" name="key" value="uploads/fun.jpg"><br>
1853 &lt;input type=hidden name="acl" value="public-read"><br>
1854 &lt;input type=hidden name="AWSAccessKeyId" value="8675309JGT9876430310"><br>
1855 &lt;input type=hidden name="Policy" value="YSBwYXRlbnRseSBmYWtlIHBvbGljeQ=="><br>
1856 &lt;input type=hidden name='Signature' value="ZmFrZSBzaWduYXR1cmU="><br>
1857 &lt;input name='file' type='file'><br>
1858 &lt;input type=submit value='Submit'><br>
1859 &lt;/form><br>
1861 <p>For full, detailed documentation of browser-based POST uploads
1862 and policy documents,
1863 see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingHTTPPOST.html">Browser-Based
1864 Uploads Using POST</a> in the Amazon S3 developer documentation.
1865 </blockquote>
1866 </div>
1869 <div class='item'>
1870 <div class='type'><a name='head'>[Function]</a></div>
1871 <div class='signature'>
1872 <code class='name'>head</code>
1873 <span class='args'>
1874 <code class='llkw'>&amp;key</code>
1875 <var>bucket</var>
1876 <var>key</var>
1877 <var>parameters</var>
1878 <var>credentials</var>
1879 </span>
1880 <span class='result'>=> <var>headers-alist</var>,
1881 <var>status-code</var>,
1882 <var>phrase</var></span>
1883 </div>
1885 <blockquote class='description'>
1886 <p>Submits a HTTP HEAD request for the resource identified by
1887 <var>bucket</var> and optionally <var>key</var>. Returns the
1888 <a href='http://weitz.de/drakma/'>Drakma</a> headers, HTTP
1889 status code, and HTTP phrase as multiple values.
1891 <p>When <var>parameters</var> is supplied, it should be an alist
1892 of keys and values to pass as GET request parameters. For
1893 example:
1895 <pre class='code'>
1896 * <b>(head :bucket "zs3-demo" :parameters (<a href='http://cliki.net/parameters-alist?download'>parameters-alist</a> :max-keys 0))</b>
1897 => ((:X-AMZ-ID-2 . "...")
1898 (:X-AMZ-REQUEST-ID . "...")
1899 (:DATE . "Sat, 27 Sep 2008 19:00:35 GMT")
1900 (:CONTENT-TYPE . "application/xml")
1901 (:TRANSFER-ENCODING . "chunked")
1902 (:SERVER . "AmazonS3")
1903 (:CONNECTION . "close")),
1904 200,
1905 "OK"</pre>
1906 </blockquote>
1907 </div>
1910 <div class='item'>
1911 <div class='type'><a name='authorized-url'>[Function]</a></div>
1912 <div class='signature'>
1913 <code class='name'>authorized-url</code>
1914 <span class='args'>
1915 <code class='llkw'>&amp;key</code>
1916 <var>bucket</var>
1917 <var>key</var>
1918 <var>vhost</var>
1919 <var>expires</var>
1920 <var>ssl</var>
1921 <var>sub-resource</var>
1922 <var>credentials</var>
1923 </span>
1924 <span class='result'>=> <var>url</var></span>
1925 </div>
1927 <blockquote class='description'>
1928 <p>Creates an URL that allows temporary access to a resource regardless
1929 of its ACL.
1931 <p>If neither <var>bucket</var> nor <var>key</var> is specified, the top-level bucket listing
1932 is accessible. If <var>key</var> is not specified, listing the keys of <var>bucket</var> is
1933 accessible. If both <var>bucket</var> and key are <var>specified</var>, the object specified
1934 by <var>bucket</var> and <var>key</var> is accessible.
1936 <p><var>expires</var> is required, and should be the integer
1937 universal time after which the URL is no longer valid.
1939 <p><var>vhost</var> controls the construction of the
1940 url. If <var>vhost</var> is nil, the constructed URL refers to the
1941 bucket, if present, as part of the path. If <var>vhost</var>
1942 is <code class='kw'>:AMAZON</code>, the bucket name is used as a
1943 prefix to the Amazon hostname. If <var>vhost</var>
1944 is <code class='kw'>:FULL</code>, the bucket name becomes the full
1945 hostname of the url. For example:
1947 <pre class='code'>
1948 * <b>(authorized-url :bucket "foo" :key "bar" :vhost nil)</b>
1949 =&gt; "http://s3.amazonaws.com/foo/bar?..."
1951 * <b>(authorized-url :bucket "foo" :key "bar" :vhost :amazon)</b>
1952 =&gt; "http://foo.s3.amazonaws.com/bar?..."
1954 * <b>(authorized-url :bucket "foo.example.com" :key "bar" :vhost :full)</b>
1955 =&gt; "http://foo.example.com/bar?..."
1956 </pre>
1958 <p>If <i>ssl</i> is <i>true</i>, the URL has "https" as the scheme,
1959 otherwise it has "http".
1961 <p>If <i>sub-resource</i> is specified, it is used as part of the
1962 query string to access a specific sub-resource. Example Amazon
1963 sub-resources include "acl" for access to the ACL, "location" for
1964 location information, and "logging" for logging information. For
1965 more information about the various sub-resources, see the Amazon
1966 S3 developer documentation.
1967 </blockquote>
1968 </div>
1971 <div class='item'>
1972 <div class='type'><a name='resource-url'>[Function]</a></div>
1973 <div class='signature'>
1974 <code class='name'>resource-url</code>
1975 <span class='args'>
1976 <code class='llkw'>&amp;key</code>
1977 <var>bucket</var>
1978 <var>key</var>
1979 <var>vhost</var>
1980 <var>ssl</var>
1981 <var>sub-resource</var>
1982 </span>
1983 <span class='result'>=> <var>url</var></span>
1984 </div>
1986 <blockquote class='description'>
1987 <p>Returns an URL that can be used to reference a resource. See
1988 <a href='#authorized-url'><tt>AUTHORIZED-URL</tt></a> for more
1989 info.
1990 </blockquote>
1991 </div>
1994 <a name='utility'><h3>Utility Functions</h3></a>
1998 <div class='item'>
1999 <div class='type'><a name='octet-vector'>[Function]</a></div>
2000 <div class='signature'>
2001 <code class='name'>octet-vector</code>
2002 <span class='args'>
2003 <code class='llkw'>&amp;rest</code>
2004 <var>octets</var>
2005 </span>
2006 <span class='result'>=> <var>octet-vector</var></span>
2007 </div>
2009 <blockquote class='description'>
2010 <p>Returns a vector of type
2011 <code>(simple-array&nbsp;(unsigned-byte&nbsp;8)&nbsp;(*))</code> initialized with <var>octets</var>.
2012 </blockquote>
2013 </div>
2016 <div class='item'>
2017 <div class='type'><a name='now+'>[Function]</a></div>
2018 <div class='signature'>
2019 <code class='name'>now+</code>
2020 <span class='args'>
2021 <var>delta</var>
2022 </span>
2023 <span class='result'>=> <var>universal-time</var></span>
2024 </div>
2026 <blockquote class='description'>
2027 <p>Returns a universal time that represents the current time
2028 incremented by <var>delta</var> seconds. It's useful for passing
2029 as the <code class='kw'>:EXPIRES</code> parameter to functions
2030 like <a href='#put-object'><tt>PUT-OBJECT</tt></a>
2031 and <a href='#authorized-url'><tt>AUTHORIZED-URL</tt></a>.
2032 </blockquote>
2033 </div>
2036 <div class='item'>
2037 <div class='type'><a name='now-'>[Function]</a></div>
2038 <div class='signature'>
2039 <code class='name'>now-</code>
2040 <span class='args'>
2041 <var>delta</var>
2042 </span>
2043 <span class='result'>=> <var>universal-time</var></span>
2044 </div>
2046 <blockquote class='description'>
2047 <p>Like <a href='#now+'><tt>NOW+</tt></a>, but decrements the
2048 current time instead of incrementing it.
2049 </blockquote>
2050 </div>
2053 <div class='item'>
2054 <div class='type'><a name='file-etag'>[Function]</a></div>
2055 <div class='signature'>
2056 <code class='name'>file-etag</code>
2057 <span class='args'>
2058 <var>pathname</var>
2059 </span>
2060 <span class='result'>=> <var>etag</var></span>
2061 </div>
2063 <blockquote class='description'>
2064 <p>Returns the etag of <var>pathname</var>. This can be useful for the
2065 conditional arguments
2066 <code class='kw'>:WHEN-ETAG-MATCHES</code> and
2067 <code class='kw'>:UNLESS-ETAG-MATCHES</code>
2068 in <a href='#get-object'><tt>GET-OBJECT</tt></a>
2069 and <a href='#copy-object'><tt>COPY-OBJECT</tt></a>.
2070 </blockquote>
2071 </div>
2074 <div class='item'>
2075 <div class='type'><a name='parameters-alist'>[Function]</a></div>
2076 <div class='signature'>
2077 <code class='name'>parameters-alist</code>
2078 <span class='args'>
2079 <code class='llkw'>&amp;rest</code>
2080 <var>parameters</var>
2081 <code class='llkw'>&amp;key</code>
2082 <code class='llkw'>&amp;allow-other-keys</code>
2083 </span>
2084 <span class='result'>=> <var>alist</var></span>
2085 </div>
2087 <blockquote class='description'>
2088 <p>Returns an alist based on all keyword arguments passed to the
2089 function. Keywords are converted to their lowercase symbol name and
2090 values are converted to strings. For example:
2092 <pre class='code'>
2093 * <b>(parameters-alist :name "Bob" :age 21)</b>
2094 => (("name" . "Bob") ("age" . "21"))
2095 </pre>
2097 <p>This can be used to construct Amazon metadata alists
2098 for <a href='#put-object'><tt>PUT-OBJECT</tt></a>
2099 and <a href='#copy-object'><tt>COPY-OBJECT</tt></a>, or request
2100 parameters in <a href='#head'><tt>HEAD</tt></a>.
2102 </blockquote>
2103 </div>
2107 <div class='item'>
2108 <div class='type'><a name='clear-redirects'>[Function]</a></div>
2109 <div class='signature'>
2110 <code class='name'>clear-redirects</code>
2111 <span class='args'>
2112 </span>
2113 <span class='result'>=> |</span>
2114 </div>
2116 <blockquote class='description'>
2117 <p>Clear ZS3's internal cache of redirections.
2119 <p>Most ZS3 requests are submitted against the Amazon S3 endpoint
2120 "s3.amazonaws.com". Some requests, however, are permanently
2121 redirected by S3 to new endpoints. ZS3 maintains an internal cache
2122 of permanent redirects, but it's possible for that cache to get
2123 out of sync if external processes alter the bucket structure
2125 <p>For example, if the bucket "eu.zs3" is created with a EU
2126 location constraint, S3 will respond to requests to that bucket
2127 with a permanent redirect to "eu.zs3.s3.amazonaws.com", and ZS3
2128 will cache that redirect information. But if the bucket is
2129 deleted and recreated by a third party, the redirect might no
2130 longer be necessary.
2131 </blockquote>
2132 </div>
2135 <a name='cloudfront'><h2>CloudFront</h2>
2137 <p>CloudFront functions allow the creation and manipulation of
2138 distributions. In ZS3, distributions are represented by objects that
2139 reflect the state of a distributon at some point in time. It's
2140 possible for the distribution to change behind the scenes without
2141 notice, e.g. when a distribution's <a href='#status'>status</a> is
2142 updated from "InProgress" to "Deployed".
2144 <p>The
2145 functions <a href='#enable'><tt>ENABLE</tt></a>, <a href='#disable'><tt>DISABLE</tt></a>, <a href='#ensure-cname'><tt>ENSURE-CNAME</tt></a>,
2146 <a href='#remove-cname'><tt>REMOVE-CNAME</tt></a>,
2147 and <a href='#set-comment'><tt>SET-COMMENT</tt></a> are designed so
2148 that regardless of the state of the distribution provided, after the
2149 function completes, the new state of the distribution will reflect
2150 the desired update. The
2151 functions <a href='#status'><tt>STATUS</tt></a>, <a href='#cnames'><tt>CNAMES</tt></a>,
2153 <a href='#enabledp'><tt>ENABLEDP</tt></a> do not automatically
2154 refresh the object and therefore might reflect outdated
2155 information. To ensure the object has the most recent information,
2156 use <a href='#refresh'><tt>REFRESH</tt></a>. For example, to fetch
2157 the current, live status, use <tt>(status (refresh
2158 distribution))</tt>.
2162 <div class='item'>
2163 <div class='type'><a name='all-distributions'>[Function]</a></div>
2164 <div class='signature'>
2165 <code class='name'>all-distributions</code>
2166 <span class='args'>
2167 </span>
2168 <span class='result'>=> |</span>
2169 </div>
2171 <blockquote class='description'>
2172 <p>Returns a list of all distributions.
2173 </blockquote>
2174 </div>
2176 <div class='item'>
2177 <div class='type'><a name='create-distribution'>[Function]</a></div>
2178 <div class='signature'>
2179 <code class='name'>create-distribution</code>
2180 <span class='args'>
2181 <var>bucket-name</var>
2182 <code class='llkw'>&amp;key</code>
2183 <var>cnames</var>
2184 <var>enabled</var>
2185 <var>comment</var>
2186 </span>
2187 <span class='result'>=> <var>distribution</var></span>
2188 </div>
2190 <blockquote class='description'>
2191 Creates and returns a new distribution object that will cache
2192 objects from the bucket named
2193 by <var>bucket-name</var>.
2195 <p>If <var>cnames</var> is provided, it is taken as a designator
2196 for a list of additional domain names that can be used to access
2197 the distribution.
2199 <p>If <var>enabled</var> is NIL, the distribution is initially
2200 created in a disabled state. The default value is is T.
2202 <p>If <var>comment</var> is provided, it becomes part of the newly
2203 created distribution.
2204 </blockquote>
2205 </div>
2207 <div class='item'>
2208 <div class='type'><a name='delete-distribution'>[Function]</a></div>
2209 <div class='signature'>
2210 <code class='name'>delete-distribution</code>
2211 <span class='args'>
2212 <var>distribution</var>
2213 </span>
2214 <span class='result'>=> |</span>
2215 </div>
2217 <blockquote class='description'>
2218 <p>Deletes <var>distribution</var>. Distributions must be disabled
2219 before deletion; see <a href='#disable'><tt>DISABLE</tt></a>.
2220 </blockquote>
2221 </div>
2224 <div class='item'>
2225 <div class='type'><a name='refresh'>[Function]</a></div>
2226 <div class='signature'>
2227 <code class='name'>refresh</code>
2228 <span class='args'>
2229 <var>distribution</var>
2230 </span>
2231 <span class='result'>=> <var>distribution</var></span>
2232 </div>
2234 <blockquote class='description'>
2235 <p>Queries Amazon for the latest information
2236 regarding <var>distribution</var> and destructively modifies the
2237 instance with the new information. Returns its argument.
2238 </blockquote>
2239 </div>
2242 <div class='item'>
2243 <div class='type'><a name='enable'>[Function]</a></div>
2244 <div class='signature'>
2245 <code class='name'>enable</code>
2246 <span class='args'>
2247 <var>distribution</var>
2248 </span>
2249 <span class='result'>=> |</span>
2250 </div>
2252 <blockquote class='description'>
2253 <p>Enables <var>distribution</var>.
2254 </blockquote>
2255 </div>
2258 <div class='item'>
2259 <div class='type'><a name='disable'>[Function]</a></div>
2260 <div class='signature'>
2261 <code class='name'>disable</code>
2262 <span class='args'>
2263 <var>distribution</var>
2264 </span>
2265 <span class='result'>=> |</span>
2266 </div>
2268 <blockquote class='description'>
2269 <p>Disables <var>distribution</var>.
2270 </blockquote>
2271 </div>
2274 <div class='item'>
2275 <div class='type'><a name='ensure-cname'>[Function]</a></div>
2276 <div class='signature'>
2277 <code class='name'>ensure-cname</code>
2278 <span class='args'>
2279 <var>distribution</var>
2280 <var>cname</var>
2281 </span>
2282 <span class='result'>=> |</span>
2283 </div>
2285 <blockquote class='description'>
2286 <p>Adds <var>cname</var> to the CNAMEs of <var>distribution</var>,
2287 if necessary.
2288 </blockquote>
2289 </div>
2291 <div class='item'>
2292 <div class='type'><a name='remove-cname'>[Function]</a></div>
2293 <div class='signature'>
2294 <code class='name'>remove-cname</code>
2295 <span class='args'>
2296 <var>distribution</var>
2297 <var>cname</var>
2298 </span>
2299 <span class='result'>=> |</span>
2300 </div>
2302 <blockquote class='description'>
2303 <p>Removes <var>cname</var> from the CNAMEs of <var>distribution</var>.
2304 </blockquote>
2305 </div>
2308 <div class='item'>
2309 <div class='type'><a name='set-comment'>[Function]</a></div>
2310 <div class='signature'>
2311 <code class='name'>set-comment</code>
2312 <span class='args'>
2313 <var>distribution</var>
2314 <var>comment</var>
2315 </span>
2316 <span class='result'>=> |</span>
2317 </div>
2319 <blockquote class='description'>
2320 <p>Sets the comment of <var>distribution</var> to <var>comment</var>.
2321 </blockquote>
2322 </div>
2325 <div class='item'>
2326 <div class='type'><a name='distributions-for-bucket'>[Function]</a></div>
2327 <div class='signature'>
2328 <code class='name'>distributions-for-bucket</code>
2329 <span class='args'>
2330 <var>bucket-name</var>
2331 </span>
2332 <span class='result'>=> |</span>
2333 </div>
2335 <blockquote class='description'>
2336 <p>Returns a list of distributions that
2337 have <var>bucket-name</var> as the origin bucket.
2338 </blockquote>
2339 </div>
2342 <div class='item'>
2343 <div class='type'><a name='distribution-error'>[Condition]</a></div>
2344 <div class='signature'>
2345 <code class='name'>distribution-error</code>
2346 </div>
2348 <blockquote class='description'>
2349 <p>All errors signaled as a result of a CloudFront request error
2350 are subtypes of <tt>distribution-error</tt>.
2351 </blockquote>
2352 </div>
2355 <div class='item'>
2356 <div class='type'><a name='distribution-not-disabled'>[Condition]</a></div>
2357 <div class='signature'>
2358 <code class='name'>distribution-not-disabled</code>
2359 </div>
2361 <blockquote class='description'>
2362 <p>Distributions must be fully disabled before they are
2363 deleted. If they have not been disabled, or the status of the
2364 distribution is still
2365 "InProgress", <tt>distribution-not-disabled</tt> is signaled.
2366 </blockquote>
2367 </div>
2370 <div class='item'>
2371 <div class='type'><a name='cname-already-exists'>[Condition]</a></div>
2372 <div class='signature'>
2373 <code class='name'>cname-already-exists</code>
2374 </div>
2376 <blockquote class='description'>
2377 <p>A CNAME may only appear on one distribution. If you attempt to
2378 add a CNAME to a distribution that is already present on some
2379 other distribution, <tt>cname-already-exists</tt> is signaled.
2380 </blockquote>
2381 </div>
2384 <div class='item'>
2385 <div class='type'><a name='too-many-distributions'>[Condition]</a></div>
2386 <div class='signature'>
2387 <code class='name'>too-many-distributions</code>
2388 </div>
2390 <blockquote class='description'>
2391 <p>If creating a new distribution
2392 via <a href='#create-distribution'><tt>CREATE-DISTRIBUTION</tt></a>
2393 would exceed the account limit of total distributions,
2394 <tt>too-many-distributions</tt> is signaled.
2395 </blockquote>
2396 </div>
2399 <div class='item'>
2400 <div class='type'><a name='status'>[Function]</a></div>
2401 <div class='signature'>
2402 <code class='name'>status</code>
2403 <span class='args'>
2404 <var>distribution</var>
2405 </span>
2406 <span class='result'>=> <var>status</var></span>
2407 </div>
2409 <blockquote class='description'>
2410 <p>Returns a string describing the status
2411 of <var>distribution</var>. The status is either "InProgress",
2412 meaning that the distribution's configuration has not fully
2413 propagated through the CloudFront system, or "Deployed".
2414 </blockquote>
2415 </div>
2418 <div class='item'>
2419 <div class='type'><a name='origin-bucket'>[Function]</a></div>
2420 <div class='signature'>
2421 <code class='name'>origin-bucket</code>
2422 <span class='args'>
2423 <var>distribution</var>
2424 </span>
2425 <span class='result'>=> <var>origin-bucket</var></span>
2426 </div>
2428 <blockquote class='description'>
2429 <p>Returns the origin bucket for <var>distribution</var>. It is
2430 different from a normal ZS3 bucket name, because it has
2431 ".s3.amazonaws.com" as a suffix.
2432 </blockquote>
2433 </div>
2436 <div class='item'>
2437 <div class='type'><a name='domain-name'>[Function]</a></div>
2438 <div class='signature'>
2439 <code class='name'>domain-name</code>
2440 <span class='args'>
2441 <var>distribution</var>
2442 </span>
2443 <span class='result'>=> <var>domain-name</var></span>
2444 </div>
2446 <blockquote class='description'>
2447 <p>Returns the domain name through which CloudFront-enabled access
2448 to a resource may be made.
2449 </blockquote>
2450 </div>
2453 <div class='item'>
2454 <div class='type'><a name='cnames'>[Function]</a></div>
2455 <div class='signature'>
2456 <code class='name'>cnames</code>
2457 <span class='args'>
2458 <var>distribution</var>
2459 </span>
2460 <span class='result'>=> <var>cnames</var></span>
2461 </div>
2463 <blockquote class='description'>
2464 Returns a list of CNAMEs associated with <var>distribution</var>.
2465 </blockquote>
2466 </div>
2469 <div class='item'>
2470 <div class='type'><a name='enabledp'>[Function]</a></div>
2471 <div class='signature'>
2472 <code class='name'>enabledp</code>
2473 <span class='args'>
2474 <var>distribution</var>
2475 </span>
2476 <span class='result'>=> <var>boolean</var></span>
2477 </div>
2479 <blockquote class='description'>
2480 <p>Returns <i>true</i> if <var>distribution</var> is enabled, NIL
2481 otherwise.
2482 </blockquote>
2483 </div>
2486 <div class='item'>
2487 <div class='type'><a name='invalidate-paths'>[Function]</a></div>
2488 <div class='signature'>
2489 <code class='name'>invalidate-paths</code>
2490 <span class='args'>
2491 <var>distribution</var>
2492 <var>paths</var>
2493 </span>
2494 <span class='result'>=> <var>invalidation</var></span>
2495 </div>
2497 <blockquote class='description'>
2498 <p>Initiates the invalidation of resources identified
2499 by <var>paths</var> in <var>distribution</var>. <var>paths</var>
2500 should consist of key names that correspond to objects in the
2501 distribution's S3 bucket.
2503 <p>The <var>invalidation</var> object reports on the status of the
2504 invalidation request. It can be queried
2505 with <a href='#status'><tt>STATUS</tt></a> and refreshed
2506 with <a href='#refresh'><tt>REFRESH</tt></a>.
2508 <pre class='code'>
2509 * <b>(invalidate-paths distribution '("/css/site.css" "/js/site.js"))</b>
2510 #&lt;INVALIDATION "I1HJC711OFAVKO" [InProgress]>
2511 * <b>(progn (sleep 300) (refresh *))</b>
2512 #&lt;INVALIDATION "I1HJC711OFAVKO" [Completed]>
2513 </pre>
2514 </blockquote>
2515 </div>
2520 <a name='references'><h2>References</h2></a>
2522 <ul>
2523 <li> Amazon, <a href="http://developer.amazonwebservices.com/connect/entry.jspa?externalID=123&categoryID=48">Amazon
2524 S3 Technical Documentation</a>
2525 <li> Amazon, <a href="http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1876&categoryID=213">Amazon CloudFront Technical Documentation</a>
2526 </ul>
2531 <a name='acknowledgements'><h2>Acknowledgements</h2>
2533 <p>Several people on <a href='http://freenode.net/'>freenode</a>
2534 #lisp pointed out typos and glitches in this
2535 documentation. Special thanks to Bart "_3b" Botta for providing a
2536 detailed documentation review that pointed out glitches,
2537 omissions, and overly confusing passages.
2539 <p>James Wright corrected a problem with computing the string to
2540 sign and URL encoding.
2542 <a name='feedback'><h2>Feedback</h2></a>
2544 <p>If you have any questions or comments about ZS3, please email
2545 me, <a href='mailto:xach@xach.com'>Zach Beane</a>
2547 <p>For ZS3 announcements and development discussion, please see the
2548 <a href="http://groups.google.com/group/zs3-devel">zs3-devel</a>
2549 mailing list.
2551 <p><i>2010-09-03</i>
2553 <p class='copyright'>Copyright &copy; 2008-2010 Zachary Beane, All Rights Reserved
2556 </div>
2557 </body>
2558 </html>