aws-sdk-s3 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +7 -0
  2. data/lib/aws-sdk-s3.rb +66 -0
  3. data/lib/aws-sdk-s3/bucket.rb +595 -0
  4. data/lib/aws-sdk-s3/bucket_acl.rb +168 -0
  5. data/lib/aws-sdk-s3/bucket_cors.rb +146 -0
  6. data/lib/aws-sdk-s3/bucket_lifecycle.rb +164 -0
  7. data/lib/aws-sdk-s3/bucket_logging.rb +142 -0
  8. data/lib/aws-sdk-s3/bucket_notification.rb +187 -0
  9. data/lib/aws-sdk-s3/bucket_policy.rb +138 -0
  10. data/lib/aws-sdk-s3/bucket_region_cache.rb +79 -0
  11. data/lib/aws-sdk-s3/bucket_request_payment.rb +128 -0
  12. data/lib/aws-sdk-s3/bucket_tagging.rb +143 -0
  13. data/lib/aws-sdk-s3/bucket_versioning.rb +188 -0
  14. data/lib/aws-sdk-s3/bucket_website.rb +177 -0
  15. data/lib/aws-sdk-s3/client.rb +3171 -0
  16. data/lib/aws-sdk-s3/client_api.rb +1991 -0
  17. data/lib/aws-sdk-s3/customizations.rb +29 -0
  18. data/lib/aws-sdk-s3/customizations/bucket.rb +127 -0
  19. data/lib/aws-sdk-s3/customizations/multipart_upload.rb +42 -0
  20. data/lib/aws-sdk-s3/customizations/object.rb +257 -0
  21. data/lib/aws-sdk-s3/customizations/object_summary.rb +65 -0
  22. data/lib/aws-sdk-s3/customizations/types/list_object_versions_output.rb +11 -0
  23. data/lib/aws-sdk-s3/encryption.rb +19 -0
  24. data/lib/aws-sdk-s3/encryption/client.rb +369 -0
  25. data/lib/aws-sdk-s3/encryption/decrypt_handler.rb +178 -0
  26. data/lib/aws-sdk-s3/encryption/default_cipher_provider.rb +63 -0
  27. data/lib/aws-sdk-s3/encryption/default_key_provider.rb +38 -0
  28. data/lib/aws-sdk-s3/encryption/encrypt_handler.rb +50 -0
  29. data/lib/aws-sdk-s3/encryption/errors.rb +13 -0
  30. data/lib/aws-sdk-s3/encryption/io_auth_decrypter.rb +50 -0
  31. data/lib/aws-sdk-s3/encryption/io_decrypter.rb +29 -0
  32. data/lib/aws-sdk-s3/encryption/io_encrypter.rb +69 -0
  33. data/lib/aws-sdk-s3/encryption/key_provider.rb +29 -0
  34. data/lib/aws-sdk-s3/encryption/kms_cipher_provider.rb +71 -0
  35. data/lib/aws-sdk-s3/encryption/materials.rb +58 -0
  36. data/lib/aws-sdk-s3/encryption/utils.rb +79 -0
  37. data/lib/aws-sdk-s3/errors.rb +23 -0
  38. data/lib/aws-sdk-s3/file_part.rb +75 -0
  39. data/lib/aws-sdk-s3/file_uploader.rb +58 -0
  40. data/lib/aws-sdk-s3/legacy_signer.rb +186 -0
  41. data/lib/aws-sdk-s3/multipart_file_uploader.rb +187 -0
  42. data/lib/aws-sdk-s3/multipart_upload.rb +287 -0
  43. data/lib/aws-sdk-s3/multipart_upload_error.rb +16 -0
  44. data/lib/aws-sdk-s3/multipart_upload_part.rb +314 -0
  45. data/lib/aws-sdk-s3/object.rb +942 -0
  46. data/lib/aws-sdk-s3/object_acl.rb +214 -0
  47. data/lib/aws-sdk-s3/object_copier.rb +99 -0
  48. data/lib/aws-sdk-s3/object_multipart_copier.rb +179 -0
  49. data/lib/aws-sdk-s3/object_summary.rb +794 -0
  50. data/lib/aws-sdk-s3/object_version.rb +406 -0
  51. data/lib/aws-sdk-s3/plugins/accelerate.rb +92 -0
  52. data/lib/aws-sdk-s3/plugins/bucket_dns.rb +89 -0
  53. data/lib/aws-sdk-s3/plugins/bucket_name_restrictions.rb +23 -0
  54. data/lib/aws-sdk-s3/plugins/dualstack.rb +70 -0
  55. data/lib/aws-sdk-s3/plugins/expect_100_continue.rb +29 -0
  56. data/lib/aws-sdk-s3/plugins/get_bucket_location_fix.rb +23 -0
  57. data/lib/aws-sdk-s3/plugins/http_200_errors.rb +47 -0
  58. data/lib/aws-sdk-s3/plugins/location_constraint.rb +33 -0
  59. data/lib/aws-sdk-s3/plugins/md5s.rb +79 -0
  60. data/lib/aws-sdk-s3/plugins/redirects.rb +41 -0
  61. data/lib/aws-sdk-s3/plugins/s3_signer.rb +208 -0
  62. data/lib/aws-sdk-s3/plugins/sse_cpk.rb +68 -0
  63. data/lib/aws-sdk-s3/plugins/url_encoded_keys.rb +94 -0
  64. data/lib/aws-sdk-s3/presigned_post.rb +647 -0
  65. data/lib/aws-sdk-s3/presigner.rb +160 -0
  66. data/lib/aws-sdk-s3/resource.rb +96 -0
  67. data/lib/aws-sdk-s3/types.rb +5750 -0
  68. data/lib/aws-sdk-s3/waiters.rb +178 -0
  69. metadata +154 -0
@@ -0,0 +1,214 @@
1
+ # WARNING ABOUT GENERATED CODE
2
+ #
3
+ # This file is generated. See the contributing for info on making contributions:
4
+ # https://github.com/aws/aws-sdk-ruby/blob/master/CONTRIBUTING.md
5
+ #
6
+ # WARNING ABOUT GENERATED CODE
7
+
8
+ module Aws
9
+ module S3
10
+ class ObjectAcl
11
+
12
+ extend Aws::Deprecations
13
+
14
+ # @overload def initialize(bucket_name, object_key, options = {})
15
+ # @param [String] bucket_name
16
+ # @param [String] object_key
17
+ # @option options [Client] :client
18
+ # @overload def initialize(options = {})
19
+ # @option options [required, String] :bucket_name
20
+ # @option options [required, String] :object_key
21
+ # @option options [Client] :client
22
+ def initialize(*args)
23
+ options = Hash === args.last ? args.pop.dup : {}
24
+ @bucket_name = extract_bucket_name(args, options)
25
+ @object_key = extract_object_key(args, options)
26
+ @data = options.delete(:data)
27
+ @client = options.delete(:client) || Client.new(options)
28
+ end
29
+
30
+ # @!group Read-Only Attributes
31
+
32
+ # @return [String]
33
+ def bucket_name
34
+ @bucket_name
35
+ end
36
+
37
+ # @return [String]
38
+ def object_key
39
+ @object_key
40
+ end
41
+
42
+ # @return [Types::Owner]
43
+ def owner
44
+ data.owner
45
+ end
46
+
47
+ # A list of grants.
48
+ # @return [Array<Types::Grant>]
49
+ def grants
50
+ data.grants
51
+ end
52
+
53
+ # If present, indicates that the requester was successfully charged for
54
+ # the request.
55
+ # @return [String]
56
+ def request_charged
57
+ data.request_charged
58
+ end
59
+
60
+ # @!endgroup
61
+
62
+ # @return [Client]
63
+ def client
64
+ @client
65
+ end
66
+
67
+ # Loads, or reloads {#data} for the current {ObjectAcl}.
68
+ # Returns `self` making it possible to chain methods.
69
+ #
70
+ # object_acl.reload.data
71
+ #
72
+ # @return [self]
73
+ def load
74
+ resp = @client.get_object_acl(
75
+ bucket: @bucket_name,
76
+ key: @object_key
77
+ )
78
+ @data = resp.data
79
+ self
80
+ end
81
+ alias :reload :load
82
+
83
+ # @return [Types::GetObjectAclOutput]
84
+ # Returns the data for this {ObjectAcl}. Calls
85
+ # {Client#get_object_acl} if {#data_loaded?} is `false`.
86
+ def data
87
+ load unless @data
88
+ @data
89
+ end
90
+
91
+ # @return [Boolean]
92
+ # Returns `true` if this resource is loaded. Accessing attributes or
93
+ # {#data} on an unloaded resource will trigger a call to {#load}.
94
+ def data_loaded?
95
+ !!@data
96
+ end
97
+
98
+ # @!group Actions
99
+
100
+ # @example Request syntax with placeholder values
101
+ #
102
+ # object_acl.put({
103
+ # acl: "private", # accepts private, public-read, public-read-write, authenticated-read, aws-exec-read, bucket-owner-read, bucket-owner-full-control
104
+ # access_control_policy: {
105
+ # grants: [
106
+ # {
107
+ # grantee: {
108
+ # display_name: "DisplayName",
109
+ # email_address: "EmailAddress",
110
+ # id: "ID",
111
+ # type: "CanonicalUser", # required, accepts CanonicalUser, AmazonCustomerByEmail, Group
112
+ # uri: "URI",
113
+ # },
114
+ # permission: "FULL_CONTROL", # accepts FULL_CONTROL, WRITE, WRITE_ACP, READ, READ_ACP
115
+ # },
116
+ # ],
117
+ # owner: {
118
+ # display_name: "DisplayName",
119
+ # id: "ID",
120
+ # },
121
+ # },
122
+ # content_md5: "ContentMD5",
123
+ # grant_full_control: "GrantFullControl",
124
+ # grant_read: "GrantRead",
125
+ # grant_read_acp: "GrantReadACP",
126
+ # grant_write: "GrantWrite",
127
+ # grant_write_acp: "GrantWriteACP",
128
+ # request_payer: "requester", # accepts requester
129
+ # version_id: "ObjectVersionId",
130
+ # })
131
+ # @param [Hash] options ({})
132
+ # @option options [String] :acl
133
+ # The canned ACL to apply to the object.
134
+ # @option options [Types::AccessControlPolicy] :access_control_policy
135
+ # @option options [String] :content_md5
136
+ # @option options [String] :grant_full_control
137
+ # Allows grantee the read, write, read ACP, and write ACP permissions on
138
+ # the bucket.
139
+ # @option options [String] :grant_read
140
+ # Allows grantee to list the objects in the bucket.
141
+ # @option options [String] :grant_read_acp
142
+ # Allows grantee to read the bucket ACL.
143
+ # @option options [String] :grant_write
144
+ # Allows grantee to create, overwrite, and delete any object in the
145
+ # bucket.
146
+ # @option options [String] :grant_write_acp
147
+ # Allows grantee to write the ACL for the applicable bucket.
148
+ # @option options [String] :request_payer
149
+ # Confirms that the requester knows that she or he will be charged for
150
+ # the request. Bucket owners need not specify this parameter in their
151
+ # requests. Documentation on downloading objects from requester pays
152
+ # buckets can be found at
153
+ # http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html
154
+ # @option options [String] :version_id
155
+ # VersionId used to reference a specific version of the object.
156
+ # @return [Types::PutObjectAclOutput]
157
+ def put(options = {})
158
+ options = options.merge(
159
+ bucket: @bucket_name,
160
+ key: @object_key
161
+ )
162
+ resp = @client.put_object_acl(options)
163
+ resp.data
164
+ end
165
+
166
+ # @!group Associations
167
+
168
+ # @return [Object]
169
+ def object
170
+ Object.new(
171
+ bucket_name: @bucket_name,
172
+ key: @object_key,
173
+ client: @client
174
+ )
175
+ end
176
+
177
+ # @deprecated
178
+ # @api private
179
+ def identifiers
180
+ {
181
+ bucket_name: @bucket_name,
182
+ object_key: @object_key
183
+ }
184
+ end
185
+ deprecated(:identifiers)
186
+
187
+ private
188
+
189
+ def extract_bucket_name(args, options)
190
+ value = args[0] || options.delete(:bucket_name)
191
+ case value
192
+ when String then value
193
+ when nil then raise ArgumentError, "missing required option :bucket_name"
194
+ else
195
+ msg = "expected :bucket_name to be a String, got #{value.class}"
196
+ raise ArgumentError, msg
197
+ end
198
+ end
199
+
200
+ def extract_object_key(args, options)
201
+ value = args[1] || options.delete(:object_key)
202
+ case value
203
+ when String then value
204
+ when nil then raise ArgumentError, "missing required option :object_key"
205
+ else
206
+ msg = "expected :object_key to be a String, got #{value.class}"
207
+ raise ArgumentError, msg
208
+ end
209
+ end
210
+
211
+ class Collection < Aws::Resources::Collection; end
212
+ end
213
+ end
214
+ end
@@ -0,0 +1,99 @@
1
+ require 'thread'
2
+
3
+ module Aws
4
+ module S3
5
+ # @api private
6
+ class ObjectCopier
7
+
8
+ # @param [S3::Object] object
9
+ def initialize(object, options = {})
10
+ @object = object
11
+ @options = options.merge(client: @object.client)
12
+ end
13
+
14
+ def copy_from(source, options = {})
15
+ copy_object(source, @object, merge_options(source, options))
16
+ end
17
+
18
+ def copy_to(target, options = {})
19
+ copy_object(@object, target, merge_options(target, options))
20
+ end
21
+
22
+ private
23
+
24
+ def copy_object(source, target, options)
25
+ target_bucket, target_key = copy_target(target)
26
+ options[:bucket] = target_bucket
27
+ options[:key] = target_key
28
+ options[:copy_source] = copy_source(source)
29
+ if options.delete(:multipart_copy)
30
+ apply_source_client(source, options)
31
+ ObjectMultipartCopier.new(@options).copy(options)
32
+ else
33
+ @object.client.copy_object(options)
34
+ end
35
+ end
36
+
37
+ def copy_source(source)
38
+ case source
39
+ when String then source
40
+ when Hash
41
+ src = "#{source[:bucket]}/#{escape(source[:key])}"
42
+ src += "?versionId=#{source[:version_id]}" if source.key?(:version_id)
43
+ src
44
+ when S3::Object, S3::ObjectSummary
45
+ "#{source.bucket_name}/#{escape(source.key)}"
46
+ when S3::ObjectVersion
47
+ "#{source.bucket_name}/#{escape(source.object_key)}?versionId=#{source.id}"
48
+ else
49
+ msg = "expected source to be an Aws::S3::Object, Hash, or String"
50
+ raise ArgumentError, msg
51
+ end
52
+ end
53
+
54
+ def copy_target(target)
55
+ case target
56
+ when String then target.match(/([^\/]+?)\/(.+)/)[1,2]
57
+ when Hash then target.values_at(:bucket, :key)
58
+ when S3::Object then [target.bucket_name, target.key]
59
+ else
60
+ msg = "expected target to be an Aws::S3::Object, Hash, or String"
61
+ raise ArgumentError, msg
62
+ end
63
+ end
64
+
65
+ def merge_options(source_or_target, options)
66
+ if Hash === source_or_target
67
+ source_or_target.inject(options.dup) do |opts, (key, value)|
68
+ opts[key] = value unless [:bucket, :key, :version_id].include?(key)
69
+ opts
70
+ end
71
+ else
72
+ options.dup
73
+ end
74
+ end
75
+
76
+ def apply_source_client(source, options)
77
+
78
+ if source.respond_to?(:client)
79
+ options[:copy_source_client] ||= source.client
80
+ end
81
+
82
+ if options[:copy_source_region]
83
+ config = @object.client.config
84
+ config = config.each_pair.inject({}) { |h, (k,v)| h[k] = v; h }
85
+ config[:region] = options.delete(:copy_source_region)
86
+ options[:copy_source_client] ||= S3::Client.new(config)
87
+ end
88
+
89
+ options[:copy_source_client] ||= @object.client
90
+
91
+ end
92
+
93
+ def escape(str)
94
+ Seahorse::Util.uri_path_escape(str)
95
+ end
96
+
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,179 @@
1
+ require 'thread'
2
+
3
+ module Aws
4
+ module S3
5
+ # @api private
6
+ class ObjectMultipartCopier
7
+
8
+ FIVE_MB = 5 * 1024 * 1024 # 5MB
9
+
10
+ FILE_TOO_SMALL = "unable to multipart copy files smaller than 5MB"
11
+
12
+ MAX_PARTS = 10_000
13
+
14
+ # @option options [Client] :client
15
+ # @option [Integer] :min_part_size (52428800) Size of copied parts.
16
+ # Defaults to 50MB.
17
+ # will be constructed from the given `options' hash.
18
+ # @option [Integer] :thread_count (10) Number of concurrent threads to
19
+ # use for copying parts.
20
+ def initialize(options = {})
21
+ @thread_count = options.delete(:thread_count) || 10
22
+ @min_part_size = options.delete(:min_part_size) || (FIVE_MB * 10)
23
+ @client = options[:client] || Client.new
24
+ end
25
+
26
+ # @return [Client]
27
+ attr_reader :client
28
+
29
+ # @option (see S3::Client#copy_object)
30
+ def copy(options = {})
31
+ size = source_size(options)
32
+ options[:upload_id] = initiate_upload(options)
33
+ begin
34
+ parts = copy_parts(size, default_part_size(size), options)
35
+ complete_upload(parts, options)
36
+ rescue => error
37
+ abort_upload(options)
38
+ raise error
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def initiate_upload(options)
45
+ options = options_for(:create_multipart_upload, options)
46
+ @client.create_multipart_upload(options).upload_id
47
+ end
48
+
49
+ def copy_parts(size, default_part_size, options)
50
+ queue = PartQueue.new(compute_parts(size, default_part_size, options))
51
+ threads = []
52
+ @thread_count.times do
53
+ threads << copy_part_thread(queue)
54
+ end
55
+ threads.map(&:value).flatten.sort_by{ |part| part[:part_number] }
56
+ end
57
+
58
+ def copy_part_thread(queue)
59
+ Thread.new do
60
+ begin
61
+ completed = []
62
+ while part = queue.shift
63
+ completed << copy_part(part)
64
+ end
65
+ completed
66
+ rescue => error
67
+ queue.clear!
68
+ raise error
69
+ end
70
+ end
71
+ end
72
+
73
+ def copy_part(part)
74
+ {
75
+ etag: @client.upload_part_copy(part).copy_part_result.etag,
76
+ part_number: part[:part_number],
77
+ }
78
+ end
79
+
80
+ def complete_upload(parts, options)
81
+ options = options_for(:complete_multipart_upload, options)
82
+ options[:multipart_upload] = { parts: parts }
83
+ @client.complete_multipart_upload(options)
84
+ end
85
+
86
+ def abort_upload(options)
87
+ @client.abort_multipart_upload({
88
+ bucket: options[:bucket],
89
+ key: options[:key],
90
+ upload_id: options[:upload_id],
91
+ })
92
+ end
93
+
94
+ def compute_parts(size, default_part_size, options)
95
+ part_number = 1
96
+ offset = 0
97
+ parts = []
98
+ options = options_for(:upload_part_copy, options)
99
+ while offset < size
100
+ parts << options.merge({
101
+ part_number: part_number,
102
+ copy_source_range: byte_range(offset, default_part_size, size),
103
+ })
104
+ part_number += 1
105
+ offset += default_part_size
106
+ end
107
+ parts
108
+ end
109
+
110
+ def byte_range(offset, default_part_size, size)
111
+ if offset + default_part_size < size
112
+ "bytes=#{offset}-#{offset + default_part_size - 1}"
113
+ else
114
+ "bytes=#{offset}-#{size - 1}"
115
+ end
116
+ end
117
+
118
+ def source_size(options)
119
+ return options.delete(:content_length) if options[:content_length]
120
+
121
+ client = options[:copy_source_client] || @client
122
+
123
+ if vid_match = options[:copy_source].match(/([^\/]+?)\/(.+)\?versionId=(.+)/)
124
+ bucket, key, version_id = vid_match[1,3]
125
+ else
126
+ bucket, key = options[:copy_source].match(/([^\/]+?)\/(.+)/)[1,2]
127
+ end
128
+
129
+ key = CGI.unescape(key)
130
+ opts = { bucket: bucket, key: key }
131
+ opts[:version_id] = version_id if version_id
132
+ client.head_object(opts).content_length
133
+ end
134
+
135
+ def default_part_size(source_size)
136
+ if source_size < FIVE_MB
137
+ raise ArgumentError, FILE_TOO_SMALL
138
+ else
139
+ [(source_size.to_f / MAX_PARTS).ceil, @min_part_size].max.to_i
140
+ end
141
+ end
142
+
143
+ def options_for(operation_name, options)
144
+ API_OPTIONS[operation_name].inject({}) do |hash, opt_name|
145
+ hash[opt_name] = options[opt_name] if options.key?(opt_name)
146
+ hash
147
+ end
148
+ end
149
+
150
+ # @api private
151
+ def self.options_for(shape_name)
152
+ Client.api.metadata['shapes'][shape_name].member_names
153
+ end
154
+
155
+ API_OPTIONS = {
156
+ create_multipart_upload: Types::CreateMultipartUploadRequest.members,
157
+ upload_part_copy: Types::UploadPartCopyRequest.members,
158
+ complete_multipart_upload: Types::CompleteMultipartUploadRequest.members,
159
+ }
160
+
161
+ class PartQueue
162
+
163
+ def initialize(parts = [])
164
+ @parts = parts
165
+ @mutex = Mutex.new
166
+ end
167
+
168
+ def shift
169
+ @mutex.synchronize { @parts.shift }
170
+ end
171
+
172
+ def clear!
173
+ @mutex.synchronize { @parts.clear }
174
+ end
175
+
176
+ end
177
+ end
178
+ end
179
+ end