s33r 0.4.1 → 0.4.2

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 (75) hide show
  1. data/examples/cli/simple.rb +17 -0
  2. data/examples/fores33r/app/controllers/browser_controller.rb +32 -8
  3. data/examples/fores33r/app/views/browser/_create_bucket.rhtml +6 -0
  4. data/examples/fores33r/app/views/browser/_upload.rhtml +5 -0
  5. data/examples/fores33r/app/views/browser/index.rhtml +1 -8
  6. data/examples/fores33r/app/views/browser/plain_bucket.rhtml +3 -0
  7. data/examples/fores33r/app/views/browser/s3_index.rhtml +9 -0
  8. data/examples/fores33r/app/views/browser/show_bucket.rhtml +6 -8
  9. data/examples/fores33r/app/views/layouts/application.rhtml +2 -0
  10. data/examples/fores33r/app/views/layouts/s3_layout.rhtml +14 -0
  11. data/examples/fores33r/config/environment.rb +1 -1
  12. data/examples/fores33r/config/routes.rb +2 -0
  13. data/examples/fores33r/public/stylesheets/core.css +2 -2
  14. data/html/classes/Net/HTTPResponse.html +3 -0
  15. data/html/classes/S33r.html +127 -116
  16. data/html/classes/S33r/BucketListing.html +119 -94
  17. data/html/classes/S33r/Client.html +602 -536
  18. data/html/classes/S33r/LoggingResource.html +3 -3
  19. data/html/classes/S33r/NamedBucket.html +235 -191
  20. data/html/classes/S33r/OrderlyXmlMarkup.html +7 -7
  21. data/html/classes/S33r/S33rException.html +1 -0
  22. data/html/classes/S33r/S33rException/TryingToPutEmptyResource.html +117 -0
  23. data/html/classes/S33r/S3ACL/ACLDoc.html +94 -94
  24. data/html/classes/S33r/S3ACL/AmazonCustomer.html +5 -5
  25. data/html/classes/S33r/S3ACL/CanonicalUser.html +12 -12
  26. data/html/classes/S33r/S3ACL/Grant.html +64 -64
  27. data/html/classes/S33r/S3ACL/Grantee.html +36 -36
  28. data/html/classes/S33r/S3ACL/Group.html +8 -8
  29. data/html/classes/S33r/S3Object.html +387 -79
  30. data/html/classes/XML.html +15 -15
  31. data/html/created.rid +1 -1
  32. data/html/files/CHANGELOG.html +7 -1
  33. data/html/files/MIT-LICENSE.html +1 -1
  34. data/html/files/README_txt.html +3 -7
  35. data/html/files/lib/s33r/bucket_listing_rb.html +1 -9
  36. data/html/files/lib/s33r/builder_rb.html +1 -1
  37. data/html/files/lib/s33r/client_rb.html +1 -1
  38. data/html/files/lib/s33r/core_rb.html +1 -2
  39. data/html/files/lib/s33r/libxml_extensions_rb.html +1 -7
  40. data/html/files/lib/s33r/libxml_loader_rb.html +109 -0
  41. data/html/files/lib/s33r/logging_rb.html +1 -2
  42. data/html/files/lib/s33r/mimetypes_rb.html +1 -1
  43. data/html/files/lib/s33r/named_bucket_rb.html +1 -1
  44. data/html/files/lib/s33r/s33r_exception_rb.html +1 -1
  45. data/html/files/lib/s33r/s33r_http_rb.html +1 -1
  46. data/html/files/lib/s33r/s3_acl_rb.html +1 -2
  47. data/html/files/lib/s33r/s3_obj_rb.html +108 -0
  48. data/html/files/lib/s33r/sync_rb.html +1 -1
  49. data/html/files/lib/s33r_rb.html +1 -1
  50. data/html/fr_class_index.html +1 -0
  51. data/html/fr_file_index.html +2 -0
  52. data/html/fr_method_index.html +80 -71
  53. data/lib/s33r/bucket_listing.rb +30 -55
  54. data/lib/s33r/client.rb +70 -28
  55. data/lib/s33r/core.rb +9 -4
  56. data/lib/s33r/libxml_extensions.rb +2 -0
  57. data/lib/s33r/libxml_loader.rb +6 -0
  58. data/lib/s33r/logging.rb +3 -3
  59. data/lib/s33r/named_bucket.rb +33 -15
  60. data/lib/s33r/s33r_exception.rb +4 -0
  61. data/lib/s33r/s33r_http.rb +1 -1
  62. data/lib/s33r/s3_acl.rb +3 -2
  63. data/lib/s33r/s3_obj.rb +186 -0
  64. data/test/cases/spec_bucket_listing.rb +9 -33
  65. data/test/cases/spec_s3_object.rb +35 -0
  66. data/test/files/suspect_bucket_listing.xml +19 -0
  67. metadata +94 -89
  68. data/examples/fores33r/log/development.log +0 -5960
  69. data/examples/fores33r/log/production.log +0 -0
  70. data/examples/fores33r/log/server.log +0 -0
  71. data/examples/fores33r/log/test.log +0 -0
  72. data/examples/fores33r/tmp/sessions/ruby_sess.2ea325f604aa5fb9 +0 -0
  73. data/examples/fores33r/tmp/sessions/ruby_sess.39d37e054d21d545 +0 -0
  74. data/examples/fores33r/tmp/sessions/ruby_sess.acf71fc73aa74983 +0 -0
  75. data/examples/fores33r/tmp/sessions/ruby_sess.c1697b7d6670f3cd +0 -0
@@ -56,7 +56,7 @@
56
56
  </tr>
57
57
  <tr class="top-aligned-row">
58
58
  <td><strong>Last Update:</strong></td>
59
- <td>Tue Sep 26 11:41:33 BST 2006</td>
59
+ <td>Wed Jan 03 11:27:57 GMT 2007</td>
60
60
  </tr>
61
61
  </table>
62
62
  </div>
@@ -56,7 +56,7 @@
56
56
  </tr>
57
57
  <tr class="top-aligned-row">
58
58
  <td><strong>Last Update:</strong></td>
59
- <td>Mon Aug 21 15:21:33 BST 2006</td>
59
+ <td>Wed Jan 03 11:27:58 GMT 2007</td>
60
60
  </tr>
61
61
  </table>
62
62
  </div>
@@ -45,6 +45,7 @@
45
45
  <a href="classes/S33r/S33rException/MissingRequiredHeaders.html">S33r::S33rException::MissingRequiredHeaders</a><br />
46
46
  <a href="classes/S33r/S33rException/MissingResource.html">S33r::S33rException::MissingResource</a><br />
47
47
  <a href="classes/S33r/S33rException/S3FallenOver.html">S33r::S33rException::S3FallenOver</a><br />
48
+ <a href="classes/S33r/S33rException/TryingToPutEmptyResource.html">S33r::S33rException::TryingToPutEmptyResource</a><br />
48
49
  <a href="classes/S33r/S33rException/UnsupportedCannedACL.html">S33r::S33rException::UnsupportedCannedACL</a><br />
49
50
  <a href="classes/S33r/S33rException/UnsupportedHTTPMethod.html">S33r::S33rException::UnsupportedHTTPMethod</a><br />
50
51
  <a href="classes/S33r/S3ACL.html">S33r::S3ACL</a><br />
@@ -29,12 +29,14 @@
29
29
  <a href="files/lib/s33r/client_rb.html">lib/s33r/client.rb</a><br />
30
30
  <a href="files/lib/s33r/core_rb.html">lib/s33r/core.rb</a><br />
31
31
  <a href="files/lib/s33r/libxml_extensions_rb.html">lib/s33r/libxml_extensions.rb</a><br />
32
+ <a href="files/lib/s33r/libxml_loader_rb.html">lib/s33r/libxml_loader.rb</a><br />
32
33
  <a href="files/lib/s33r/logging_rb.html">lib/s33r/logging.rb</a><br />
33
34
  <a href="files/lib/s33r/mimetypes_rb.html">lib/s33r/mimetypes.rb</a><br />
34
35
  <a href="files/lib/s33r/named_bucket_rb.html">lib/s33r/named_bucket.rb</a><br />
35
36
  <a href="files/lib/s33r/s33r_exception_rb.html">lib/s33r/s33r_exception.rb</a><br />
36
37
  <a href="files/lib/s33r/s33r_http_rb.html">lib/s33r/s33r_http.rb</a><br />
37
38
  <a href="files/lib/s33r/s3_acl_rb.html">lib/s33r/s3_acl.rb</a><br />
39
+ <a href="files/lib/s33r/s3_obj_rb.html">lib/s33r/s3_obj.rb</a><br />
38
40
  <a href="files/lib/s33r/sync_rb.html">lib/s33r/sync.rb</a><br />
39
41
  </div>
40
42
  </div>
@@ -22,149 +22,158 @@
22
22
  <div id="index-entries">
23
23
  <a href="classes/S33r/S3ACL/Grant.html#M000084">== (S33r::S3ACL::Grant)</a><br />
24
24
  <a href="classes/S33r/S3ACL/Grantee.html#M000074">== (S33r::S3ACL::Grantee)</a><br />
25
- <a href="classes/S33r/NamedBucket.html#M000095">[] (S33r::NamedBucket)</a><br />
26
- <a href="classes/MIME/Types.html#M000011">[] (MIME::Types)</a><br />
27
- <a href="classes/S33r/BucketListing.html#M000111">[] (S33r::BucketListing)</a><br />
25
+ <a href="classes/S33r/BucketListing.html#M000155">[] (S33r::BucketListing)</a><br />
28
26
  <a href="classes/MIME/Types.html#M000015">[] (MIME::Types)</a><br />
29
- <a href="classes/S33r/OrderlyXmlMarkup.html#M000148">_insert_attributes (S33r::OrderlyXmlMarkup)</a><br />
27
+ <a href="classes/MIME/Types.html#M000011">[] (MIME::Types)</a><br />
28
+ <a href="classes/S33r/NamedBucket.html#M000102">[] (S33r::NamedBucket)</a><br />
29
+ <a href="classes/S33r/OrderlyXmlMarkup.html#M000157">_insert_attributes (S33r::OrderlyXmlMarkup)</a><br />
30
30
  <a href="classes/MIME/Types.html#M000014">add (MIME::Types)</a><br />
31
31
  <a href="classes/MIME/Types.html#M000018">add (MIME::Types)</a><br />
32
- <a href="classes/S33r/Client.html#M000142">add_client_headers (S33r::Client)</a><br />
32
+ <a href="classes/S33r/Client.html#M000145">add_client_headers (S33r::Client)</a><br />
33
33
  <a href="classes/S33r.html#M000044">add_default_headers (S33r)</a><br />
34
34
  <a href="classes/S33r/S3ACL/ACLDoc.html#M000067">add_grant (S33r::S3ACL::ACLDoc)</a><br />
35
35
  <a href="classes/S33r/S3ACL/ACLDoc.html#M000072">add_log_target_grants (S33r::S3ACL::ACLDoc)</a><br />
36
36
  <a href="classes/S33r/S3ACL/ACLDoc.html#M000070">add_public_read_grant (S33r::S3ACL::ACLDoc)</a><br />
37
37
  <a href="classes/MIME/Type.html#M000032">ascii? (MIME::Type)</a><br />
38
38
  <a href="classes/MIME/Type.html#M000031">binary? (MIME::Type)</a><br />
39
- <a href="classes/S33r/Client.html#M000124">bucket_exists? (S33r::Client)</a><br />
39
+ <a href="classes/S33r/Client.html#M000126">bucket_exists? (S33r::Client)</a><br />
40
40
  <a href="classes/S33r.html#M000048">bucket_name_valid? (S33r)</a><br />
41
41
  <a href="classes/S33r.html#M000046">canned_acl_header (S33r)</a><br />
42
42
  <a href="classes/Net/HTTPResponse.html#M000005">check_s3_availability (Net::HTTPResponse)</a><br />
43
43
  <a href="classes/MIME/Type.html#M000036">complete? (MIME::Type)</a><br />
44
- <a href="classes/S33r/Client.html#M000122">create_bucket (S33r::Client)</a><br />
44
+ <a href="classes/S33r/Client.html#M000124">create_bucket (S33r::Client)</a><br />
45
45
  <a href="classes/MIME/Type.html#M000020">default_encoding (MIME::Type)</a><br />
46
- <a href="classes/S33r/S3Object.html#M000088">delete (S33r::S3Object)</a><br />
47
- <a href="classes/S33r/Client.html#M000123">delete_bucket (S33r::Client)</a><br />
48
- <a href="classes/S33r/NamedBucket.html#M000105">delete_resource (S33r::NamedBucket)</a><br />
49
- <a href="classes/S33r/Client.html#M000141">delete_resource (S33r::Client)</a><br />
50
- <a href="classes/S33r/NamedBucket.html#M000098">destroy (S33r::NamedBucket)</a><br />
51
- <a href="classes/S33r/Client.html#M000134">disable_log_target (S33r::Client)</a><br />
52
- <a href="classes/S33r/Client.html#M000136">disable_logging (S33r::Client)</a><br />
53
- <a href="classes/S33r/Client.html#M000147">do_delete (S33r::Client)</a><br />
54
- <a href="classes/S33r/Client.html#M000143">do_get (S33r::Client)</a><br />
55
- <a href="classes/S33r/Client.html#M000144">do_head (S33r::Client)</a><br />
56
- <a href="classes/S33r/Client.html#M000145">do_post (S33r::Client)</a><br />
57
- <a href="classes/S33r/Client.html#M000146">do_put (S33r::Client)</a><br />
58
- <a href="classes/S33r/Client.html#M000117">do_request (S33r::Client)</a><br />
46
+ <a href="classes/S33r/NamedBucket.html#M000113">delete (S33r::NamedBucket)</a><br />
47
+ <a href="classes/S33r/S3Object.html#M000096">delete (S33r::S3Object)</a><br />
48
+ <a href="classes/S33r/Client.html#M000125">delete_bucket (S33r::Client)</a><br />
49
+ <a href="classes/S33r/Client.html#M000144">delete_resource (S33r::Client)</a><br />
50
+ <a href="classes/S33r/NamedBucket.html#M000106">destroy (S33r::NamedBucket)</a><br />
51
+ <a href="classes/S33r/Client.html#M000137">disable_log_target (S33r::Client)</a><br />
52
+ <a href="classes/S33r/Client.html#M000139">disable_logging (S33r::Client)</a><br />
53
+ <a href="classes/S33r/Client.html#M000150">do_delete (S33r::Client)</a><br />
54
+ <a href="classes/S33r/Client.html#M000146">do_get (S33r::Client)</a><br />
55
+ <a href="classes/S33r/Client.html#M000147">do_head (S33r::Client)</a><br />
56
+ <a href="classes/S33r/Client.html#M000148">do_post (S33r::Client)</a><br />
57
+ <a href="classes/S33r/Client.html#M000149">do_put (S33r::Client)</a><br />
58
+ <a href="classes/S33r/Client.html#M000119">do_request (S33r::Client)</a><br />
59
59
  <a href="classes/MIME/Type.html#M000023">docs= (MIME::Type)</a><br />
60
- <a href="classes/S33r/NamedBucket.html#M000100">each_item (S33r::NamedBucket)</a><br />
61
- <a href="classes/S33r/Client.html#M000133">enable_log_target (S33r::Client)</a><br />
62
- <a href="classes/S33r/Client.html#M000135">enable_logging (S33r::Client)</a><br />
63
- <a href="classes/S33r/NamedBucket.html#M000097">exists? (S33r::NamedBucket)</a><br />
60
+ <a href="classes/S33r/NamedBucket.html#M000108">each_object (S33r::NamedBucket)</a><br />
61
+ <a href="classes/S33r/Client.html#M000136">enable_log_target (S33r::Client)</a><br />
62
+ <a href="classes/S33r/Client.html#M000138">enable_logging (S33r::Client)</a><br />
63
+ <a href="classes/S33r/NamedBucket.html#M000105">exists? (S33r::NamedBucket)</a><br />
64
64
  <a href="classes/S33r/S3ACL/Grant.html#M000078">for_amazon_customer (S33r::S3ACL::Grant)</a><br />
65
65
  <a href="classes/S33r/S3ACL/Grant.html#M000079">for_canonical_user (S33r::S3ACL::Grant)</a><br />
66
66
  <a href="classes/S33r/S3ACL/Grant.html#M000080">for_group (S33r::S3ACL::Grant)</a><br />
67
67
  <a href="classes/MIME/Type.html#M000026">from_array (MIME::Type)</a><br />
68
+ <a href="classes/S33r/S3Object.html#M000089">from_file (S33r::S3Object)</a><br />
68
69
  <a href="classes/MIME/Type.html#M000027">from_hash (MIME::Type)</a><br />
69
70
  <a href="classes/MIME/Type.html#M000028">from_mime_type (MIME::Type)</a><br />
71
+ <a href="classes/S33r/S3Object.html#M000093">from_response (S33r::S3Object)</a><br />
70
72
  <a href="classes/S33r/S3ACL/CanonicalUser.html#M000062">from_xml (S33r::S3ACL::CanonicalUser)</a><br />
71
73
  <a href="classes/S33r/S3ACL/Grantee.html#M000076">from_xml (S33r::S3ACL::Grantee)</a><br />
72
74
  <a href="classes/S33r/S3ACL/ACLDoc.html#M000065">from_xml (S33r::S3ACL::ACLDoc)</a><br />
75
+ <a href="classes/S33r/S3Object.html#M000091">from_xml_node (S33r::S3Object)</a><br />
76
+ <a href="classes/S33r/S3Object.html#M000090">from_xml_string (S33r::S3Object)</a><br />
73
77
  <a href="classes/S33r.html#M000042">generate_auth_header_value (S33r)</a><br />
74
78
  <a href="classes/S33r.html#M000041">generate_canonical_string (S33r)</a><br />
75
79
  <a href="classes/S33r.html#M000049">generate_querystring (S33r)</a><br />
76
80
  <a href="classes/S33r.html#M000043">generate_signature (S33r)</a><br />
77
- <a href="classes/S33r/Client.html#M000128">get_acl (S33r::Client)</a><br />
78
- <a href="classes/S33r/Client.html#M000114">get_client (S33r::Client)</a><br />
79
- <a href="classes/S33r/Client.html#M000137">get_logging (S33r::Client)</a><br />
80
- <a href="classes/S33r/Client.html#M000127">get_object (S33r::Client)</a><br />
81
- <a href="classes/S33r/Client.html#M000118">get_requester (S33r::Client)</a><br />
82
- <a href="classes/S33r/Client.html#M000125">get_resource (S33r::Client)</a><br />
81
+ <a href="classes/S33r/Client.html#M000131">get_acl (S33r::Client)</a><br />
82
+ <a href="classes/S33r/Client.html#M000116">get_client (S33r::Client)</a><br />
83
+ <a href="classes/S33r/Client.html#M000140">get_logging (S33r::Client)</a><br />
84
+ <a href="classes/S33r/Client.html#M000127">get_named_bucket (S33r::Client)</a><br />
85
+ <a href="classes/S33r/Client.html#M000130">get_object (S33r::Client)</a><br />
86
+ <a href="classes/S33r/NamedBucket.html#M000103">get_raw (S33r::NamedBucket)</a><br />
87
+ <a href="classes/S33r/Client.html#M000120">get_requester (S33r::Client)</a><br />
88
+ <a href="classes/S33r/Client.html#M000128">get_resource (S33r::Client)</a><br />
83
89
  <a href="classes/XML.html#M000002">get_xml_doc (XML)</a><br />
84
90
  <a href="classes/S33r.html#M000047">guess_mime_type (S33r)</a><br />
85
- <a href="classes/S33r/Client.html#M000115">init (S33r::Client)</a><br />
86
- <a href="classes/S33r/NamedBucket.html#M000091">init (S33r::NamedBucket)</a><br />
87
- <a href="classes/S33r/NamedBucket.html#M000101">key_exists? (S33r::NamedBucket)</a><br />
88
- <a href="classes/S33r/NamedBucket.html#M000099">keys (S33r::NamedBucket)</a><br />
91
+ <a href="classes/S33r/NamedBucket.html#M000098">init (S33r::NamedBucket)</a><br />
92
+ <a href="classes/S33r/Client.html#M000117">init (S33r::Client)</a><br />
93
+ <a href="classes/S33r/NamedBucket.html#M000109">key_exists? (S33r::NamedBucket)</a><br />
94
+ <a href="classes/S33r/NamedBucket.html#M000107">keys (S33r::NamedBucket)</a><br />
89
95
  <a href="classes/S33r.html#M000056">keys_to_symbols (S33r)</a><br />
90
- <a href="classes/S33r/BucketListing.html#M000110">last_key (S33r::BucketListing)</a><br />
96
+ <a href="classes/S33r/BucketListing.html#M000154">last_key (S33r::BucketListing)</a><br />
91
97
  <a href="classes/MIME/Type.html#M000019">like? (MIME::Type)</a><br />
92
- <a href="classes/S33r/Client.html#M000120">list (S33r::Client)</a><br />
93
- <a href="classes/S33r/Client.html#M000121">list_bucket (S33r::Client)</a><br />
94
- <a href="classes/S33r/Client.html#M000119">list_buckets (S33r::Client)</a><br />
95
- <a href="classes/S33r/NamedBucket.html#M000096">listing (S33r::NamedBucket)</a><br />
96
- <a href="classes/S33r/Client.html#M000116">load_config (S33r::Client)</a><br />
98
+ <a href="classes/S33r/Client.html#M000122">list (S33r::Client)</a><br />
99
+ <a href="classes/S33r/Client.html#M000123">list_bucket (S33r::Client)</a><br />
100
+ <a href="classes/S33r/Client.html#M000121">list_buckets (S33r::Client)</a><br />
101
+ <a href="classes/S33r/NamedBucket.html#M000104">listing (S33r::NamedBucket)</a><br />
102
+ <a href="classes/S33r/S3Object.html#M000095">load (S33r::S3Object)</a><br />
103
+ <a href="classes/S33r/Client.html#M000118">load_config (S33r::Client)</a><br />
97
104
  <a href="classes/S33r/S3ACL/Grant.html#M000082">log_target_grants (S33r::S3ACL::Grant)</a><br />
98
105
  <a href="classes/S33r/S3ACL/ACLDoc.html#M000071">log_targetable? (S33r::S3ACL::ACLDoc)</a><br />
99
- <a href="classes/S33r/Client.html#M000132">make_private (S33r::Client)</a><br />
100
- <a href="classes/S33r/Client.html#M000131">make_public (S33r::Client)</a><br />
106
+ <a href="classes/S33r/Client.html#M000135">make_private (S33r::Client)</a><br />
107
+ <a href="classes/S33r/Client.html#M000134">make_public (S33r::Client)</a><br />
101
108
  <a href="classes/S33r/Sync.html#M000059">md5sum (S33r::Sync)</a><br />
102
109
  <a href="classes/S33r.html#M000045">metadata_headers (S33r)</a><br />
103
110
  <a href="classes/S33r/S3ACL/Grantee.html#M000075">method_missing (S33r::S3ACL::Grantee)</a><br />
104
- <a href="classes/S33r/S3ACL/AmazonCustomer.html#M000063">new (S33r::S3ACL::AmazonCustomer)</a><br />
105
- <a href="classes/S33r/Client.html#M000113">new (S33r::Client)</a><br />
106
- <a href="classes/MIME/Type.html#M000029">new (MIME::Type)</a><br />
107
- <a href="classes/S33r/LoggingResource.html#M000085">new (S33r::LoggingResource)</a><br />
108
111
  <a href="classes/S33r/S3ACL/Group.html#M000060">new (S33r::S3ACL::Group)</a><br />
109
- <a href="classes/S33r/S3Object.html#M000087">new (S33r::S3Object)</a><br />
110
- <a href="classes/S33r/S3ACL/CanonicalUser.html#M000061">new (S33r::S3ACL::CanonicalUser)</a><br />
111
- <a href="classes/MIME/Types.html#M000010">new (MIME::Types)</a><br />
112
112
  <a href="classes/S33r/S3ACL/ACLDoc.html#M000064">new (S33r::S3ACL::ACLDoc)</a><br />
113
+ <a href="classes/S33r/S3ACL/CanonicalUser.html#M000061">new (S33r::S3ACL::CanonicalUser)</a><br />
113
114
  <a href="classes/S33r/S3ACL/Grant.html#M000077">new (S33r::S3ACL::Grant)</a><br />
114
- <a href="classes/S33r/BucketListing.html#M000107">new (S33r::BucketListing)</a><br />
115
- <a href="classes/S33r/NamedBucket.html#M000092">new (S33r::NamedBucket)</a><br />
115
+ <a href="classes/S33r/BucketListing.html#M000151">new (S33r::BucketListing)</a><br />
116
+ <a href="classes/S33r/S3Object.html#M000087">new (S33r::S3Object)</a><br />
117
+ <a href="classes/MIME/Types.html#M000010">new (MIME::Types)</a><br />
118
+ <a href="classes/MIME/Type.html#M000029">new (MIME::Type)</a><br />
119
+ <a href="classes/S33r/LoggingResource.html#M000085">new (S33r::LoggingResource)</a><br />
120
+ <a href="classes/S33r/Client.html#M000115">new (S33r::Client)</a><br />
121
+ <a href="classes/S33r/NamedBucket.html#M000099">new (S33r::NamedBucket)</a><br />
122
+ <a href="classes/S33r/S3ACL/AmazonCustomer.html#M000063">new (S33r::S3ACL::AmazonCustomer)</a><br />
116
123
  <a href="classes/Net/HTTPResponse.html#M000008">not_found (Net::HTTPResponse)</a><br />
117
124
  <a href="classes/MIME/Type.html#M000022">obsolete? (MIME::Type)</a><br />
118
125
  <a href="classes/MIME/Types.html#M000013">of (MIME::Types)</a><br />
119
126
  <a href="classes/MIME/Types.html#M000017">of (MIME::Types)</a><br />
120
127
  <a href="classes/Net/HTTPResponse.html#M000006">ok? (Net::HTTPResponse)</a><br />
121
128
  <a href="classes/S33r.html#M000057">parse_expiry (S33r)</a><br />
122
- <a href="classes/S33r/BucketListing.html#M000109">parse_listing (S33r::BucketListing)</a><br />
129
+ <a href="classes/S33r/BucketListing.html#M000153">parse_listing (S33r::BucketListing)</a><br />
130
+ <a href="classes/S33r/S3Object.html#M000094">parse_response (S33r::S3Object)</a><br />
131
+ <a href="classes/S33r/S3Object.html#M000092">parse_xml_node (S33r::S3Object)</a><br />
123
132
  <a href="classes/MIME/Type.html#M000035">platform? (MIME::Type)</a><br />
124
- <a href="classes/S33r/BucketListing.html#M000112">pretty (S33r::BucketListing)</a><br />
125
- <a href="classes/S33r/NamedBucket.html#M000093">public_contents? (S33r::NamedBucket)</a><br />
133
+ <a href="classes/S33r/BucketListing.html#M000156">pretty (S33r::BucketListing)</a><br />
134
+ <a href="classes/S33r/NamedBucket.html#M000100">public_contents? (S33r::NamedBucket)</a><br />
126
135
  <a href="classes/S33r/S3ACL/Grant.html#M000081">public_read_grant (S33r::S3ACL::Grant)</a><br />
127
136
  <a href="classes/S33r/S3ACL/ACLDoc.html#M000069">public_readable? (S33r::S3ACL::ACLDoc)</a><br />
128
- <a href="classes/S33r/NamedBucket.html#M000103">put_file (S33r::NamedBucket)</a><br />
129
- <a href="classes/S33r/Client.html#M000140">put_file (S33r::Client)</a><br />
130
- <a href="classes/S33r/Client.html#M000138">put_resource (S33r::Client)</a><br />
131
- <a href="classes/S33r/NamedBucket.html#M000104">put_stream (S33r::NamedBucket)</a><br />
132
- <a href="classes/S33r/Client.html#M000139">put_text (S33r::Client)</a><br />
133
- <a href="classes/S33r/NamedBucket.html#M000102">put_text (S33r::NamedBucket)</a><br />
137
+ <a href="classes/S33r/Client.html#M000143">put_file (S33r::Client)</a><br />
138
+ <a href="classes/S33r/NamedBucket.html#M000111">put_file (S33r::NamedBucket)</a><br />
139
+ <a href="classes/S33r/Client.html#M000141">put_resource (S33r::Client)</a><br />
140
+ <a href="classes/S33r/NamedBucket.html#M000112">put_stream (S33r::NamedBucket)</a><br />
141
+ <a href="classes/S33r/NamedBucket.html#M000110">put_text (S33r::NamedBucket)</a><br />
142
+ <a href="classes/S33r/Client.html#M000142">put_text (S33r::Client)</a><br />
134
143
  <a href="classes/MIME/Type.html#M000030">registered? (MIME::Type)</a><br />
135
144
  <a href="classes/S33r/S3ACL/ACLDoc.html#M000068">remove_grant (S33r::S3ACL::ACLDoc)</a><br />
136
145
  <a href="classes/S33r/S3ACL/ACLDoc.html#M000073">remove_log_target_grants (S33r::S3ACL::ACLDoc)</a><br />
137
146
  <a href="classes/S33r.html#M000058">remove_namespace (S33r)</a><br />
138
- <a href="classes/S33r/Client.html#M000126">resource_exists? (S33r::Client)</a><br />
147
+ <a href="classes/S33r/Client.html#M000129">resource_exists? (S33r::Client)</a><br />
139
148
  <a href="classes/S33r.html#M000050">s3_acl_path (S33r)</a><br />
140
- <a href="classes/S33r/NamedBucket.html#M000106">s3_authenticated_url (S33r::NamedBucket)</a><br />
141
149
  <a href="classes/S33r.html#M000055">s3_authenticated_url (S33r)</a><br />
150
+ <a href="classes/S33r/NamedBucket.html#M000114">s3_authenticated_url (S33r::NamedBucket)</a><br />
142
151
  <a href="classes/S33r.html#M000051">s3_logging_path (S33r)</a><br />
143
152
  <a href="classes/S33r.html#M000054">s3_path (S33r)</a><br />
144
153
  <a href="classes/S33r.html#M000053">s3_public_url (S33r)</a><br />
145
154
  <a href="classes/S33r.html#M000052">s3_url (S33r)</a><br />
155
+ <a href="classes/S33r/S3Object.html#M000097">save (S33r::S3Object)</a><br />
146
156
  <a href="classes/Net/HTTPGenericRequest.html#M000004">send_request_with_body_stream (Net::HTTPGenericRequest)</a><br />
147
- <a href="classes/S33r/Client.html#M000129">set_acl (S33r::Client)</a><br />
148
- <a href="classes/S33r/S3Object.html#M000090">set_from_node (S33r::S3Object)</a><br />
149
- <a href="classes/S33r/S3Object.html#M000089">set_from_xml_string (S33r::S3Object)</a><br />
150
- <a href="classes/S33r/BucketListing.html#M000108">set_listing_xml (S33r::BucketListing)</a><br />
151
- <a href="classes/S33r/Client.html#M000130">set_logging (S33r::Client)</a><br />
157
+ <a href="classes/S33r/Client.html#M000132">set_acl (S33r::Client)</a><br />
158
+ <a href="classes/S33r/BucketListing.html#M000152">set_listing_xml (S33r::BucketListing)</a><br />
159
+ <a href="classes/S33r/Client.html#M000133">set_logging (S33r::Client)</a><br />
160
+ <a href="classes/S33r/S3Object.html#M000088">set_properties (S33r::S3Object)</a><br />
152
161
  <a href="classes/MIME/Type.html#M000033">signature? (MIME::Type)</a><br />
153
162
  <a href="classes/MIME/Type.html#M000025">simplified (MIME::Type)</a><br />
154
- <a href="classes/S33r/NamedBucket.html#M000094">strict? (S33r::NamedBucket)</a><br />
163
+ <a href="classes/S33r/NamedBucket.html#M000101">strict? (S33r::NamedBucket)</a><br />
155
164
  <a href="classes/Net/HTTPResponse.html#M000007">success (Net::HTTPResponse)</a><br />
156
165
  <a href="classes/MIME/Type.html#M000034">system? (MIME::Type)</a><br />
157
166
  <a href="classes/MIME/Type.html#M000039">to_a (MIME::Type)</a><br />
158
167
  <a href="classes/MIME/Type.html#M000040">to_hash (MIME::Type)</a><br />
168
+ <a href="classes/MIME/Type.html#M000037">to_s (MIME::Type)</a><br />
159
169
  <a href="classes/Net/HTTPResponse.html#M000009">to_s (Net::HTTPResponse)</a><br />
160
170
  <a href="classes/Net/HTTPGenericRequest.html#M000003">to_s (Net::HTTPGenericRequest)</a><br />
161
- <a href="classes/MIME/Type.html#M000037">to_s (MIME::Type)</a><br />
162
171
  <a href="classes/MIME/Type.html#M000038">to_str (MIME::Type)</a><br />
163
- <a href="classes/S33r/S3ACL/Grant.html#M000083">to_xml (S33r::S3ACL::Grant)</a><br />
164
172
  <a href="classes/S33r/LoggingResource.html#M000086">to_xml (S33r::LoggingResource)</a><br />
173
+ <a href="classes/S33r/S3ACL/Grant.html#M000083">to_xml (S33r::S3ACL::Grant)</a><br />
165
174
  <a href="classes/S33r/S3ACL/ACLDoc.html#M000066">to_xml (S33r::S3ACL::ACLDoc)</a><br />
166
- <a href="classes/MIME/Types.html#M000012">type_for (MIME::Types)</a><br />
167
175
  <a href="classes/MIME/Types.html#M000016">type_for (MIME::Types)</a><br />
176
+ <a href="classes/MIME/Types.html#M000012">type_for (MIME::Types)</a><br />
168
177
  <a href="classes/MIME/Type.html#M000024">urls (MIME::Type)</a><br />
169
178
  <a href="classes/MIME/Type.html#M000021">use_instead (MIME::Type)</a><br />
170
179
  <a href="classes/XML.html#M000001">xget (XML)</a><br />
@@ -1,6 +1,6 @@
1
- require 'date'
2
- require 'xml/libxml'
3
- require File.join(File.dirname(__FILE__), 's3_acl')
1
+ base = File.dirname(__FILE__)
2
+ require File.join(base, 'libxml_loader')
3
+ require File.join(base, 's3_acl')
4
4
 
5
5
  module S33r
6
6
  # Object representation of the content of a bucket.
@@ -15,6 +15,9 @@ module S33r
15
15
  attr_accessor :named_bucket
16
16
  # The last key listed in this BucketListing.
17
17
  attr_reader :last_key
18
+ # Set to true to show raw parsing errors, instead of the catch all error message
19
+ # (useful for debugging).
20
+ attr_accessor :raw
18
21
 
19
22
  # Create a new object representing a ListBucketResult.
20
23
  #
@@ -24,28 +27,44 @@ module S33r
24
27
  # +named_bucket+ can be set to an existing NamedBucket instance, so that any objects
25
28
  # inside this listing can be associated with that instance. This enables objects to be easily deleted
26
29
  # without having to create a new Client instance.
27
- def initialize(bucket_listing_xml, named_bucket=nil)
30
+ #
31
+ # If +raw+ is set to true, you get ugly parser errors.
32
+ def initialize(bucket_listing_xml, named_bucket=nil, raw=false)
28
33
  @contents = {}
29
34
  @common_prefixes = {}
30
35
  # the NamedBucket instance associated with this listing (if any)
31
36
  @named_bucket = named_bucket
37
+ @raw = raw
32
38
  set_listing_xml(bucket_listing_xml)
33
39
  end
34
40
 
35
41
  # Convert a ListBucketResult XML document into an object representation.
36
42
  def set_listing_xml(bucket_listing_xml)
37
- begin
43
+ # proc to remove the namespace and parse the listing
44
+ work = lambda do |bucket_listing_xml|
38
45
  # remove the namespace declaration: libxml doesn't like it
39
46
  bucket_listing_xml = S33r.remove_namespace(bucket_listing_xml)
40
47
  parse_listing(bucket_listing_xml)
41
- rescue
42
- message = "Cannot create bucket listing from supplied XML"
43
- message += " (was nil)" if bucket_listing_xml.nil?
44
- raise S33rException::InvalidBucketListing, message
48
+ end
49
+
50
+ if @raw
51
+ work.call(bucket_listing_xml)
52
+ else
53
+ begin
54
+ work.call(bucket_listing_xml)
55
+ rescue
56
+ message = "Cannot create bucket listing from supplied XML"
57
+ message += " (was nil)" if bucket_listing_xml.nil?
58
+ raise S33rException::InvalidBucketListing, message
59
+ end
45
60
  end
46
61
  end
47
62
 
48
63
  # Parse raw XML ListBucketResponse from S3 into object instances.
64
+ # The S3Objects are skeletons, and are not automatically populated
65
+ # from S3 (their @value attributes are nil). To load the data into
66
+ # an object, grab it from the listing and call its load method to
67
+ # pull the data down from S3.
49
68
  def parse_listing(bucket_listing_xml)
50
69
  doc = XML.get_xml_doc(bucket_listing_xml)
51
70
 
@@ -64,7 +83,7 @@ module S33r
64
83
 
65
84
  # contents
66
85
  doc.find('//Contents').to_a.each do |node|
67
- obj = S3Object.new(node)
86
+ obj = S3Object.from_xml_node(node)
68
87
  # Add to the content listing for the bucket
69
88
  @contents[obj.key] = obj
70
89
  end
@@ -102,48 +121,4 @@ module S33r
102
121
  end
103
122
 
104
123
  end
105
-
106
- # Representation of an object stored in a bucket.
107
- class S3Object
108
- attr_reader :named_bucket, :key, :last_modified, :etag, :size, :owner, :storage_class
109
- attr_writer :named_bucket
110
-
111
- # Create from a node.
112
- def initialize(node=nil, named_bucket=nil)
113
- @named_bucket = named_bucket
114
- self.set_from_node(node) unless node.nil?
115
- end
116
-
117
- # Remove this object from associated NamedBucket.
118
- def delete
119
- @named_bucket.delete_key(@key) unless @named_bucket.nil?
120
- end
121
-
122
- # Set properties of the object from an XML string.
123
- #
124
- # +xml_str+ should be a string representing a full XML document,
125
- # containing a <Contents> element as its root element.
126
- def set_from_xml_string(xml_str)
127
- set_from_node(XML.get_xml_doc(xml_str))
128
- end
129
-
130
- # Set properties of the object from an XML document.
131
- #
132
- # +doc+: XML::Document instance to parse to get properties for this object.
133
- def set_from_node(doc)
134
- @key = doc.xget('Key')
135
- @last_modified = DateTime.parse(doc.xget('LastModified'))
136
- @etag = doc.xget('ETag').gsub("\"", "")
137
- @size = doc.xget('Size').to_i
138
-
139
- # Build representation of the owner.
140
- user_xml_doc = doc.find('Owner').to_a.first
141
- @owner = S3ACL::CanonicalUser.from_xml(user_xml_doc)
142
-
143
- # TODO: if setting from a full object listing (GET on a resource key),
144
- # do additional field setting here (e.g. x-amz-meta- headers)
145
- # and assign the response body to some data field; detect whether
146
- # these fields exist before attempting to set properties
147
- end
148
- end
149
- end
124
+ end
@@ -2,8 +2,9 @@ require 'net/https'
2
2
  require 'cgi'
3
3
  require 'erb'
4
4
  require 'yaml'
5
- require File.join(File.dirname(__FILE__), 's3_acl')
6
- require File.join(File.dirname(__FILE__), 's33r_exception')
5
+ base = File.dirname(__FILE__)
6
+ require File.join(base, 's3_acl')
7
+ require File.join(base, 's33r_exception')
7
8
 
8
9
  module S33r
9
10
  include Net
@@ -36,6 +37,10 @@ module S33r
36
37
 
37
38
  # Default log bucket location.
38
39
  attr_accessor :log_bucket
40
+
41
+ # The options used to create the client (useful when spawning
42
+ # NamedBucket instances from Client instances).
43
+ attr_reader :options
39
44
 
40
45
  # Configure either an SSL-enabled or plain HTTP client.
41
46
  # (If using SSL, no verification of server certificate is performed.)
@@ -46,6 +51,7 @@ module S33r
46
51
  def initialize(aws_access_key, aws_secret_access_key, options={})
47
52
  @use_ssl = true
48
53
  @use_ssl = false if (false == options[:use_ssl])
54
+ options[:use_ssl] = @use_ssl
49
55
 
50
56
  @dump_requests = (true == options[:dump_requests])
51
57
 
@@ -60,6 +66,9 @@ module S33r
60
66
 
61
67
  # headers sent with every request made by this client
62
68
  @client_headers = {}
69
+
70
+ # keep a record of the options used to create this instance
71
+ @options = options
63
72
  end
64
73
 
65
74
  # Get an HTTP client instance.
@@ -95,9 +104,9 @@ module S33r
95
104
  # Note that the loader also runs the config. file through ERB, so you can
96
105
  # add dynamic blocks of ERB (Ruby) code into your files.
97
106
  #
98
- # The +options+ section contains settings specific to Client and NamedClient instances; +custom+
99
- # contains extra settings specific to your application.
100
- # +options+ and +custom+ sections can be omitted, but settings for AWS keys are required.
107
+ # The +options+ section contains other settings, either specific to the Client or
108
+ # NamedBucket classes, or general application settings.
109
+ # The +options+ section can be omitted, but settings for AWS keys are required.
101
110
  #
102
111
  # Returns an array <tt>[aws_access_key, aws_secret_access_key, options]</tt>, where +options+
103
112
  # is a hash.
@@ -160,7 +169,8 @@ module S33r
160
169
  client.start do
161
170
  response = client.request(req, data)
162
171
 
163
- # Check the response to see whether S3 is down.
172
+ # Check the response to see whether S3 is down;
173
+ # raises an S3FallenOver error if S3 returns a 500-503 response code
164
174
  response.check_s3_availability
165
175
 
166
176
  response
@@ -175,7 +185,9 @@ module S33r
175
185
 
176
186
  # List all buckets.
177
187
  #
178
- # Returns an Array of NamedBucket instances.
188
+ # Returns an array of NamedBucket instances; array will be empty if
189
+ # the BucketListing parse fails for any reason (i.e. no <Bucket> elements
190
+ # occur in it).
179
191
  def list_buckets
180
192
  bucket_list_xml = do_get('/').body
181
193
  doc = XML.get_xml_doc(S33r.remove_namespace(bucket_list_xml))
@@ -184,8 +196,12 @@ module S33r
184
196
 
185
197
  doc.find("//Bucket").to_a.each do |node|
186
198
  bucket_name = node.xget('Name')
187
- named_buckets << NamedBucket.new(@aws_access_key, @aws_secret_access_key,
188
- {:default_bucket => bucket_name, :dump_request => self.dump_requests})
199
+ if bucket_name
200
+ # The NamedBucket instances inherit the request dumping behaviour
201
+ # of this client.
202
+ named_buckets << NamedBucket.new(@aws_access_key, @aws_secret_access_key,
203
+ {:default_bucket => bucket_name, :dump_request => self.dump_requests})
204
+ end
189
205
  end
190
206
 
191
207
  named_buckets
@@ -226,7 +242,7 @@ module S33r
226
242
  raise S33rException::BucketListingMaxKeysError, "max_keys option to list bucket cannot be > #{BUCKET_LIST_MAX_MAX_KEYS}" \
227
243
  if max_keys > BUCKET_LIST_MAX_MAX_KEYS
228
244
 
229
- # convert max_keys parameter to :max-keys parameter
245
+ # convert :max_keys querystring parameter to 'max-keys' parameter
230
246
  query_params['max-keys'] = query_params.delete(:max_keys)
231
247
  end
232
248
 
@@ -261,36 +277,51 @@ module S33r
261
277
  end
262
278
 
263
279
  # Check whether a bucket exists or not.
264
- #
265
- # Returns true if bucket exists.
266
280
  def bucket_exists?(bucket_name)
267
281
  resource_exists?(bucket_name)
268
282
  end
269
283
 
284
+ # Create a NamedBucket instance.
285
+ #
286
+ # +options+ is a hash of extra options to use when creating
287
+ # the NamedBucket instance (see NamedBucket.initialize);
288
+ # specify :parent to use the same options used to create this Client
289
+ # instance.
290
+ def get_named_bucket(bucket_name, options={}, &block)
291
+ options = @options if :parent == options
292
+ options[:default_bucket] = bucket_name
293
+ named_bucket = NamedBucket.new(@aws_access_key, @aws_secret_access_key, options)
294
+ yield named_bucket if block_given?
295
+ named_bucket
296
+ end
297
+
270
298
  # Fetch a resource.
299
+ #
300
+ # Returns a plain response, not an S3Object: if you want an object back,
301
+ # use get_object instead.
271
302
  def get_resource(bucket_name, resource_key, headers={})
272
303
  do_get("/#{bucket_name}/#{resource_key}", headers)
273
304
  end
274
305
 
275
306
  # Check whether a bucket contains a key.
276
307
  #
277
- # Returns true if resource_key exists inside bucket_name exists.
308
+ # Returns true if resource_key exists inside bucket_name.
278
309
  def resource_exists?(bucket_name, resource_key=nil)
279
310
  path = "/#{bucket_name}"
280
311
  path += "/#{resource_key}" unless resource_key.nil?
281
312
  do_head(path).ok?
282
313
  end
283
314
 
284
- # Fetch an object.
285
- #
286
- # TODO: return S3Object
287
- def get_object(bucket_name, resource_key, headers)
315
+ # Fetch an object. Note that this actually pulls down the
316
+ # object from S3 and instantiates the S3Object instance with it.
317
+ def get_object(bucket_name, resource_key, headers={})
288
318
  response = get_resource(bucket_name, resource_key, headers)
319
+ S3Object.from_response(resource_key, response)
289
320
  end
290
321
 
291
322
  # Fetch the ACL document for a resource.
292
323
  #
293
- # Returns nil if there is a problem with the resource
324
+ # Raises an exception if there is a problem with the resource
294
325
  # (e.g. it doesn't exist).
295
326
  def get_acl(bucket_name, resource_key='')
296
327
  path = s3_acl_path(bucket_name, resource_key)
@@ -302,7 +333,7 @@ module S33r
302
333
  end
303
334
  end
304
335
 
305
- # Put the ACL document for a resource.
336
+ # Put the ACL document back to a resource.
306
337
  #
307
338
  # +acl_doc+ is an S33r::S3ACL::ACLDoc instance.
308
339
  #
@@ -338,7 +369,7 @@ module S33r
338
369
  end
339
370
  end
340
371
 
341
- # TODO
372
+ #-- TODO
342
373
  def make_private
343
374
  end
344
375
 
@@ -369,7 +400,7 @@ module S33r
369
400
  !acl.log_targetable?
370
401
  end
371
402
 
372
- # Enable logging for a resource (bucket or key).
403
+ # Enable logging for a resource (only buckets are supported presently).
373
404
  #
374
405
  # +log_prefix+ is the prefix for the logs.
375
406
  # +bucket_name+ is the bucket to log.
@@ -380,8 +411,10 @@ module S33r
380
411
  # (NB this is not currently supported by S3).
381
412
  # +:log_prefix => 'prefix'+ is the (optional) log file prefix
382
413
  # (defaults to bucket_name + '-')
383
- #
414
+ #
415
+ #-- TODO: tests
384
416
  def enable_logging(bucket_name, log_bucket=nil, options={})
417
+ # Set to the default log_bucket if not set explicitly.
385
418
  log_bucket ||= @log_bucket
386
419
 
387
420
  resource_key = options[:for_key]
@@ -398,17 +431,24 @@ module S33r
398
431
  set_logging(logging_resource, bucket_name, resource_key)
399
432
  end
400
433
 
401
- # TODO
434
+ # Turn off logging of a resource.
435
+ #-- TODO
402
436
  def disable_logging
403
437
  end
404
438
 
405
- # TODO
439
+ # Get the logging status of a resource.
440
+ #-- TODO
406
441
  def get_logging
407
442
  end
408
443
 
409
444
  # Put some generic resource onto S3.
445
+ #
446
+ # To stream with this method, +data+ should respond to the +stat+
447
+ # method; examples of data types which respond to this include File instances.
410
448
  def put_resource(bucket_name, resource_key, data, headers={})
411
- do_put("/#{bucket_name}/" + "#{CGI::escape(resource_key)}", data, headers)
449
+ raise S33r::S33rException::TryingToPutEmptyResource, "No data to put for key '#{resource_key}'" unless data
450
+ resp = do_put("/#{bucket_name}/" + "#{CGI::escape(resource_key)}", data, headers)
451
+ resp.ok?
412
452
  end
413
453
 
414
454
  # Put a string onto S3.
@@ -447,13 +487,15 @@ module S33r
447
487
  # (MIME::Types returns an array of possible MIME types)
448
488
  mime_type = MIME::Types[headers[:content_type]][0]
449
489
  else
490
+ # we're not going to use this much, just for parsing the content type etc.
450
491
  mime_type = guess_mime_type(filename)
451
492
  end
452
493
  content_type = mime_type.simplified
453
494
  headers['Content-Type'] = content_type
454
495
  headers['Content-Transfer-Encoding'] = 'binary' if mime_type.binary?
455
496
 
456
- # the data we want to put (handle to file, so we can stream from it)
497
+ # Open the file, and pass the handle to the HTTP client so content
498
+ # can be streamed.
457
499
  File.open(filename) do |data|
458
500
  # send the put request
459
501
  put_resource(bucket_name, resource_key, data, headers)
@@ -462,7 +504,7 @@ module S33r
462
504
 
463
505
  # Delete a resource from S3.
464
506
  #
465
- # Note that S3 returns the same response code () regardless
507
+ # Note that S3 returns the same response code regardless
466
508
  # of whether the resource was successfully deleted, or didn't exist
467
509
  # in the first place.
468
510
  def delete_resource(bucket_name, resource_key, headers={})
@@ -500,4 +542,4 @@ module S33r
500
542
  end
501
543
 
502
544
  end
503
- end
545
+ end