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

+
+
[Function]
+
+ 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

+
+
[Function]
+
+ 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