/lib/s3upload.rb

http://github.com/slaskis/s3upload · Ruby · 68 lines · 53 code · 13 blank · 2 comment · 1 complexity · f8ef046bf532cc6d5fba7fe877d72e4c MD5 · raw file

  1. require 'openssl'
  2. require 'digest/sha1'
  3. require "base64"
  4. module S3
  5. class Upload
  6. attr_accessor :bucket, :expires, :secret_key, :access_key_id, :acl
  7. def initialize( access_key_id , secret_key , bucket , acl="public-read" , expires=nil)
  8. @access_key_id = access_key_id
  9. @secret_key = secret_key
  10. @bucket = bucket
  11. @acl = acl
  12. # default to one hour from now
  13. @expires = expires || (Time.now + 3600)
  14. end
  15. def to_xml( key , content_type )
  16. @key = key
  17. @content_type = content_type
  18. props = {
  19. :accessKeyId => access_key_id,
  20. :acl => acl,
  21. :bucket => bucket,
  22. :contentType => @content_type,
  23. :expires => expiration_str,
  24. :key => @key,
  25. :secure => false,
  26. :signature => signature,
  27. :policy => policy
  28. }
  29. # Create xml of the properties
  30. xml = "<s3>"
  31. props.each {|k,v| xml << "<#{k}>#{v}</#{k}>"}
  32. xml << "</s3>"
  33. end
  34. private
  35. def expiration_str
  36. @expires.utc.strftime('%Y-%m-%dT%H:%M:%S.000Z')
  37. end
  38. def policy
  39. @policy ||= Base64.encode64( "{
  40. 'expiration': '#{expiration_str}',
  41. 'conditions': [
  42. {'bucket': '#{bucket}'},
  43. {'key': '#{@key}'},
  44. {'acl': '#{acl}'},
  45. {'Content-Type': '#{@content_type}'},
  46. ['starts-with', '$Filename', ''],
  47. ['eq', '$success_action_status', '201']
  48. ]
  49. }").gsub(/\n|\r/, '')
  50. end
  51. def signature
  52. [OpenSSL::HMAC.digest(OpenSSL::Digest::Digest.new('sha1'), secret_key, policy)].pack("m").strip
  53. end
  54. end
  55. end