Skip to content

Instantly share code, notes, and snippets.

@therabidbanana
Created September 20, 2012 17:03
Show Gist options
  • Save therabidbanana/3757080 to your computer and use it in GitHub Desktop.
Save therabidbanana/3757080 to your computer and use it in GitHub Desktop.
Allows generating signed PUT urls.

Usage:

s3 = AWS::S3.new(...) 
s3.buckets['bucket-name'].objects['object-name.jpg'].url_for(:write, content_type: 'image/jpeg')

Generates a signed request allowing a PUT /bucket-name/object-name.jpg with an image file, so that an HTTP PUT can be used instead of a presigned_post request with HTTP POST and a bunch of hidden fields.

require 'aws'
# Monkey patched
module AWS
class S3
class S3Object
# new version of signature method that sets content type
def hacked_signature(method, expires, request, content_type = "")
parts = []
parts << method
parts << ""
parts << content_type
parts << expires
if config.credential_provider.session_token
parts << "x-amz-security-token:"
parts << "#{config.credential_provider.session_token}"
end
parts << request.canonicalized_resource
string_to_sign = parts.join("\n")
secret = config.credential_provider.secret_access_key
Core::Signer.sign(secret, string_to_sign, 'sha1')
end
def url_for(method, options = {})
req = request_for_signing(options)
method = http_method(method)
content_type = options.delete(:content_type) || ""
expires = expiration_timestamp(options[:expires])
req.add_param("AWSAccessKeyId",
config.credential_provider.access_key_id)
req.add_param("versionId", options[:version_id]) if options[:version_id]
req.add_param("Signature", hacked_signature(method, expires, req, content_type))
req.add_param("Expires", expires)
req.add_param("x-amz-security-token",
config.credential_provider.session_token) if
config.credential_provider.session_token
build_uri(options[:secure] != false, req)
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment