zs3
zs3 copied to clipboard
AUTHORIZED-URL does not allow extra parameters
S3 supports a number of useful parameters, such as response-content-disposition. It would be neat if AUTHORIZED-URL supported these.
The following is a workaround I created in order to provide this functionality. Note that the call to puri-canonicalized-path has been removed. This is because Puri is not able to process a URL with spaces in it (to reproduce that problem, simply specify a content-disposition value with a space in it, such as: attachment; filename=foo.lisp).
(defun zs3-authorized-url (&key bucket key vhost expires ssl sub-resource content-disposition
((:credentials zs3:*credentials*) zs3:*credentials*))
(unless (and expires (integerp expires) (plusp expires))
(error "~S option must be a positive integer" :expires))
(let* ((extra-parameters (append (if content-disposition
(list (cons "response-content-disposition" content-disposition)))))
(request (make-instance 'zs3::url-based-request
:method :get
:bucket bucket
:sub-resource sub-resource
:key key
:expires (zs3::unix-time expires)
:parameters extra-parameters))
(parameters
(zs3::alist-to-url-encoded-string
(list* (cons "AWSAccessKeyId" (zs3:access-key zs3:*credentials*))
(cons "Expires" (format nil "~D" (zs3::expires request)))
(cons "Signature" (zs3::signature request))
extra-parameters))))
(case vhost
(:cname
(format nil "http~@[s~*~]://~A/~@[~A~]?~@[~A&~]~A"
ssl bucket (zs3::url-encode key) sub-resource parameters))
(:amazon
(format nil "http~@[s~*~]://~A.s3.amazonaws.com/~@[~A~]?~@[~A&~]~A"
ssl bucket (zs3::url-encode key) sub-resource parameters))
((nil)
(format nil "http~@[s~*~]://s3.amazonaws.com/~@[~A/~]~@[~A~]?~@[~A&~]~A"
ssl (zs3::url-encode bucket) (zs3::url-encode key) sub-resource
parameters)))))
(defmethod zs3::signed-path ((request zs3::request))
(let ((*print-pretty* nil))
(with-output-to-string (stream)
(write-char #\/ stream)
(when (zs3::bucket request)
(write-string (zs3::url-encode (zs3::name (zs3::bucket request))) stream)
(write-char #\/ stream))
(when (zs3::key request)
(write-string (zs3::url-encode (zs3::name (zs3::key request))) stream))
(when (or (zs3::parameters request) (zs3::sub-resource request))
(write-string "?" stream)
(if (zs3::parameters request)
(loop
for param in (zs3::parameters request)
for first = t then nil
unless first
do (write-string "&" stream)
do (progn
(write-string (zs3::url-encode (car param)) stream)
(write-string "=" stream)
(write-string (cdr param) stream)))
(write-string (zs3::url-encode (zs3::sub-resource request)) stream))))))