aws-sdk-s3 1.0.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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