aws_sdk 3.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (390) hide show
  1. data/lib/aws-sdk.rb +14 -0
  2. data/lib/aws.rb +49 -0
  3. data/lib/aws/api_config/AutoScaling-2011-01-01.yml +791 -0
  4. data/lib/aws/api_config/CloudFormation-2010-05-15.yml +303 -0
  5. data/lib/aws/api_config/DynamoDB-2011-12-05.yml +540 -0
  6. data/lib/aws/api_config/EC2-2011-12-15.yml +3638 -0
  7. data/lib/aws/api_config/EC2-2012-04-01.yml +3739 -0
  8. data/lib/aws/api_config/ELB-2011-08-15.yml +512 -0
  9. data/lib/aws/api_config/IAM-2010-05-08.yml +1221 -0
  10. data/lib/aws/api_config/SNS-2010-03-31.yml +248 -0
  11. data/lib/aws/api_config/SQS-2011-10-01.yml +314 -0
  12. data/lib/aws/api_config/STS-2011-06-15.yml +54 -0
  13. data/lib/aws/api_config/SimpleDB-2009-04-15.yml +305 -0
  14. data/lib/aws/api_config/SimpleEmailService-2010-12-01.yml +231 -0
  15. data/lib/aws/api_config/SimpleWorkflow-2012-01-25.yml +721 -0
  16. data/lib/aws/auto_scaling.rb +162 -0
  17. data/lib/aws/auto_scaling/activity.rb +102 -0
  18. data/lib/aws/auto_scaling/activity_collection.rb +82 -0
  19. data/lib/aws/auto_scaling/client.rb +765 -0
  20. data/lib/aws/auto_scaling/config.rb +18 -0
  21. data/lib/aws/auto_scaling/errors.rb +22 -0
  22. data/lib/aws/auto_scaling/group.rb +420 -0
  23. data/lib/aws/auto_scaling/group_collection.rb +96 -0
  24. data/lib/aws/auto_scaling/group_options.rb +146 -0
  25. data/lib/aws/auto_scaling/instance.rb +192 -0
  26. data/lib/aws/auto_scaling/instance_collection.rb +63 -0
  27. data/lib/aws/auto_scaling/launch_configuration.rb +150 -0
  28. data/lib/aws/auto_scaling/launch_configuration_collection.rb +144 -0
  29. data/lib/aws/auto_scaling/notification_configuration.rb +89 -0
  30. data/lib/aws/auto_scaling/notification_configuration_collection.rb +184 -0
  31. data/lib/aws/auto_scaling/request.rb +23 -0
  32. data/lib/aws/auto_scaling/scaling_policy.rb +125 -0
  33. data/lib/aws/auto_scaling/scaling_policy_collection.rb +72 -0
  34. data/lib/aws/auto_scaling/scaling_policy_options.rb +61 -0
  35. data/lib/aws/auto_scaling/scheduled_action.rb +145 -0
  36. data/lib/aws/auto_scaling/scheduled_action_collection.rb +195 -0
  37. data/lib/aws/auto_scaling/tag.rb +59 -0
  38. data/lib/aws/auto_scaling/tag_collection.rb +112 -0
  39. data/lib/aws/cloud_formation.rb +270 -0
  40. data/lib/aws/cloud_formation/client.rb +339 -0
  41. data/lib/aws/cloud_formation/config.rb +18 -0
  42. data/lib/aws/cloud_formation/errors.rb +22 -0
  43. data/lib/aws/cloud_formation/request.rb +29 -0
  44. data/lib/aws/cloud_formation/stack.rb +256 -0
  45. data/lib/aws/cloud_formation/stack_collection.rb +206 -0
  46. data/lib/aws/cloud_formation/stack_event.rb +75 -0
  47. data/lib/aws/cloud_formation/stack_event_collection.rb +47 -0
  48. data/lib/aws/cloud_formation/stack_options.rb +72 -0
  49. data/lib/aws/cloud_formation/stack_output.rb +53 -0
  50. data/lib/aws/cloud_formation/stack_resource.rb +117 -0
  51. data/lib/aws/cloud_formation/stack_resource_collection.rb +84 -0
  52. data/lib/aws/cloud_formation/stack_resource_summary_collection.rb +72 -0
  53. data/lib/aws/cloud_formation/stack_summary.rb +71 -0
  54. data/lib/aws/cloud_formation/stack_summary_collection.rb +127 -0
  55. data/lib/aws/core.rb +474 -0
  56. data/lib/aws/core/async_handle.rb +90 -0
  57. data/lib/aws/core/autoloader.rb +64 -0
  58. data/lib/aws/core/cacheable.rb +78 -0
  59. data/lib/aws/core/client.rb +541 -0
  60. data/lib/aws/core/client/query_json.rb +110 -0
  61. data/lib/aws/core/client/query_xml.rb +122 -0
  62. data/lib/aws/core/collection.rb +234 -0
  63. data/lib/aws/core/collection/limitable.rb +99 -0
  64. data/lib/aws/core/collection/simple.rb +90 -0
  65. data/lib/aws/core/configuration.rb +445 -0
  66. data/lib/aws/core/data.rb +242 -0
  67. data/lib/aws/core/default_signer.rb +67 -0
  68. data/lib/aws/core/http/curb_handler.rb +136 -0
  69. data/lib/aws/core/http/handler.rb +77 -0
  70. data/lib/aws/core/http/httparty_handler.rb +114 -0
  71. data/lib/aws/core/http/net_http_handler.rb +85 -0
  72. data/lib/aws/core/http/request.rb +250 -0
  73. data/lib/aws/core/http/response.rb +74 -0
  74. data/lib/aws/core/indifferent_hash.rb +88 -0
  75. data/lib/aws/core/inflection.rb +47 -0
  76. data/lib/aws/core/lazy_error_classes.rb +90 -0
  77. data/lib/aws/core/log_formatter.rb +454 -0
  78. data/lib/aws/core/meta_utils.rb +45 -0
  79. data/lib/aws/core/model.rb +57 -0
  80. data/lib/aws/core/naming.rb +30 -0
  81. data/lib/aws/core/option_grammar.rb +700 -0
  82. data/lib/aws/core/page_result.rb +73 -0
  83. data/lib/aws/core/policy.rb +916 -0
  84. data/lib/aws/core/resource.rb +408 -0
  85. data/lib/aws/core/resource_cache.rb +40 -0
  86. data/lib/aws/core/response.rb +202 -0
  87. data/lib/aws/core/response_cache.rb +50 -0
  88. data/lib/aws/core/service_interface.rb +61 -0
  89. data/lib/aws/core/session_signer.rb +90 -0
  90. data/lib/aws/core/signature/version_2.rb +42 -0
  91. data/lib/aws/core/signature/version_3.rb +73 -0
  92. data/lib/aws/core/signature/version_3_http.rb +72 -0
  93. data/lib/aws/core/signature/version_4.rb +138 -0
  94. data/lib/aws/core/uri_escape.rb +42 -0
  95. data/lib/aws/core/xml/frame.rb +242 -0
  96. data/lib/aws/core/xml/frame_stack.rb +85 -0
  97. data/lib/aws/core/xml/grammar.rb +299 -0
  98. data/lib/aws/core/xml/parser.rb +70 -0
  99. data/lib/aws/core/xml/root_frame.rb +65 -0
  100. data/lib/aws/core/xml/sax_handlers/libxml.rb +47 -0
  101. data/lib/aws/core/xml/sax_handlers/nokogiri.rb +55 -0
  102. data/lib/aws/core/xml/sax_handlers/ox.rb +41 -0
  103. data/lib/aws/core/xml/sax_handlers/rexml.rb +43 -0
  104. data/lib/aws/core/xml/stub.rb +123 -0
  105. data/lib/aws/dynamo_db.rb +213 -0
  106. data/lib/aws/dynamo_db/attribute_collection.rb +460 -0
  107. data/lib/aws/dynamo_db/batch_get.rb +206 -0
  108. data/lib/aws/dynamo_db/batch_write.rb +251 -0
  109. data/lib/aws/dynamo_db/client.rb +888 -0
  110. data/lib/aws/dynamo_db/config.rb +20 -0
  111. data/lib/aws/dynamo_db/errors.rb +20 -0
  112. data/lib/aws/dynamo_db/expectations.rb +40 -0
  113. data/lib/aws/dynamo_db/item.rb +130 -0
  114. data/lib/aws/dynamo_db/item_collection.rb +852 -0
  115. data/lib/aws/dynamo_db/item_data.rb +31 -0
  116. data/lib/aws/dynamo_db/keys.rb +41 -0
  117. data/lib/aws/dynamo_db/primary_key_element.rb +47 -0
  118. data/lib/aws/dynamo_db/request.rb +28 -0
  119. data/lib/aws/dynamo_db/resource.rb +33 -0
  120. data/lib/aws/dynamo_db/table.rb +489 -0
  121. data/lib/aws/dynamo_db/table_collection.rb +165 -0
  122. data/lib/aws/dynamo_db/types.rb +86 -0
  123. data/lib/aws/ec2.rb +431 -0
  124. data/lib/aws/ec2/attachment.rb +140 -0
  125. data/lib/aws/ec2/attachment_collection.rb +54 -0
  126. data/lib/aws/ec2/availability_zone.rb +87 -0
  127. data/lib/aws/ec2/availability_zone_collection.rb +43 -0
  128. data/lib/aws/ec2/block_device_mappings.rb +53 -0
  129. data/lib/aws/ec2/client.rb +4121 -0
  130. data/lib/aws/ec2/collection.rb +36 -0
  131. data/lib/aws/ec2/config.rb +18 -0
  132. data/lib/aws/ec2/config_transform.rb +63 -0
  133. data/lib/aws/ec2/customer_gateway.rb +90 -0
  134. data/lib/aws/ec2/customer_gateway_collection.rb +73 -0
  135. data/lib/aws/ec2/dhcp_options.rb +106 -0
  136. data/lib/aws/ec2/dhcp_options_collection.rb +87 -0
  137. data/lib/aws/ec2/elastic_ip.rb +157 -0
  138. data/lib/aws/ec2/elastic_ip_collection.rb +97 -0
  139. data/lib/aws/ec2/errors.rb +32 -0
  140. data/lib/aws/ec2/filtered_collection.rb +90 -0
  141. data/lib/aws/ec2/has_permissions.rb +44 -0
  142. data/lib/aws/ec2/image.rb +254 -0
  143. data/lib/aws/ec2/image_collection.rb +228 -0
  144. data/lib/aws/ec2/instance.rb +669 -0
  145. data/lib/aws/ec2/instance_collection.rb +346 -0
  146. data/lib/aws/ec2/internet_gateway.rb +122 -0
  147. data/lib/aws/ec2/internet_gateway/attachment.rb +78 -0
  148. data/lib/aws/ec2/internet_gateway_collection.rb +54 -0
  149. data/lib/aws/ec2/key_pair.rb +82 -0
  150. data/lib/aws/ec2/key_pair_collection.rb +99 -0
  151. data/lib/aws/ec2/network_acl.rb +256 -0
  152. data/lib/aws/ec2/network_acl/association.rb +56 -0
  153. data/lib/aws/ec2/network_acl/entry.rb +147 -0
  154. data/lib/aws/ec2/network_acl_collection.rb +64 -0
  155. data/lib/aws/ec2/network_interface.rb +228 -0
  156. data/lib/aws/ec2/network_interface/attachment.rb +100 -0
  157. data/lib/aws/ec2/network_interface_collection.rb +103 -0
  158. data/lib/aws/ec2/permission_collection.rb +174 -0
  159. data/lib/aws/ec2/region.rb +97 -0
  160. data/lib/aws/ec2/region_collection.rb +51 -0
  161. data/lib/aws/ec2/request.rb +22 -0
  162. data/lib/aws/ec2/reserved_instances.rb +53 -0
  163. data/lib/aws/ec2/reserved_instances_collection.rb +40 -0
  164. data/lib/aws/ec2/reserved_instances_offering.rb +58 -0
  165. data/lib/aws/ec2/reserved_instances_offering_collection.rb +39 -0
  166. data/lib/aws/ec2/resource.rb +161 -0
  167. data/lib/aws/ec2/resource_tag_collection.rb +211 -0
  168. data/lib/aws/ec2/route_table.rb +205 -0
  169. data/lib/aws/ec2/route_table/association.rb +119 -0
  170. data/lib/aws/ec2/route_table/route.rb +113 -0
  171. data/lib/aws/ec2/route_table_collection.rb +72 -0
  172. data/lib/aws/ec2/security_group.rb +458 -0
  173. data/lib/aws/ec2/security_group/egress_ip_permission_collection.rb +63 -0
  174. data/lib/aws/ec2/security_group/ingress_ip_permission_collection.rb +61 -0
  175. data/lib/aws/ec2/security_group/ip_permission.rb +128 -0
  176. data/lib/aws/ec2/security_group_collection.rb +135 -0
  177. data/lib/aws/ec2/snapshot.rb +143 -0
  178. data/lib/aws/ec2/snapshot_collection.rb +131 -0
  179. data/lib/aws/ec2/subnet.rb +161 -0
  180. data/lib/aws/ec2/subnet_collection.rb +115 -0
  181. data/lib/aws/ec2/tag.rb +81 -0
  182. data/lib/aws/ec2/tag_collection.rb +107 -0
  183. data/lib/aws/ec2/tagged_collection.rb +53 -0
  184. data/lib/aws/ec2/tagged_item.rb +85 -0
  185. data/lib/aws/ec2/volume.rb +170 -0
  186. data/lib/aws/ec2/volume_collection.rb +97 -0
  187. data/lib/aws/ec2/vpc.rb +166 -0
  188. data/lib/aws/ec2/vpc_collection.rb +70 -0
  189. data/lib/aws/ec2/vpn_connection.rb +99 -0
  190. data/lib/aws/ec2/vpn_connection/telemetry.rb +49 -0
  191. data/lib/aws/ec2/vpn_connection_collection.rb +96 -0
  192. data/lib/aws/ec2/vpn_gateway.rb +123 -0
  193. data/lib/aws/ec2/vpn_gateway/attachment.rb +45 -0
  194. data/lib/aws/ec2/vpn_gateway_collection.rb +77 -0
  195. data/lib/aws/elb.rb +65 -0
  196. data/lib/aws/elb/availability_zone_collection.rb +138 -0
  197. data/lib/aws/elb/backend_server_policy_collection.rb +140 -0
  198. data/lib/aws/elb/client.rb +539 -0
  199. data/lib/aws/elb/config.rb +18 -0
  200. data/lib/aws/elb/errors.rb +26 -0
  201. data/lib/aws/elb/instance_collection.rb +174 -0
  202. data/lib/aws/elb/listener.rb +189 -0
  203. data/lib/aws/elb/listener_collection.rb +119 -0
  204. data/lib/aws/elb/listener_opts.rb +45 -0
  205. data/lib/aws/elb/load_balancer.rb +253 -0
  206. data/lib/aws/elb/load_balancer_collection.rb +113 -0
  207. data/lib/aws/elb/load_balancer_policy.rb +93 -0
  208. data/lib/aws/elb/load_balancer_policy_collection.rb +208 -0
  209. data/lib/aws/elb/request.rb +23 -0
  210. data/lib/aws/errors.rb +122 -0
  211. data/lib/aws/iam.rb +418 -0
  212. data/lib/aws/iam/access_key.rb +180 -0
  213. data/lib/aws/iam/access_key_collection.rb +128 -0
  214. data/lib/aws/iam/account_alias_collection.rb +79 -0
  215. data/lib/aws/iam/client.rb +1609 -0
  216. data/lib/aws/iam/collection.rb +83 -0
  217. data/lib/aws/iam/config.rb +18 -0
  218. data/lib/aws/iam/errors.rb +22 -0
  219. data/lib/aws/iam/group.rb +111 -0
  220. data/lib/aws/iam/group_collection.rb +132 -0
  221. data/lib/aws/iam/group_policy_collection.rb +47 -0
  222. data/lib/aws/iam/group_user_collection.rb +84 -0
  223. data/lib/aws/iam/login_profile.rb +99 -0
  224. data/lib/aws/iam/mfa_device.rb +52 -0
  225. data/lib/aws/iam/mfa_device_collection.rb +127 -0
  226. data/lib/aws/iam/policy.rb +46 -0
  227. data/lib/aws/iam/policy_collection.rb +188 -0
  228. data/lib/aws/iam/request.rb +29 -0
  229. data/lib/aws/iam/resource.rb +71 -0
  230. data/lib/aws/iam/server_certificate.rb +141 -0
  231. data/lib/aws/iam/server_certificate_collection.rb +138 -0
  232. data/lib/aws/iam/signing_certificate.rb +169 -0
  233. data/lib/aws/iam/signing_certificate_collection.rb +131 -0
  234. data/lib/aws/iam/user.rb +205 -0
  235. data/lib/aws/iam/user_collection.rb +133 -0
  236. data/lib/aws/iam/user_group_collection.rb +98 -0
  237. data/lib/aws/iam/user_policy.rb +90 -0
  238. data/lib/aws/iam/user_policy_collection.rb +45 -0
  239. data/lib/aws/iam/virtual_mfa_device.rb +139 -0
  240. data/lib/aws/iam/virtual_mfa_device_collection.rb +73 -0
  241. data/lib/aws/rails.rb +195 -0
  242. data/lib/aws/record.rb +116 -0
  243. data/lib/aws/record/abstract_base.rb +645 -0
  244. data/lib/aws/record/attributes.rb +384 -0
  245. data/lib/aws/record/conversion.rb +38 -0
  246. data/lib/aws/record/dirty_tracking.rb +285 -0
  247. data/lib/aws/record/errors.rb +143 -0
  248. data/lib/aws/record/exceptions.rb +48 -0
  249. data/lib/aws/record/hash_model.rb +161 -0
  250. data/lib/aws/record/hash_model/attributes.rb +182 -0
  251. data/lib/aws/record/hash_model/finder_methods.rb +172 -0
  252. data/lib/aws/record/hash_model/scope.rb +108 -0
  253. data/lib/aws/record/model.rb +427 -0
  254. data/lib/aws/record/model/attributes.rb +379 -0
  255. data/lib/aws/record/model/finder_methods.rb +232 -0
  256. data/lib/aws/record/model/scope.rb +213 -0
  257. data/lib/aws/record/naming.rb +31 -0
  258. data/lib/aws/record/scope.rb +199 -0
  259. data/lib/aws/record/validations.rb +694 -0
  260. data/lib/aws/record/validator.rb +237 -0
  261. data/lib/aws/record/validators/acceptance.rb +51 -0
  262. data/lib/aws/record/validators/block.rb +38 -0
  263. data/lib/aws/record/validators/confirmation.rb +43 -0
  264. data/lib/aws/record/validators/count.rb +108 -0
  265. data/lib/aws/record/validators/exclusion.rb +43 -0
  266. data/lib/aws/record/validators/format.rb +57 -0
  267. data/lib/aws/record/validators/inclusion.rb +56 -0
  268. data/lib/aws/record/validators/length.rb +107 -0
  269. data/lib/aws/record/validators/method.rb +33 -0
  270. data/lib/aws/record/validators/numericality.rb +138 -0
  271. data/lib/aws/record/validators/presence.rb +45 -0
  272. data/lib/aws/s3.rb +135 -0
  273. data/lib/aws/s3/access_control_list.rb +250 -0
  274. data/lib/aws/s3/acl_object.rb +264 -0
  275. data/lib/aws/s3/bucket.rb +393 -0
  276. data/lib/aws/s3/bucket_collection.rb +143 -0
  277. data/lib/aws/s3/bucket_lifecycle_configuration.rb +360 -0
  278. data/lib/aws/s3/bucket_version_collection.rb +77 -0
  279. data/lib/aws/s3/client.rb +1184 -0
  280. data/lib/aws/s3/client/xml.rb +177 -0
  281. data/lib/aws/s3/config.rb +26 -0
  282. data/lib/aws/s3/data_options.rb +100 -0
  283. data/lib/aws/s3/errors.rb +81 -0
  284. data/lib/aws/s3/multipart_upload.rb +317 -0
  285. data/lib/aws/s3/multipart_upload_collection.rb +68 -0
  286. data/lib/aws/s3/object_collection.rb +337 -0
  287. data/lib/aws/s3/object_metadata.rb +96 -0
  288. data/lib/aws/s3/object_upload_collection.rb +77 -0
  289. data/lib/aws/s3/object_version.rb +143 -0
  290. data/lib/aws/s3/object_version_collection.rb +89 -0
  291. data/lib/aws/s3/paginated_collection.rb +75 -0
  292. data/lib/aws/s3/policy.rb +74 -0
  293. data/lib/aws/s3/prefix_and_delimiter_collection.rb +47 -0
  294. data/lib/aws/s3/prefixed_collection.rb +81 -0
  295. data/lib/aws/s3/presigned_post.rb +553 -0
  296. data/lib/aws/s3/request.rb +201 -0
  297. data/lib/aws/s3/s3_object.rb +1037 -0
  298. data/lib/aws/s3/tree.rb +118 -0
  299. data/lib/aws/s3/tree/branch_node.rb +68 -0
  300. data/lib/aws/s3/tree/child_collection.rb +104 -0
  301. data/lib/aws/s3/tree/leaf_node.rb +94 -0
  302. data/lib/aws/s3/tree/node.rb +22 -0
  303. data/lib/aws/s3/tree/parent.rb +87 -0
  304. data/lib/aws/s3/uploaded_part.rb +80 -0
  305. data/lib/aws/s3/uploaded_part_collection.rb +84 -0
  306. data/lib/aws/simple_db.rb +217 -0
  307. data/lib/aws/simple_db/attribute.rb +154 -0
  308. data/lib/aws/simple_db/attribute_collection.rb +231 -0
  309. data/lib/aws/simple_db/client.rb +349 -0
  310. data/lib/aws/simple_db/config.rb +20 -0
  311. data/lib/aws/simple_db/consistent_read_option.rb +42 -0
  312. data/lib/aws/simple_db/delete_attributes.rb +62 -0
  313. data/lib/aws/simple_db/domain.rb +121 -0
  314. data/lib/aws/simple_db/domain_collection.rb +113 -0
  315. data/lib/aws/simple_db/domain_metadata.rb +110 -0
  316. data/lib/aws/simple_db/errors.rb +55 -0
  317. data/lib/aws/simple_db/expect_condition_option.rb +45 -0
  318. data/lib/aws/simple_db/item.rb +93 -0
  319. data/lib/aws/simple_db/item_collection.rb +649 -0
  320. data/lib/aws/simple_db/item_data.rb +73 -0
  321. data/lib/aws/simple_db/put_attributes.rb +60 -0
  322. data/lib/aws/simple_db/request.rb +23 -0
  323. data/lib/aws/simple_email_service.rb +426 -0
  324. data/lib/aws/simple_email_service/client.rb +286 -0
  325. data/lib/aws/simple_email_service/config.rb +19 -0
  326. data/lib/aws/simple_email_service/email_address_collection.rb +69 -0
  327. data/lib/aws/simple_email_service/errors.rb +22 -0
  328. data/lib/aws/simple_email_service/identity.rb +91 -0
  329. data/lib/aws/simple_email_service/identity_collection.rb +81 -0
  330. data/lib/aws/simple_email_service/quotas.rb +64 -0
  331. data/lib/aws/simple_email_service/request.rb +29 -0
  332. data/lib/aws/simple_workflow.rb +226 -0
  333. data/lib/aws/simple_workflow/activity_task.rb +173 -0
  334. data/lib/aws/simple_workflow/activity_task_collection.rb +123 -0
  335. data/lib/aws/simple_workflow/activity_type.rb +131 -0
  336. data/lib/aws/simple_workflow/activity_type_collection.rb +93 -0
  337. data/lib/aws/simple_workflow/client.rb +1434 -0
  338. data/lib/aws/simple_workflow/config.rb +18 -0
  339. data/lib/aws/simple_workflow/count.rb +49 -0
  340. data/lib/aws/simple_workflow/decision_task.rb +601 -0
  341. data/lib/aws/simple_workflow/decision_task_collection.rb +225 -0
  342. data/lib/aws/simple_workflow/domain.rb +122 -0
  343. data/lib/aws/simple_workflow/domain_collection.rb +169 -0
  344. data/lib/aws/simple_workflow/errors.rb +20 -0
  345. data/lib/aws/simple_workflow/history_event.rb +276 -0
  346. data/lib/aws/simple_workflow/history_event_collection.rb +76 -0
  347. data/lib/aws/simple_workflow/option_formatters.rb +82 -0
  348. data/lib/aws/simple_workflow/request.rb +36 -0
  349. data/lib/aws/simple_workflow/resource.rb +94 -0
  350. data/lib/aws/simple_workflow/type.rb +89 -0
  351. data/lib/aws/simple_workflow/type_collection.rb +140 -0
  352. data/lib/aws/simple_workflow/workflow_execution.rb +386 -0
  353. data/lib/aws/simple_workflow/workflow_execution_collection.rb +617 -0
  354. data/lib/aws/simple_workflow/workflow_type.rb +177 -0
  355. data/lib/aws/simple_workflow/workflow_type_collection.rb +91 -0
  356. data/lib/aws/sns.rb +74 -0
  357. data/lib/aws/sns/client.rb +371 -0
  358. data/lib/aws/sns/config.rb +18 -0
  359. data/lib/aws/sns/errors.rb +22 -0
  360. data/lib/aws/sns/has_delivery_policy.rb +68 -0
  361. data/lib/aws/sns/policy.rb +47 -0
  362. data/lib/aws/sns/request.rb +23 -0
  363. data/lib/aws/sns/subscription.rb +144 -0
  364. data/lib/aws/sns/subscription_collection.rb +80 -0
  365. data/lib/aws/sns/topic.rb +403 -0
  366. data/lib/aws/sns/topic_collection.rb +67 -0
  367. data/lib/aws/sns/topic_subscription_collection.rb +55 -0
  368. data/lib/aws/sqs.rb +79 -0
  369. data/lib/aws/sqs/client.rb +360 -0
  370. data/lib/aws/sqs/config.rb +18 -0
  371. data/lib/aws/sqs/errors.rb +101 -0
  372. data/lib/aws/sqs/policy.rb +48 -0
  373. data/lib/aws/sqs/queue.rb +725 -0
  374. data/lib/aws/sqs/queue_collection.rb +170 -0
  375. data/lib/aws/sqs/received_message.rb +181 -0
  376. data/lib/aws/sqs/received_sns_message.rb +112 -0
  377. data/lib/aws/sqs/request.rb +43 -0
  378. data/lib/aws/sts.rb +152 -0
  379. data/lib/aws/sts/client.rb +105 -0
  380. data/lib/aws/sts/config.rb +18 -0
  381. data/lib/aws/sts/errors.rb +22 -0
  382. data/lib/aws/sts/federated_session.rb +56 -0
  383. data/lib/aws/sts/policy.rb +30 -0
  384. data/lib/aws/sts/request.rb +29 -0
  385. data/lib/aws/sts/session.rb +48 -0
  386. data/lib/net/http/connection_pool.rb +210 -0
  387. data/lib/net/http/connection_pool/connection.rb +132 -0
  388. data/lib/net/http/connection_pool/session.rb +93 -0
  389. data/lib/user.rb +49 -0
  390. metadata +433 -0
@@ -0,0 +1,360 @@
1
+ # Copyright 2011-2012 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 'builder'
15
+ require 'uuidtools'
16
+
17
+ module AWS
18
+ class S3
19
+
20
+ # A lifecycle configuration is collections of rules for a single
21
+ # bucket that instructs that instruct
22
+ # Amazon S3 to delete certain objects after a period of days.
23
+ #
24
+ # == Rules
25
+ #
26
+ # Each lifecycle configuration has a list of rules. Each rule has the
27
+ # following attributes:
28
+ #
29
+ # * +#prefix+
30
+ # * +#expiration_days+
31
+ # * +#status+
32
+ # * +#id+
33
+ #
34
+ # Objects with keys matching a rule prefix will be deleted after
35
+ # #expiration_days have passed.
36
+ #
37
+ # A rule is comprised primarily of a prefix and number of expiration days.
38
+ # Objects with keys that start with the given prefix will be automatically
39
+ # deleted after "expiration days" have passed. Rules also have an
40
+ # ID and a status (they can be disabled).
41
+ #
42
+ # See {Rule} for more information on all of the attributes and methods
43
+ # available for rules.
44
+ #
45
+ # == Adding Rules
46
+ #
47
+ # You can add a rule to a bucket lifecycle configuration using {#add_rule}.
48
+ #
49
+ # # add a rule that deletes backups after they are 1 year old
50
+ # bucket.lifecycle_configuration.update do
51
+ # add_rule('backups/', 365)
52
+ # end
53
+ #
54
+ # If you perfer to specify a rule's ID or status (defaults to 'Enabled')
55
+ # you can do this with {#add_rule}.
56
+ #
57
+ # # add a rule that deletes backups after they are 1 year old
58
+ # bucket.lifecycle_configuration.update do
59
+ # add_rule('backups/', 365, :id => 'backup-rule', :disabled => true
60
+ # end
61
+ #
62
+ # == Replacing Rules
63
+ #
64
+ # If you prefer to completely replace a lifecycle configuration, call
65
+ # {#add_rule} inside a #replace block instead of an #update block:
66
+ #
67
+ # # replace all existing rules with the following
68
+ # bucket.lifecycle_configuration.replace do
69
+ # add_rule('backups/', 30)
70
+ # add_rule('temp/', 10)
71
+ # end
72
+ #
73
+ # == Removing Rules
74
+ #
75
+ # You can delete specific rules with #remove_rule.
76
+ #
77
+ # # delete all disabled rules
78
+ # bucket.lifecycle_configuration.update do
79
+ # rules.each do |rule|
80
+ # remove_rule(rule) if rule.disabled?
81
+ # end
82
+ # end
83
+ #
84
+ # You can also remove all rules in a single call:
85
+ #
86
+ # # remove all rules from this lifecycle configuration
87
+ # bucket.lifecycle_configuration.clear
88
+ #
89
+ # == Editing Existing Rules
90
+ #
91
+ # You can also make changes to existing rules.
92
+ #
93
+ # # change the expiration days to 10 for EVERY rule
94
+ # bucket.lifecycle_configuration.update do
95
+ # rules.each do |rule|
96
+ # rule.expiration_days = 10
97
+ # end
98
+ # end
99
+ #
100
+ # Please be aware, if you add, remove or edit rules outside of an
101
+ # #update or #replace block, then you must call {#update} yourself
102
+ # or the changes will not be persisted.
103
+ #
104
+ class BucketLifecycleConfiguration
105
+
106
+ # @private
107
+ def initialize bucket, options = {}
108
+ @bucket = bucket
109
+ @rules = parse_xml(options[:xml]) if options[:xml]
110
+ @rules = [] if options[:empty] == true
111
+ end
112
+
113
+ # @return [Bucket] Returns the bucket this lifecycle configuration
114
+ # belongs to.
115
+ attr_reader :bucket
116
+
117
+ # @return [Array<Hash>] Returns an array of rules.
118
+ def rules
119
+ @rules ||= begin
120
+ begin
121
+ opts = { :bucket_name => bucket.name }
122
+ response = bucket.client.get_bucket_lifecycle_configuration(opts)
123
+ parse_xml(response.http_response.body)
124
+ rescue Errors::NoSuchLifecycleConfiguration
125
+ []
126
+ end
127
+ end
128
+ end
129
+
130
+ # @param [String] prefix
131
+ #
132
+ # @param [Integer] expiration_days Indicates the lifetime for objects
133
+ # matching the given prefix.
134
+ #
135
+ # @param [Hash] options
136
+ #
137
+ # @option options [String] :id A unique ID for this rule. If an ID
138
+ # is not provided, one will be generated.
139
+ #
140
+ # @option options [Boolean] :disabled (false) By default, all rules
141
+ # will have the status of enabled. You can override this default
142
+ # by passing +:disabled+ => true.
143
+ #
144
+ # @return [Rule] Returns the rule that was added, as a {Rule} object.
145
+ #
146
+ def add_rule prefix, expiration_days, options = {}
147
+ id = options[:id] || UUIDTools::UUID.random_create.to_s
148
+ status = options[:disabled] == true ? 'Disabled' : 'Enabled'
149
+ rule = Rule.new(self, id, prefix, expiration_days, status)
150
+ self.rules << rule
151
+ rule
152
+ end
153
+
154
+ # Removes a single rule. You can pass a rule id or a {Rule}
155
+ # object.
156
+ #
157
+ # # remove a single rule by its ID
158
+ # bucket.lifecycle_configuration.update do
159
+ # remove_rule('rule-id')
160
+ # end
161
+ #
162
+ # # remove all disabled rules
163
+ # bucket.lifecycle_configuration.update do
164
+ # rules.each do |rule|
165
+ # remove_rule(rule) if rule.disabled?
166
+ # end
167
+ # end
168
+ #
169
+ # If you call #remove_rule outside an update block
170
+ # you need to call #update to save the changes.
171
+ #
172
+ # @param [Rule,String] rule_or_rule_id
173
+ #
174
+ # @return [nil]
175
+ #
176
+ def remove_rule rule_or_rule_id
177
+ rule_id = rule_or_rule_id
178
+ if rule_id.nil?
179
+ raise ArgumentError, "expected a rule or rule id, got nil"
180
+ end
181
+ rule_id = rule_id.id unless rule_id.is_a?(String)
182
+ @rules = rules.select{|r| r.id != rule_id }
183
+ nil
184
+ end
185
+
186
+ # Saves changes made to this lifecycle configuration.
187
+ #
188
+ # # set the number of days before expiration for all rules to 10
189
+ # config = bucket.lifecycle_configuration
190
+ # config.rules.each do |rule|
191
+ # rule.expiration_days = 10
192
+ # end
193
+ # config.update
194
+ #
195
+ # You can call #update with a block. Changes are persisted at the
196
+ # end of the block.
197
+ #
198
+ # # shorter version of the example above
199
+ # bucket.lifecycle_configuration.update do
200
+ # rules.each {|rule| rule.expiration_days = 10 }
201
+ # end
202
+ #
203
+ # A block method for updating a BucketLifecycleConfiguration.
204
+ # All modifications made inside the block are persisted at the end of
205
+ # the block.
206
+ #
207
+ # # 1 request
208
+ # bucket.lifecycle_configuration.update do
209
+ # add_rule 'prefix/a', 10
210
+ # add_rule 'prefix/b', 5
211
+ # end
212
+ #
213
+ # # 2 requests
214
+ # bucket.lifecycle_configuration.add_rule 'prefix/a', 10
215
+ # bucket.lifecycle_configuration.add_rule 'prefix/b', 5
216
+ #
217
+ # @return [nil]
218
+ #
219
+ def update &block
220
+ begin
221
+ @batching = true
222
+ instance_eval(&block) if block_given?
223
+ persist(true)
224
+ ensure
225
+ @batching = false
226
+ end
227
+ nil
228
+ end
229
+
230
+ # Yields to the given block. Before yielding, the current
231
+ # rules will be blanked out. This allows you to provide all
232
+ # new rules.
233
+ #
234
+ # When the block is complete, a single call will be made to save
235
+ # the new rules.
236
+ #
237
+ # bucket.lifecycle_configuration.rules.size #=> 3
238
+ #
239
+ # # replace the existing 3 rules with a single rule
240
+ # bucket.lifecycle_configuration.replace
241
+ # add_rule 'temp/', 10
242
+ # end
243
+ #
244
+ # bucket.lifecycle_configuration.rules.size #=> 1
245
+ #
246
+ def replace &block
247
+ @rules = []
248
+ update(&block)
249
+ end
250
+
251
+ def clear
252
+ @rules = []
253
+ bucket.lifecycle_configuration = nil
254
+ end
255
+ alias_method :remove, :clear
256
+
257
+ # @return [String] Returns an xml string representation of this
258
+ # bucket lifecycle configuration.
259
+ def to_xml
260
+ xml = Builder::XmlMarkup.new(:indent => 2)
261
+ xml.LifecycleConfiguration do
262
+ rules.each do |rule|
263
+ xml.Rule do
264
+ xml.ID rule.id
265
+ xml.Prefix rule.prefix
266
+ xml.Status rule.status
267
+ xml.Expiration do
268
+ xml.Days rule.expiration_days
269
+ end
270
+ end
271
+ end
272
+ end.strip
273
+ end
274
+
275
+ protected
276
+ def persist force = false
277
+ unless @batching and force == false
278
+ if rules.empty?
279
+ bucket.lifecycle_configuration = nil
280
+ else
281
+ bucket.lifecycle_configuration = self
282
+ end
283
+ end
284
+ end
285
+
286
+ protected
287
+ def parse_xml xml
288
+ Client::XML::GetBucketLifecycleConfiguration.parse(xml).rules.map do |r|
289
+ Rule.new(self, r.id, r.prefix, r.expiration.days, r.status)
290
+ end
291
+ end
292
+
293
+ # Represents a single rule from an Amazon S3 bucket lifecycle
294
+ # configuration.
295
+ #
296
+ # # delete all objects with the prefix 'temporary/' after 10 days
297
+ # bucket.lifecycle_configuration.add_rule 'temporary/', 10
298
+ #
299
+ # # remove the rule created above
300
+ # bucket.lifecycle_configuration.remove_rule 'temporary/'
301
+ #
302
+ #
303
+ class Rule
304
+
305
+ def initialize configuration, id, prefix, expiration_days, status
306
+ @configuration = configuration
307
+ @id = id
308
+ @prefix = prefix
309
+ @expiration_days = expiration_days
310
+ @status = status
311
+ end
312
+
313
+ # @return [BucketLifecycleConfiguration]
314
+ attr_reader :configuration
315
+
316
+ # @return [String]
317
+ attr_reader :id
318
+
319
+ # @return [String]
320
+ attr_accessor :prefix
321
+
322
+ # @return [Integer]
323
+ attr_accessor :expiration_days
324
+
325
+ # @return [String] Returns the rule status, 'Enabled' or 'Disabled'
326
+ attr_accessor :status
327
+
328
+ def enabled?
329
+ status == 'Enabled'
330
+ end
331
+
332
+ def enable!
333
+ self.status = 'Enabled'
334
+ end
335
+
336
+ def disabled?
337
+ status == 'Disabled'
338
+ end
339
+
340
+ def disabled!
341
+ self.status = 'Disabled'
342
+ end
343
+
344
+ # @private
345
+ def eql? other
346
+ other.is_a?(Rule) and
347
+ other.configuration.bucket == configuration.bucket and
348
+ other.id == id and
349
+ other.prefix == prefix and
350
+ other.expiration_days == expiration_days and
351
+ other.status == status
352
+ end
353
+ alias_method :==, :eql?
354
+
355
+ end
356
+
357
+ end
358
+
359
+ end
360
+ end
@@ -0,0 +1,77 @@
1
+ # Copyright 2011-2012 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
+ module AWS
15
+ class S3
16
+
17
+ # A collection of versioned objects for the entire bucket.
18
+ #
19
+ # @see PrefixedCollection
20
+ class BucketVersionCollection
21
+
22
+ include PrefixAndDelimiterCollection
23
+
24
+ # @param [Bucket] bucket
25
+ def initialize bucket, options = {}
26
+ @bucket = bucket
27
+ super
28
+ end
29
+
30
+ # @return [Bucket] The bucket this collection belongs to.
31
+ attr_reader :bucket
32
+
33
+ # @return [ObjectVersion] Returns the most recently created object
34
+ # version in the entire bucket.
35
+ def latest
36
+ first
37
+ #self.find{|version| true }
38
+ end
39
+
40
+ # Yields once for each version in the bucket.
41
+ #
42
+ # @yield [object_version]
43
+ #
44
+ # @yieldparam [ObjectVersion] object_version
45
+ #
46
+ # @return nil
47
+ #
48
+ def each options = {}, &block; super; end
49
+
50
+ # @private
51
+ protected
52
+ def each_member_in_page(page, &block)
53
+ super
54
+ page.versions.each do |version|
55
+ object_version = ObjectVersion.new(bucket.objects[version.key],
56
+ version.version_id, :delete_marker => version.delete_marker?)
57
+ yield(object_version)
58
+ end
59
+ end
60
+
61
+ # @private
62
+ protected
63
+ def list_request(options)
64
+ client.list_object_versions(options)
65
+ end
66
+
67
+ # @private
68
+ protected
69
+ def limit_param; :max_keys; end
70
+
71
+ # @private
72
+ protected
73
+ def pagination_markers; super + [:version_id_marker]; end
74
+
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,1184 @@
1
+ # Copyright 2011-2012 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 'rexml/document'
15
+ require 'pathname'
16
+ require 'stringio'
17
+ require 'json'
18
+ require 'digest/md5'
19
+
20
+ module AWS
21
+ class S3
22
+
23
+ # Client class for Amazon Simple Storage Service (S3).
24
+ class Client < Core::Client
25
+
26
+ API_VERSION = '2006-03-01'
27
+
28
+ XMLNS = "http://s3.amazonaws.com/doc/#{API_VERSION}/"
29
+
30
+ AWS.register_autoloads(self) do
31
+ autoload :XML, 'xml'
32
+ end
33
+
34
+ # @private
35
+ EMPTY_BODY_ERRORS = {
36
+ 304 => Errors::NotModified,
37
+ 404 => Errors::NoSuchKey
38
+ }
39
+
40
+ # @private
41
+ CACHEABLE_REQUESTS = Set[]
42
+
43
+ include DataOptions
44
+ include Core::UriEscape
45
+
46
+ protected
47
+
48
+ def self.bucket_method(method_name, verb, *args, &block)
49
+
50
+ method_options = (args.pop if args.last.kind_of?(Hash)) || {}
51
+ xml_grammar = (args.pop if args.last.respond_to?(:rules))
52
+ verb = verb.to_s.upcase
53
+ subresource = args.first
54
+
55
+ add_client_request_method(method_name) do
56
+
57
+ configure_request do |req, options|
58
+ require_bucket_name!(options[:bucket_name])
59
+ req.http_method = verb
60
+ req.bucket = options[:bucket_name]
61
+ req.add_param(subresource) if subresource
62
+
63
+ if header_options = method_options[:header_options]
64
+ header_options.each do |(option_name, header)|
65
+ req.headers[header] = options[option_name] if
66
+ options[option_name]
67
+ end
68
+ end
69
+
70
+ end
71
+
72
+ instance_eval(&block) if block
73
+
74
+ if xml_grammar
75
+
76
+ parser = Core::XML::Parser.new(xml_grammar.rules)
77
+
78
+ process_response do |resp|
79
+ resp.data = parser.parse(resp.http_response.body)
80
+ super(resp)
81
+ end
82
+
83
+ simulate_response do |resp|
84
+ resp.data = parser.simulate
85
+ super(resp)
86
+ end
87
+
88
+ end
89
+
90
+ end
91
+ end
92
+
93
+ def self.object_method(method_name, verb, *args, &block)
94
+ bucket_method(method_name, verb, *args) do
95
+ configure_request do |req, options|
96
+ validate_key!(options[:key])
97
+ super(req, options)
98
+ req.key = options[:key]
99
+ end
100
+
101
+ instance_eval(&block) if block
102
+ end
103
+ end
104
+
105
+ public
106
+
107
+ # Creates a bucket.
108
+ # @overload create_bucket(options = {})
109
+ # @param [Hash] options
110
+ # @option options [required,String] :bucket_name
111
+ # @return [Core::Response]
112
+ bucket_method(:create_bucket, :put) do
113
+ configure_request do |req, options|
114
+ validate_bucket_name!(options[:bucket_name])
115
+ req.canned_acl = options[:acl]
116
+ if location = options[:location_constraint]
117
+ xmlns = "http://s3.amazonaws.com/doc/#{API_VERSION}/"
118
+ req.body = <<-XML
119
+ <CreateBucketConfiguration xmlns="#{xmlns}">
120
+ <LocationConstraint>#{location}</LocationConstraint>
121
+ </CreateBucketConfiguration>
122
+ XML
123
+ end
124
+ super(req, options)
125
+ end
126
+ end
127
+
128
+ # Deletes an empty bucket.
129
+ # @overload delete_bucket(options = {})
130
+ # @param [Hash] options
131
+ # @option options [required,String] :bucket_name
132
+ # @return [Core::Response]
133
+ bucket_method(:delete_bucket, :delete)
134
+
135
+ # @overload set_bucket_lifecycle_configuration(options = {})
136
+ # @param [Hash] options
137
+ # @option options [required,String] :bucket_name
138
+ # @option options [required,String] :lifecycle_configuration
139
+ # @return [Core::Response]
140
+ bucket_method(:set_bucket_lifecycle_configuration, :put) do
141
+
142
+ configure_request do |req, options|
143
+ xml = options[:lifecycle_configuration]
144
+ md5 = Base64.encode64(Digest::MD5.digest(xml)).strip
145
+ req.add_param('lifecycle')
146
+ req.body = xml
147
+ req.headers['content-md5'] = md5
148
+ super(req, options)
149
+ end
150
+
151
+ end
152
+
153
+ # @overload get_bucket_lifecycle_configuration(options = {})
154
+ # @param [Hash] options
155
+ # @option options [required,String] :bucket_name
156
+ # @return [Core::Response]
157
+ bucket_method(:get_bucket_lifecycle_configuration, :get) do
158
+
159
+ configure_request do |req, options|
160
+ req.add_param('lifecycle')
161
+ super(req, options)
162
+ end
163
+
164
+ process_response do |resp|
165
+ xml = resp.http_response.body
166
+ resp.data = XML::GetBucketLifecycleConfiguration.parse(xml)
167
+ end
168
+
169
+ end
170
+
171
+ # @overload delete_bucket_lifecycle_configuration(options = {})
172
+ # @param [Hash] options
173
+ # @option options [required,String] :bucket_name
174
+ # @return [Core::Response]
175
+ bucket_method(:delete_bucket_lifecycle_configuration, :delete) do
176
+
177
+ configure_request do |req, options|
178
+ req.add_param('lifecycle')
179
+ super(req, options)
180
+ end
181
+
182
+ end
183
+
184
+ # @overload list_buckets(options = {})
185
+ # @param [Hash] options
186
+ # @return [Core::Response]
187
+ add_client_request_method(:list_buckets) do
188
+
189
+ configure_request do |req, options|
190
+ req.http_method = "GET"
191
+ end
192
+
193
+ process_response do |resp|
194
+ resp.data = XML::ListBuckets.parse(resp.http_response.body)
195
+ end
196
+
197
+ simulate_response do |resp|
198
+ resp.data = Core::XML::Parser.new(XML::ListBuckets.rules).simulate
199
+ end
200
+
201
+ end
202
+
203
+ # Sets the access policy for a bucket.
204
+ # @overload set_bucket_policy(options = {})
205
+ # @param [Hash] options
206
+ # @option options [required,String] :bucket_name
207
+ # @option options [required,String] :policy This can be a String
208
+ # or any object that responds to +#to_json+.
209
+ # @return [Core::Response]
210
+ bucket_method(:set_bucket_policy, :put, 'policy') do
211
+
212
+ configure_request do |req, options|
213
+ require_policy!(options[:policy])
214
+ super(req, options)
215
+ policy = options[:policy]
216
+ policy = policy.to_json unless policy.respond_to?(:to_str)
217
+ req.body = policy
218
+ end
219
+
220
+ end
221
+
222
+ # Gets the access policy for a bucket.
223
+ # @overload get_bucket_policy(options = {})
224
+ # @param [Hash] options
225
+ # @option options [required,String] :bucket_name
226
+ # @return [Core::Response]
227
+ bucket_method(:get_bucket_policy, :get, 'policy') do
228
+
229
+ process_response do |resp|
230
+ resp.data[:policy] = resp.http_response.body
231
+ end
232
+
233
+ end
234
+
235
+ # Deletes the access policy for a bucket.
236
+ # @overload delete_bucket_policy(options = {})
237
+ # @param [Hash] options
238
+ # @option options [required,String] :bucket_name
239
+ # @return [Core::Response]
240
+ bucket_method(:delete_bucket_policy, :delete, 'policy')
241
+
242
+ # @overload set_bucket_versioning(options = {})
243
+ # @param [Hash] options
244
+ # @option options [required,String] :bucket_name
245
+ # @option options [required,String] :state
246
+ # @return [Core::Response]
247
+ bucket_method(:set_bucket_versioning, :put, 'versioning') do
248
+
249
+ configure_request do |req, options|
250
+ state = options[:state].to_s.downcase.capitalize
251
+ unless state =~ /^(Enabled|Suspended)$/
252
+ raise ArgumentError, "invalid versioning state `#{state}`"
253
+ end
254
+ super(req, options)
255
+ req.body = <<-XML.strip
256
+ <VersioningConfiguration xmlns="#{XMLNS}">
257
+ <Status>#{state}</Status>
258
+ </VersioningConfiguration>
259
+ XML
260
+ end
261
+
262
+ end
263
+
264
+ # Gets the bucket's location constraint.
265
+ # @overload get_bucket_location(options = {})
266
+ # @param [Hash] options
267
+ # @option options [required,String] :bucket_name
268
+ # @return [Core::Response]
269
+ bucket_method(:get_bucket_location, :get, 'location') do
270
+
271
+ process_response do |response|
272
+ regex = />(.*)<\/LocationConstraint>/
273
+ matches = response.http_response.body.match(regex)
274
+ response.data[:location_constraint] = matches ? matches[1] : nil
275
+ end
276
+
277
+ end
278
+
279
+ # @overload get_bucket_versioning(options = {})
280
+ # @param [Hash] options
281
+ # @option options [required,String] :bucket_name
282
+ # @return [Core::Response]
283
+ bucket_method(:get_bucket_versioning, :get, 'versioning',
284
+ XML::GetBucketVersioning)
285
+
286
+ # @overload list_object_versions(options = {})
287
+ # @param [Hash] options
288
+ # @option options [required,String] :bucket_name
289
+ # @option options [String] :prefix
290
+ # @option options [String] :delimiter
291
+ # @option options [String] :max_keys
292
+ # @option options [String] :key_marker
293
+ # @option options [String] :version_id_marker
294
+ # @return [Core::Response]
295
+ bucket_method(:list_object_versions, :get, 'versions',
296
+ XML::ListObjectVersions) do
297
+
298
+ configure_request do |req, options|
299
+ super(req, options)
300
+ params = %w(delimiter key_marker max_keys prefix version_id_marker)
301
+ params.each do |param|
302
+ if options[param.to_sym]
303
+ req.add_param(param.gsub(/_/, '-'), options[param.to_sym])
304
+ end
305
+ end
306
+ end
307
+
308
+ end
309
+
310
+ # Sets the access control list for a bucket.
311
+ # @overload set_bucket_acl(options = {})
312
+ # @param [Hash] options
313
+ # @option options [required,String] :bucket_name
314
+ # @option options [required,String,AccessControlList,Hash] :acl
315
+ # This may be any of the following:
316
+ # * An XML policy as a string (which is passed to S3 uninterpreted)
317
+ # * An {AccessControlList} object
318
+ # * Any object that responds to +#to_xml+
319
+ # * A hash that is compatible with {AccessControlList} #new.
320
+ # @return [Core::Response]
321
+ bucket_method(:set_bucket_acl, :put, 'acl') do
322
+
323
+ configure_request do |req, options|
324
+ require_acl!(options[:acl])
325
+ super(req, options)
326
+ if options[:acl].kind_of?(Hash)
327
+ req.body = AccessControlList.new(options[:acl]).to_xml
328
+ elsif options[:acl].respond_to?(:to_str)
329
+ req.body = options[:acl]
330
+ else
331
+ req.body = options[:acl].to_xml
332
+ end
333
+ end
334
+
335
+ end
336
+
337
+ # Gets the access control list for a bucket.
338
+ # @overload get_bucket_acl(options = {})
339
+ # @param [Hash] options
340
+ # @option options [required,String] :bucket_name
341
+ # @return [Core::Response]
342
+ bucket_method(:get_bucket_acl, :get, 'acl', XML::GetBucketAcl)
343
+
344
+ # Sets the access control list for an object.
345
+ # @overload set_object_acl(options = {})
346
+ # @param [Hash] options
347
+ # @option options [required,String] :bucket_name
348
+ # @option options [required,String] :key
349
+ # @option options [required,String,AccessControlList,Hash] :acl
350
+ # This may be any of the following:
351
+ # * An XML policy as a string (which is passed to S3 uninterpreted)
352
+ # * An {AccessControlList} object
353
+ # * Any object that responds to +#to_xml+
354
+ # * A hash that is compatible with {AccessControlList} #new.
355
+ # @return [Core::Response]
356
+ object_method(:set_object_acl, :put, 'acl') do
357
+ configure_request do |req, options|
358
+ require_acl!(options[:acl]) unless options[:acl].kind_of?(Symbol)
359
+ super(req, options)
360
+ if options[:acl].kind_of?(Hash)
361
+ req.body = AccessControlList.new(options[:acl]).to_xml
362
+ elsif options[:acl].kind_of?(Symbol)
363
+ req.headers["x-amz-acl"] = options[:acl].to_s.tr("_","-")
364
+ elsif options[:acl].respond_to?(:to_str)
365
+ req.body = options[:acl]
366
+ else
367
+ req.body = options[:acl].to_xml
368
+ end
369
+ end
370
+ end
371
+
372
+ # Gets the access control list for an object.
373
+ # @overload get_object_acl(options = {})
374
+ # @param [Hash] options
375
+ # @option options [required,String] :bucket_name
376
+ # @option options [required,String] :key
377
+ # @return [Core::Response]
378
+ object_method(:get_object_acl, :get, 'acl', XML::GetBucketAcl)
379
+
380
+ # Puts data into an object, replacing the current contents.
381
+ #
382
+ # s3_client.put_object({
383
+ # :bucket_name => 'bucket-name',
384
+ # :key => 'readme.txt',
385
+ # :data => 'This is the readme for ...',
386
+ # })
387
+ #
388
+ # == Block Form
389
+ #
390
+ # In block form, this method yields a stream to the block that
391
+ # accepts data chunks. For example:
392
+ #
393
+ # s3_client.put_object(
394
+ # :bucket_name => 'mybucket',
395
+ # :key => 'some/key'
396
+ # :content_length => File.size('myfile')
397
+ # ) do |buffer|
398
+ #
399
+ # File.open('myfile') do |io|
400
+ # buffer.write(io.read(length)) until io.eof?
401
+ # end
402
+ #
403
+ # end
404
+ #
405
+ # This form is useful if you need finer control over how
406
+ # potentially large amounts of data are read from another
407
+ # source before being sent to S3; for example, if you are
408
+ # using a non-blocking IO model and reading from a large file
409
+ # on disk or from another network stream. Some HTTP handlers
410
+ # do not support streaming request bodies, so if you plan to
411
+ # upload large objects using this interface you should make
412
+ # sure the HTTP handler you configure for the client meets
413
+ # your needs.
414
+ #
415
+ # @overload put_object(options = {})
416
+ # @param [Hash] options
417
+ # @option options [required,String] :bucket_name
418
+ # @option options [required,String] :key
419
+ # @option options [required,String,Pathname,File,IO] :data
420
+ # The data to upload. This can be provided as a string,
421
+ # a Pathname object, or any object that responds to
422
+ # +#read+ and +#eof?+ (e.g. IO, File, Tempfile, StringIO, etc).
423
+ # @option options [Integer] :content_length
424
+ # Required if you are using block form to write data or if it is
425
+ # not possible to determine the size of +:data+. A best effort
426
+ # is made to determine the content length of strings, files,
427
+ # tempfiles, io objects, and any object that responds
428
+ # to +#length+ or +#size+.
429
+ # @option options [Hash] :metadata
430
+ # A hash of metadata to be included with the
431
+ # object. These will be sent to S3 as headers prefixed with
432
+ # +x-amz-meta+.
433
+ # @option options [Symbol] :acl (:private) A canned access
434
+ # control policy. Accepted values include:
435
+ # * +:private+
436
+ # * +:public_read+
437
+ # * ...
438
+ # @option options [Symbol] :storage_class+ (:standard)
439
+ # Controls whether Reduced Redundancy Storage is enabled for
440
+ # the object. Valid values are +:standard+ and
441
+ # +:reduced_redundancy+.
442
+ # @option options [String] :cache_control
443
+ # Can be used to specify caching behavior.
444
+ # @option opitons [String] :content_disposition
445
+ # Specifies presentational information.
446
+ # @option options [String] :content_encoding
447
+ # Specifies the content encoding.
448
+ # @option options [String] :content_md5
449
+ # The base64 encoded content md5 of the +:data+.
450
+ # @option options [String] :content_type
451
+ # Specifies the content type.
452
+ # @option options [String] :expires
453
+ # @return [Core::Response]
454
+ #
455
+ object_method(:put_object, :put,
456
+ :header_options => {
457
+ :content_md5 => 'Content-MD5',
458
+ :cache_control => 'Cache-Control',
459
+ :content_disposition => 'Content-Disposition',
460
+ :content_encoding => 'Content-Encoding',
461
+ :content_type => 'Content-Type',
462
+ :storage_class => 'x-amz-storage-class',
463
+ :server_side_encryption => 'x-amz-server-side-encryption',
464
+ :expires => 'Expires'
465
+ }) do
466
+ configure_request do |request, options, block|
467
+ options[:server_side_encryption] =
468
+ options[:server_side_encryption].to_s.upcase if
469
+ options[:server_side_encryption].kind_of?(Symbol)
470
+ super(request, options)
471
+ set_request_data(request, options, block)
472
+ request.metadata = options[:metadata]
473
+ request.canned_acl = options[:acl]
474
+ request.storage_class = options[:storage_class]
475
+ end
476
+
477
+ process_response do |response|
478
+
479
+ response.data[:version_id] =
480
+ response.http_response.header('x-amz-version-id')
481
+
482
+ response.data[:etag] = response.http_response.header('ETag')
483
+
484
+ if time = response.http_response.header('Last-Modified')
485
+ response.data[:last_modified] = Time.parse(time)
486
+ end
487
+
488
+ add_sse_to_response(response)
489
+ end
490
+
491
+ simulate_response do |response|
492
+ response.data[:etag] = 'abc123'
493
+ response.data[:version_id] = nil
494
+ end
495
+
496
+ end
497
+
498
+ # Gets the data for a key.
499
+ # @overload get_object(options = {})
500
+ # @param [Hash] options
501
+ # @option options [required,String] :bucket_name
502
+ # @option options [required,String] :key
503
+ # @option options [Time] :if_modified_since If specified, the
504
+ # response will contain an additional +:modified+ value that
505
+ # returns true if the object was modified after the given
506
+ # time. If +:modified+ is false, then the response
507
+ # +:data+ value will be +nil+.
508
+ # @option options [Time] :if_unmodified_since If specified, the
509
+ # response will contain an additional +:unmodified+ value
510
+ # that is true if the object was not modified after the
511
+ # given time. If +:unmodified+ returns false, the +:data+
512
+ # value will be +nil+.
513
+ # @option options [String] :if_match If specified, the response
514
+ # will contain an additional +:matches+ value that is true
515
+ # if the object ETag matches the value for this option. If
516
+ # +:matches+ is false, the +:data+ value of the
517
+ # response will be +nil+.
518
+ # @option options [String] :if_none_match If specified, the
519
+ # response will contain an additional +:matches+ value that
520
+ # is true if and only if the object ETag matches the value for
521
+ # this option. If +:matches+ is true, the +:data+ value
522
+ # of the response will be +nil+.
523
+ # @option options [Range<Integer>] :range A byte range of data to request.
524
+ # @return [Core::Response]
525
+ #
526
+ object_method(:get_object, :get,
527
+ :header_options => {
528
+ :if_modified_since => "If-Modified-Since",
529
+ :if_unmodified_since => "If-Unmodified-Since",
530
+ :if_match => "If-Match",
531
+ :if_none_match => "If-None-Match"
532
+ }) do
533
+ configure_request do |req, options|
534
+
535
+ super(req, options)
536
+
537
+ if options[:version_id]
538
+ req.add_param('versionId', options[:version_id])
539
+ end
540
+
541
+ ["If-Modified-Since",
542
+ "If-Unmodified-Since"].each do |date_header|
543
+ case value = req.headers[date_header]
544
+ when DateTime
545
+ req.headers[date_header] = Time.parse(value.to_s).rfc2822
546
+ when Time
547
+ req.headers[date_header] = value.rfc2822
548
+ end
549
+ end
550
+
551
+ if options[:range]
552
+ range = options[:range]
553
+ range = "bytes=#{range.first}-#{range.last}" if range.is_a?(Range)
554
+ req.headers['Range'] = range
555
+ end
556
+
557
+ end
558
+
559
+ process_response do |resp|
560
+ resp.data[:data] = resp.http_response.body
561
+ resp.data[:version_id] = resp.http_response.header('x-amz-version-id')
562
+ add_sse_to_response(resp)
563
+ end
564
+ end
565
+
566
+ # @overload head_object(options = {})
567
+ # @param [Hash] options
568
+ # @option options [required,String] :bucket_name
569
+ # @option options [required,String] :key
570
+ # @option options [String] :version_id
571
+ # @return [Core::Response]
572
+ object_method(:head_object, :head) do
573
+
574
+ configure_request do |req, options|
575
+ super(req, options)
576
+ if options[:version_id]
577
+ req.add_param('versionId', options[:version_id])
578
+ end
579
+ end
580
+
581
+ process_response do |resp|
582
+
583
+ # create a hash of user-supplied metadata
584
+ meta = {}
585
+ resp.http_response.headers.each_pair do |name,value|
586
+ if name =~ /^x-amz-meta-(.+)$/i
587
+ meta[$1] = [value].flatten.join
588
+ end
589
+ end
590
+ meta
591
+ resp.data[:meta] = meta
592
+
593
+ if expiry = resp.http_response.headers['x-amz-expiration']
594
+ expiry.first =~ /^expiry-date="(.+)", rule-id="(.+)"$/
595
+ exp_date = DateTime.parse($1)
596
+ exp_rule_id = $2
597
+ else
598
+ exp_date = nil
599
+ exp_rule_id = nil
600
+ end
601
+
602
+ resp.data[:expiration_date] = exp_date
603
+ resp.data[:expiration_rule_id] = exp_rule_id
604
+
605
+ {
606
+ 'x-amz-version-id' => :version_id,
607
+ 'content-type' => :content_type,
608
+ 'etag' => :etag,
609
+ }.each_pair do |header,method|
610
+ resp.data[method] = resp.http_response.header(header)
611
+ end
612
+
613
+ if time = resp.http_response.header('Last-Modified')
614
+ resp.data[:last_modified] = Time.parse(time)
615
+ end
616
+
617
+ resp.data[:content_length] =
618
+ resp.http_response.header('content-length').to_i
619
+
620
+ add_sse_to_response(resp)
621
+
622
+ end
623
+ end
624
+
625
+ # @overload delete_object(options = {})
626
+ # @param [Hash] options
627
+ # @option options [required,String] :bucket_name
628
+ # @option options [required,String] :key
629
+ # @option options [String] :version_id
630
+ # @return [Core::Response]
631
+ object_method(:delete_object, :delete) do
632
+
633
+ configure_request do |req, options|
634
+ super(req, options)
635
+ if options[:version_id]
636
+ req.add_param('versionId', options[:version_id])
637
+ end
638
+ end
639
+
640
+ process_response do |resp|
641
+ resp.data[:version_id] = resp.http_response.header('x-amz-version-id')
642
+ end
643
+
644
+ end
645
+
646
+ # @overload list_objects(options = {})
647
+ # @param [Hash] options
648
+ # @option options [required,String] :bucket_name
649
+ # @option options [String] :delimiter
650
+ # @option options [String] :marker
651
+ # @option options [String] :max_keys
652
+ # @option options [String] :prefix
653
+ # @return [Core::Response]
654
+ bucket_method(:list_objects, :get, XML::ListObjects) do
655
+ configure_request do |req, options|
656
+ super(req, options)
657
+ params = %w(delimiter marker max_keys prefix)
658
+ params.each do |param|
659
+ if options[param.to_sym]
660
+ req.add_param(param.gsub(/_/, '-'), options[param.to_sym])
661
+ end
662
+ end
663
+ end
664
+ end
665
+
666
+ alias_method :get_bucket, :list_objects
667
+
668
+ # @overload initiate_multipart_upload(options = {})
669
+ # @param [Hash] options
670
+ # @option options [required,String] :bucket_name
671
+ # @option options [required,String] :key
672
+ # @option options [Hash] :metadata
673
+ # @option options [Symbol] :acl
674
+ # @option options [String] :cache_control
675
+ # @option options [String] :content_disposition
676
+ # @option options [String] :content_encoding
677
+ # @option options [String] :content_type
678
+ # @option options [String] :storage_class
679
+ # @option options [String] :server_side_encryption
680
+ # @option options [String] :expires
681
+ # @return [Core::Response]
682
+ object_method(:initiate_multipart_upload, :post, 'uploads',
683
+ XML::InitiateMultipartUpload,
684
+ :header_options => {
685
+ :cache_control => 'Cache-Control',
686
+ :content_disposition => 'Content-Disposition',
687
+ :content_encoding => 'Content-Encoding',
688
+ :content_type => 'Content-Type',
689
+ :storage_class => 'x-amz-storage-class',
690
+ :server_side_encryption => 'x-amz-server-side-encryption',
691
+ :expires => 'Expires'
692
+ }) do
693
+ configure_request do |req, options|
694
+ options[:server_side_encryption] =
695
+ options[:server_side_encryption].to_s.upcase if
696
+ options[:server_side_encryption].kind_of?(Symbol)
697
+ super(req, options)
698
+ req.metadata = options[:metadata]
699
+ req.canned_acl = options[:acl]
700
+ req.storage_class = options[:storage_class]
701
+ end
702
+
703
+ process_response do |response|
704
+ add_sse_to_response(response)
705
+ end
706
+ end
707
+
708
+ # @overload list_multipart_uploads(options = {})
709
+ # @param [Hash] options
710
+ # @option options [required,String] :bucket_name
711
+ # @option options [String] :delimiter
712
+ # @option options [String] :key_marker
713
+ # @option options [String] :max_keys
714
+ # @option options [String] :upload_id_marker
715
+ # @option options [String] :max_uploads
716
+ # @option options [String] :prefix
717
+ # @return [Core::Response]
718
+ bucket_method(:list_multipart_uploads,
719
+ :get, 'uploads',
720
+ XML::ListMultipartUploads) do
721
+ configure_request do |req, options|
722
+ super(req, options)
723
+ params = %w(delimiter key_marker max_keys) +
724
+ %w(upload_id_marker max_uploads prefix)
725
+ params.each do |param|
726
+ if options[param.to_sym]
727
+ req.add_param(param.gsub(/_/, '-'), options[param.to_sym])
728
+ end
729
+ end
730
+ end
731
+ end
732
+
733
+ # @overload delete_objects(options = {})
734
+ # @param [Hash] options
735
+ # @option options [required,String] :bucket_name
736
+ # @option options [required,Array<String>] :keys
737
+ # @option options [Boolean] :quiet (true)
738
+ # @return [Core::Response]
739
+ bucket_method(:delete_objects, :post, 'delete', XML::DeleteObjects) do
740
+ configure_request do |req, options|
741
+
742
+ super(req, options)
743
+
744
+ quiet = options.key?(:quiet) ? options[:quiet] : true
745
+
746
+ # previously named this option :objects, since renamed
747
+ keys = options[:objects] || options[:keys]
748
+
749
+ objects = keys.inject('') do |xml,o|
750
+ xml << "<Object><Key>#{o[:key]}</Key>"
751
+ xml << "<VersionId>#{o[:version_id]}</VersionId>" if o[:version_id]
752
+ xml << "</Object>"
753
+ end
754
+
755
+ xml = '<?xml version="1.0" encoding="UTF-8"?>'
756
+ xml << "<Delete><Quiet>#{quiet}</Quiet>#{objects}</Delete>"
757
+
758
+ req.body = xml
759
+
760
+ md5 = Base64.encode64(Digest::MD5.digest(xml)).strip
761
+
762
+ req.headers['content-md5'] = md5
763
+
764
+ end
765
+ end
766
+
767
+ # @overload upload_part(options = {})
768
+ # @param [Hash] options
769
+ # @option options [required,String] :bucket_name
770
+ # @option options [required,String] :key
771
+ # @option options [required,String,Pathname,File,IO] :data
772
+ # The data to upload. This can be provided as a string,
773
+ # a Pathname object, or any object that responds to
774
+ # +#read+ and +#eof?+ (e.g. IO, File, Tempfile, StringIO, etc).
775
+ # @option options [required,String] :upload_id
776
+ # @option options [required,Integer] :part_number
777
+ # @return [Core::Response]
778
+ object_method(:upload_part, :put,
779
+ :header_options => {
780
+ :content_md5 => 'Content-MD5'
781
+ }) do
782
+ configure_request do |request, options, block|
783
+ require_upload_id!(options[:upload_id])
784
+ validate!("part_number", options[:part_number]) do
785
+ "must not be blank" if options[:part_number].to_s.empty?
786
+ end
787
+ super(request, options)
788
+ set_request_data(request, options, block)
789
+ request.add_param('uploadId', options[:upload_id])
790
+ request.add_param('partNumber', options[:part_number])
791
+ end
792
+
793
+ process_response do |response|
794
+ response.data[:etag] = response.http_response.header('ETag')
795
+ if time = response.http_response.header('Last-Modified')
796
+ response.data[:last_modified] = Time.parse(time)
797
+ end
798
+ add_sse_to_response(response)
799
+ end
800
+
801
+ simulate_response do |response|
802
+ response.data[:etag] = 'abc123'
803
+ end
804
+ end
805
+
806
+ # @overload complete_multipart_upload(options = {})
807
+ # @param [Hash] options
808
+ # @option options [required,String] :bucket_name
809
+ # @option options [required,String] :key
810
+ # @option options [required,String] :upload_id
811
+ # @option options [required,Array<String>] :parts
812
+ # @return [Core::Response]
813
+ object_method(:complete_multipart_upload, :post,
814
+ XML::CompleteMultipartUpload) do
815
+ configure_request do |req, options|
816
+ require_upload_id!(options[:upload_id])
817
+ validate_parts!(options[:parts])
818
+ super(req, options)
819
+ req.add_param('uploadId', options[:upload_id])
820
+ parts_xml = options[:parts].map do |part|
821
+ "<Part>"+
822
+ "<PartNumber>#{part[:part_number].to_i}</PartNumber>"+
823
+ "<ETag>#{REXML::Text.normalize(part[:etag].to_s)}</ETag>"+
824
+ "</Part>"
825
+ end.join
826
+ req.body =
827
+ "<CompleteMultipartUpload>#{parts_xml}</CompleteMultipartUpload>"
828
+ end
829
+
830
+ process_response do |response|
831
+ add_sse_to_response(response)
832
+ response.data[:version_id] =
833
+ response.http_response.header('x-amz-version-id')
834
+ end
835
+
836
+ simulate_response do |response|
837
+ response.data[:version_id] = nil
838
+ end
839
+ end
840
+
841
+ # @overload abort_multipart_upload(options = {})
842
+ # @param [Hash] options
843
+ # @option options [required,String] :bucket_name
844
+ # @option options [required,String] :key
845
+ # @option options [required,String] :upload_id
846
+ # @return [Core::Response]
847
+ object_method(:abort_multipart_upload, :delete) do
848
+ configure_request do |req, options|
849
+ require_upload_id!(options[:upload_id])
850
+ super(req, options)
851
+ req.add_param('uploadId', options[:upload_id])
852
+ end
853
+ end
854
+
855
+ # @overload list_parts(options = {})
856
+ # @param [Hash] options
857
+ # @option options [required,String] :bucket_name
858
+ # @option options [required,String] :key
859
+ # @option options [required,String] :upload_id
860
+ # @option options [Integer] :max_parts
861
+ # @option options [Integer] :part_number_marker
862
+ # @return [Core::Response]
863
+ object_method(:list_parts, :get, XML::ListParts) do
864
+
865
+ configure_request do |req, options|
866
+ require_upload_id!(options[:upload_id])
867
+ super(req, options)
868
+ req.add_param('uploadId', options[:upload_id])
869
+ req.add_param('max-parts', options[:max_parts])
870
+ req.add_param('part-number-marker', options[:part_number_marker])
871
+ end
872
+
873
+ end
874
+
875
+ # Copies an object from one key to another.
876
+ # @overload copy_object(options = {})
877
+ # @param [Hash] options
878
+ # @option options [required, String] :bucket_name Name of the bucket
879
+ # to copy a object into.
880
+ # @option options [required, String] :key Where (object key) in the
881
+ # bucket the object should be copied to.
882
+ # @option options [required, String] :copy_source The source
883
+ # bucket name and key, joined by a forward slash ('/').
884
+ # This string must be URL-encoded. Additionally, you must
885
+ # have read access to the source object.
886
+ # @option options [Symbol] :acl
887
+ # @return [Core::Response]
888
+ object_method(:copy_object, :put,
889
+ :header_options => {
890
+ :copy_source => 'x-amz-copy-source',
891
+ :cache_control => 'Cache-Control',
892
+ :metadata_directive => 'x-amz-metadata-directive',
893
+ :storage_class => 'x-amz-storage-class',
894
+ :server_side_encryption => 'x-amz-server-side-encryption',
895
+ :content_type => 'Content-Type',
896
+ }) do
897
+
898
+ configure_request do |req, options|
899
+ # TODO : validate metadata directive COPY / REPLACE
900
+ # TODO : validate storage class STANDARD / REDUCED_REDUNDANCY
901
+ # TODO : add validations for storage class in other places used
902
+ validate!(:copy_source, options[:copy_source]) do
903
+ "may not be blank" if options[:copy_source].to_s.empty?
904
+ end
905
+ options = options.merge(:copy_source => escape_path(options[:copy_source]))
906
+ options[:server_side_encryption] =
907
+ options[:server_side_encryption].to_s.upcase if
908
+ options[:server_side_encryption].kind_of?(Symbol)
909
+ super(req, options)
910
+ req.canned_acl = options[:acl]
911
+ req.metadata = options[:metadata]
912
+ req.storage_class = options[:storage_class]
913
+ if options[:version_id]
914
+ req.headers['x-amz-copy-source'] += "?versionId=#{options[:version_id]}"
915
+ end
916
+ end
917
+
918
+ process_response do |response|
919
+ response.data[:version_id] =
920
+ response.http_response.header('x-amz-version-id')
921
+ response.data[:etag] = response.http_response.header('ETag')
922
+ if time = response.http_response.header('Last-Modified')
923
+ response.data[:last_modified] = Time.parse(time)
924
+ end
925
+ add_sse_to_response(response)
926
+ end
927
+
928
+ end
929
+
930
+ protected
931
+
932
+ def extract_error_details response
933
+ if
934
+ (response.http_response.status >= 300 ||
935
+ response.request_type == :complete_multipart_upload) and
936
+ body = response.http_response.body and
937
+ error = Core::XML::Parser.parse(body) and
938
+ error[:code]
939
+ then
940
+ [error[:code], error[:message]]
941
+ end
942
+ end
943
+
944
+ # There are a few of s3 requests that can generate empty bodies and
945
+ # yet still be errors. These return empty bodies to comply with the
946
+ # HTTP spec. We have to detect these errors specially.
947
+ def populate_error resp
948
+ code = resp.http_response.status
949
+ if EMPTY_BODY_ERRORS.include?(code) and resp.http_response.body.nil?
950
+ error_class = EMPTY_BODY_ERRORS[code]
951
+ resp.error = error_class.new(resp.http_request, resp.http_response)
952
+ else
953
+ super
954
+ end
955
+ end
956
+
957
+ def should_retry? response
958
+ super or
959
+ response.request_type == :complete_multipart_upload &&
960
+ extract_error_details(response)
961
+ # complete multipart upload can return an error inside a
962
+ # 200 level response -- this forces us to parse the
963
+ # response for errors every time
964
+ end
965
+
966
+ def set_request_data request, options, block
967
+ request.body_stream = data_stream_from(options, &block)
968
+ request.headers['Content-Length'] = content_length_from(options)
969
+ end
970
+
971
+ def new_request
972
+ S3::Request.new
973
+ end
974
+
975
+ def add_sse_to_response response
976
+ if sse = response.http_response.header('x-amz-server-side-encryption')
977
+ sse = sse.downcase.to_sym
978
+ end
979
+ response.data[:server_side_encryption] = sse
980
+ end
981
+
982
+ module Validators
983
+
984
+ # @return [Boolean] Returns true if the given bucket name is valid.
985
+ def valid_bucket_name?(bucket_name)
986
+ validate_bucket_name!(bucket_name) rescue false
987
+ end
988
+
989
+ # Returns true if the given +bucket_name+ is DNS compatible.
990
+ #
991
+ # DNS compatible bucket names may be accessed like:
992
+ #
993
+ # http://dns.compat.bucket.name.s3.amazonaws.com/
994
+ #
995
+ # Whereas non-dns compatible bucket names must place the bucket
996
+ # name in the url path, like:
997
+ #
998
+ # http://s3.amazonaws.com/dns_incompat_bucket_name/
999
+ #
1000
+ # @return [Boolean] Returns true if the given bucket name may be
1001
+ # is dns compatible.
1002
+ # this bucket n
1003
+ #
1004
+ def dns_compatible_bucket_name?(bucket_name)
1005
+ return false if
1006
+ !valid_bucket_name?(bucket_name) or
1007
+
1008
+ # Bucket names should not contain underscores (_)
1009
+ bucket_name["_"] or
1010
+
1011
+ # Bucket names should be between 3 and 63 characters long
1012
+ bucket_name.size > 63 or
1013
+
1014
+ # Bucket names should not end with a dash
1015
+ bucket_name[-1,1] == '-' or
1016
+
1017
+ # Bucket names cannot contain two, adjacent periods
1018
+ bucket_name['..'] or
1019
+
1020
+ # Bucket names cannot contain dashes next to periods
1021
+ # (e.g., "my-.bucket.com" and "my.-bucket" are invalid)
1022
+ (bucket_name['-.'] || bucket_name['.-'])
1023
+
1024
+ true
1025
+ end
1026
+
1027
+ # Returns true if the bucket name must be used in the request
1028
+ # path instead of as a sub-domain when making requests against
1029
+ # S3.
1030
+ #
1031
+ # This can be an issue if the bucket name is DNS compatible but
1032
+ # contains '.' (periods). These cause the SSL certificate to
1033
+ # become invalid when making authenticated requets over SSL to the
1034
+ # bucket name. The solution is to send this as a path argument
1035
+ # instead.
1036
+ #
1037
+ # @return [Boolean] Returns true if the bucket name should be used
1038
+ # as a path segement instead of dns prefix when making requests
1039
+ # against s3.
1040
+ #
1041
+ def path_style_bucket_name? bucket_name
1042
+ if dns_compatible_bucket_name?(bucket_name)
1043
+ bucket_name =~ /\./ ? true : false
1044
+ else
1045
+ true
1046
+ end
1047
+ end
1048
+
1049
+ def validate! name, value, &block
1050
+ if error_msg = yield
1051
+ raise ArgumentError, "#{name} #{error_msg}"
1052
+ end
1053
+ value
1054
+ end
1055
+
1056
+ def validate_key!(key)
1057
+ validate!('key', key) do
1058
+ case
1059
+ when key.nil? || key == ''
1060
+ 'may not be blank'
1061
+ end
1062
+ end
1063
+ end
1064
+
1065
+ def require_bucket_name! bucket_name
1066
+ if [nil, ''].include?(bucket_name)
1067
+ raise ArgumentError, "bucket_name may not be blank"
1068
+ end
1069
+ end
1070
+
1071
+ # Returns true if the given bucket name is valid. If the name
1072
+ # is invalid, an ArgumentError is raised.
1073
+ def validate_bucket_name!(bucket_name)
1074
+ validate!('bucket_name', bucket_name) do
1075
+ case
1076
+ when bucket_name.nil? || bucket_name == ''
1077
+ 'may not be blank'
1078
+ when bucket_name !~ /^[a-z0-9._\-]+$/
1079
+ 'may only contain lowercase letters, numbers, periods (.), ' +
1080
+ 'underscores (_), and dashes (-)'
1081
+ when bucket_name !~ /^[a-z0-9]/
1082
+ 'must start with a letter or a number'
1083
+ when !(3..255).include?(bucket_name.size)
1084
+ 'must be between 3 and 255 characters long'
1085
+ when bucket_name =~ /(\d+\.){3}\d+/
1086
+ 'must not be formatted like an IP address (e.g., 192.168.5.4)'
1087
+ when bucket_name =~ /\n/
1088
+ 'must not contain a newline character'
1089
+ end
1090
+ end
1091
+ end
1092
+
1093
+ def require_policy!(policy)
1094
+ validate!('policy', policy) do
1095
+ case
1096
+ when policy.nil? || policy == ''
1097
+ 'may not be blank'
1098
+ else
1099
+ json_validation_message(policy)
1100
+ end
1101
+ end
1102
+ end
1103
+
1104
+ def require_acl!(acl)
1105
+ validate!('acl', acl) do
1106
+ case
1107
+ when acl.kind_of?(Hash)
1108
+ AccessControlList.new(acl).validate!
1109
+ nil
1110
+ when !acl.respond_to?(:to_str) && !acl.respond_to?(:to_xml)
1111
+ "must support to_xml: #{acl.inspect}"
1112
+ when acl.nil? || acl == ''
1113
+ 'may not be blank'
1114
+ else
1115
+ xml_validation_message(acl)
1116
+ end
1117
+ end
1118
+ end
1119
+
1120
+ def require_upload_id!(upload_id)
1121
+ validate!("upload_id", upload_id) do
1122
+ "must not be blank" if upload_id.to_s.empty?
1123
+ end
1124
+ end
1125
+
1126
+ def validate_parts!(parts)
1127
+ validate!("parts", parts) do
1128
+ if !parts.kind_of?(Array)
1129
+ "must not be blank"
1130
+ elsif parts.empty?
1131
+ "must contain at least one entry"
1132
+ elsif !parts.all? { |p| p.kind_of?(Hash) }
1133
+ "must be an array of hashes"
1134
+ elsif !parts.all? { |p| p[:part_number] }
1135
+ "must contain part_number for each part"
1136
+ elsif !parts.all? { |p| p[:etag] }
1137
+ "must contain etag for each part"
1138
+ elsif parts.any? { |p| p[:part_number].to_i < 1 }
1139
+ "must not have part numbers less than 1"
1140
+ end
1141
+ end
1142
+ end
1143
+
1144
+ def json_validation_message(obj)
1145
+ if obj.respond_to?(:to_str)
1146
+ obj = obj.to_str
1147
+ elsif obj.respond_to?(:to_json)
1148
+ obj = obj.to_json
1149
+ end
1150
+
1151
+ error = nil
1152
+ begin
1153
+ JSON.parse(obj)
1154
+ rescue => e
1155
+ error = e
1156
+ end
1157
+ "contains invalid JSON: #{error}" if error
1158
+ end
1159
+
1160
+ def xml_validation_message(obj)
1161
+ if obj.respond_to?(:to_str)
1162
+ obj = obj.to_str
1163
+ elsif obj.respond_to?(:to_xml)
1164
+ obj = obj.to_xml
1165
+ end
1166
+
1167
+ error = nil
1168
+ begin
1169
+ REXML::Document.new(obj)
1170
+ rescue => e
1171
+ error = e
1172
+ end
1173
+ "contains invalid XML: #{error}" if error
1174
+ end
1175
+
1176
+ end
1177
+
1178
+ include Validators
1179
+ extend Validators
1180
+
1181
+ end
1182
+
1183
+ end
1184
+ end