zs3 icon indicating copy to clipboard operation
zs3 copied to clipboard

AUTHORIZED-URL does not allow extra parameters

Open lokedhs opened this issue 10 years ago • 0 comments

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))))))

lokedhs avatar Nov 19 '14 04:11 lokedhs