aws_sdk 3.1.5

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