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>
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
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. Development of ZS3
18 is hosted
<a href=
"https://github.com/xach/zs3/">on GitHub
</a>.
20 The latest version is
1.3.3, released on September
29th,
2019.
22 <p>Download shortcut:
<a href='http://www.xach.com/lisp/zs3.tgz'
>http://www.xach.com/lisp/zs3.tgz
</a>
27 <li> <a href='#installation'
>Installation
</a>
28 <li> <a href='#overview'
>Overview
</a>
29 <li> <a href='#example'
>Example Use
</a>
30 <li> <a href='#limitations'
>Limitations
</a>
31 <li> <a href='#dictionary'
>The ZS3 Dictionary
</a>
33 <li> <a href='#credentials'
>Credentials
</a>
34 <li> <a href='#responses'
>Responses
</a>
35 <li> <a href='#bucket-ops'
>Operations on Buckets
</a>
36 <li> <a href='#querying-buckets'
>Querying Buckets
</a>
37 <li> <a href='#object-ops'
>Operations on Objects
</a>
38 <li> <a href='#access-control'
>Access Control
</a>
39 <li> <a href='#access-logging'
>Access Logging
</a>
40 <li> <a href='#misc'
>Miscellaneous Operations
</a>
41 <li> <a href='#utility'
>Utility Functions
</a>
42 <li> <a href='#cloudfront'
>CloudFront
</a>
44 <li> <a href='#references'
>References
</a>
45 <li> <a href='#acknowledgements'
>Acknowledgements
</a>
46 <li> <a href='#feedback'
>Feedback
</a>
49 <a name='installation'
><h2>Installation
</h2></a>
51 <p>ZS3 depends on the following libraries:
54 <li> <a href=
"http://common-lisp.net/project/cxml/">Closure XML
</a>
55 <li> <a href=
"http://weitz.de/drakma/">Drakma
</a> <b>1.0.0 or newer
</b>
56 <li> <a href=
"http://method-combination.net/lisp/ironclad/">Ironclad
</a>
57 <li> <a href=
"http://files.b9.com/cl-base64/">cl-base64
</a>
58 <li> <a href=
"http://puri.b9.com/">Puri
</a>
61 <p>The easiest way to install ZS3 and all its required libraries is
62 with
<A href=
"http://www.quicklisp.org/">Quicklisp
</a>. After
63 Quicklisp is installed, the following will fetch and load ZS3:
69 <p>For more information about incorporating ASDF-using libraries like
70 ZS3 into your own projects,
71 see
<a href=
"http://xach.livejournal.com/278047.html">this short
75 <a name='overview'
><h2>Overview
</h2></a>
77 <p>ZS3 provides an interface to two separate, but related, Amazon
78 services:
<a href=
"http://aws.amazon.com/s3/">S3
</a>
79 and
<a href=
"http://aws.amazon.com/cloudfront/">CloudFront
</a>
81 <p>Using Amazon S3 involves working with two kinds of resources:
84 <p>Buckets are containers, and are used to organize and manage
85 objects. Buckets are identified by their name, which must be unique
86 across all of S3. A user may have up to
100 buckets in S3.
88 <p>Objects are stored within buckets. Objects consist of arbitrary
89 binary data, from
1 byte to
5 gigabytes. They are identified by a
90 key, which must be unique within a bucket. Objects can also have
91 associated S3-specific metadata and HTTP metadata.
93 <p>For full documentation of the Amazon S3 system, see
94 the
<a href=
"http://aws.amazon.com/documentation/s3/">Amazon
95 S3 Documentation
</a>. ZS3 uses the REST
96 interface for all its operations.
98 <p>Using Amazon CloudFront involves working with
99 distributions. Distributions are objects that associate an S3
100 bucket with primary cloudfront.net hostname and zero or more
101 arbitrary CNAMEs. S3 objects requested through a CloudFront
102 distribution are distributed to and cached in multiple locations
103 throughout the world, reducing latency and improving throughput,
104 compared to direct S3 requests.
106 <p>For full documentation of the Amazon CloudFront system, see the
107 <a href=
"http://aws.amazon.com/documentation/cloudfront/">Amazon
108 CloudFront Documentation
</a>.
110 <p>For help with using ZS3, please see
111 the
<a href=
"http://groups.google.com/group/zs3-devel">zs3-devel
</a>
114 <a name='example'
><h2>Example Use
</h2></a>
118 *
<b>(asdf:oos 'asdf:load-op '#:zs3)
</b>
119 =
> <i>lots of stuff
</i>
121 *
<b>(defpackage #:demo (:use #:cl #:zs3))
</b>
122 =
> #
<PACKAGE
"DEMO">
124 *
<b>(in-package #:demo)
</b>
125 =
> #
<PACKAGE
"DEMO">
127 *
<b>(setf
<a href='#*credentials*'
>*credentials*
</a> (
<a href='#file-credentials'
>file-credentials
</a> "~/.aws"))
</b>
128 =
> #
<FILE-CREDENTIALS {
100482AF91}
>
130 *
<b>(
<a href='#bucket-exists-p'
>bucket-exists-p
</a> "zs3-demo")
</b>
133 *
<b>(
<a href='#create-bucket'
>create-bucket
</a> "zs3-demo")
</b>
134 =
> #
<RESPONSE
200 "OK" {
10040D3281}
>
136 *
<b>(
<a href='#http-code''
>http-code
</a> *)
</b>
139 *
<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>
140 =
> #
<RESPONSE
200 "OK" {
10033EC2E1}
>
142 *
<b>(create-bucket
"zs3 demo")
</b>
144 InvalidBucketName: The specified bucket is not valid.
145 For more information, see:
146 <a href=
"http://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html">http://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html
</a>
147 [Condition of type INVALID-BUCKET-NAME]
149 *
<b>(
<a href='#copy-object'
>copy-object
</a> :from-bucket
"zs3-demo" :from-key
"jenny" :to-key
"j2")
</b>
150 =
> #
<RESPONSE
200 "OK" {
10040E3EA1}
>
152 *
<b>(
<a href='#get-vector'
>get-vector
</a> "zs3-demo" "j2")
</b>
154 ((:X-AMZ-ID-
2 .
"Huwo...")
155 (:X-AMZ-REQUEST-ID .
"304...")
156 (:DATE .
"Sat, 27 Sep 2008 15:01:03 GMT")
157 (:LAST-MODIFIED .
"Sat, 27 Sep 2008 14:57:31 GMT")
158 (:ETAG .
"\"f9e71fe2c41a10c0a78218e98a025520\
"")
159 (:CONTENT-TYPE .
"binary/octet-stream")
160 (:CONTENT-LENGTH .
"7")
161 (:CONNECTION .
"close")
162 (:SERVER .
"AmazonS3"))
164 *
<b>(
<a href='#put-string'
>put-string
</a> "Nämen" "zs3-demo" "bork")
</b>
165 =
> #
<RESPONSE
200 "OK" {
10047A3791}
>
167 *
<b>(values (get-vector
"zs3-demo" "bork"))
</b>
168 =
> #(
78 195 164 109 101 110)
170 *
<b>(values (
<a href='#get-file'
>get-file
</a> "zs3-demo" "bork" "bork.txt"))
</b>
173 *
<b>(setf *distribution* (
<a href='#create-distribution'
>create-distribution
</a> "zs3-demo" :cnames
"cdn.wigflip.com")
</b>
174 =
> #
<DISTRIBUTION X2S94L4KLZK5G0 for
"zs3-demo.s3.amazonaws.com" [InProgress]
>
176 *
<b>(progn (sleep
180) (
<a href='#refresh'
>refresh
</a> *distribution*))
</b>
177 =
> #
<DISTRIBUTION X2S94L4KLZK5G0 for
"zs3-demo.s3.amazonaws.com" [Deployed]
>
179 *
<b>(
<a href='#domain-name'
>domain-name
</a> *distribution*)
</b>
180 =
> "x214g1hzpjm1zp.cloudfront.net"
182 *
<b>(
<a href='#cnames'
>cnames
</a> *distribution*)
</b>
183 =
> (
"cdn.wigflip.com")
185 *
<b>(put-string
"Hello, world" "zs3-demo" "cloudfront" :public t)
</b>
186 #
<RESPONSE
200 "OK" {
10042689F1}
>
188 *
<b>(drakma:http-request
"http://x214g1hzpjm1zp.cloudfront.net/cloudfront")
</b>
191 ((:X-AMZ-ID-
2 .
"NMc3IY3NzHGGEvV/KlzPgZMyDfPVT+ITtHo47Alqg00MboTxSX2f5XJzVTErfuHr")
192 (:X-AMZ-REQUEST-ID .
"52B050DC18638A00")
193 (:DATE .
"Thu, 05 Mar 2009 16:24:25 GMT")
194 (:LAST-MODIFIED .
"Thu, 05 Mar 2009 16:24:10 GMT")
195 (:ETAG .
"\"bc6e6f16b8a077ef5fbc8d59d0b931b9\
"")
196 (:CONTENT-TYPE .
"text/plain")
197 (:CONTENT-LENGTH .
"12")
198 (:SERVER .
"AmazonS3")
199 (:X-CACHE .
"Miss from cloudfront")
200 (:VIA .
"1.0 ad78cb56da368c171e069e4444b2cbf6.cloudfront.net:11180")
201 (:CONNECTION .
"close"))
202 #
<PURI:URI http://x214g1hzpjm1zp.cloudfront.net/cloudfront
>
203 #
<FLEXI-STREAMS:FLEXI-IO-STREAM {
1002CE0781}
>
207 *
<b>(drakma:http-request
"http://x214g1hzpjm1zp.cloudfront.net/cloudfront")
</b>
210 ((:X-AMZ-ID-
2 .
"NMc3IY3NzHGGEvV/KlzPgZMyDfPVT+ITtHo47Alqg00MboTxSX2f5XJzVTErfuHr")
211 (:X-AMZ-REQUEST-ID .
"52B050DC18638A00")
212 (:DATE .
"Thu, 05 Mar 2009 16:24:25 GMT")
213 (:LAST-MODIFIED .
"Thu, 05 Mar 2009 16:24:10 GMT")
214 (:ETAG .
"\"bc6e6f16b8a077ef5fbc8d59d0b931b9\
"")
215 (:CONTENT-TYPE .
"text/plain")
216 (:CONTENT-LENGTH .
"12")
217 (:SERVER .
"AmazonS3")
219 (:X-CACHE .
"Hit from cloudfront")
220 (:VIA .
"1.0 0d78cb56da368c171e069e4444b2cbf6.cloudfront.net:11180")
221 (:CONNECTION .
"close"))
222 #
<PURI:URI http://x214g1hzpjm1zp.cloudfront.net/cloudfront
>
223 #
<FLEXI-STREAMS:FLEXI-IO-STREAM {
100360A781}
>
230 <a name='limitations'
><h2>Limitations
</h2></a>
232 <p>ZS3 supports many of the features of Amazon's S3 REST
233 interface. Some features are unsupported or incompletely supported:
236 <li> No direct support
237 for
<a href=
"http://docs.aws.amazon.com/AmazonDevPay/latest/DevPayDeveloperGuide/Welcome.html">Amazon
240 <li> No support for checking the
100-Continue response to avoid
241 unnecessary large requests; this will hopefully be fixed with a
242 future
<a href='http://weitz.de/drakma/'
>Drakma
</a> release
244 <li> If a character in a key is encoded with multiple bytes in
245 UTF-
8, a bad interaction
246 between
<a href=
"http://puri.b9.com/">PURI
</a> and Amazon's web
247 servers will trigger a validation error.
251 <a name='dictionary'
><h2>The ZS3 Dictionary
</h2></a>
253 <p>The following sections document the symbols that are exported from
257 <a name='credentials'
><h3>Credentials
</h3></a>
262 <div class='type'
><a name='*credentials*'
>[Special variable]
</a></div>
263 <div class='signature'
>
264 <code class='name'
>*credentials*
</code>
267 <blockquote class='description'
>
268 <p><code>*CREDENTIALS*
</code> is the source of the Amazon Access
269 Key and Secret Key for authenticated requests. Any object that has
270 methods for the
<a href='#access-key'
><tt>ACCESS-KEY
</tt></a>
271 and
<a href='#secret-key'
><tt>SECRET-KEY
</tt></a> generic
272 functions may be used.
274 <p>If
<code>*CREDENTIALS*
</code> is a cons, it is treated as a
275 list, and the first element of the list is taken as the access
276 key and the second element of the list is taken as the secret
279 <p>The default value of
<code>*CREDENTIALS*
</code> is NIL, which
280 will signal an error. You must set
<code>*CREDENTIALS*
</code> to
281 something that follows the credentials generic function protocol
284 <p>All ZS3 functions that involve authenticated requests take an
285 optional
<code class='kw'
>:CREDENTIALS
</code> keyword
286 parameter. This parameter is bound to
<code>*CREDENTIALS*
</code>
287 for the duration of the function call.
289 <p>The following illustrates how to implement a credentials object
290 that gets the access and secret key from external environment
294 (defclass environment-credentials () ())
296 (defmethod access-key ((credentials environment-credentials))
297 (declare (ignore credentials))
298 (getenv
"AWS_ACCESS_KEY"))
300 (defmethod secret-key ((credentials environment-credentials))
301 (declare (ignore credentials))
302 (getenv
"AWS_SECRET_KEY"))
304 (setf *credentials* (make-instance 'environment-credentials))
311 <div class='type'
><a name='access-key'
>[Generic function]
</a></div>
312 <div class='signature'
>
313 <code class='name'
>access-key
</code>
315 <var>credentials
</var>
317 <span class='result'
>=
> <var>access-key-string
</var></span>
320 <blockquote class='description'
>
321 <p>Returns the access key for
<var>credentials
</var>.
327 <div class='type'
><a name='security-token'
>[Function]
</a></div>
328 <div class='signature'
>
329 <code class='name'
>security-token
</code>
331 <var>credentials
</var>
333 <span class='result'
>=
> <var>security-token-string
</var></span>
336 <blockquote class='description'
>
337 <p>Returns the security token string for
<var>credentials
</var>,
338 or NIL if there is no associated security token.
</p>
344 <div class='type'
><a name='secret-key'
>[Generic function]
</a></div>
345 <div class='signature'
>
346 <code class='name'
>secret-key
</code>
348 <var>credentials
</var>
350 <span class='result'
>=
> <var>secret-key-string
</var></span>
353 <blockquote class='description'
>
354 <p>Returns the secret key for
<var>credentials
</var>.
359 <div class='type'
><a name='file-credentials'
>[Function]
</a></div>
360 <div class='signature'
>
361 <code class='name'
>file-credentials
</code>
365 <span class='result'
>=
> <var>credentials
</var></span>
368 <blockquote class='description'
>
369 <p>Loads credentials on demand from
<var>pathname
</var>. The file
370 named by
<var>pathname
</var> should be a text file with the
371 access key on the first line and the secret key on the second
374 <p>It can be used like so:
377 (setf *credentials* (file-credentials
"/etc/s3.conf"))
384 <a name='responses'
><h3>Responses
</h3></a>
387 Some operations return a response as an additional value. All
388 response objects can be interrogated to obtain the HTTP code,
393 The outcome of some requests
— a very small proportion
394 — will be an error
<cite>internal
</cite> to the AWS server. In these
395 circumstances an exponential backoff policy operates; if this
396 encounters too many failures then ZS3 signals an
<tt>internal-error
</tt>
397 which can be interrogated to obtain the response object, and
398 through that the HTTP response code and headers:
404 #
<ZS3:INTERNAL-ERROR @ #x1000296bc92
>
405 *
<b>(setf r (zs3:request-error-response e))
</b>
406 #
<ZS3::AMAZON-ERROR
"InternalError">
407 *
<b>(zs3:http-code r)
</b>
409 *
<b>(zs3:http-headers r)
</b>
410 ((:X-AMZ-REQUEST-ID .
"3E20E3BAC24AB9AA")
411 (:X-AMZ-ID-
2 .
"80sxu4PDKtx1BWLOcSrUVWD90mMMVaMx6y9c+sz5VBGa2eAES2YlNaefn5kqRsfvrbaF+7QGNXA=")
412 (:CONTENT-TYPE .
"application/xml")
413 (:TRANSFER-ENCODING .
"chunked")
414 (:DATE .
"Fri, 30 Sep 2016 10:10:11 GMT")
415 (:CONNECTION .
"close")
416 (:SERVER .
"AmazonS3"))
417 *
<b>(zs3:http-phrase r)
</b>
418 "Internal Server Error"
422 <div class='type'
><a name='*backoff*'
>[Special variable]
</a></div>
423 <div class='signature'
>
424 <code class='name'
>*backoff*
</code>
427 <blockquote class='description'
>
429 Used as the default value of
<code>:backoff
</code> when
430 submitting a request. The value should be a cons of two
431 numbers: how many times to try before giving up, and how long
432 to wait (in ms) before trying for the second time. Each
433 subsequent attempt will double that time.
437 The default value is
<code>(
3 .
100)
</code>.
441 If a requst fails more times than permitted by
442 <code>*backoff*
</code>, an error will be signalled. It is the
443 application's responsibility to handle this error.
</p>
449 <div class='type'
><a name='request-error-response'
>[Function]
</a></div>
450 <div class='signature'
>
451 <code class='name'
>request-error-response
</code>
453 <var>request-error
</var>
455 <span class='result'
>=
> <var>response
</var></span>
458 <blockquote class='description'
>
459 <p>Returns the
<code>response
</code> object associated with a request-error.
465 <div class='type'
><a name='http-code'
>[Function]
</a></div>
466 <div class='signature'
>
467 <code class='name'
>http-code
</code>
471 <span class='result'
>=
> <var>code
</var></span>
474 <blockquote class='description'
>
475 <p>Returns the HTTP code associated with a
<code>response
</code> object.
481 <div class='type'
><a name='http-headers'
>[Function]
</a></div>
482 <div class='signature'
>
483 <code class='name'
>http-headers
</code>
487 <span class='result'
>=
> <var>headers
</var></span>
490 <blockquote class='description'
>
491 <p>Returns the HTTP headers associated with a
<code>response
</code> object.
497 <div class='type'
><a name='http-phrase'
>[Function]
</a></div>
498 <div class='signature'
>
499 <code class='name'
>http-phrase
</code>
503 <span class='result'
>=
> <var>phrase
</var></span>
506 <blockquote class='description'
>
507 <p>Returns the HTTP phrase associated with a
<code>response
</code> object.
512 <a name='bucket-ops'
><h3>Operations on Buckets
</h3></a>
514 <p>With ZS3, you can put, get, copy, and delete buckets. You can also
515 get information about the bucket.
518 <div class='type'
><a name='all-buckets'
>[Function]
</a></div>
519 <div class='signature'
>
520 <code class='name'
>all-buckets
</code>
522 <code class='llkw'
>&key
</code> <var>credentials
</var> <var>backoff
</var>
524 <span class='result'
>=
> <var>bucket-vector
</var></span>
527 <blockquote class='description'
>
528 <p>Returns a vector of all bucket objects. Bucket object
529 attributes are accessible via
<a href='#name'
><tt>NAME
</tt></a>
530 and
<a href='#creation-date'
><tt>CREATION-DATE
</tt></a>.
535 <div class='type'
><a name='creation-date'
>[Function]
</a></div>
536 <div class='signature'
>
537 <code class='name'
>creation-date
</code>
539 <var>bucket-object
</var>
541 <span class='result'
>=
> <var>creation-universal-time
</var></span>
544 <blockquote class='description'
>
545 <p>Returns the creation date of
<var>bucket-object
</var>, which
546 must be a bucket object, as a universal time.
552 <div class='type'
><a name='name'
>[Function]
</a></div>
553 <div class='signature'
>
554 <code class='name'
>name
</code>
558 <span class='result'
>=
> <var>name-string
</var></span>
561 <blockquote class='description'
>
562 <p>Returns the string name of
<var>object
</var>, which must be a
563 key object or bucket object.
569 <div class='type'
><a name='all-keys'
>[Function]
</a></div>
570 <div class='signature'
>
571 <code class='name'
>all-keys
</code>
574 <code class='llkw'
>&key
</code>
576 <var>credentials
</var>
579 <span class='result'
>=
> <var>key-vector
</var></span>
582 <blockquote class='description'
>
583 <p>Returns a vector of all key objects in
<var>bucket
</var> with names
584 that start with the string
<var>prefix
</var>. If no prefix is
585 specified, returns all keys. Keys in the vector are in
586 alphabetical order by name. Key
587 object attributes are accessible via
588 <a href='#name'
><tt>NAME
</tt></a>,
589 <a href='#size'
><tt>SIZE
</tt></a>,
590 <a href='#etag'
><tt>ETAG
</tt></a>,
591 <a href='#last-modified'
><tt>LAST-MODIFIED
</tt></a>,
592 <a href='#owner'
><tt>OWNER
</tt>, and
593 <a href='#storage-class'
><tt>STORAGE-CLASS
</tt></a></a>.
595 <p>This function is built
596 on
<a href='#query-bucket'
><tt>QUERY-BUCKET
</tt></a> and may
597 involve multiple requests if a bucket has more than
1000 keys.
603 <div class='type'
><a name='bucket-exists-p'
>[Function]
</a></div>
604 <div class='signature'
>
605 <code class='name'
>bucket-exists-p
</code>
608 <code class='llkw'
>&key
</code>
609 <var>credentials
</var>
612 <span class='result'
>=
> <var>boolean
</var></span>
615 <blockquote class='description'
>
616 <p>Returns
<i>true
</i> if
<var>bucket
</var> exists.
622 <div class='type'
><a name='create-bucket'
>[Function]
</a></div>
623 <div class='signature'
>
624 <code class='name'
>create-bucket
</code>
627 <code class='llkw'
>&key
</code>
628 <var>access-policy
</var>
631 <var>credentials
</var>
634 <span class='result'
>=
> <var>response
</var></span>
637 <blockquote class='description'
>
638 <p>Creates a bucket named
<var>name
</var>.
640 <p>If provided,
<var>access-policy
</var> should be one of the
644 <li> <code class='kw'
>:PRIVATE
</code> - bucket owner is
645 granted
<code class='kw'
>:FULL-CONTROL
</code>; this is the
646 default behavior if no access policy is provided
647 <li> <code class='kw'
>:PUBLIC-READ
</code> - all users,
648 regardless of authentication, can query the bucket's contents
649 <li> <code class='kw'
>:PUBLIC-READ-WRITE
</code> - all users,
650 regardless of authentication, can query the bucket's
651 contents and create new objects in the bucket
652 <li> <code class='kw'
>:AUTHENTICATED-READ
</code> -
653 authenticated Amazon AWS users can query the bucket
656 <p>For more information about access policies,
657 see
<a href='http://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl'
>Canned ACL
</a>
658 in the Amazon S3 developer documentation.
660 <p>If
<var>public
</var> is
<i>true
</i>, it has the same effect as
661 providing an
<var>access-policy
</var>
662 of
<code class='kw'
>:PUBLIC-READ
</code>. An error is signaled if
663 both
<var>public
</var> and
664 <var>access-policy
</var> are provided.
666 <p>If
<var>location
</var> is specified, the bucket will be created
667 in a region matching the given location constraint. If no
668 location is specified, the bucket is created in the US. Valid
669 locations change over time, but currently include
"EU",
670 "us-west-1",
"us-west-2",
"eu-west-1",
"eu-central-1",
671 "ap-southeast-1",
"ap-southeast-2",
"ap-northeast-1", and
673 See
<a href=
"http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region">Regions
674 and Endpoints
</a> in the Amazon S3 developer documentation for
675 the current information about location constraints.
681 <div class='type'
><a name='delete-bucket'
>[Function]
</a></div>
682 <div class='signature'
>
683 <code class='name'
>delete-bucket
</code>
685 <var>bucket
</var> <code class='llkw'
>&key
</code>
686 <var>credentials
</var>
689 <span class='result'
>=
> <var>response
</var></span>
692 <blockquote class='description'
>
693 <p>Deletes
<var>bucket
</var>. Signals a BUCKET-NOT-EMPTY error if
694 the bucket is not empty, or a NO-SUCH-BUCKET error if there is no
695 bucket with the given name.
702 <div class='type'
><a name='bucket-location'
>[Function]
</a></div>
703 <div class='signature'
>
704 <code class='name'
>bucket-location
</code>
706 <var>bucket
</var> <code class='llkw'
>&key
</code>
707 <var>credentials
</var>
710 <span class='result'
>=
> <var>location
</var></span>
713 <blockquote class='description'
>
714 <p>Returns the location specified when creating a bucket, or NIL if no
715 location was specified.
720 <div class='type'
><a name='bucket-lifecycle'
>[Function]
</a></div>
721 <div class='signature'
>
722 <code class='name'
>bucket-lifecycle
</code>
726 <span class='result'
>=
> <var>rules-list
</var></span>
729 <blockquote class='description'
>
730 <p>Returns a list of lifecycle rules
731 for
<var>bucket
</var>. Signals a NO-SUCH-LIFECYCLE-CONFIGURATION
732 error if the bucket has no lifecycle rules configured.
734 <p>Bucket lifecycle rules are used to control the automatic
735 deletion of objects in a bucket. For more information about
736 bucket lifecycle configuration,
737 see
<a href=
"http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectExpiration.html">Object
738 Expiration
</a> in the Amazon S3 developer documentation.
743 <div class='type'
><a name='setf-bucket-lifecycle'
>[Function]
</a></div>
744 <div class='signature'
>
745 <code class='name'
>(setf bucket-lifecycle)
</code>
747 <var>rules
</var> <var>bucket
</var>
749 <span class='result'
>=
> <var>rules
</var>,
<var>response
</var></span>
752 <blockquote class='description'
>
753 <p>Sets the lifecycle configuration of
<var>bucket
</var> to the
754 designator for a list of bucket lifecycle rules
<var>rules
</var>.
757 bucket lifecycle rule,
758 use
<a href='#lifecycle-rule'
><tt>LIFECYCLE-RULE
</tt></a>. For
759 example, to automatically delete objects with keys matching a
760 "logs/" prefix after
30 days:
763 (setf (bucket-lifecycle
"my-bucket") (lifecycle-rule :prefix
"logs/" :days
30))
766 <p>To delete a bucket's lifecycle configuration, use an empty list
770 (setf (bucket-lifecycle
"my-bucket") nil)
777 <div class='type'
><a name='lifecycle-rule'
>[Function]
</a></div>
778 <div class='signature'
>
779 <code class='name'
>lifecycle-rule
</code>
781 <code class='llkw'
>&key
</code>
787 <span class='result'
>=
> <var>rule
</var></span>
790 <blockquote class='description'
>
791 <p>Creates a rule object suitable for passing
792 to
<a href='#setf-bucket-lifecycle'
><tt>(SETF
793 BUCKET-LIFECYCLE)
</tt></a>.
795 <p><var>action
</var> should be either
<tt>:expire
</tt> (the
796 default) or
<tt>:transition
</tt>. For
<tt>:expire
</tt>, matching
797 objects are deleted. For
<tt>:transition
</tt>, matching objects
798 are transitioned to the GLACIER storage class. For more
799 information about S3-to-Glacier object transition,
800 see
<a href=
"http://docs.aws.amazon.com/AmazonS3/latest/dev/object-archival.html">Object
801 Archival (Transition Objects to the Glacier Storage Class)
</a> in
802 the Amazon S3 Developer's Guide.
804 <p><var>prefix
</var> is a string; all objects in a bucket with
805 keys matching the prefix will be affected by the rule.
807 <p><var>days
</var> is the number of days after which an object
810 <p><var>date
</var> is the date after which objects will be affected.
812 <p>Only one of
<var>days
</var> or
<var>date
</var> may be provided.
817 <div class='type'
><a name='restore-object'
>[Function]
</a></div>
818 <div class='signature'
>
819 <code class='name'
>restore-object
</code>
823 <code class='llkw'
>&body
</code>
825 <var>credentials
</var>
828 <span class='result'
>=
> <var>response
</var></span>
831 <blockquote class='description'
>
832 <p>Initiates a restoration operation on the object identified
833 by
<var>bucket
</var> and
<var>key
</var>. A restoration
834 operation can take several hours to complete. The restored
835 object is temporarily stored with the reduced redundancy storage
836 class. The status of the operation may monitored
837 via
<a href='#object-restoration-status'
><tt>OBJECT-RESTORATION-STATUS
</tt></a>.
839 <p><var>days
</var> is the number of days for which the restored
840 object should be avilable for normal retrieval before
841 transitioning back to archival storage.
843 <p>Object restoration operation is only applicable to objects that
844 have been transitioned to Glacier storage by the containing
845 bucket's lifecycle configuration.
847 <p>For more information,
848 see
<a href=
"http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOSTrestore.html">POST
849 Object restore
</a> in the S3 documentation.
854 <div class='type'
><a name='object-restoration-status'
>[Function]
</a></div>
855 <div class='signature'
>
856 <code class='name'
>object-restoration-status
</code>
860 <code class='llkw'
>&key
</code>
861 <var>credentials
</var>
864 <span class='result'
>=
> <var>status-string
</var></span>
867 <blockquote class='description'
>
868 <p>Returns a string describing the status of restoring the object
869 identified by
<var>bucket
</var> and
<var>key
</var>. If no
870 restoration is in progress, or the operation is not applicable,
877 <a name='querying-buckets'
><h3>Querying Buckets
</h3></a>
879 <p>S3 has a flexible interface for querying a bucket for information
880 about its contents. ZS3 supports this interface via
881 <a href='#query-bucket'
><tt>QUERY-BUCKET
</tt></a>,
882 <a href='#continue-bucket-query'
><tt>CONTINUE-BUCKET-QUERY
</tt></a>,
883 and related functions.
886 <div class='type'
><a name='query-bucket'
>[Function]
</a></div>
887 <div class='signature'
>
888 <code class='name'
>query-bucket
</code>
891 <code class='llkw'
>&key
</code>
896 <var>credentials
</var>
899 <span class='result'
>=
> <var>response
</var></span>
902 <blockquote class='description'
>
903 <p>Query
<var>bucket
</var> for key information. Returns a response
904 object that has the result of the query. Response attributes are
906 <a href='#bucket-name'
><tt>BUCKET-NAME
</tt></a>,
907 <a href='#prefix'
><tt>PREFIX
</tt></a>,
908 <a href='#marker'
><tt>MARKER
</tt></a>,
909 <a href='#delimiter'
><tt>DELIMITER
</tt></a>,
910 <a href='#truncatedp'
><tt>TRUNCATEDP
</tt></a>,
911 <a href='#keys'
><tt>KEYS
</tt></a>, and
912 <a href='#common-prefixes'
><tt>COMMON-PREFIXES
</tt></a>.
914 <p>Amazon might return fewer key objects than actually match the
915 query parameters, based on
<var>max-keys
</var> or the result
916 limit of
1000 key objects. In that
917 case,
<a href='#truncatedp'
><tt>TRUNCATEDP
</tt></a>
918 for
<var>response
</var> is
<i>true
</i>, and
919 <a href='#continue-bucket-query'
><tt>CONTINUE-BUCKET-QUERY
</tt></a>
920 can be used with
<var>response
</var> be used to get successive
921 responses for the query parameters.
923 <p>When
<var>prefix
</var> is supplied, only key objects with names
924 that start with
<var>prefix
</var> will be returned
925 in
<var>response
</var>.
927 <p>When
<var>marker
</var> is supplied, only key objects with names
928 occurring lexically after
<var>marker
</var> will be returned in
931 <p>When
<var>max-keys
</var> is supplied, it places an inclusive
932 upper limit on the number of key objects returned
933 in
<var>response
</var>. Note that Amazon currently limits
934 responses to at most
1000 key objects even
935 if
<var>max-keys
</var> is greater than
1000.
937 <p>When
<var>delimiter
</var> is supplied, key objects that have
938 the delimiter string after
<var>prefix
</var> in their names are
939 not returned in the
<a href='#keys'
><tt>KEYS
</tt></a> attribute
940 of the response, but are instead accumulated into the
941 <a href='#common-prefixes'
><tt>COMMON-PREFIXES
</tt></a>
942 attribute of the response. For example:
944 *
<b>(all-keys
"zs3-demo")
</b>
953 *
<b>(setf *response* (query-bucket
"zs3-demo" :delimiter
"/"))
</b>
954 =
> #
<BUCKET-LISTING
"zs3-demo">
956 *
<b>(values (keys *response*) (common-prefixes *response*))
</b>
957 =
> #(#
<KEY
"a" 4>),
961 *
<b>(setf *response* (query-bucket
"zs3-demo" :delimiter
"/" :prefix
"b/"))
</b>
962 =
> #
<BUCKET-LISTING
"zs3-demo">
964 *
<b>(values (keys *response*) (common-prefixes *response*))
</b>
965 =
> #(#
<KEY
"b/1" 4>
970 <p>For more information about bucket queries,
971 see
<a href=
"http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGET.html">GET
972 Bucket
</a> in the Amazon S3 developer documentation.
980 <div class='type'
><a name='continue-bucket-query'
>[Function]
</a></div>
981 <div class='signature'
>
982 <code class='name'
>continue-bucket-query
</code>
986 <span class='result'
>=
> <var>response
</var></span>
989 <blockquote class='description'
>
990 <p>If
<var>response
</var> is a truncated response from a previous
992 <a href='#query-bucket'
><tt>QUERY-BUCKET
</tt></a>,
993 continue-bucket-query returns the result of resuming the query at the
994 truncation point. When there are no more results,
995 continue-bucket-query returns NIL.
1000 <div class='type'
><a name='bucket-name'
>[Function]
</a></div>
1001 <div class='signature'
>
1002 <code class='name'
>bucket-name
</code>
1006 <span class='result'
>=
> <var>name
</var></span>
1009 <blockquote class='description'
>
1010 <p>Returns the name of the bucket used in the call
1011 to
<a href='#query-bucket'
><tt>QUERY-BUCKET
</tt></a> that
1012 produced
<var>response
</var>.
1020 <div class='type'
><a name='keys'
>[Function]
</a></div>
1021 <div class='signature'
>
1022 <code class='name'
>keys
</code>
1026 <span class='result'
>=
> <var>keys-vector
</var></span>
1029 <blockquote class='description'
>
1030 <p>Returns the vector of key objects in
<var>response
</var>. Key
1031 object attributes are accessible via
1032 <a href='#name'
><tt>NAME
</tt></a>,
1033 <a href='#size'
><tt>SIZE
</tt></a>,
1034 <a href='#etag'
><tt>ETAG
</tt></a>,
1035 <a href='#last-modified'
><tt>LAST-MODIFIED
</tt></a>,
1036 and
<a href='#owner'
><tt>OWNER
</tt></a>.
1042 <div class='type'
><a name='common-prefixes'
>[Function]
</a></div>
1043 <div class='signature'
>
1044 <code class='name'
>common-prefixes
</code>
1048 <span class='result'
>=
> <var>prefix-vector
</var></span>
1051 <blockquote class='description'
>
1052 <p>Returns a vector of common prefix strings, based on the
1053 delimiter argument of
1054 the
<a href='#query-bucket'
><tt>QUERY-BUCKET
</tt></a> call that
1055 produced
<var>response
</var>.
1061 <div class='type'
><a name='prefix'
>[Function]
</a></div>
1062 <div class='signature'
>
1063 <code class='name'
>prefix
</code>
1067 <span class='result'
>=
> <var>prefix-string
</var></span>
1070 <blockquote class='description'
>
1071 <p>Returns the prefix given to
1072 the
<a href='#query-bucket'
><tt>QUERY-BUCKET
</tt></a> call that
1073 produced
<var>response
</var>. If present, all keys
1074 in
<var>response
</var> have
<var>prefix-string
</var> as a prefix.
1079 <div class='type'
><a name='marker'
>[Function]
</a></div>
1080 <div class='signature'
>
1081 <code class='name'
>marker
</code>
1085 <span class='result'
>=
> <var>marker
</var></span>
1088 <blockquote class='description'
>
1089 <p>Returns the marker given to
1090 the
<a href='#query-bucket'
><tt>QUERY-BUCKET
</tt></a> call that
1091 produced
<var>response
</var>. If present,
1092 it lexically precedes all key names in the response.
1097 <div class='type'
><a name='delimiter'
>[Function]
</a></div>
1098 <div class='signature'
>
1099 <code class='name'
>delimiter
</code>
1103 <span class='result'
>=
> <var>delimiter
</var></span>
1106 <blockquote class='description'
>
1107 <p>Returns the delimiter used in
1108 the
<a href='#query-bucket'
><tt>QUERY-BUCKET
</tt></a> call that
1109 produced
<var>response
</var>.
1115 <div class='type'
><a name='truncatedp'
>[Function]
</a></div>
1116 <div class='signature'
>
1117 <code class='name'
>truncatedp
</code>
1121 <span class='result'
>=
> <var>boolean
</var></span>
1124 <blockquote class='description'
>
1125 <p>Returns
<i>true
</i> if
<var>response
</var> is truncated; that
1126 is, if there is more data to retrieve for a
1127 given
<a href='#query-bucket'
><tt>QUERY-BUCKET
</tt></a>
1128 query.
<a href='#continue-bucket-query'
><tt>CONTINUE-BUCKET-QUERY
</tt></a>
1129 may be used to fetch more data.
1135 <div class='type'
><a name='last-modified'
>[Function]
</a></div>
1136 <div class='signature'
>
1137 <code class='name'
>last-modified
</code>
1139 <var>key-object
</var>
1141 <span class='result'
>=
> <var>universal-time
</var></span>
1144 <blockquote class='description'
>
1145 <p>Returns a universal time representing the last modified time
1146 of
<var>key-object
</var>.
1152 <div class='type'
><a name='etag'
>[Function]
</a></div>
1153 <div class='signature'
>
1154 <code class='name'
>etag
</code>
1156 <var>key-object
</var>
1158 <span class='result'
>=
> <var>etag-string
</var></span>
1161 <blockquote class='description'
>
1162 <p>Returns the etag for
<var>key-object
</var>.
1168 <div class='type'
><a name='size'
>[Function]
</a></div>
1169 <div class='signature'
>
1170 <code class='name'
>size
</code>
1172 <var>key-object
</var>
1174 <span class='result'
>=
> <var>size
</var></span>
1177 <blockquote class='description'
>
1178 <p>Returns the size, in octets, of
<var>key-object
</var>.
1184 <div class='type'
><a name='owner'
>[Function]
</a></div>
1185 <div class='signature'
>
1186 <code class='name'
>owner
</code>
1188 <var>key-object
</var>
1190 <span class='result'
>=
> <var>owner
</var></span>
1193 <blockquote class='description'
>
1194 <p>Returns the owner of
<var>key-object
</var>, or NIL if no owner
1195 information is available.
1201 <div class='type'
><a name='storage-class'
>[Function]
</a></div>
1202 <div class='signature'
>
1203 <code class='name'
>storage-class
</code>
1205 <var>key-object
</var>
1207 <span class='result'
>=
> <var>storage-class
</var></span>
1210 <blockquote class='description'
>
1211 <p>Returns the storage class of
<var>key-object
</var>.
1219 <a name='object-ops'
><h3>Operations on Objects
</h3></a>
1221 <p>Objects are the stored binary data in S3. Every object is uniquely
1222 identified by a bucket/key pair. ZS3 has several functions for
1223 storing and fetching objects, and querying object attributes.
1226 <div class='type'
><a name='get-object'
>[Function]
</a></div>
1227 <div class='signature'
>
1228 <code class='name'
>get-object
</code>
1232 <code class='llkw'
>&key
</code>
1233 <var>output
</var> <br>
1234 <var>start
</var> <var>end
</var> <br>
1235 <var>when-modified-since
</var> <var>unless-modified-since
</var> <br>
1236 <var>when-etag-matches
</var> <var>unless-etag-matches
</var> <br>
1237 <var>if-exists
</var> <var>string-external-format
</var>
1238 <var>credentials
</var>
1241 <span class='result'
>=
> <var>object
</var></span>
1244 <blockquote class='description'
>
1245 <p>Fetch the object referenced by
<var>bucket
</var>
1246 and
<var>key
</var>. The secondary value of all successful requests
1247 is an alist of
<a href='http://weitz.de/drakma/'
>Drakma
</a>-style
1248 response HTTP headers.
1250 <p>If
<var>output
</var> is
<code class='kw'
>:VECTOR
</code> (the
1251 default), the object's octets are returned in a vector.
1253 <p>If
<var>output
</var> is
<code class='kw'
>:STRING
</code>, the
1254 object's octets are converted to a string using the encoding
1255 specified by
<var>string-external-format
</var>, which defaults
1256 to
<code class='kw'
>:UTF-
8</code>. See
<a href=
"http://weitz.de/flexi-streams/#external-formats">External
1257 formats
</a> in the FLEXI-STREAMS documentation for supported
1258 values for the string external format. Note that, even
1259 when
<var>output
</var> is
<code class='kw'
>:STRING
</code>, the
1260 start and end arguments operate on the object's underlying octets,
1261 not the string representation in a particular encoding. It's
1262 possible to produce a subsequence of the object's octets that are
1263 not valid in the desired encoding.
1265 <p>If
<var>output
</var> is a string or pathname, the object's
1266 octets are saved to a file identified by the string or
1267 pathname. The
<var>if-exists
</var> argument is passed
1268 to
<code>WITH-OPEN-FILE
</code> to control the behavior when the
1269 output file already exists. It defaults
1270 to
<code class='kw'
>:SUPERSEDE
</code>.
1272 <p>If
<var>output
</var> is
<code class='kw'
>:STREAM
</code>, a
1273 stream is returned from which the object's contents may be read.
1275 <p><var>start
</var> marks the first index fetched from the
1276 object's data.
<var>end
</var> specifies the index after the last
1277 octet fetched. If start is NIL, it defaults to
0. If end is nil,
1278 it defaults to the total length of the object. If
1279 both
<var>start
</var> and
<var>end
</var> are
1280 provided,
<var>start
</var> must be less than or equal
1283 <p><var>when-modified-since
</var>
1284 and
<var>unless-modified-since
</var> are optional. If
1285 <var>when-modified-since
</var> is provided, the result will be the normal
1286 object value if the object has been modified since the provided
1287 universal time, NIL otherwise. The logic is reversed for
1288 <var>unless-modified-since
</var>.
1290 <p><var>when-etag-matches
</var> and
<var>unless-etag-matches
</var> are optional. If
1291 <var>when-etag-matches
</var> is provided, the result will be the
1292 normal object value if the object's etag matches the provided
1293 string, NIL otherwise. The logic is reversed
1294 for
<var>unless-etag-matches
</var>.
1300 <div class='type'
><a name='get-vector'
>[Function]
</a></div>
1301 <div class='signature'
>
1302 <code class='name'
>get-vector
</code>
1304 <var>bucket
</var> <var>key
</var>
1305 <code class='llkw'
>&key
</code>
1306 <var>start
</var> <var>end
</var>
1307 <var>when-modified-since
</var> <var>unless-modified-since
</var>
1308 <var>when-etag-matches
</var> <var>unless-etag-matches
</var>
1309 <var>credentials
</var>
1312 <span class='result'
>=
> <var>vector
</var></span>
1315 <blockquote class='description'
>
1316 <p>get-vector is a convenience interface to
<a href='#get-object'
><tt>GET-OBJECT
</tt></a>. It is equivalent
1320 (get-object bucket key
<b>:output :vector
</b> ...)
1326 <div class='type'
><a name='get-string'
>[Function]
</a></div>
1327 <div class='signature'
>
1328 <code class='name'
>get-string
</code>
1330 <var>bucket
</var> <var>key
</var>
1331 <code class='llkw'
>&key
</code>
1332 <var>external-format
</var>
1333 <var>start
</var> <var>end
</var>
1334 <var>when-modified-since
</var>
1335 <var>unless-modified-since
</var>
1336 <var>when-etag-matches
</var>
1337 <var>unless-etag-matches
</var>
1338 <var>credentials
</var>
1341 <span class='result'
>=
> <var>string
</var></span>
1344 <blockquote class='description'
>
1345 get-string is a convenience interface
1346 to
<a href='#get-object'
><tt>GET-OBJECT
</tt></a>. It is equivalent
1350 (get-object bucket key
<b>:output :string
</b> :string-external-format external-format ...)
1357 <div class='type'
><a name='get-file'
>[Function]
</a></div>
1358 <div class='signature'
>
1359 <code class='name'
>get-file
</code>
1361 <var>bucket
</var> <var>key
</var> <var>file
</var>
1362 <code class='llkw'
>&key
</code>
1363 <var>start
</var> <var>end
</var>
1364 <var>when-modified-since
</var>
1365 <var>unless-modified-since
</var>
1366 <var>when-etag-matches
</var>
1367 <var>unless-etag-matches
</var>
1368 <var>credentials
</var>
1371 <span class='result'
>=
> <var>pathname
</var></span>
1374 <blockquote class='description'
>
1375 <p>get-file is a convenience interface
1376 to
<a href='#get-object'
><tt>GET-OBJECT
</tt></a>. It is
1377 equivalent to calling:
1380 (get-object bucket key
<b>:output file
</b> ...)
1388 <div class='type'
><a name='put-object'
>[Function]
</a></div>
1389 <div class='signature'
>
1390 <code class='name'
>put-object
</code>
1392 <var>object
</var> <var>bucket
</var> <var>key
</var>
1393 <code class='llkw'
>&key
</code>
1394 <var>access-policy
</var>
1397 <var>string-external-format
</var>
1398 <var>cache-control
</var>
1399 <var>content-encoding
</var>
1400 <var>content-disposition
</var>
1401 <var>content-type
</var>
1403 <var>storage-class
</var>
1405 <var>credentials
</var>
1408 <span class='result'
>=
> <var>response
</var></span>
1411 <blockquote class='description'
>
1412 <p>Stores the octets of
<var>object
</var> in the location
1413 identified by
<var>bucket
</var> and
<var>key
</var>.
1415 <p>If
<i>object
</i> is an octet vector, it is stored directly.
1417 <p>If
<i>object
</i> is a string, it is converted to an octet
1418 vector using
<i>string-external-format
</i>, which defaults
1419 to
<code class='kw'
>:UTF-
8</code>, then
1420 stored. See
<a href=
"http://weitz.de/flexi-streams/#external-formats">External
1421 formats
</a> in the FLEXI-STREAMS documentation for supported
1422 values for the string external format.
1424 <p>If
<i>object
</i> is a pathname, its contents are loaded in
1425 memory as an octet vector and stored.
1427 <p>If provided,
<var>access-policy
</var> should be one of the
1431 <li> <code class='kw'
>:PRIVATE
</code> - object owner is
1432 granted
<code class='kw'
>:FULL-CONTROL
</code>; this is the
1433 default behavior if no access policy is provided
1434 <li> <code class='kw'
>:PUBLIC-READ
</code> - all users,
1435 regardless of authentication, can read the object
1436 <li> <code class='kw'
>:AUTHENTICATED-READ
</code> -
1437 authenticated Amazon AWS users can read the object
1440 <p>For more information about access policies,
1441 see
<a href='http://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl'
>Canned ACL
</a> in the Amazon S3 developer documentation.
1443 <p>If
<var>public
</var> is
<i>true
</i>, it has the same effect as
1444 providing an
<var>access-policy
</var>
1445 of
<code class='kw'
>:PUBLIC-READ
</code>. An error is signaled if
1446 both
<var>public
</var> and
1447 <var>access-policy
</var> are provided.
1450 <p>If provided,
<var>metadata
</var> should be an alist of Amazon
1451 metadata to set on the object. When the object is fetched again,
1452 the metadata will be returned in HTTP headers prefixed with
1455 <p>The
<i>cache-control
</i>,
<i>content-encoding
</i>,
<i>content-disposition
</i>,
1456 <i>content-type
</i>, and
<i>expires
</i> values are all used to set
1457 HTTP properties of the object that are returned with subsequent
1458 GET or HEAD requests. If
<i>content-type
</i> is not set, it
1459 defaults to
"binary/octet-stream". The others default to
1460 NIL. If
<i>expires
</i> is provided, it should be a universal time.
1462 <p>If provided,
<var>storage-class
</var> should refer to one of
1463 the standard storage classes available for S3; currently the
1464 accepted values are the strings
"STANDARD" and
1465 "REDUCED_REDUNDANCY". Using other values may trigger an API error
1466 from S3. For more information about reduced redundancy storage,
1467 see
<a href=
"http://docs.aws.amazon.com/AmazonS3/latest/dev/Introduction.html#RRS">reduced
1468 Redundancy Storage
</a> in the Developer Guide.
1470 <p>If provided,
<var>tagging
</var> specifies the set of tags
1471 to be associated with the object. The set is given as an alist.
1472 For more information, see
<a href=
"http://docs.aws.amazon.com/AmazonS3/latest/dev/object-tagging.html">
1473 Object Tagging
</a> in the Developer Guide.
1477 <div class='type'
><a name='put-vector'
>[Function]
</a></div>
1478 <div class='signature'
>
1479 <code class='name'
>put-vector
</code>
1483 <var>key
</var> <code class='llkw'
>&key
</code>
1484 <var>start
</var> <var>end
</var>
1485 <var>access-policy
</var>
1486 <var>public
</var> <var>metadata
</var>
1487 <var>content-disposition
</var>
1488 <var>content-encoding
</var>
1489 <var>content-type
</var>
1491 <var>storage-class
</var>
1493 <var>credentials
</var>
1496 <span class='result'
>=
> <var>response
</var></span>
1499 <blockquote class='description'
>
1500 <p>put-vector is a convenience interface
1501 to
<a href='#put-object'
><tt>PUT-OBJECT
</tt></a>. It is similar
1505 (put-object vector bucket key ...)
1509 <p>If one of
<var>start
</var> or
<var>end
</var> is provided, they
1510 are used as bounding index designators on the string, and only a
1511 subsequence is used.
1515 <div class='type'
><a name='put-string'
>[Function]
</a></div>
1516 <div class='signature'
>
1517 <code class='name'
>put-string
</code>
1519 <var>string
</var> <var>bucket
</var> <var>key
</var>
1520 <code class='llkw'
>&key
</code>
1521 <var>start
</var> <var>end
</var>
1522 <var>external-format
</var>
1523 <var>access-policy
</var>
1524 <var>public
</var> <var>metadata
</var>
1525 <var>content-disposition
</var>
1526 <var>content-encoding
</var>
1527 <var>content-type
</var>
1529 <var>storage-class
</var>
1531 <var>credentials
</var>
1534 <span class='result'
>=
> <var>response
</var></span>
1537 <blockquote class='description'
>
1538 <p>put-string is a convenience interface
1539 to
<a href='#put-object'
><tt>PUT-OBJECT
</tt></a>. It is similar to
1543 (put-object string bucket key :string-external-format external-format ...)
1547 <p>If one of
<var>start
</var> or end is
<var>supplied
</var>, they
1548 are used as bounding index designators on the string, and only a
1553 <div class='type'
><a name='put-file'
>[Function]
</a></div>
1554 <div class='signature'
>
1555 <code class='name'
>put-file
</code>
1557 <var>file
</var> <var>bucket
</var> <var>key
</var>
1558 <code class='llkw'
>&key
</code>
1559 <var>start
</var> <var>end
</var>
1560 <var>access-policy
</var>
1561 <var>public
</var> <var>metadata
</var>
1562 <var>content-disposition
</var> <var>content-encoding
</var> <var>content-type
</var>
1564 <var>storage-class
</var>
1566 <var>credentials
</var>
1569 <span class='result'
>=
> <var>response
</var></span>
1572 <blockquote class='description'
>
1573 <p>put-file is a convenience interface
1574 to
<a href='#put-object'
><tt>PUT-OBJECT
</tt></a>. It is almost
1575 equivalent to calling:
1578 (put-object (pathname file) bucket key ...)
1581 <p>If
<var>key
</var> is T, the
<code>FILE-NAMESTRING
</code> of
1582 the file is used as the key instead of
<i>key
</i>.
1584 <p>If one of
<var>start
</var> or
<var>end
</var> is supplied, only
1585 a subset of the file is used. If
<var>start
</var> is not
1586 NIL,
<var>start
</var> octets starting from the beginning of the
1587 file are skipped. If
<var>end
</var> is not NIL, octets in the
1588 file at and after
<var>end
</var> are ignored. An error of type
1589 <tt>CL:END-OF-FILE
</tt> is signaled if
<var>end
</var> is
1590 provided and the file size is less than
<var>end
</var>.
1596 <div class='type'
><a name='put-stream'
>[Function]
</a></div>
1597 <div class='signature'
>
1598 <code class='name'
>put-stream
</code>
1600 <var>file
</var> <var>bucket
</var> <var>key
</var>
1601 <code class='llkw'
>&key
</code>
1602 <var>start
</var> <var>end
</var>
1603 <var>access-policy
</var>
1604 <var>public
</var> <var>metadata
</var>
1605 <var>content-disposition
</var> <var>content-encoding
</var> <var>content-type
</var>
1607 <var>storage-class
</var>
1609 <var>credentials
</var>
1612 <span class='result'
>=
> <var>response
</var></span>
1615 <blockquote class='description'
>
1616 <p>put-stream is similar to
1617 to
<a href='#put-object'
><tt>PUT-OBJECT
</tt></a>. It has the same
1618 effect as collecting octets from
<var>stream
</var> into a vector
1622 (put-object vector bucket key ...)
1625 <p>If
<var>start
</var> is not NIL,
<var>start
</var> octets
1626 starting from the current position in the stream are skipped
1629 <p>If
<var>end
</var> is NIL, octets are collected until the end of
1630 the stream is reached.
1632 <p>If
<var>end
</var> is not NIL, collecting octets stops just
1633 before reaching
<var>end
</var> in the stream. An error of type
1634 <tt>CL:END-OF-FILE
</tt> is signaled if the stream ends
1641 <div class='type'
><a name='copy-object'
>[Function]
</a></div>
1642 <div class='signature'
>
1643 <code class='name'
>copy-object
</code>
1645 <code class='llkw'
>&key
</code>
1646 <var>from-bucket
</var>
1648 <var>to-bucket
</var>
1649 <var>to-key
</var> <br>
1650 <var>access-policy
</var>
1651 <var>public
</var> <br>
1652 <var>when-etag-matches
</var>
1653 <var>unless-etag-matches
</var> <br>
1654 <var>when-modified-since
</var>
1655 <var>unless-modified-since
</var> <br>
1656 <var>metadata
</var> <var>public
</var> <var>precondition-errors
</var>
1657 <var>storage-class
</var>
1659 <var>credentials
</var>
1662 <span class='result'
>=
> <var>response
</var></span>
1665 <blockquote class='description'
>
1666 <p>Copies the object identified by
<var>from-bucket
</var>
1667 and
<var>from-key
</var> to a new location identified by
1668 <var>to-bucket
</var> and
<var>to-key
</var>.
1670 If
<var>to-bucket
</var> is NIL,
<var>from-bucket
</var> is used as
1671 the target. If
<var>to-key
</var> is nil,
<var>from-key
</var> is
1672 used as the target. An error is signaled if both
<var>to-bucket
</var> and
1673 <var>to-key
</var> are NIL.
1675 <p><var>access-policy
</var> and
<var>public
</var> have the same
1676 effect on the target object as
1677 in
<a href='#put-object'
><tt>PUT-OBJECT
</tt></a>.
1679 <p>The precondition arguments
<var>when-etag-matches
</var>,
<var>unless-etag-matches
</var>,
1680 <var>when-modified-since
</var>, and
<var>unless-modified-since
</var> work the same way they
1681 do in
<a href='#get-object'
><tt>GET-OBJECT
</tt></a>, but with one difference: if
<var>precondition-errors
</var> is
1682 <i>true
</i>, an
<code>PRECONDITION-FAILED
</code> error is signaled
1683 when a precondition does not hold, instead of returning NIL.
1685 <p>If
<var>metadata
</var> is explicitly provided, it follows the
1687 with
<a href='#put-object'
><tt>PUT-OBJECT
</tt></a>. Passing NIL
1688 means that the new object has no metadata. Otherwise, the metadata
1689 is copied from the original object.
1691 <p>If
<var>tagging
</var> is explicitly provided, it follows the
1693 with
<a href='#put-object'
><tt>PUT-OBJECT
</tt></a>. Passing NIL
1694 means that the new object has no tags. Otherwise, tagging is copied
1695 from the original object.
1697 <p>If
<var>storage-class
</var> is provided, it should refer to one
1698 of the standard storage classes available for S3; currently the
1699 accepted values are the strings
"STANDARD" and
1700 "REDUCED_REDUNDANCY". Using other values may trigger an API error
1701 from S3. For more information about reduced redundancy storage,
1702 see
<a href=
"http://docs.aws.amazon.com/AmazonS3/latest/dev/Introduction.html#RRS">Reduced
1703 Redundancy Storage
</a> in the Developer Guide.
1708 <div class='type'
><a name='delete-object'
>[Function]
</a></div>
1709 <div class='signature'
>
1710 <code class='name'
>delete-object
</code>
1714 <code class='llkw'
>&key
</code>
1715 <var>credentials
</var>
1718 <span class='result'
>=
> <var>response
</var></span>
1721 <blockquote class='description'
>
1722 <p>Deletes the object identified by
<var>bucket
</var>
1724 <p>If
<var>bucket
</var> is a valid bucket for
1725 which you have delete access granted, S3 will always return a success
1726 response, even if
<var>key
</var> does not reference an existing
1732 <div class='type'
><a name='delete-objects'
>[Function]
</a></div>
1733 <div class='signature'
>
1734 <code class='name'
>delete-objects
</code>
1738 <code class='llkw'
>&key
</code>
1739 <var>credentials
</var>
1742 <span class='result'
>=
> <var>deleted-count
</var>,
<var>errors
</var></span>
1745 <blockquote class='description'
>
1746 <p>Deletes
<var>keys
</var>, which should be a sequence of keys,
1747 from
<var>bucket
</var>. The primary value is the number of objects
1748 deleted. The secondary value is a list of error plists; if there
1749 are no errors deleting any of the keys, the secondary value is
1755 <div class='type'
><a name='delete-all-objects'
>[Function]
</a></div>
1756 <div class='signature'
>
1757 <code class='name'
>delete-all-objects
</code>
1760 <code class='llkw'
>&key
</code>
1761 <var>credentials
</var>
1764 <span class='result'
>=
> <var>count
</var></span>
1767 <blockquote class='description'
>
1768 <p>Deletes all objects in
<var>bucket
</var> and returns the count
1775 <div class='type'
><a name='object-metadata'
>[Function]
</a></div>
1776 <div class='signature'
>
1777 <code class='name'
>object-metadata
</code>
1781 <code class='llkw'
>&key
</code>
1782 <var>credentials
</var>
1785 <span class='result'
>=
> <var>metadata-alist
</var></span>
1788 <blockquote class='description'
>
1789 <p>Returns the metadata for the object identified by
<var>bucket
</var> and
<var>key
</var>, or
1790 NIL if there is no metadata. For example:
1793 *
<b>(put-string
"Hadjaha!" "zs3-demo" "hadjaha.txt" :metadata (parameters-alist :language
"Swedish"))
</b>
1794 =
> #
<RESPONSE
200 "OK" {
1003BD2841}
>
1796 *
<b>(object-metadata
"zs3-demo" "hadjaha.txt")
</b>
1797 =
> ((:LANGUAGE .
"Swedish"))
1804 <div class='type'
><a name='set-storage-class'
>[Function]
</a></div>
1805 <div class='signature'
>
1806 <code class='name'
>set-storage-class
</code>
1810 <var>storage-class
</var>
1811 <code class='llkw'
>&key
</code>
1812 <var>credentials
</var>
1815 <span class='result'
>=
> <var>response
</var></span>
1818 <blockquote class='description'
>
1819 <p>Sets the storage class of the object identified
1820 by
<var>bucket
</var> and
<var>key
</var>
1821 to
<var>storage-class
</var>. This is a convenience function that
1822 uses
<a href='#copy-object'
><tt>COPY-OBJECT
</tt></a> to make
1823 storage class changes.
1825 <p>The storage class of an object can be determined by querying
1826 the bucket with
<a href='#all-keys'
><tt>ALL-KEYS
</tt></a>
1827 or
<a href='#query-bucket'
><tt>QUERY-BUCKET
</tt></a> and
1828 using
<a href='#storage-class'
><tt>STORAGE-CLASS
</tt></a> on one
1829 of the resulting key objects.
1835 <a name='access-control'
><h3>Access Control
</h3></a>
1837 <p>Each S3 resource has an associated access control list that is
1838 created automatically when the resource is created. The access
1839 control list specifies the resource owner and a list of permission
1842 <p>Grants consist of a permission and a grantee. The permission must
1843 be one of
<code class='kw'
>:READ
</code>,
<code class='kw'
>:WRITE
</code>,
1844 <code class='kw'
>:READ-ACL
</code>,
<code class='kw'
>:WRITE-ACL
</code>,
1845 or
<code class='kw'
>:FULL-CONTROL
</code>. The grantee should be a
1846 person object, an acl-group object, or an acl-email object.
1848 <p>ZS3 has several functions that assist in reading, modifying, and
1849 storing access control lists.
1853 <div class='type'
><a name='get-acl'
>[Function]
</a></div>
1854 <div class='signature'
>
1855 <code class='name'
>get-acl
</code>
1857 <code class='llkw'
>&key
</code>
1860 <var>credentials
</var>
1863 <span class='result'
>=
> <var>owner
</var>,
<var>grants
</var></span>
1866 <blockquote class='description'
>
1867 <p>Returns the owner and grant list for a resource as
1874 <div class='type'
><a name='put-acl'
>[Function]
</a></div>
1875 <div class='signature'
>
1876 <code class='name'
>put-acl
</code>
1878 <var>owner
</var> <var>grants
</var>
1879 <code class='llkw'
>&key
</code>
1882 <var>credentials
</var>
1885 <span class='result'
>=
> <var>response
</var></span>
1888 <blockquote class='description'
>
1889 <p>Sets the owner and grant list of a resource.
1895 <div class='type'
><a name='grant'
>[Function]
</a></div>
1896 <div class='signature'
>
1897 <code class='name'
>grant
</code>
1899 <var>permission
</var>
1900 <code class='llkw'
>&key
</code>
1903 <span class='result'
>=
> <var>grant
</var></span>
1906 <blockquote class='description'
>
1907 <p>Returns a grant object that represents a permission (one of
<code class='kw'
>:READ
</code>,
<code class='kw'
>:WRITE
</code>,
1908 <code class='kw'
>:READ-ACL
</code>,
<code class='kw'
>:WRITE-ACL
</code>,
1909 or
<code class='kw'
>:FULL-CONTROL
</code>) for the
1910 grantee
<var>to
</var>. For example:
1913 *
<b>(grant :full-control :to (
<a href='#acl-email'
>acl-email
</a> "bob@example.com"))
</b>
1914 =
> #
<GRANT :FULL-CONTROL to
"bob@example.com">
1916 *
<b>(grant :read :to
<a href='#*all-users*'
>*all-users*
</a>)
</b>
1917 =
> #
<GRANT :READ to
"AllUsers">
1920 <p>It can be used to create or modify a grant list for use
1921 with
<a href='#put-acl'
><tt>PUT-ACL
</tt></a>.
1927 <div class='type'
><a name='acl-eqv'
>[Function]
</a></div>
1928 <div class='signature'
>
1929 <code class='name'
>acl-eqv
</code>
1931 <var>a
</var> <var>b
</var>
1933 <span class='result'
>=
> <var>boolean
</var></span>
1936 <blockquote class='description'
>
1937 <p>Returns
<i>true
</i> if
<var>a
</var> and
<var>b
</var> are equivalent
1938 ACL-related objects (person, group, email, or grant).
1944 <div class='type'
><a name='*all-users*'
>[Special variable]
</a></div>
1945 <div class='signature'
>
1946 <code class='name'
>*all-users*
</code>
1949 <blockquote class='description'
>
1950 <p>This acl-group includes all users, including unauthenticated
1957 <div class='type'
><a name='*aws-users*'
>[Special variable]
</a></div>
1958 <div class='signature'
>
1959 <code class='name'
>*aws-users*
</code>
1962 <blockquote class='description'
>
1963 <p>This acl-group object includes only users that have an
1964 Amazon Web Services account.
1970 <div class='type'
><a name='*log-delivery*'
>[Special variable]
</a></div>
1971 <div class='signature'
>
1972 <code class='name'
>*log-delivery*
</code>
1975 <blockquote class='description'
>
1976 <p>This acl-group object includes the S3 system user that creates
1977 logfile objects. See
1978 also
<a href='#enable-logging-to'
><tt>ENABLE-LOGGING-TO
</tt></a>.
1984 <div class='type'
><a name='acl-email'
>[Function]
</a></div>
1985 <div class='signature'
>
1986 <code class='name'
>acl-email
</code>
1988 <var>email-address
</var>
1990 <span class='result'
>=
> <var>acl-email
</var></span>
1993 <blockquote class='description'
>
1994 <p>Returns an acl-email object, which can be used as a grantee for
1995 <a href='#grant'
><tt>GRANT
</tt></a>.
2001 <div class='type'
><a name='acl-person'
>[Function]
</a></div>
2002 <div class='signature'
>
2003 <code class='name'
>acl-person
</code>
2006 <code class='llkw'
>&optional
</code>
2007 <var>display-name
</var>
2009 <span class='result'
>=
> <var>acl-person
</var></span>
2012 <blockquote class='description'
>
2013 <p>Returns an acl-person object for use as a resource owner (for
2014 <a href='#put-acl'
><tt>PUT-ACL
</tt></a>) or as a grantee
2015 (for
<a href='#grant'
><tt>GRANT
</tt></a>).
<var>id
</var> must be
2016 a string representing the person's Amazon AWS canonical ID; for
2017 information about getting the canonical ID, see
2018 the
<a href=
"http://docs.aws.amazon.com/AmazonS3/latest/dev/S3_ACLs_UsingACLs.html">Managing
2019 Access with ACLS
</a>
2020 in the Amazon S3 developer
2021 documentation. If
<var>display-name
</var> is provided, it is
2022 used only for printing the object in Lisp; it is ignored when
2029 <div class='type'
><a name='me'
>[Function]
</a></div>
2030 <div class='signature'
>
2031 <code class='name'
>me
</code>
2033 <code class='llkw'
>&key
</code>
2034 <var>credentials
</var>
2037 <span class='result'
>=
> <var>acl-person
</var></span>
2040 <blockquote class='description'
>
2041 <p>Returns the acl-person object associated with the current
2044 <p>This data requires a S3 request, but the result is always the
2045 same per credentials and is cached.
2051 <div class='type'
><a name='make-public'
>[Function]
</a></div>
2052 <div class='signature'
>
2053 <code class='name'
>make-public
</code>
2055 <code class='llkw'
>&key
</code>
2058 <var>credentials
</var>
2061 <span class='result'
>=
> <var>response
</var></span>
2064 <blockquote class='description'
>
2065 <p>Makes a resource publicly accessible, i.e. readable by
2066 the
<a href='#*all-users*'
><tt>*ALL-USERS*
</tt></a> group.
2072 <div class='type'
><a name='make-private'
>[Function]
</a></div>
2073 <div class='signature'
>
2074 <code class='name'
>make-private
</code>
2076 <code class='llkw'
>&key
</code>
2079 <var>credentials
</var>
2082 <span class='result'
>=
> <var>response
</var></span>
2085 <blockquote class='description'
>
2086 <p>Removes public access to a resource, i.e. removes all
2088 the
<a href='#*all-users*'
><tt>*ALL-USERS*
</tt></a> group.
2094 <a name='access-logging'
><h3>Access Logging
</h3></a>
2096 <p>S3 offers support for logging information about client
2097 requests. Logfile objects are delivered by a system user in
2098 the
<a href='#*log-delivery*'
><tt>*LOG-DELIVERY*
</tt></a> group to a
2099 bucket of your choosing. For more information about S3 access
2100 logging and the logfile format, see
2101 the
<a href=
"http://docs.aws.amazon.com/AmazonS3/latest/dev/ServerLogs.html">Server
2102 Access Logging
</a> in the Amazon S3
2103 developer documentation.
2106 <div class='type'
><a name='enable-logging-to'
>[Function]
</a></div>
2107 <div class='signature'
>
2108 <code class='name'
>enable-logging-to
</code>
2111 <code class='llkw'
>&key
</code>
2112 <var>credentials
</var>
2115 <span class='result'
>=
> <var>response
</var></span>
2118 <blockquote class='description'
>
2119 Adds the necessary permission grants to
<var>bucket
</var> to allow
2120 S3 to write logfile objects into it.
2126 <div class='type'
><a name='disable-logging-to'
>[Function]
</a></div>
2127 <div class='signature'
>
2128 <code class='name'
>disable-logging-to
</code>
2131 <code class='llkw'
>&key
</code>
2132 <var>credentials
</var>
2135 <span class='result'
>=
> <var>response
</var></span>
2138 <blockquote class='description'
>
2139 <p>Changes the access control list of
<var>bucket
</var> to remove
2141 the
<a href='#*log-delivery*'
><tt>*LOG-DELIVERY*
</tt></a> group.
2147 <div class='type'
><a name='enable-logging'
>[Function]
</a></div>
2148 <div class='signature'
>
2149 <code class='name'
>enable-logging
</code>
2152 <var>target-bucket
</var>
2153 <var>target-prefix
</var>
2154 <code class='llkw'
>&key
</code>
2155 <var>target-grants
</var>
2156 <var>credentials
</var>
2159 <span class='result'
>=
> <var>response
</var></span>
2162 <blockquote class='description'
>
2163 <p>Enables logging of all requests
2164 involving
<var>bucket
</var>. Logfile objects are created in
2165 <var>target-bucket
</var> and each logfile's key starts with
2166 <var>target-prefix
</var>.
2168 <p>When a new logfile is
2169 created, its list of access control grants is extended with
2170 <var>target-grants
</var>, if any.
2172 <p>If
<var>target-bucket
</var> does not have the necessary grants
2173 to allow logging, the grants are implicitly added by
2174 calling
<a href='#enable-logging-to'
><tt>ENABLE-LOGGING-TO
</tt></a>.
2180 <div class='type'
><a name='disable-logging'
>[Function]
</a></div>
2181 <div class='signature'
>
2182 <code class='name'
>disable-logging
</code>
2184 <var>bucket
</var> <code class='llkw'
>&key
</code>
2185 <var>credentials
</var>
2188 <span class='result'
>=
> <var>response
</var></span>
2191 <blockquote class='description'
>
2192 Disables logging for
<var>bucket
</var>.
2198 <div class='type'
><a name='logging-setup'
>[Function]
</a></div>
2199 <div class='signature'
>
2200 <code class='name'
>logging-setup
</code>
2203 <code class='llkw'
>&key
</code>
2204 <var>credentials
</var>
2207 <span class='result'
>=
> <var>target-bucket
</var>,
2208 <var>target-prefix
</var>,
2209 <var>target-grants
</var></span>
2212 <blockquote class='description'
>
2213 <p>If logging is enabled for
<var>bucket
</var>, returns the target
2214 bucket, target prefix, and target grants as multiple values.
2218 <a name='tagging'
><h3>Object Tagging
</h3></a>
2220 <p>In S3, a set of tags can be associated with each key and
2221 bucket. Tagging offers a way to categorize objects that is
2222 orthogonal to key prefixes. They resemble object metadata but,
2223 unlike metadata, tagging be used in access control, lifecycle
2224 rules, and metrics. For more information, please refer to
2225 the
<a href=
"http://docs.aws.amazon.com/AmazonS3/latest/dev/object-tagging.html">Object
2226 Tagging
</a> section on the S3 Developer Guide.
2229 <div class='type'
><a name='get-tagging'
>[Function]
</a></div>
2230 <div class='signature'
>
2231 <code class='name'
>get-tagging
</code>
2233 <code class='llkw'
>&key
</code>
2236 <var>credentials
</var>
2239 <span class='result'
>=
> <var>tag-set
</var></span>
2242 <blockquote class='description'
>
2243 <p>Returns the object's current tag set as an
2250 <div class='type'
><a name='put-tagging'
>[Function]
</a></div>
2251 <div class='signature'
>
2252 <code class='name'
>put-tagging
</code>
2255 <code class='llkw'
>&key
</code>
2258 <var>credentials
</var>
2261 <span class='result'
>=
> <var>response
</var></span>
2264 <blockquote class='description'
>
2265 <p>Sets the object's tagging resource to the given set of tags.
2266 The tags are given as an alist.
2272 <div class='type'
><a name='delete-tagging'
>[Function]
</a></div>
2273 <div class='signature'
>
2274 <code class='name'
>delete-tagging
</code>
2276 <code class='llkw'
>&key
</code>
2279 <var>credentials
</var>
2282 <span class='result'
>=
> <var>response
</var></span>
2285 <blockquote class='description'
>
2286 <p>Deletes the tagging resource associated with the object.
2291 <a name='misc'
><h3>Miscellaneous Operations
</h3></a>
2296 <div class='type'
><a name='*use-ssl*'
>[Special variable]
</a></div>
2297 <div class='signature'
>
2298 <code class='name'
>*use-ssl*
</code>
2301 <blockquote class='description'
>
2302 <p>When
<i>true
</i>, requests to S3 are sent via HTTPS. The
2308 <div class='type'
><a name='*use-keep-alive*'
>[Special variable]
</a></div>
2309 <div class='signature'
>
2310 <code class='name'
>*use-keep-alive*
</code>
2313 <blockquote class='description'
>
2314 <p>When
<i>true
</i>, HTTP keep-alives are used to reuse a single
2315 network connection for multiple requests.
</p>
2320 <div class='type'
><a name='with-keep-alive'
>[Macro]
</a></div>
2321 <div class='signature'
>
2322 <code class='name'
>with-keep-alive
</code>
2324 <code class='llkw'
>&body
</code> <var>body
</var>
2326 <span class='result'
>=
> |
</span>
2329 <blockquote class='description'
>
2330 <p>Evaluate
<var>body
</var> in a context
2331 where
<a href='#*use-keep-alive*'
><tt>*USE-KEEP-ALIVE*
</tt></a>
2339 <div class='type'
><a name='make-post-policy'
>[Function]
</a></div>
2340 <div class='signature'
>
2341 <code class='name'
>make-post-policy
</code>
2343 <code class='llkw'
>&key
</code>
2345 <var>conditions
</var>
2346 <var>credentials
</var>
2348 <span class='result'
>=
> <var>policy
</var>,
<var>signature
</var></span>
2351 <blockquote class='description'
>
2352 <p>Returns an encoded HTML POST form policy and its signature as
2353 multiple values. The policy can be used to conditionally allow any
2354 user to put objects into S3.
2356 <p><var>expires
</var> must be a universal time after which
2357 the policy is no longer accepted.
2359 <p><var>conditions
</var> must be a list of conditions that the
2360 posted form fields must satisfy. Each condition is a list of a
2361 condition keyword, a form field name, and the form field
2362 value. For example, the following are all valid conditions:
2366 <li> <code>(:starts-with
"key" "uploads/")
</code>
2367 <li> <code>(:eq
"bucket" "user-uploads")
</code>
2368 <li> <code>(:eq
"acl" "public-read")
</code>
2369 <li> <code>(:range
"content-length-range" 1 10000)
</code>
2372 <p>These conditions are converted into a post policy description,
2373 base64-encoded, and returned as
<var>policy
</var>. The signature
2374 is returned as
<var>signature
</var>. These values can then be
2375 embedded in an HTML form and used to allow direct browser uploads.
2377 <p>For example, if
<var>policy
</var> is
2378 "YSBwYXRlbnRseSBmYWtlIHBvbGljeQ==" and the policy signature is
2379 "ZmFrZSBzaWduYXR1cmU=", you could construct a form like this:
2382 <form
action=
"http://user-uploads.s3.amazonaws.com/" method=
"post" enctype=
"multipart/form-data"><br>
2383 <input
type=
"input" name=
"key" value=
"uploads/fun.jpg"><br>
2384 <input type=hidden
name=
"acl" value=
"public-read"><br>
2385 <input type=hidden
name=
"AWSAccessKeyId" value=
"8675309JGT9876430310"><br>
2386 <input type=hidden
name=
"Policy" value=
"YSBwYXRlbnRseSBmYWtlIHBvbGljeQ=="><br>
2387 <input type=hidden name='Signature'
value=
"ZmFrZSBzaWduYXR1cmU="><br>
2388 <input name='file' type='file'
><br>
2389 <input type=submit value='Submit'
><br>
2392 <p>For full, detailed documentation of browser-based POST uploads
2393 and policy documents,
2394 see
<a href=
"http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingHTTPPOST.html">Browser-Based
2395 Uploads Using POST
</a> in the Amazon S3 developer documentation.
2401 <div class='type'
><a name='head'
>[Function]
</a></div>
2402 <div class='signature'
>
2403 <code class='name'
>head
</code>
2405 <code class='llkw'
>&key
</code>
2408 <var>parameters
</var>
2409 <var>credentials
</var>
2412 <span class='result'
>=
> <var>headers-alist
</var>,
2413 <var>status-code
</var>,
2414 <var>phrase
</var></span>
2417 <blockquote class='description'
>
2418 <p>Submits a HTTP HEAD request for the resource identified by
2419 <var>bucket
</var> and optionally
<var>key
</var>. Returns the
2420 <a href='http://weitz.de/drakma/'
>Drakma
</a> headers, HTTP
2421 status code, and HTTP phrase as multiple values.
2423 <p>When
<var>parameters
</var> is supplied, it should be an alist
2424 of keys and values to pass as GET request parameters. For
2428 *
<b>(head :bucket
"zs3-demo" :parameters (
<a href='http://cliki.net/parameters-alist?download'
>parameters-alist
</a> :max-keys
0))
</b>
2429 =
> ((:X-AMZ-ID-
2 .
"...")
2430 (:X-AMZ-REQUEST-ID .
"...")
2431 (:DATE .
"Sat, 27 Sep 2008 19:00:35 GMT")
2432 (:CONTENT-TYPE .
"application/xml")
2433 (:TRANSFER-ENCODING .
"chunked")
2434 (:SERVER .
"AmazonS3")
2435 (:CONNECTION .
"close")),
2443 <div class='type'
><a name='authorized-url'
>[Function]
</a></div>
2444 <div class='signature'
>
2445 <code class='name'
>authorized-url
</code>
2447 <code class='llkw'
>&key
</code>
2453 <var>sub-resource
</var>
2454 <var>credentials
</var>
2456 <span class='result'
>=
> <var>url
</var></span>
2459 <blockquote class='description'
>
2460 <p>Creates an URL that allows temporary access to a resource regardless
2463 <p>If neither
<var>bucket
</var> nor
<var>key
</var> is specified, the top-level bucket listing
2464 is accessible. If
<var>key
</var> is not specified, listing the keys of
<var>bucket
</var> is
2465 accessible. If both
<var>bucket
</var> and key are
<var>specified
</var>, the object specified
2466 by
<var>bucket
</var> and
<var>key
</var> is accessible.
2468 <p><var>expires
</var> is required, and should be the integer
2469 universal time after which the URL is no longer valid.
2471 <p><var>vhost
</var> controls the construction of the
2472 url. If
<var>vhost
</var> is nil, the constructed URL refers to the
2473 bucket, if present, as part of the path. If
<var>vhost
</var>
2474 is
<code class='kw'
>:AMAZON
</code>, the bucket name is used as a
2475 prefix to the Amazon hostname. If
<var>vhost
</var>
2476 is
<code class='kw'
>:FULL
</code>, the bucket name becomes the full
2477 hostname of the url. For example:
2480 *
<b>(authorized-url :bucket
"foo" :key
"bar" :vhost nil)
</b>
2481 =
> "http://s3.amazonaws.com/foo/bar?..."
2483 *
<b>(authorized-url :bucket
"foo" :key
"bar" :vhost :amazon)
</b>
2484 =
> "http://foo.s3.amazonaws.com/bar?..."
2486 *
<b>(authorized-url :bucket
"foo.example.com" :key
"bar" :vhost :full)
</b>
2487 =
> "http://foo.example.com/bar?..."
2490 <p>If
<i>ssl
</i> is
<i>true
</i>, the URL has
"https" as the scheme,
2491 otherwise it has
"http".
2493 <p>If
<i>sub-resource
</i> is specified, it is used as part of the
2494 query string to access a specific sub-resource. Example Amazon
2495 sub-resources include
"acl" for access to the ACL,
"location" for
2496 location information, and
"logging" for logging information. For
2497 more information about the various sub-resources, see the Amazon
2498 S3 developer documentation.
2504 <div class='type'
><a name='resource-url'
>[Function]
</a></div>
2505 <div class='signature'
>
2506 <code class='name'
>resource-url
</code>
2508 <code class='llkw'
>&key
</code>
2513 <var>sub-resource
</var>
2515 <span class='result'
>=
> <var>url
</var></span>
2518 <blockquote class='description'
>
2519 <p>Returns an URL that can be used to reference a resource. See
2520 <a href='#authorized-url'
><tt>AUTHORIZED-URL
</tt></a> for more
2526 <a name='utility'
><h3>Utility Functions
</h3></a>
2531 <div class='type'
><a name='octet-vector'
>[Function]
</a></div>
2532 <div class='signature'
>
2533 <code class='name'
>octet-vector
</code>
2535 <code class='llkw'
>&rest
</code>
2538 <span class='result'
>=
> <var>octet-vector
</var></span>
2541 <blockquote class='description'
>
2542 <p>Returns a vector of type
2543 <code>(simple-array
(unsigned-byte
8)
(*))
</code> initialized with
<var>octets
</var>.
2549 <div class='type'
><a name='now+'
>[Function]
</a></div>
2550 <div class='signature'
>
2551 <code class='name'
>now+
</code>
2555 <span class='result'
>=
> <var>universal-time
</var></span>
2558 <blockquote class='description'
>
2559 <p>Returns a universal time that represents the current time
2560 incremented by
<var>delta
</var> seconds. It's useful for passing
2561 as the
<code class='kw'
>:EXPIRES
</code> parameter to functions
2562 like
<a href='#put-object'
><tt>PUT-OBJECT
</tt></a>
2563 and
<a href='#authorized-url'
><tt>AUTHORIZED-URL
</tt></a>.
2569 <div class='type'
><a name='now-'
>[Function]
</a></div>
2570 <div class='signature'
>
2571 <code class='name'
>now-
</code>
2575 <span class='result'
>=
> <var>universal-time
</var></span>
2578 <blockquote class='description'
>
2579 <p>Like
<a href='#now+'
><tt>NOW+
</tt></a>, but decrements the
2580 current time instead of incrementing it.
2586 <div class='type'
><a name='file-etag'
>[Function]
</a></div>
2587 <div class='signature'
>
2588 <code class='name'
>file-etag
</code>
2592 <span class='result'
>=
> <var>etag
</var></span>
2595 <blockquote class='description'
>
2596 <p>Returns the etag of
<var>pathname
</var>. This can be useful for the
2597 conditional arguments
2598 <code class='kw'
>:WHEN-ETAG-MATCHES
</code> and
2599 <code class='kw'
>:UNLESS-ETAG-MATCHES
</code>
2600 in
<a href='#get-object'
><tt>GET-OBJECT
</tt></a>
2601 and
<a href='#copy-object'
><tt>COPY-OBJECT
</tt></a>.
2607 <div class='type'
><a name='parameters-alist'
>[Function]
</a></div>
2608 <div class='signature'
>
2609 <code class='name'
>parameters-alist
</code>
2611 <code class='llkw'
>&rest
</code>
2612 <var>parameters
</var>
2613 <code class='llkw'
>&key
</code>
2614 <code class='llkw'
>&allow-other-keys
</code>
2616 <span class='result'
>=
> <var>alist
</var></span>
2619 <blockquote class='description'
>
2620 <p>Returns an alist based on all keyword arguments passed to the
2621 function. Keywords are converted to their lowercase symbol name and
2622 values are converted to strings. For example:
2625 *
<b>(parameters-alist :name
"Bob" :age
21)
</b>
2626 =
> ((
"name" .
"Bob") (
"age" .
"21"))
2629 <p>This can be used to construct Amazon metadata alists
2630 for
<a href='#put-object'
><tt>PUT-OBJECT
</tt></a>
2631 and
<a href='#copy-object'
><tt>COPY-OBJECT
</tt></a>, or request
2632 parameters in
<a href='#head'
><tt>HEAD
</tt></a>.
2640 <div class='type'
><a name='clear-redirects'
>[Function]
</a></div>
2641 <div class='signature'
>
2642 <code class='name'
>clear-redirects
</code>
2645 <span class='result'
>=
> |
</span>
2648 <blockquote class='description'
>
2649 <p>Clear ZS3's internal cache of redirections.
2651 <p>Most ZS3 requests are submitted against the Amazon S3 endpoint
2652 "s3.amazonaws.com". Some requests, however, are permanently
2653 redirected by S3 to new endpoints. ZS3 maintains an internal cache
2654 of permanent redirects, but it's possible for that cache to get
2655 out of sync if external processes alter the bucket structure
2657 <p>For example, if the bucket
"eu.zs3" is created with a EU
2658 location constraint, S3 will respond to requests to that bucket
2659 with a permanent redirect to
"eu.zs3.s3.amazonaws.com", and ZS3
2660 will cache that redirect information. But if the bucket is
2661 deleted and recreated by a third party, the redirect might no
2662 longer be necessary.
2667 <a name='cloudfront'
><h2>CloudFront
</h2>
2669 <p>CloudFront functions allow the creation and manipulation of
2670 distributions. In ZS3, distributions are represented by objects that
2671 reflect the state of a distributon at some point in time. It's
2672 possible for the distribution to change behind the scenes without
2673 notice, e.g. when a distribution's
<a href='#status'
>status
</a> is
2674 updated from
"InProgress" to
"Deployed".
2677 functions
<a href='#enable'
><tt>ENABLE
</tt></a>,
<a href='#disable'
><tt>DISABLE
</tt></a>,
<a href='#ensure-cname'
><tt>ENSURE-CNAME
</tt></a>,
2678 <a href='#remove-cname'
><tt>REMOVE-CNAME
</tt></a>,
2679 and
<a href='#set-comment'
><tt>SET-COMMENT
</tt></a> are designed so
2680 that regardless of the state of the distribution provided, after the
2681 function completes, the new state of the distribution will reflect
2682 the desired update. The
2683 functions
<a href='#status'
><tt>STATUS
</tt></a>,
<a href='#cnames'
><tt>CNAMES
</tt></a>,
2685 <a href='#enabledp'
><tt>ENABLEDP
</tt></a> do not automatically
2686 refresh the object and therefore might reflect outdated
2687 information. To ensure the object has the most recent information,
2688 use
<a href='#refresh'
><tt>REFRESH
</tt></a>. For example, to fetch
2689 the current, live status, use
<tt>(status (refresh
2690 distribution))
</tt>.
2695 <div class='type'
><a name='all-distributions'
>[Function]
</a></div>
2696 <div class='signature'
>
2697 <code class='name'
>all-distributions
</code>
2700 <span class='result'
>=
> |
</span>
2703 <blockquote class='description'
>
2704 <p>Returns a list of all distributions.
2709 <div class='type'
><a name='create-distribution'
>[Function]
</a></div>
2710 <div class='signature'
>
2711 <code class='name'
>create-distribution
</code>
2713 <var>bucket-name
</var>
2714 <code class='llkw'
>&key
</code>
2719 <span class='result'
>=
> <var>distribution
</var></span>
2722 <blockquote class='description'
>
2723 Creates and returns a new distribution object that will cache
2724 objects from the bucket named
2725 by
<var>bucket-name
</var>.
2727 <p>If
<var>cnames
</var> is provided, it is taken as a designator
2728 for a list of additional domain names that can be used to access
2731 <p>If
<var>enabled
</var> is NIL, the distribution is initially
2732 created in a disabled state. The default value is is T.
2734 <p>If
<var>comment
</var> is provided, it becomes part of the newly
2735 created distribution.
2740 <div class='type'
><a name='delete-distribution'
>[Function]
</a></div>
2741 <div class='signature'
>
2742 <code class='name'
>delete-distribution
</code>
2744 <var>distribution
</var>
2746 <span class='result'
>=
> |
</span>
2749 <blockquote class='description'
>
2750 <p>Deletes
<var>distribution
</var>. Distributions must be disabled
2751 before deletion; see
<a href='#disable'
><tt>DISABLE
</tt></a>.
2757 <div class='type'
><a name='refresh'
>[Function]
</a></div>
2758 <div class='signature'
>
2759 <code class='name'
>refresh
</code>
2761 <var>distribution
</var>
2763 <span class='result'
>=
> <var>distribution
</var></span>
2766 <blockquote class='description'
>
2767 <p>Queries Amazon for the latest information
2768 regarding
<var>distribution
</var> and destructively modifies the
2769 instance with the new information. Returns its argument.
2775 <div class='type'
><a name='enable'
>[Function]
</a></div>
2776 <div class='signature'
>
2777 <code class='name'
>enable
</code>
2779 <var>distribution
</var>
2781 <span class='result'
>=
> |
</span>
2784 <blockquote class='description'
>
2785 <p>Enables
<var>distribution
</var>.
2791 <div class='type'
><a name='disable'
>[Function]
</a></div>
2792 <div class='signature'
>
2793 <code class='name'
>disable
</code>
2795 <var>distribution
</var>
2797 <span class='result'
>=
> |
</span>
2800 <blockquote class='description'
>
2801 <p>Disables
<var>distribution
</var>.
2807 <div class='type'
><a name='ensure-cname'
>[Function]
</a></div>
2808 <div class='signature'
>
2809 <code class='name'
>ensure-cname
</code>
2811 <var>distribution
</var>
2814 <span class='result'
>=
> |
</span>
2817 <blockquote class='description'
>
2818 <p>Adds
<var>cname
</var> to the CNAMEs of
<var>distribution
</var>,
2824 <div class='type'
><a name='remove-cname'
>[Function]
</a></div>
2825 <div class='signature'
>
2826 <code class='name'
>remove-cname
</code>
2828 <var>distribution
</var>
2831 <span class='result'
>=
> |
</span>
2834 <blockquote class='description'
>
2835 <p>Removes
<var>cname
</var> from the CNAMEs of
<var>distribution
</var>.
2841 <div class='type'
><a name='set-comment'
>[Function]
</a></div>
2842 <div class='signature'
>
2843 <code class='name'
>set-comment
</code>
2845 <var>distribution
</var>
2848 <span class='result'
>=
> |
</span>
2851 <blockquote class='description'
>
2852 <p>Sets the comment of
<var>distribution
</var> to
<var>comment
</var>.
2858 <div class='type'
><a name='distributions-for-bucket'
>[Function]
</a></div>
2859 <div class='signature'
>
2860 <code class='name'
>distributions-for-bucket
</code>
2862 <var>bucket-name
</var>
2864 <span class='result'
>=
> |
</span>
2867 <blockquote class='description'
>
2868 <p>Returns a list of distributions that
2869 have
<var>bucket-name
</var> as the origin bucket.
2875 <div class='type'
><a name='distribution-error'
>[Condition]
</a></div>
2876 <div class='signature'
>
2877 <code class='name'
>distribution-error
</code>
2880 <blockquote class='description'
>
2881 <p>All errors signaled as a result of a CloudFront request error
2882 are subtypes of
<tt>distribution-error
</tt>.
2888 <div class='type'
><a name='distribution-not-disabled'
>[Condition]
</a></div>
2889 <div class='signature'
>
2890 <code class='name'
>distribution-not-disabled
</code>
2893 <blockquote class='description'
>
2894 <p>Distributions must be fully disabled before they are
2895 deleted. If they have not been disabled, or the status of the
2896 distribution is still
2897 "InProgress",
<tt>distribution-not-disabled
</tt> is signaled.
2903 <div class='type'
><a name='cname-already-exists'
>[Condition]
</a></div>
2904 <div class='signature'
>
2905 <code class='name'
>cname-already-exists
</code>
2908 <blockquote class='description'
>
2909 <p>A CNAME may only appear on one distribution. If you attempt to
2910 add a CNAME to a distribution that is already present on some
2911 other distribution,
<tt>cname-already-exists
</tt> is signaled.
2917 <div class='type'
><a name='too-many-distributions'
>[Condition]
</a></div>
2918 <div class='signature'
>
2919 <code class='name'
>too-many-distributions
</code>
2922 <blockquote class='description'
>
2923 <p>If creating a new distribution
2924 via
<a href='#create-distribution'
><tt>CREATE-DISTRIBUTION
</tt></a>
2925 would exceed the account limit of total distributions,
2926 <tt>too-many-distributions
</tt> is signaled.
2932 <div class='type'
><a name='status'
>[Function]
</a></div>
2933 <div class='signature'
>
2934 <code class='name'
>status
</code>
2936 <var>distribution
</var>
2938 <span class='result'
>=
> <var>status
</var></span>
2941 <blockquote class='description'
>
2942 <p>Returns a string describing the status
2943 of
<var>distribution
</var>. The status is either
"InProgress",
2944 meaning that the distribution's configuration has not fully
2945 propagated through the CloudFront system, or
"Deployed".
2951 <div class='type'
><a name='origin-bucket'
>[Function]
</a></div>
2952 <div class='signature'
>
2953 <code class='name'
>origin-bucket
</code>
2955 <var>distribution
</var>
2957 <span class='result'
>=
> <var>origin-bucket
</var></span>
2960 <blockquote class='description'
>
2961 <p>Returns the origin bucket for
<var>distribution
</var>. It is
2962 different from a normal ZS3 bucket name, because it has
2963 ".s3.amazonaws.com" as a suffix.
2969 <div class='type'
><a name='domain-name'
>[Function]
</a></div>
2970 <div class='signature'
>
2971 <code class='name'
>domain-name
</code>
2973 <var>distribution
</var>
2975 <span class='result'
>=
> <var>domain-name
</var></span>
2978 <blockquote class='description'
>
2979 <p>Returns the domain name through which CloudFront-enabled access
2980 to a resource may be made.
2986 <div class='type'
><a name='cnames'
>[Function]
</a></div>
2987 <div class='signature'
>
2988 <code class='name'
>cnames
</code>
2990 <var>distribution
</var>
2992 <span class='result'
>=
> <var>cnames
</var></span>
2995 <blockquote class='description'
>
2996 Returns a list of CNAMEs associated with
<var>distribution
</var>.
3002 <div class='type'
><a name='enabledp'
>[Function]
</a></div>
3003 <div class='signature'
>
3004 <code class='name'
>enabledp
</code>
3006 <var>distribution
</var>
3008 <span class='result'
>=
> <var>boolean
</var></span>
3011 <blockquote class='description'
>
3012 <p>Returns
<i>true
</i> if
<var>distribution
</var> is enabled, NIL
3019 <div class='type'
><a name='invalidate-paths'
>[Function]
</a></div>
3020 <div class='signature'
>
3021 <code class='name'
>invalidate-paths
</code>
3023 <var>distribution
</var>
3026 <span class='result'
>=
> <var>invalidation
</var></span>
3029 <blockquote class='description'
>
3030 <p>Initiates the invalidation of resources identified
3031 by
<var>paths
</var> in
<var>distribution
</var>.
<var>paths
</var>
3032 should consist of key names that correspond to objects in the
3033 distribution's S3 bucket.
3035 <p>The
<var>invalidation
</var> object reports on the status of the
3036 invalidation request. It can be queried
3037 with
<a href='#status'
><tt>STATUS
</tt></a> and refreshed
3038 with
<a href='#refresh'
><tt>REFRESH
</tt></a>.
3041 *
<b>(invalidate-paths distribution '(
"/css/site.css" "/js/site.js"))
</b>
3042 #
<INVALIDATION
"I1HJC711OFAVKO" [InProgress]
>
3043 *
<b>(progn (sleep
300) (refresh *))
</b>
3044 #
<INVALIDATION
"I1HJC711OFAVKO" [Completed]
>
3052 <a name='references'
><h2>References
</h2></a>
3055 <li> Amazon,
<a href=
"http://aws.amazon.com/documentation/s3/">Amazon
3056 S3 Technical Documentation
</a>
3057 <li> Amazon,
<a href=
"http://aws.amazon.com/documentation/cloudfront/">Amazon CloudFront Technical Documentation
</a>
3063 <a name='acknowledgements'
><h2>Acknowledgements
</h2>
3065 <p>Several people on
<a href='http://freenode.net/'
>freenode
</a>
3066 #lisp pointed out typos and glitches in this
3067 documentation. Special thanks to Bart
"_3b" Botta for providing a
3068 detailed documentation review that pointed out glitches,
3069 omissions, and overly confusing passages.
3071 <p>James Wright corrected a problem with computing the string to
3072 sign and URL encoding.
3074 <a name='feedback'
><h2>Feedback
</h2></a>
3076 <p>If you have any questions or comments about ZS3, please email
3077 me,
<a href='mailto:xach@xach.com'
>Zach Beane
</a>
3079 <p>For ZS3 announcements and development discussion, please see the
3080 <a href=
"http://groups.google.com/group/zs3-devel">zs3-devel
</a>
3083 <p><i>2016-
06-
17</i>
3085 <p class='copyright'
>Copyright
© 2008-
2016 Zachary Beane, All Rights Reserved