aws-sdk 1.0.0
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.
- data/.yardopts +6 -0
- data/LICENSE.txt +171 -0
- data/NOTICE.txt +2 -0
- data/README.rdoc +189 -0
- data/lib/aws-sdk.rb +14 -0
- data/lib/aws.rb +63 -0
- data/lib/aws/api_config.rb +45 -0
- data/lib/aws/api_config/.document +0 -0
- data/lib/aws/api_config/EC2-2011-02-28.yml +2314 -0
- data/lib/aws/api_config/SNS-2010-03-31.yml +171 -0
- data/lib/aws/api_config/SQS-2009-02-01.yml +161 -0
- data/lib/aws/api_config/SimpleDB-2009-04-15.yml +278 -0
- data/lib/aws/api_config/SimpleEmailService-2010-12-01.yml +147 -0
- data/lib/aws/api_config_transform.rb +32 -0
- data/lib/aws/async_handle.rb +90 -0
- data/lib/aws/authorize_v2.rb +37 -0
- data/lib/aws/authorize_v3.rb +37 -0
- data/lib/aws/base_client.rb +524 -0
- data/lib/aws/cacheable.rb +92 -0
- data/lib/aws/common.rb +228 -0
- data/lib/aws/configurable.rb +36 -0
- data/lib/aws/configuration.rb +272 -0
- data/lib/aws/configured_client_methods.rb +81 -0
- data/lib/aws/configured_grammars.rb +65 -0
- data/lib/aws/configured_option_grammars.rb +46 -0
- data/lib/aws/configured_xml_grammars.rb +47 -0
- data/lib/aws/default_signer.rb +38 -0
- data/lib/aws/ec2.rb +321 -0
- data/lib/aws/ec2/attachment.rb +149 -0
- data/lib/aws/ec2/attachment_collection.rb +57 -0
- data/lib/aws/ec2/availability_zone.rb +80 -0
- data/lib/aws/ec2/availability_zone_collection.rb +47 -0
- data/lib/aws/ec2/block_device_mappings.rb +53 -0
- data/lib/aws/ec2/client.rb +54 -0
- data/lib/aws/ec2/client/xml.rb +127 -0
- data/lib/aws/ec2/collection.rb +39 -0
- data/lib/aws/ec2/config_transform.rb +63 -0
- data/lib/aws/ec2/elastic_ip.rb +107 -0
- data/lib/aws/ec2/elastic_ip_collection.rb +85 -0
- data/lib/aws/ec2/errors.rb +29 -0
- data/lib/aws/ec2/filtered_collection.rb +65 -0
- data/lib/aws/ec2/has_permissions.rb +46 -0
- data/lib/aws/ec2/image.rb +245 -0
- data/lib/aws/ec2/image_collection.rb +235 -0
- data/lib/aws/ec2/instance.rb +515 -0
- data/lib/aws/ec2/instance_collection.rb +276 -0
- data/lib/aws/ec2/key_pair.rb +86 -0
- data/lib/aws/ec2/key_pair_collection.rb +102 -0
- data/lib/aws/ec2/permission_collection.rb +177 -0
- data/lib/aws/ec2/region.rb +81 -0
- data/lib/aws/ec2/region_collection.rb +55 -0
- data/lib/aws/ec2/request.rb +27 -0
- data/lib/aws/ec2/reserved_instances.rb +50 -0
- data/lib/aws/ec2/reserved_instances_collection.rb +44 -0
- data/lib/aws/ec2/reserved_instances_offering.rb +55 -0
- data/lib/aws/ec2/reserved_instances_offering_collection.rb +43 -0
- data/lib/aws/ec2/resource.rb +340 -0
- data/lib/aws/ec2/resource_tag_collection.rb +218 -0
- data/lib/aws/ec2/security_group.rb +246 -0
- data/lib/aws/ec2/security_group/ip_permission.rb +70 -0
- data/lib/aws/ec2/security_group/ip_permission_collection.rb +59 -0
- data/lib/aws/ec2/security_group_collection.rb +132 -0
- data/lib/aws/ec2/snapshot.rb +138 -0
- data/lib/aws/ec2/snapshot_collection.rb +90 -0
- data/lib/aws/ec2/tag.rb +88 -0
- data/lib/aws/ec2/tag_collection.rb +114 -0
- data/lib/aws/ec2/tagged_collection.rb +48 -0
- data/lib/aws/ec2/tagged_item.rb +87 -0
- data/lib/aws/ec2/volume.rb +190 -0
- data/lib/aws/ec2/volume_collection.rb +95 -0
- data/lib/aws/errors.rb +129 -0
- data/lib/aws/http/builtin_handler.rb +69 -0
- data/lib/aws/http/curb_handler.rb +123 -0
- data/lib/aws/http/handler.rb +77 -0
- data/lib/aws/http/httparty_handler.rb +61 -0
- data/lib/aws/http/request.rb +136 -0
- data/lib/aws/http/request_param.rb +63 -0
- data/lib/aws/http/response.rb +75 -0
- data/lib/aws/ignore_result_element.rb +38 -0
- data/lib/aws/indifferent_hash.rb +86 -0
- data/lib/aws/inflection.rb +46 -0
- data/lib/aws/lazy_error_classes.rb +64 -0
- data/lib/aws/meta_utils.rb +43 -0
- data/lib/aws/model.rb +57 -0
- data/lib/aws/naming.rb +32 -0
- data/lib/aws/option_grammar.rb +544 -0
- data/lib/aws/policy.rb +912 -0
- data/lib/aws/rails.rb +209 -0
- data/lib/aws/record.rb +79 -0
- data/lib/aws/record/attribute.rb +94 -0
- data/lib/aws/record/attribute_macros.rb +288 -0
- data/lib/aws/record/attributes/boolean.rb +49 -0
- data/lib/aws/record/attributes/datetime.rb +86 -0
- data/lib/aws/record/attributes/float.rb +48 -0
- data/lib/aws/record/attributes/integer.rb +68 -0
- data/lib/aws/record/attributes/sortable_float.rb +60 -0
- data/lib/aws/record/attributes/sortable_integer.rb +95 -0
- data/lib/aws/record/attributes/string.rb +69 -0
- data/lib/aws/record/base.rb +728 -0
- data/lib/aws/record/conversion.rb +38 -0
- data/lib/aws/record/dirty_tracking.rb +286 -0
- data/lib/aws/record/errors.rb +153 -0
- data/lib/aws/record/exceptions.rb +48 -0
- data/lib/aws/record/finder_methods.rb +262 -0
- data/lib/aws/record/naming.rb +31 -0
- data/lib/aws/record/scope.rb +157 -0
- data/lib/aws/record/validations.rb +653 -0
- data/lib/aws/record/validator.rb +237 -0
- data/lib/aws/record/validators/acceptance.rb +51 -0
- data/lib/aws/record/validators/block.rb +38 -0
- data/lib/aws/record/validators/confirmation.rb +43 -0
- data/lib/aws/record/validators/count.rb +108 -0
- data/lib/aws/record/validators/exclusion.rb +43 -0
- data/lib/aws/record/validators/format.rb +57 -0
- data/lib/aws/record/validators/inclusion.rb +56 -0
- data/lib/aws/record/validators/length.rb +107 -0
- data/lib/aws/record/validators/numericality.rb +138 -0
- data/lib/aws/record/validators/presence.rb +45 -0
- data/lib/aws/resource_cache.rb +39 -0
- data/lib/aws/response.rb +113 -0
- data/lib/aws/response_cache.rb +50 -0
- data/lib/aws/s3.rb +109 -0
- data/lib/aws/s3/access_control_list.rb +252 -0
- data/lib/aws/s3/acl_object.rb +266 -0
- data/lib/aws/s3/bucket.rb +320 -0
- data/lib/aws/s3/bucket_collection.rb +122 -0
- data/lib/aws/s3/bucket_version_collection.rb +85 -0
- data/lib/aws/s3/client.rb +999 -0
- data/lib/aws/s3/client/xml.rb +190 -0
- data/lib/aws/s3/data_options.rb +99 -0
- data/lib/aws/s3/errors.rb +43 -0
- data/lib/aws/s3/multipart_upload.rb +318 -0
- data/lib/aws/s3/multipart_upload_collection.rb +78 -0
- data/lib/aws/s3/object_collection.rb +159 -0
- data/lib/aws/s3/object_metadata.rb +67 -0
- data/lib/aws/s3/object_upload_collection.rb +83 -0
- data/lib/aws/s3/object_version.rb +141 -0
- data/lib/aws/s3/object_version_collection.rb +78 -0
- data/lib/aws/s3/paginated_collection.rb +94 -0
- data/lib/aws/s3/policy.rb +76 -0
- data/lib/aws/s3/prefix_and_delimiter_collection.rb +56 -0
- data/lib/aws/s3/prefixed_collection.rb +84 -0
- data/lib/aws/s3/presigned_post.rb +504 -0
- data/lib/aws/s3/request.rb +198 -0
- data/lib/aws/s3/s3_object.rb +794 -0
- data/lib/aws/s3/tree.rb +116 -0
- data/lib/aws/s3/tree/branch_node.rb +71 -0
- data/lib/aws/s3/tree/child_collection.rb +108 -0
- data/lib/aws/s3/tree/leaf_node.rb +99 -0
- data/lib/aws/s3/tree/node.rb +22 -0
- data/lib/aws/s3/tree/parent.rb +90 -0
- data/lib/aws/s3/uploaded_part.rb +82 -0
- data/lib/aws/s3/uploaded_part_collection.rb +86 -0
- data/lib/aws/service_interface.rb +60 -0
- data/lib/aws/simple_db.rb +202 -0
- data/lib/aws/simple_db/attribute.rb +159 -0
- data/lib/aws/simple_db/attribute_collection.rb +227 -0
- data/lib/aws/simple_db/client.rb +52 -0
- data/lib/aws/simple_db/client/options.rb +34 -0
- data/lib/aws/simple_db/client/xml.rb +68 -0
- data/lib/aws/simple_db/consistent_read_option.rb +42 -0
- data/lib/aws/simple_db/delete_attributes.rb +64 -0
- data/lib/aws/simple_db/domain.rb +118 -0
- data/lib/aws/simple_db/domain_collection.rb +116 -0
- data/lib/aws/simple_db/domain_metadata.rb +112 -0
- data/lib/aws/simple_db/errors.rb +46 -0
- data/lib/aws/simple_db/expect_condition_option.rb +45 -0
- data/lib/aws/simple_db/item.rb +84 -0
- data/lib/aws/simple_db/item_collection.rb +594 -0
- data/lib/aws/simple_db/item_data.rb +70 -0
- data/lib/aws/simple_db/put_attributes.rb +62 -0
- data/lib/aws/simple_db/request.rb +27 -0
- data/lib/aws/simple_email_service.rb +373 -0
- data/lib/aws/simple_email_service/client.rb +39 -0
- data/lib/aws/simple_email_service/client/options.rb +24 -0
- data/lib/aws/simple_email_service/client/xml.rb +38 -0
- data/lib/aws/simple_email_service/email_address_collection.rb +66 -0
- data/lib/aws/simple_email_service/errors.rb +29 -0
- data/lib/aws/simple_email_service/quotas.rb +64 -0
- data/lib/aws/simple_email_service/request.rb +27 -0
- data/lib/aws/sns.rb +69 -0
- data/lib/aws/sns/client.rb +37 -0
- data/lib/aws/sns/client/options.rb +24 -0
- data/lib/aws/sns/client/xml.rb +38 -0
- data/lib/aws/sns/errors.rb +29 -0
- data/lib/aws/sns/policy.rb +49 -0
- data/lib/aws/sns/request.rb +27 -0
- data/lib/aws/sns/subscription.rb +100 -0
- data/lib/aws/sns/subscription_collection.rb +84 -0
- data/lib/aws/sns/topic.rb +384 -0
- data/lib/aws/sns/topic_collection.rb +70 -0
- data/lib/aws/sns/topic_subscription_collection.rb +58 -0
- data/lib/aws/sqs.rb +70 -0
- data/lib/aws/sqs/client.rb +38 -0
- data/lib/aws/sqs/client/xml.rb +36 -0
- data/lib/aws/sqs/errors.rb +33 -0
- data/lib/aws/sqs/policy.rb +50 -0
- data/lib/aws/sqs/queue.rb +507 -0
- data/lib/aws/sqs/queue_collection.rb +105 -0
- data/lib/aws/sqs/received_message.rb +184 -0
- data/lib/aws/sqs/received_sns_message.rb +112 -0
- data/lib/aws/sqs/request.rb +44 -0
- data/lib/aws/xml_grammar.rb +923 -0
- data/rails/init.rb +15 -0
- metadata +298 -0
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# Copyright 2011 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
|
5
|
+
# the License is located at
|
|
6
|
+
#
|
|
7
|
+
# http://aws.amazon.com/apache2.0/
|
|
8
|
+
#
|
|
9
|
+
# or in the "license" file accompanying this file. This file is
|
|
10
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
|
11
|
+
# ANY KIND, either express or implied. See the License for the specific
|
|
12
|
+
# language governing permissions and limitations under the License.
|
|
13
|
+
|
|
14
|
+
require 'aws/xml_grammar'
|
|
15
|
+
require 'aws/base_client'
|
|
16
|
+
|
|
17
|
+
module AWS
|
|
18
|
+
class S3
|
|
19
|
+
class Client < BaseClient
|
|
20
|
+
|
|
21
|
+
# @private
|
|
22
|
+
module XML
|
|
23
|
+
|
|
24
|
+
Error = XmlGrammar.customize { }
|
|
25
|
+
|
|
26
|
+
module HasCommonPrefixes
|
|
27
|
+
|
|
28
|
+
def self.included(mod)
|
|
29
|
+
mod.module_eval do
|
|
30
|
+
element "CommonPrefixes" do
|
|
31
|
+
collect_values
|
|
32
|
+
format_value {|value| value.prefix }
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
ListBuckets = XmlGrammar.customize do
|
|
40
|
+
element "Buckets" do
|
|
41
|
+
element "Bucket" do
|
|
42
|
+
collect_values
|
|
43
|
+
end
|
|
44
|
+
format_value { |value| super(value.bucket) }
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
GetBucketAcl = GetObjectAcl = XmlGrammar.customize do
|
|
49
|
+
wrapper(:acl,
|
|
50
|
+
:for => ["Owner",
|
|
51
|
+
"AccessControlList"]) do
|
|
52
|
+
construct_value { AccessControlList.new }
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
element "Owner" do
|
|
56
|
+
construct_value { AccessControlList::Owner.new }
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
element "AccessControlList" do
|
|
60
|
+
element "Grant" do
|
|
61
|
+
collect_values
|
|
62
|
+
construct_value { AccessControlList::Grant.new }
|
|
63
|
+
|
|
64
|
+
element "Grantee" do
|
|
65
|
+
construct_value { AccessControlList::Grantee.new }
|
|
66
|
+
element "ID" do
|
|
67
|
+
rename :canonical_user_id
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
element "Permission" do
|
|
72
|
+
symbol_value
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
format_value { |value| super(value.grant) }
|
|
77
|
+
rename :grants
|
|
78
|
+
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
ListObjects = XmlGrammar.customize do
|
|
83
|
+
|
|
84
|
+
element("Name") { rename "bucket_name" }
|
|
85
|
+
element("MaxKeys") { integer_value }
|
|
86
|
+
element("IsTruncated") { rename "truncated"; boolean_value }
|
|
87
|
+
element("Delimiter") { force }
|
|
88
|
+
|
|
89
|
+
element("Contents") do
|
|
90
|
+
list
|
|
91
|
+
element("Owner") do
|
|
92
|
+
element("ID") { }
|
|
93
|
+
element("DisplayName") { }
|
|
94
|
+
end
|
|
95
|
+
element("Key") { }
|
|
96
|
+
element("Size") { }
|
|
97
|
+
element("StorageClass") { }
|
|
98
|
+
element("ETag") { rename "etag" }
|
|
99
|
+
|
|
100
|
+
# DateTime is more general, Time is much faster to construct
|
|
101
|
+
element("LastModified") { time_value }
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
include HasCommonPrefixes
|
|
105
|
+
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
GetBucketVersioning = XmlGrammar.customize do
|
|
109
|
+
element("Status") do
|
|
110
|
+
symbol_value
|
|
111
|
+
format_value {|value| super(value) || :unversioned }
|
|
112
|
+
force
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
ListObjectVersions = XmlGrammar.customize do
|
|
117
|
+
|
|
118
|
+
element("MaxKeys") { integer_value }
|
|
119
|
+
element("IsTruncated") { rename "Truncated"; boolean_value }
|
|
120
|
+
element("NextKeyMarker") { force }
|
|
121
|
+
element("NextVersionIdMarker") { force }
|
|
122
|
+
|
|
123
|
+
%w(DeleteMarker Version).each do |element_name|
|
|
124
|
+
element(element_name) do
|
|
125
|
+
collect_values
|
|
126
|
+
rename("versions")
|
|
127
|
+
element("IsLatest") { rename "latest"; boolean_value }
|
|
128
|
+
element("LastModified") { datetime_value }
|
|
129
|
+
element("ETag") { rename "etag" }
|
|
130
|
+
element("Size") { integer_value }
|
|
131
|
+
element("StorageClass") { symbol_value }
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
element "DeleteMarker" do
|
|
136
|
+
add_method(:delete_marker?) { true }
|
|
137
|
+
add_method(:version?) { false }
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
element "Version" do
|
|
141
|
+
add_method(:delete_marker?) { false }
|
|
142
|
+
add_method(:version?) { true }
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
include HasCommonPrefixes
|
|
146
|
+
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# default behavior is good enough
|
|
150
|
+
InitiateMultipartUpload = XmlGrammar.customize do
|
|
151
|
+
element("UploadId") { force }
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
ListMultipartUploads = XmlGrammar.customize do
|
|
155
|
+
element("IsTruncated") { rename "Truncated"; boolean_value }
|
|
156
|
+
element("MaxUploads") { integer_value }
|
|
157
|
+
element("NextKeyMarker") { force }
|
|
158
|
+
element("NextUploadIdMarker") { force }
|
|
159
|
+
element("Upload") do
|
|
160
|
+
collect_values
|
|
161
|
+
rename :uploads
|
|
162
|
+
element("StorageClass") { symbol_value }
|
|
163
|
+
element("Initiated") { datetime_value }
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
include HasCommonPrefixes
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# keep default behavior
|
|
170
|
+
CompleteMultipartUpload = XmlGrammar.customize
|
|
171
|
+
|
|
172
|
+
ListParts = XmlGrammar.customize do
|
|
173
|
+
element("StorageClass") { symbol_value }
|
|
174
|
+
element("IsTruncated") { rename "Truncated"; boolean_value }
|
|
175
|
+
element("MaxParts") { integer_value }
|
|
176
|
+
element("PartNumberMarker") { integer_value }
|
|
177
|
+
element("NextPartNumberMarker") { integer_value }
|
|
178
|
+
element("Part") do
|
|
179
|
+
collect_values
|
|
180
|
+
rename :parts
|
|
181
|
+
element("PartNumber") { integer_value }
|
|
182
|
+
element("LastModified") { datetime_value }
|
|
183
|
+
element("Size") { integer_value }
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Copyright 2011 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
|
5
|
+
# the License is located at
|
|
6
|
+
#
|
|
7
|
+
# http://aws.amazon.com/apache2.0/
|
|
8
|
+
#
|
|
9
|
+
# or in the "license" file accompanying this file. This file is
|
|
10
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
|
11
|
+
# ANY KIND, either express or implied. See the License for the specific
|
|
12
|
+
# language governing permissions and limitations under the License.
|
|
13
|
+
|
|
14
|
+
require 'pathname'
|
|
15
|
+
|
|
16
|
+
module AWS
|
|
17
|
+
class S3
|
|
18
|
+
module DataOptions
|
|
19
|
+
|
|
20
|
+
protected
|
|
21
|
+
def data_stream_from options, &block
|
|
22
|
+
|
|
23
|
+
validate_data!(options, block)
|
|
24
|
+
|
|
25
|
+
# block format
|
|
26
|
+
if block_given?
|
|
27
|
+
buffer = StringIO.new
|
|
28
|
+
yield(buffer)
|
|
29
|
+
buffer.rewind
|
|
30
|
+
return buffer
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# string, pathname, file, io-like object, etc
|
|
34
|
+
data = options[:data]
|
|
35
|
+
file_opts = ["r"]
|
|
36
|
+
file_opts << { :encoding => "BINARY" } if Object.const_defined?(:Encoding)
|
|
37
|
+
case
|
|
38
|
+
when data.is_a?(String)
|
|
39
|
+
data.force_encoding("BINARY") if data.respond_to?(:force_encoding)
|
|
40
|
+
StringIO.new(data)
|
|
41
|
+
when data.is_a?(Pathname) then File.open(data.to_s, *file_opts)
|
|
42
|
+
when options[:file] then File.open(options[:file], *file_opts)
|
|
43
|
+
else data
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
protected
|
|
49
|
+
def content_length_from options
|
|
50
|
+
data = options[:data]
|
|
51
|
+
case
|
|
52
|
+
when options[:content_length] then options[:content_length]
|
|
53
|
+
when options[:file] then File.size(options[:file])
|
|
54
|
+
when data.is_a?(Pathname) then File.size(data.to_s)
|
|
55
|
+
when data.is_a?(File) then File.size(data.path)
|
|
56
|
+
when data.respond_to?(:bytesize) then data.bytesize
|
|
57
|
+
when data.respond_to?(:size) then data.size
|
|
58
|
+
when data.respond_to?(:length) then data.length
|
|
59
|
+
else raise ArgumentError, 'content_length was not provided ' +
|
|
60
|
+
'and could not be determined'
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
protected
|
|
65
|
+
def validate_data! options, block
|
|
66
|
+
|
|
67
|
+
data = options[:data]
|
|
68
|
+
filename = options[:file]
|
|
69
|
+
|
|
70
|
+
raise ArgumentError, 'data passed multiple ways' if
|
|
71
|
+
[data, filename, block].compact.size > 1
|
|
72
|
+
|
|
73
|
+
# accepting block format
|
|
74
|
+
return if block and block.arity == 1
|
|
75
|
+
|
|
76
|
+
# accepting file path
|
|
77
|
+
return if filename.kind_of?(String)
|
|
78
|
+
|
|
79
|
+
# accepting strings
|
|
80
|
+
return if data.kind_of?(String)
|
|
81
|
+
|
|
82
|
+
# accepting pathname
|
|
83
|
+
return if data.kind_of?(Pathname)
|
|
84
|
+
|
|
85
|
+
# accepts io-like objects (responds to read and eof?)
|
|
86
|
+
if data.respond_to?(:read) and
|
|
87
|
+
data.method(:read).arity != 0 and
|
|
88
|
+
data.respond_to?(:eof?) then
|
|
89
|
+
return true
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
raise ArgumentError, 'data must be provided as a String, ' +
|
|
93
|
+
'Pathname, file path, or an object that responds to #read and #eof?'
|
|
94
|
+
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Copyright 2011 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
|
5
|
+
# the License is located at
|
|
6
|
+
#
|
|
7
|
+
# http://aws.amazon.com/apache2.0/
|
|
8
|
+
#
|
|
9
|
+
# or in the "license" file accompanying this file. This file is
|
|
10
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
|
11
|
+
# ANY KIND, either express or implied. See the License for the specific
|
|
12
|
+
# language governing permissions and limitations under the License.
|
|
13
|
+
|
|
14
|
+
require 'aws/lazy_error_classes'
|
|
15
|
+
require 'aws/s3/client/xml'
|
|
16
|
+
|
|
17
|
+
module AWS
|
|
18
|
+
class S3
|
|
19
|
+
|
|
20
|
+
# This module contains exception classes for each of the error
|
|
21
|
+
# types that S3 can return. You can use these classes to rescue
|
|
22
|
+
# specific errors, for example:
|
|
23
|
+
#
|
|
24
|
+
# begin
|
|
25
|
+
# S3.new.buckets.mybucket.
|
|
26
|
+
# objects.myobj.write("HELLO")
|
|
27
|
+
# rescue S3::Errors::NoSuchBucket => e
|
|
28
|
+
# S3.new.buckets.create("mybucket")
|
|
29
|
+
# retry
|
|
30
|
+
# end
|
|
31
|
+
#
|
|
32
|
+
# All errors raised as a result of error responses from the
|
|
33
|
+
# service are instances of either {ClientError} or {ServerError}.
|
|
34
|
+
# @private
|
|
35
|
+
module Errors
|
|
36
|
+
|
|
37
|
+
BASE_ERROR_GRAMMAR = Client::XML::Error
|
|
38
|
+
|
|
39
|
+
include LazyErrorClasses
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
# Copyright 2011 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
|
5
|
+
# the License is located at
|
|
6
|
+
#
|
|
7
|
+
# http://aws.amazon.com/apache2.0/
|
|
8
|
+
#
|
|
9
|
+
# or in the "license" file accompanying this file. This file is
|
|
10
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
|
11
|
+
# ANY KIND, either express or implied. See the License for the specific
|
|
12
|
+
# language governing permissions and limitations under the License.
|
|
13
|
+
|
|
14
|
+
require 'aws/model'
|
|
15
|
+
require 'aws/s3/uploaded_part'
|
|
16
|
+
require 'aws/s3/uploaded_part_collection'
|
|
17
|
+
require 'thread'
|
|
18
|
+
|
|
19
|
+
module AWS
|
|
20
|
+
class S3
|
|
21
|
+
|
|
22
|
+
# Represents a multipart upload to an S3 object. See
|
|
23
|
+
# {S3Object#multipart_upload} for a convenient way to initiate a
|
|
24
|
+
# multipart upload.
|
|
25
|
+
class MultipartUpload
|
|
26
|
+
|
|
27
|
+
include Model
|
|
28
|
+
|
|
29
|
+
# @private
|
|
30
|
+
def initialize(object, id, options = {})
|
|
31
|
+
@id = id
|
|
32
|
+
@object = object
|
|
33
|
+
|
|
34
|
+
super
|
|
35
|
+
|
|
36
|
+
@completed_parts = {}
|
|
37
|
+
@increment_mutex = Mutex.new
|
|
38
|
+
@completed_mutex = Mutex.new
|
|
39
|
+
@last_part = 0
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def bucket
|
|
43
|
+
object.bucket
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def inspect
|
|
47
|
+
"<#{self.class}:#{object.bucket.name}/#{object.key}:#{id}>"
|
|
48
|
+
end
|
|
49
|
+
# @return [String] Returns the upload id.
|
|
50
|
+
attr_reader :id
|
|
51
|
+
|
|
52
|
+
alias_method :upload_id, :id
|
|
53
|
+
|
|
54
|
+
# @return [S3Object] Returns the object this upload is intended for.
|
|
55
|
+
attr_reader :object
|
|
56
|
+
|
|
57
|
+
# @return [Boolean] Returns true if both multipart uploads
|
|
58
|
+
# represent the same object and upload.
|
|
59
|
+
def ==(other)
|
|
60
|
+
other.kind_of?(MultipartUpload) and
|
|
61
|
+
other.object == object and
|
|
62
|
+
other.id == id
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
alias_method :eql?, :==
|
|
66
|
+
|
|
67
|
+
# @return [Boolean] True if the upload exists.
|
|
68
|
+
def exists?
|
|
69
|
+
client.list_parts(base_opts)
|
|
70
|
+
rescue Errors::NoSuchUpload => e
|
|
71
|
+
false
|
|
72
|
+
else
|
|
73
|
+
true
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# @return The upload initiator. This object will have +:id+
|
|
77
|
+
# and +:display_name+ methods; if the initiator is an IAM
|
|
78
|
+
# user, the +:id+ method will return the ARN of the user, and
|
|
79
|
+
# if the initiator is an AWS account, this method will return
|
|
80
|
+
# the same data as {#owner}.
|
|
81
|
+
def initiator
|
|
82
|
+
client.list_parts(base_opts).initiator
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# @return The upload owner. This object will have +:id+
|
|
86
|
+
# and +:display_name+ methods.
|
|
87
|
+
def owner
|
|
88
|
+
client.list_parts(base_opts).owner
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# @return [Symbol] The class of storage used to store the
|
|
92
|
+
# uploaded object. Possible values:
|
|
93
|
+
#
|
|
94
|
+
# * +:standard+
|
|
95
|
+
# * +:reduced_redundancy?+
|
|
96
|
+
def storage_class
|
|
97
|
+
client.list_parts(base_opts).storage_class.downcase.to_sym
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# @return [Boolean] True if the uploaded object will be stored
|
|
101
|
+
# with reduced redundancy.
|
|
102
|
+
def reduced_redundancy?
|
|
103
|
+
storage_class == :reduced_redundancy
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Aborts the upload. After a multipart upload is aborted, no
|
|
107
|
+
# additional parts can be uploaded using that upload ID. The
|
|
108
|
+
# storage consumed by any previously uploaded parts will be
|
|
109
|
+
# freed. However, if any part uploads are currently in
|
|
110
|
+
# progress, those part uploads might or might not succeed. As
|
|
111
|
+
# a result, it might be necessary to abort a given multipart
|
|
112
|
+
# upload multiple times in order to completely free all
|
|
113
|
+
# storage consumed by all parts.
|
|
114
|
+
# @return [nil]
|
|
115
|
+
def abort
|
|
116
|
+
client.abort_multipart_upload(base_opts)
|
|
117
|
+
@aborted = true
|
|
118
|
+
nil
|
|
119
|
+
end
|
|
120
|
+
alias_method :delete, :abort
|
|
121
|
+
alias_method :cancel, :abort
|
|
122
|
+
|
|
123
|
+
# @return [Boolean] True if the upload has been aborted.
|
|
124
|
+
# @see #abort
|
|
125
|
+
def aborted?
|
|
126
|
+
@aborted
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Uploads a part.
|
|
130
|
+
#
|
|
131
|
+
# @overload add_part(data, options = {})
|
|
132
|
+
#
|
|
133
|
+
# @param data The data to upload. Valid values include:
|
|
134
|
+
#
|
|
135
|
+
# * A string
|
|
136
|
+
#
|
|
137
|
+
# * A Pathname object
|
|
138
|
+
#
|
|
139
|
+
# * Any object responding to +read+ and +eof?+; the object
|
|
140
|
+
# must support the following access methods:
|
|
141
|
+
#
|
|
142
|
+
# read # all at once
|
|
143
|
+
# read(length) until eof? # in chunks
|
|
144
|
+
#
|
|
145
|
+
# If you specify data this way, you must also include
|
|
146
|
+
# the +:content_length+ option.
|
|
147
|
+
#
|
|
148
|
+
# @param [Hash] options Additional options for the upload.
|
|
149
|
+
#
|
|
150
|
+
# @option options [Integer] :content_length If provided,
|
|
151
|
+
# this option must match the total number of bytes written
|
|
152
|
+
# to S3 during the operation. This option is required if
|
|
153
|
+
# +:data+ is an IO-like object without a +size+ method.
|
|
154
|
+
#
|
|
155
|
+
# @overload add_part(options)
|
|
156
|
+
#
|
|
157
|
+
# @param [Hash] options Options for the upload. Either
|
|
158
|
+
# +:data+ or +:file+ is required.
|
|
159
|
+
#
|
|
160
|
+
# @option options :data The data to upload. Valid values
|
|
161
|
+
# include:
|
|
162
|
+
#
|
|
163
|
+
# * A string
|
|
164
|
+
#
|
|
165
|
+
# * A Pathname object
|
|
166
|
+
#
|
|
167
|
+
# * Any object responding to +read+ and +eof?+; the object
|
|
168
|
+
# must support the following access methods:
|
|
169
|
+
#
|
|
170
|
+
# read # all at once
|
|
171
|
+
# read(length) until eof? # in chunks
|
|
172
|
+
#
|
|
173
|
+
# If you specify data this way, you must also include
|
|
174
|
+
# the +:content_length+ option.
|
|
175
|
+
#
|
|
176
|
+
# @option options [String] :file Can be specified instead of
|
|
177
|
+
# +:data+; its value specifies the path of a file to
|
|
178
|
+
# upload.
|
|
179
|
+
#
|
|
180
|
+
# @option options [Integer] :content_length If provided,
|
|
181
|
+
# this option must match the total number of bytes written
|
|
182
|
+
# to S3 during the operation. This option is required if
|
|
183
|
+
# +:data+ is an IO-like object without a +size+ method.
|
|
184
|
+
def add_part(data_or_options, options = {})
|
|
185
|
+
if data_or_options.kind_of?(Hash)
|
|
186
|
+
part_options = base_opts.merge(data_or_options)
|
|
187
|
+
else
|
|
188
|
+
part_options = base_opts.merge(:data => data_or_options)
|
|
189
|
+
end
|
|
190
|
+
part_options.merge!(options)
|
|
191
|
+
|
|
192
|
+
unless part_options[:part_number]
|
|
193
|
+
@increment_mutex.synchronize do
|
|
194
|
+
part_options[:part_number] = (@last_part += 1)
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
part_number = part_options[:part_number]
|
|
198
|
+
|
|
199
|
+
resp = client.upload_part(part_options)
|
|
200
|
+
@completed_mutex.synchronize do
|
|
201
|
+
@completed_parts[part_number] = {
|
|
202
|
+
:part_number => part_number,
|
|
203
|
+
:etag => resp.etag
|
|
204
|
+
}
|
|
205
|
+
end
|
|
206
|
+
UploadedPart.new(self, part_number)
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# Completes the upload by assembling previously uploaded
|
|
210
|
+
# parts.
|
|
211
|
+
#
|
|
212
|
+
# @return [S3Object, ObjectVersion] If the bucket has versioning
|
|
213
|
+
# enabled, returns the {ObjectVersion} representing the
|
|
214
|
+
# version that was uploaded. If versioning is disabled,
|
|
215
|
+
# returns the object.
|
|
216
|
+
def complete(*parts)
|
|
217
|
+
parts = parts.flatten
|
|
218
|
+
case parts.first
|
|
219
|
+
when :remote_parts
|
|
220
|
+
complete_opts = get_complete_opts
|
|
221
|
+
when :local_parts, nil
|
|
222
|
+
complete_opts = base_opts.merge(:parts => completed_parts)
|
|
223
|
+
else
|
|
224
|
+
part_numbers = parts.map do |part|
|
|
225
|
+
case part
|
|
226
|
+
when Integer
|
|
227
|
+
part
|
|
228
|
+
when UploadedPart
|
|
229
|
+
raise ArgumentError.new("cannot complete an upload with parts "+
|
|
230
|
+
"from a different upload") unless
|
|
231
|
+
part.upload == self
|
|
232
|
+
|
|
233
|
+
part.part_number
|
|
234
|
+
else
|
|
235
|
+
raise ArgumentError.new("expected number or UploadedPart")
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
complete_opts = get_complete_opts(part_numbers)
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
raise "no parts uploaded" if complete_opts[:parts].empty?
|
|
242
|
+
|
|
243
|
+
resp = client.complete_multipart_upload(complete_opts)
|
|
244
|
+
if resp.version_id
|
|
245
|
+
ObjectVersion.new(object, resp.version_id)
|
|
246
|
+
else
|
|
247
|
+
object
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
# Completes the upload or aborts it if no parts have been
|
|
252
|
+
# uploaded yet. Does nothing if the upload has already been
|
|
253
|
+
# aborted.
|
|
254
|
+
#
|
|
255
|
+
# @return [S3Object, ObjectVersion] If the bucket has versioning
|
|
256
|
+
# enabled, returns the {ObjectVersion} representing the
|
|
257
|
+
# version that was uploaded. If versioning is disabled,
|
|
258
|
+
# returns the object. If no upload was attempted (e.g. if it
|
|
259
|
+
# was aborted or if no parts were uploaded), returns +nil+.
|
|
260
|
+
def close
|
|
261
|
+
return if aborted?
|
|
262
|
+
if completed_parts.empty?
|
|
263
|
+
abort
|
|
264
|
+
else
|
|
265
|
+
complete
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
# @return [UploadedPartCollection] A collection representing
|
|
270
|
+
# the parts that have been uploaded to S3 for this upload.
|
|
271
|
+
def parts
|
|
272
|
+
UploadedPartCollection.new(self)
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
# @private
|
|
276
|
+
def completed_parts
|
|
277
|
+
@completed_parts.values.
|
|
278
|
+
sort { |a, b| a[:part_number] <=> b[:part_number] }
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
# @private
|
|
282
|
+
def inspect
|
|
283
|
+
"<#{self.class}:#{object.bucket.name}/#{object.key}:#{id}>"
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
# @private
|
|
287
|
+
private
|
|
288
|
+
def get_complete_opts(part_numbers = nil)
|
|
289
|
+
parts_resp = client.list_parts(base_opts)
|
|
290
|
+
complete_opts =
|
|
291
|
+
base_opts.merge(:parts =>
|
|
292
|
+
parts_resp.parts.map do |part|
|
|
293
|
+
{ :part_number => part.part_number,
|
|
294
|
+
:etag => part.etag }
|
|
295
|
+
end)
|
|
296
|
+
|
|
297
|
+
complete_opts[:parts].reject! do |part|
|
|
298
|
+
!part_numbers.include?(part[:part_number])
|
|
299
|
+
end if part_numbers
|
|
300
|
+
|
|
301
|
+
complete_opts
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
# @private
|
|
305
|
+
private
|
|
306
|
+
def base_opts
|
|
307
|
+
opts = {
|
|
308
|
+
:bucket_name => object.bucket.name,
|
|
309
|
+
:key => object.key
|
|
310
|
+
}
|
|
311
|
+
opts[:upload_id] = upload_id if upload_id
|
|
312
|
+
opts
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
end
|
|
318
|
+
end
|