diff --git a/bucket-listing.lisp b/bucket-listing.lisp
index 3a5adbb..d727b33 100644
--- a/bucket-listing.lisp
+++ b/bucket-listing.lisp
@@ -141,7 +141,8 @@
(defun key-binding-key (binding)
(alist-bind (key
last-modified etag size
- owner-id owner-display-name)
+ owner-id owner-display-name
+ storage-class)
binding
(make-instance 'key
:name key
@@ -151,7 +152,8 @@
:owner (when owner-id
(make-instance 'person
:id owner-id
- :display-name owner-display-name)))))
+ :display-name owner-display-name))
+ :storage-class storage-class)))
(defmethod specialized-initialize ((response bucket-listing) source)
(let* ((bindings (xml-bind *list-bucket-binder* source))
diff --git a/doc/index.html b/doc/index.html
index 39a8d47..1f7a81e 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -438,7 +438,8 @@
Contents
SIZE,
ETAG,
LAST-MODIFIED,
- and OWNER.
+ OWNER, and
+ STORAGE-CLASS.
This function is built
on QUERY-BUCKET and may
@@ -875,6 +876,23 @@
Contents
+
+
+
+ storage-class
+
+ key-object
+
+ => storage-class
+
+
+
+ Returns the storage class of key-object.
+
+
+
+
+
Operations on Objects
@@ -1057,6 +1075,7 @@ Contents
content-disposition
content-type
expires
+ storage-class
credentials
=> |
@@ -1113,7 +1132,14 @@ Contents
GET or HEAD requests. If content-type is not set, it
defaults to "binary/octet-stream". The others default to
NIL. If expires is provided, it should be a universal time.
-
+
+ If provided, storage-class should refer to one of
+ the standard storage classes available for S3; currently the
+ accepted values are the strings "STANDARD" and
+ "REDUCED_REDUNDANCY". Using other values may trigger an API error
+ from S3. For more information about reduced redundancy storage,
+ see Reduced
+ Redundancy Storage in the Developer Guide.
@@ -1131,6 +1157,7 @@
Contents
content-encoding
content-type
expires
+
storage-class
credentials
=> |
@@ -1166,6 +1193,7 @@
Contents
content-encoding
content-type
expires
+
storage-class
credentials
=> |
@@ -1198,6 +1226,7 @@
Contents
public metadata
content-disposition content-encoding content-type
expires
+
storage-class
credentials
=> |
@@ -1238,6 +1267,7 @@
Contents
public metadata
content-disposition content-encoding content-type
expires
+
storage-class
credentials
=> |
@@ -1285,6 +1315,7 @@
Contents
when-modified-since
unless-modified-since
metadata public precondition-errors
+
storage-class
credentials
=> |
@@ -1315,6 +1346,14 @@
Contents
with
PUT-OBJECT. Passing NIL
means that the new object has no metadata. Otherwise, the metadata
is copied from the original object.
+
+
If storage-class is provided, it should refer to one
+ of the standard storage classes available for S3; currently the
+ accepted values are the strings "STANDARD" and
+ "REDUCED_REDUNDANCY". Using other values may trigger an API error
+ from S3. For more information about reduced redundancy storage,
+ see Reduced
+ Redundancy Storage in the Developer Guide.
@@ -1410,6 +1449,36 @@ Contents
+
+
+
+ set-storage-class
+
+ bucket
+ key
+ storage-class
+ &key
+ credentials
+
+ => |
+
+
+
+ Sets the storage class of the object identified
+ by bucket and key
+ to storage-class. This is a convenience function that
+ uses COPY-OBJECT to make
+ storage class changes.
+
+
The storage class of an object can be determined by querying
+ the bucket with ALL-KEYS
+ or QUERY-BUCKET and
+ using STORAGE-CLASS on one
+ of the resulting key objects.
+
+
+
+
Access Control
diff --git a/interface.lisp b/interface.lisp
index 9fbf40b..d03b232 100644
--- a/interface.lisp
+++ b/interface.lisp
@@ -322,6 +322,7 @@ constraint."
content-disposition
expires
content-type
+ (storage-class "STANDARD")
((:credentials *credentials*) *credentials*))
(let ((content
(etypecase object
@@ -332,12 +333,16 @@ constraint."
((or vector pathname) object)))
(content-length t)
(policy-header (access-policy-header access-policy public)))
+ (setf storage-class (or storage-class "STANDARD"))
(submit-request (make-instance 'request
:method :put
:bucket bucket
:key key
:metadata metadata
- :amz-headers policy-header
+ :amz-headers
+ (append policy-header
+ (list (cons "storage-class"
+ storage-class)))
:extra-http-headers
(parameters-alist
:cache-control cache-control
@@ -360,6 +365,7 @@ constraint."
content-disposition
(content-type "binary/octet-stream")
expires
+ storage-class
((:credentials *credentials*) *credentials*))
(when (or start end)
(setf vector (subseq vector (or start 0) end)))
@@ -371,7 +377,8 @@ constraint."
:content-encoding content-encoding
:content-disposition content-disposition
:content-type content-type
- :expires expires))
+ :expires expires
+ :storage-class storage-class))
(defun put-string (string bucket key &key
start end
@@ -384,6 +391,7 @@ constraint."
content-disposition
(content-type "text/plain")
expires
+ storage-class
((:credentials *credentials*) *credentials*))
(when (or start end)
(setf string (subseq string (or start 0) end)))
@@ -396,7 +404,8 @@ constraint."
:content-encoding content-encoding
:content-type content-type
:cache-control cache-control
- :string-external-format external-format))
+ :string-external-format external-format
+ :storage-class storage-class))
(defun put-file (file bucket key &key
@@ -409,6 +418,7 @@ constraint."
content-encoding
(content-type "binary/octet-stream")
expires
+ storage-class
((:credentials *credentials*) *credentials*))
(when (eq key t)
(setf key (file-namestring file)))
@@ -424,7 +434,8 @@ constraint."
:content-disposition content-disposition
:content-encoding content-encoding
:content-type content-type
- :expires expires)))
+ :expires expires
+ :storage-class storage-class)))
(defun put-stream (stream bucket key &key
(start 0) end
@@ -436,6 +447,7 @@ constraint."
content-encoding
(content-type "binary/octet-stream")
expires
+ storage-class
((:credentials *credentials*) *credentials*))
(let ((content (stream-subset-vector stream start end)))
(put-object content bucket key
@@ -446,7 +458,8 @@ constraint."
:content-disposition content-disposition
:content-encoding content-encoding
:content-type content-type
- :expires expires)))
+ :expires expires
+ :storage-class storage-class)))
;;; Delete & copy objects
@@ -526,6 +539,7 @@ constraint."
access-policy
public
precondition-errors
+ (storage-class "STANDARD")
((:credentials *credentials*) *credentials*))
"Copy the object identified by FROM-BUCKET/FROM-KEY to
TO-BUCKET/TO-KEY.
@@ -551,8 +565,6 @@ users. Otherwise, a default ACL is present on the new object.
(error "FROM-BUCKET is required"))
(unless from-key
(error "FROM-KEY is required"))
- (unless (or to-bucket to-key)
- (error "Can't copy an object to itself."))
(setf to-bucket (or to-bucket from-bucket))
(setf to-key (or to-key from-key))
(handler-bind ((precondition-failed
@@ -564,6 +576,7 @@ users. Otherwise, a default ACL is present on the new object.
(parameters-alist :copy-source (format nil "~A/~A"
(url-encode (name from-bucket))
(url-encode (name from-key)))
+ :storage-class storage-class
:metadata-directive
(if metadata-supplied-p "REPLACE" "COPY")
:copy-source-if-match when-etag-matches
@@ -601,6 +614,16 @@ users. Otherwise, a default ACL is present on the new object.
collect (cons meta value))))))
+;;; Convenience bit for storage class
+
+(defun set-storage-class (bucket key storage-class &key
+ ((:credentials *credentials*) *credentials*))
+ "Set the storage class of the object identified by BUCKET and KEY to
+STORAGE-CLASS."
+ (copy-object :from-bucket bucket :from-key key
+ :storage-class storage-class))
+
+
;;; ACL twiddling
(defparameter *public-read-grant*
@@ -655,7 +678,6 @@ users. Otherwise, a default ACL is present on the new object.
(put-acl owner grants :bucket bucket :key key)))
-
;;; Logging
(defparameter *log-delivery-grants*
diff --git a/objects.lisp b/objects.lisp
index b4464c0..4e5504f 100644
--- a/objects.lisp
+++ b/objects.lisp
@@ -71,7 +71,10 @@
:accessor size)
(owner
:initarg :owner
- :accessor owner)))
+ :accessor owner)
+ (storage-class
+ :initarg :storage-class
+ :accessor storage-class)))
(defmethod print-object ((key key) stream)
(print-unreadable-object (key stream :type t)
diff --git a/package.lisp b/package.lisp
index 4a6caa0..f7c4cce 100644
--- a/package.lisp
+++ b/package.lisp
@@ -57,7 +57,8 @@
#:last-modified
#:etag
#:size
- #:owner)
+ #:owner
+ #:storage-class)
;; Objects
(:export #:get-object
#:get-vector
@@ -72,7 +73,8 @@
#:delete-object
#:delete-objects
#:delete-all-objects
- #:object-metadata)
+ #:object-metadata
+ #:set-storage-class)
;; Access Control
(:export #:get-acl
#:put-acl