simple_aws 0.0.1c → 0.0.1d
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +0 -4
- data/lib/aws/cloud_front.rb +117 -0
- data/lib/aws/core/util.rb +51 -2
- data/lib/aws/s3.rb +34 -4
- data/samples/cloud_front.rb +52 -0
- data/simple_aws.gemspec +1 -1
- data/test/aws/cloud_front_test.rb +109 -0
- data/test/aws/core/util_test.rb +86 -0
- data/test/aws/s3_test.rb +10 -3
- metadata +13 -10
- data/lib/aws/signing/authorization_header.rb +0 -43
- data/test/aws/signing/authorization_header_test.rb +0 -33
data/README.md
CHANGED
@@ -122,10 +122,6 @@ These are the following Amazon APIs that SimpleAWS currently handles:
|
|
122
122
|
* Mechanical Turk
|
123
123
|
* SQS (Simple Queue Service)
|
124
124
|
* SES (Simple Email Service)
|
125
|
-
|
126
|
-
Yet to be Implemented
|
127
|
-
---------------------
|
128
|
-
|
129
125
|
* CloudFront
|
130
126
|
|
131
127
|
Currently Out-Of-Scope
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'aws/api'
|
2
|
+
require 'aws/core/util'
|
3
|
+
|
4
|
+
module AWS
|
5
|
+
|
6
|
+
##
|
7
|
+
# Amazon's CloudFront
|
8
|
+
#
|
9
|
+
# http://docs.amazonwebservices.com/AmazonCloudFront/latest/APIReference/Welcome.html
|
10
|
+
#
|
11
|
+
# As CloudFront is much closer to a RESTful service than the other AWS APIs, all
|
12
|
+
# calls through this API are done through these four HTTP METHODS:
|
13
|
+
# GET, PUT, DELETE, and POST.
|
14
|
+
#
|
15
|
+
# The paths for all request get the version prepended on to them, you do not
|
16
|
+
# have to worry about that part of the path. Outside of this, in keeping with
|
17
|
+
# the goals of SimpleAWS, everything else should be exactly as you read it in
|
18
|
+
# the AWS API docs in the link above.
|
19
|
+
#
|
20
|
+
# So "GET Distribution List" is
|
21
|
+
#
|
22
|
+
# cloud_front.get "/distribution"
|
23
|
+
#
|
24
|
+
# For requests that need extra parameters, use the :params option
|
25
|
+
#
|
26
|
+
# cloud_front.get "/distribution", :params => {
|
27
|
+
# "MaxItems" => 10
|
28
|
+
# }
|
29
|
+
#
|
30
|
+
# Like :params, use :headers to add headers to the request
|
31
|
+
#
|
32
|
+
# cloud_front.get "/distribution", :headers => {
|
33
|
+
# "x-amz-security-token" => "security string"
|
34
|
+
# }
|
35
|
+
#
|
36
|
+
# The details of CloudFront requests are all passed through XML bodies.
|
37
|
+
# To make this as simple and painless as possible, this API supports the
|
38
|
+
# :xml option to turn a Hash into an XML string
|
39
|
+
#
|
40
|
+
# cloud_front.post "/distribution", :xml => {
|
41
|
+
# :DistributionConfig => {
|
42
|
+
# ...
|
43
|
+
# }
|
44
|
+
# }
|
45
|
+
#
|
46
|
+
# Do note that this XML building is very simple, does not support attributes,
|
47
|
+
# and will only work on Hashes, Arrays, and objects that can be easily #to_s-ed.
|
48
|
+
# Anything else will error out or might result in invalid request bodies.
|
49
|
+
#
|
50
|
+
# If you already have the XML string and just need to give it to the
|
51
|
+
# request, you can use :body to set the raw value of the request body:
|
52
|
+
#
|
53
|
+
# cloud_front.post "/distribution", :body => raw_body_xml
|
54
|
+
#
|
55
|
+
# All responses are wrapped in an AWS::Response object.
|
56
|
+
##
|
57
|
+
class CloudFront < API
|
58
|
+
endpoint "cloudfront"
|
59
|
+
use_https true
|
60
|
+
version "2010-11-01"
|
61
|
+
|
62
|
+
def initialize(key, secret)
|
63
|
+
super(key, secret)
|
64
|
+
end
|
65
|
+
|
66
|
+
[:get, :post, :put, :delete].each do |method|
|
67
|
+
define_method(method) do |*args|
|
68
|
+
self.call method, *args
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def call(method, path, options = {})
|
73
|
+
request = AWS::Request.new method, self.uri, "/#{self.version}#{path}"
|
74
|
+
|
75
|
+
(options[:params] || {}).each do |k, v|
|
76
|
+
request.params[k] = v
|
77
|
+
end
|
78
|
+
|
79
|
+
(options[:headers] || {}).each do |k, v|
|
80
|
+
request.headers[k] = v
|
81
|
+
end
|
82
|
+
|
83
|
+
if xml = options[:xml]
|
84
|
+
raise ":xml must be a Hash" unless xml.is_a?(Hash)
|
85
|
+
|
86
|
+
namespace = "http://cloudfront.amazonaws.com/doc/#{self.version}"
|
87
|
+
request.body = AWS::Util.build_xml_from xml, namespace
|
88
|
+
request.headers["Content-Type"] = "text/xml"
|
89
|
+
else
|
90
|
+
request.body = options[:body]
|
91
|
+
end
|
92
|
+
|
93
|
+
connection = AWS::Connection.new
|
94
|
+
connection.call finish_and_sign_request(request)
|
95
|
+
end
|
96
|
+
|
97
|
+
protected
|
98
|
+
|
99
|
+
##
|
100
|
+
# Build and sign the final request, as per the rules here:
|
101
|
+
# http://docs.amazonwebservices.com/AmazonCloudFront/latest/DeveloperGuide/RESTAuthentication.html
|
102
|
+
##
|
103
|
+
def finish_and_sign_request(request)
|
104
|
+
request.headers["Date"] = Time.now.utc.httpdate
|
105
|
+
request.headers["Authorization"] =
|
106
|
+
"AWS #{self.access_key}:#{Base64.encode64(build_signature_for(request)).chomp}"
|
107
|
+
|
108
|
+
request
|
109
|
+
end
|
110
|
+
|
111
|
+
def build_signature_for(request)
|
112
|
+
date = request.headers["x-amz-date"] || request.headers["Date"]
|
113
|
+
|
114
|
+
OpenSSL::HMAC.digest("sha1", self.secret_key, date)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
data/lib/aws/core/util.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'ox'
|
2
|
+
|
1
3
|
module AWS
|
2
4
|
##
|
3
5
|
# Collection of helper methods used in the library
|
@@ -7,7 +9,7 @@ module AWS
|
|
7
9
|
##
|
8
10
|
# Simpler version of ActiveSupport's camelize
|
9
11
|
##
|
10
|
-
def
|
12
|
+
def camelcase(string, lower_first_char = false)
|
11
13
|
return string if string =~ /[A-Z]/
|
12
14
|
|
13
15
|
if lower_first_char
|
@@ -19,7 +21,7 @@ module AWS
|
|
19
21
|
|
20
22
|
|
21
23
|
# AWS URI escaping, as implemented by Fog
|
22
|
-
def
|
24
|
+
def uri_escape(string)
|
23
25
|
# Quick hack for already escaped string, don't escape again
|
24
26
|
# I don't think any requests require a % in a parameter, but if
|
25
27
|
# there is one I'll need to rethink this
|
@@ -30,5 +32,52 @@ module AWS
|
|
30
32
|
}
|
31
33
|
end
|
32
34
|
|
35
|
+
##
|
36
|
+
# Take a hash and build a simple XML string from
|
37
|
+
# that Hash. This does not support properties on elements,
|
38
|
+
# and is meant for request bodies like what CloudFront expects.
|
39
|
+
#
|
40
|
+
# The hash body can contain symbols, strings, arrays and hashes
|
41
|
+
##
|
42
|
+
def build_xml_from(hash, namespace = nil)
|
43
|
+
doc = Ox::Document.new(:version => 1.0, :standalone => true)
|
44
|
+
|
45
|
+
root_key = hash.keys.first
|
46
|
+
root = Ox::Element.new root_key
|
47
|
+
root[:xmlns] = namespace if namespace
|
48
|
+
|
49
|
+
doc << root
|
50
|
+
|
51
|
+
build_body root, hash[root_key]
|
52
|
+
|
53
|
+
%|<?xml version="1.0" encoding="UTF-8"?>#{Ox.dump doc}|
|
54
|
+
end
|
55
|
+
|
56
|
+
extend self
|
57
|
+
|
58
|
+
protected
|
59
|
+
|
60
|
+
def build_body(parent, hash)
|
61
|
+
hash.each do |key, value|
|
62
|
+
case value
|
63
|
+
when Hash
|
64
|
+
node = build_node(key)
|
65
|
+
build_body node, value
|
66
|
+
parent << node
|
67
|
+
when Array
|
68
|
+
value.each do |entry|
|
69
|
+
build_body parent, {key => entry}
|
70
|
+
end
|
71
|
+
else
|
72
|
+
parent << build_node(key, value)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def build_node(key, value = nil)
|
78
|
+
child = Ox::Element.new key
|
79
|
+
child << value.to_s unless value.nil?
|
80
|
+
child
|
81
|
+
end
|
33
82
|
end
|
34
83
|
end
|
data/lib/aws/s3.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'aws/api'
|
2
|
-
require 'aws/signing/authorization_header'
|
3
2
|
|
4
3
|
module AWS
|
5
4
|
|
@@ -9,7 +8,7 @@ module AWS
|
|
9
8
|
# http://docs.amazonwebservices.com/AmazonS3/latest/API/Welcome.html
|
10
9
|
#
|
11
10
|
# As S3 is much closer to a RESTful service than the other AWS APIs, all
|
12
|
-
# calls through this API are done through
|
11
|
+
# calls through this API are done through these five handled HTTP METHODS:
|
13
12
|
# GET, PUT, DELETE, POST and HEAD. When sending a request, follow exactly what
|
14
13
|
# is described in the AWS API docs in the link above.
|
15
14
|
#
|
@@ -107,8 +106,6 @@ module AWS
|
|
107
106
|
connection.call finish_and_sign_request(request)
|
108
107
|
end
|
109
108
|
|
110
|
-
include Signing::AuthorizationHeader
|
111
|
-
|
112
109
|
##
|
113
110
|
# S3 handles region endpoints a little differently
|
114
111
|
##
|
@@ -122,6 +119,39 @@ module AWS
|
|
122
119
|
@uri
|
123
120
|
end
|
124
121
|
|
122
|
+
protected
|
123
|
+
|
124
|
+
##
|
125
|
+
# Build and sign the final request, as per the rules here:
|
126
|
+
# http://s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.html
|
127
|
+
##
|
128
|
+
def finish_and_sign_request(request)
|
129
|
+
request.headers["Date"] = Time.now.utc.httpdate
|
130
|
+
request.headers["Authorization"] =
|
131
|
+
"AWS #{self.access_key}:#{Base64.encode64(build_signature_for(request)).chomp}"
|
132
|
+
|
133
|
+
request
|
134
|
+
end
|
135
|
+
|
136
|
+
def build_signature_for(request)
|
137
|
+
amazon_headers = request.headers.select {|k, v|
|
138
|
+
k =~ /^x-amz/i
|
139
|
+
}.map {|k, v|
|
140
|
+
"#{k.downcase}:#{v}".chomp
|
141
|
+
}
|
142
|
+
|
143
|
+
to_sign = [
|
144
|
+
request.method.to_s.upcase,
|
145
|
+
request.headers["Content-Md5"] || "",
|
146
|
+
request.headers["Content-Type"] || "",
|
147
|
+
request.headers["Date"],
|
148
|
+
amazon_headers,
|
149
|
+
request.path
|
150
|
+
].flatten.join("\n")
|
151
|
+
|
152
|
+
OpenSSL::HMAC.digest("sha1", self.secret_key, to_sign)
|
153
|
+
end
|
154
|
+
|
125
155
|
end
|
126
156
|
|
127
157
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
$: << File.expand_path("../../lib", __FILE__)
|
2
|
+
|
3
|
+
require 'aws/cloud_front'
|
4
|
+
|
5
|
+
##
|
6
|
+
# Expects your Amazon keys to be in the environment, something like
|
7
|
+
#
|
8
|
+
# export AWS_KEY="KEY"
|
9
|
+
# export AWS_SECRET="SECRET"
|
10
|
+
##
|
11
|
+
|
12
|
+
cloud_front = AWS::CloudFront.new ENV["AWS_KEY"], ENV["AWS_SECRET"]
|
13
|
+
|
14
|
+
puts "First ten distribution items:", ""
|
15
|
+
|
16
|
+
cloud_front.get("/distribution", :params => {"MaxItems" => 10}).distribution_summary.each do |d|
|
17
|
+
puts "ID: #{d.id}"
|
18
|
+
puts "Domain: #{d.domain_name}"
|
19
|
+
if d["CustomOrigin"]
|
20
|
+
puts "Custom Origin: #{d.custom_origin.inspect}"
|
21
|
+
elsif d["S3Origin"]
|
22
|
+
puts "S3 Origin: #{d.s3_origin.inspect}"
|
23
|
+
end
|
24
|
+
puts "Status: #{d.status}"
|
25
|
+
puts ""
|
26
|
+
end
|
27
|
+
|
28
|
+
# Leaving this commented out. It works, but you can't quickly
|
29
|
+
# delete the new distribution so you'll have to clean up manually
|
30
|
+
#
|
31
|
+
#puts "", "Creating new test distribution", ""
|
32
|
+
#
|
33
|
+
#response = cloud_front.post "/distribution", :xml => {
|
34
|
+
# "DistributionConfig" => {
|
35
|
+
# "CustomOrigin" => {
|
36
|
+
# "DNSName" => "cnd.example.com",
|
37
|
+
# "HTTPPort" => 80,
|
38
|
+
# "OriginProtocolPolicy" => "http-only"
|
39
|
+
# },
|
40
|
+
# "CallerReference" => "simple_aws_testing_#{rand(100_000)}",
|
41
|
+
# "Enabled" => false
|
42
|
+
# }
|
43
|
+
#}
|
44
|
+
#
|
45
|
+
#p response
|
46
|
+
#
|
47
|
+
#id = response.id
|
48
|
+
#etag = response.headers["etag"]
|
49
|
+
#
|
50
|
+
#puts ""
|
51
|
+
#puts "Created distribution with id #{id} and etag #{etag}."
|
52
|
+
#puts "It's at domain #{response.domain_name}"
|
data/simple_aws.gemspec
CHANGED
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'aws/cloud_front'
|
3
|
+
|
4
|
+
describe AWS::CloudFront do
|
5
|
+
|
6
|
+
before do
|
7
|
+
@api = AWS::CloudFront.new "key", "secret"
|
8
|
+
end
|
9
|
+
|
10
|
+
it "points to the endpoint" do
|
11
|
+
@api.uri.must_equal "https://cloudfront.amazonaws.com"
|
12
|
+
end
|
13
|
+
|
14
|
+
it "does not support region selection" do
|
15
|
+
lambda {
|
16
|
+
AWS::CloudFront.new "key", "secret", "us-east-1"
|
17
|
+
}.must_raise ArgumentError
|
18
|
+
end
|
19
|
+
|
20
|
+
it "works with the current version" do
|
21
|
+
@api.version.must_equal "2010-11-01"
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "API calls" do
|
25
|
+
|
26
|
+
[:get, :post, :put, :delete].each do |method|
|
27
|
+
it "supports the #{method} HTTP method" do
|
28
|
+
AWS::Connection.any_instance.expects(:call).with do |request|
|
29
|
+
request.method.must_equal method
|
30
|
+
true
|
31
|
+
end
|
32
|
+
|
33
|
+
@api.send method, "/"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
it "pre-pends the version to the path for every request" do
|
38
|
+
AWS::Connection.any_instance.expects(:call).with do |request|
|
39
|
+
request.path.must_equal "/2010-11-01/"
|
40
|
+
true
|
41
|
+
end
|
42
|
+
|
43
|
+
@api.get "/"
|
44
|
+
end
|
45
|
+
|
46
|
+
it "takes parameters" do
|
47
|
+
AWS::Connection.any_instance.expects(:call).with do |request|
|
48
|
+
request.params["Parameter1"].must_equal "Value2"
|
49
|
+
true
|
50
|
+
end
|
51
|
+
|
52
|
+
@api.get "/", :params => { "Parameter1" => "Value2" }
|
53
|
+
end
|
54
|
+
|
55
|
+
it "takes a raw body" do
|
56
|
+
AWS::Connection.any_instance.expects(:call).with do |request|
|
57
|
+
request.body.must_equal "This is a body of text"
|
58
|
+
true
|
59
|
+
end
|
60
|
+
|
61
|
+
@api.get "/", :body => "This is a body of text"
|
62
|
+
end
|
63
|
+
|
64
|
+
it "uses :xml to take a hash and build XML from it" do
|
65
|
+
AWS::Connection.any_instance.expects(:call).with do |request|
|
66
|
+
request.headers["Content-Type"].must_equal "text/xml"
|
67
|
+
request.body.must_match(/amazonaws\.com\/doc\//)
|
68
|
+
request.body.must_match(/<InnerNode>/)
|
69
|
+
true
|
70
|
+
end
|
71
|
+
|
72
|
+
@api.get "/", :xml => {:RootNode => { :InnerNode => "Value" } }
|
73
|
+
end
|
74
|
+
|
75
|
+
it "complains if :xml doesn't contain a Hash" do
|
76
|
+
error = lambda {
|
77
|
+
@api.get "/", :xml => "not a hash"
|
78
|
+
}.must_raise RuntimeError
|
79
|
+
|
80
|
+
error.message.must_match /must be a Hash/
|
81
|
+
end
|
82
|
+
|
83
|
+
it "takes extra headers" do
|
84
|
+
AWS::Connection.any_instance.expects(:call).with do |request|
|
85
|
+
request.headers["Header14"].must_equal "Out to Lunch"
|
86
|
+
true
|
87
|
+
end
|
88
|
+
|
89
|
+
@api.get "/", :headers => { "Header14" => "Out to Lunch" }
|
90
|
+
end
|
91
|
+
|
92
|
+
it "signs the given request according to Version 3 rules" do
|
93
|
+
AWS::Connection.any_instance.expects(:call).with do |request|
|
94
|
+
request.headers["Authorization"].wont_be_nil
|
95
|
+
header = request.headers["Authorization"]
|
96
|
+
parts = header.split(":")
|
97
|
+
|
98
|
+
parts[0].must_equal "AWS key"
|
99
|
+
parts[1].wont_be_nil
|
100
|
+
|
101
|
+
Time.parse(request.headers["Date"]).wont_be_nil
|
102
|
+
true
|
103
|
+
end.returns
|
104
|
+
|
105
|
+
@api.get "/"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'aws/core/util'
|
3
|
+
|
4
|
+
describe AWS::Util do
|
5
|
+
|
6
|
+
describe "#build_xml_from" do
|
7
|
+
it "takes a hash and builds XML" do
|
8
|
+
response = AWS::Util.build_xml_from :RootNode => { :InnerNode => "Value" }
|
9
|
+
|
10
|
+
response.must_equal <<END
|
11
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
12
|
+
<RootNode>
|
13
|
+
<InnerNode>Value</InnerNode>
|
14
|
+
</RootNode>
|
15
|
+
END
|
16
|
+
end
|
17
|
+
|
18
|
+
it "will add namespace to the root node" do
|
19
|
+
response = AWS::Util.build_xml_from(
|
20
|
+
{:RootNode => { :InnerNode => "Value" }},
|
21
|
+
"http://cloudfront.amazonaws.com/doc/2010-11-01/"
|
22
|
+
)
|
23
|
+
|
24
|
+
response.must_equal <<END
|
25
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
26
|
+
<RootNode xmlns="http://cloudfront.amazonaws.com/doc/2010-11-01/">
|
27
|
+
<InnerNode>Value</InnerNode>
|
28
|
+
</RootNode>
|
29
|
+
END
|
30
|
+
end
|
31
|
+
|
32
|
+
it "works with arrays of items" do
|
33
|
+
response = AWS::Util.build_xml_from(
|
34
|
+
{:RootNode => { :InnerNode => ["Value1", "Value2", "Value3"] }}
|
35
|
+
)
|
36
|
+
|
37
|
+
response.must_equal <<END
|
38
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
39
|
+
<RootNode>
|
40
|
+
<InnerNode>Value1</InnerNode>
|
41
|
+
<InnerNode>Value2</InnerNode>
|
42
|
+
<InnerNode>Value3</InnerNode>
|
43
|
+
</RootNode>
|
44
|
+
END
|
45
|
+
end
|
46
|
+
|
47
|
+
it "works at any nestedness of hashes" do
|
48
|
+
response = AWS::Util.build_xml_from(
|
49
|
+
:RootNode => {
|
50
|
+
:InnerNode => [
|
51
|
+
{:Child => "Value1"},
|
52
|
+
{:Child => "Value2"}
|
53
|
+
]
|
54
|
+
}
|
55
|
+
)
|
56
|
+
|
57
|
+
response.must_equal <<END
|
58
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
59
|
+
<RootNode>
|
60
|
+
<InnerNode>
|
61
|
+
<Child>Value1</Child>
|
62
|
+
</InnerNode>
|
63
|
+
<InnerNode>
|
64
|
+
<Child>Value2</Child>
|
65
|
+
</InnerNode>
|
66
|
+
</RootNode>
|
67
|
+
END
|
68
|
+
end
|
69
|
+
|
70
|
+
it "auto-strings all leaf nodes" do
|
71
|
+
response = AWS::Util.build_xml_from(
|
72
|
+
:RootNode => { :BoolVal => true, :Number => 12, :BadBool => false }
|
73
|
+
)
|
74
|
+
|
75
|
+
response.must_equal <<END
|
76
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
77
|
+
<RootNode>
|
78
|
+
<BoolVal>true</BoolVal>
|
79
|
+
<Number>12</Number>
|
80
|
+
<BadBool>false</BadBool>
|
81
|
+
</RootNode>
|
82
|
+
END
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
data/test/aws/s3_test.rb
CHANGED
@@ -96,13 +96,20 @@ describe AWS::S3 do
|
|
96
96
|
@api.get "/", :file => "This is a body of text"
|
97
97
|
end
|
98
98
|
|
99
|
-
it "signs the request
|
99
|
+
it "signs the given request according to Version 3 rules" do
|
100
100
|
AWS::Connection.any_instance.expects(:call).with do |request|
|
101
|
-
request.headers["Authorization"]
|
101
|
+
header = request.headers["Authorization"]
|
102
|
+
parts = header.split(":")
|
103
|
+
|
104
|
+
parts[0].must_equal "AWS key"
|
105
|
+
parts[1].wont_be_nil
|
106
|
+
|
107
|
+
Time.parse(request.headers["Date"]).wont_be_nil
|
102
108
|
true
|
103
|
-
end
|
109
|
+
end.returns
|
104
110
|
|
105
111
|
@api.get "/"
|
106
112
|
end
|
113
|
+
|
107
114
|
end
|
108
115
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple_aws
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.1d
|
5
5
|
prerelease: 5
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2012-01-09 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ox
|
16
|
-
requirement: &
|
16
|
+
requirement: &70172190923080 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70172190923080
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: httparty
|
27
|
-
requirement: &
|
27
|
+
requirement: &70172190922660 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70172190922660
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: httmultiparty
|
38
|
-
requirement: &
|
38
|
+
requirement: &70172190922220 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70172190922220
|
47
47
|
description: The simplest and easiest to use and maintain AWS communication library
|
48
48
|
email:
|
49
49
|
- jameskilton@gmail.com
|
@@ -60,6 +60,7 @@ files:
|
|
60
60
|
- lib/aws/auto_scaling.rb
|
61
61
|
- lib/aws/call_types/action_param.rb
|
62
62
|
- lib/aws/cloud_formation.rb
|
63
|
+
- lib/aws/cloud_front.rb
|
63
64
|
- lib/aws/cloud_watch.rb
|
64
65
|
- lib/aws/core/connection.rb
|
65
66
|
- lib/aws/core/request.rb
|
@@ -76,11 +77,11 @@ files:
|
|
76
77
|
- lib/aws/rds.rb
|
77
78
|
- lib/aws/s3.rb
|
78
79
|
- lib/aws/ses.rb
|
79
|
-
- lib/aws/signing/authorization_header.rb
|
80
80
|
- lib/aws/signing/version2.rb
|
81
81
|
- lib/aws/signing/version3.rb
|
82
82
|
- lib/aws/sns.rb
|
83
83
|
- lib/aws/sqs.rb
|
84
|
+
- samples/cloud_front.rb
|
84
85
|
- samples/ec2.rb
|
85
86
|
- samples/elb.rb
|
86
87
|
- samples/iam.rb
|
@@ -92,10 +93,12 @@ files:
|
|
92
93
|
- test/aws/auto_scaling_test.rb
|
93
94
|
- test/aws/call_types/action_param_test.rb
|
94
95
|
- test/aws/cloud_formation_test.rb
|
96
|
+
- test/aws/cloud_front_test.rb
|
95
97
|
- test/aws/cloud_watch_test.rb
|
96
98
|
- test/aws/core/connection_test.rb
|
97
99
|
- test/aws/core/request_test.rb
|
98
100
|
- test/aws/core/response_test.rb
|
101
|
+
- test/aws/core/util_test.rb
|
99
102
|
- test/aws/ec2_test.rb
|
100
103
|
- test/aws/elasti_cache_test.rb
|
101
104
|
- test/aws/elastic_beanstalk_test.rb
|
@@ -107,7 +110,6 @@ files:
|
|
107
110
|
- test/aws/rds_test.rb
|
108
111
|
- test/aws/s3_test.rb
|
109
112
|
- test/aws/ses.rb
|
110
|
-
- test/aws/signing/authorization_header_test.rb
|
111
113
|
- test/aws/signing/version2_test.rb
|
112
114
|
- test/aws/signing/version3.rb
|
113
115
|
- test/aws/sns_test.rb
|
@@ -142,10 +144,12 @@ test_files:
|
|
142
144
|
- test/aws/auto_scaling_test.rb
|
143
145
|
- test/aws/call_types/action_param_test.rb
|
144
146
|
- test/aws/cloud_formation_test.rb
|
147
|
+
- test/aws/cloud_front_test.rb
|
145
148
|
- test/aws/cloud_watch_test.rb
|
146
149
|
- test/aws/core/connection_test.rb
|
147
150
|
- test/aws/core/request_test.rb
|
148
151
|
- test/aws/core/response_test.rb
|
152
|
+
- test/aws/core/util_test.rb
|
149
153
|
- test/aws/ec2_test.rb
|
150
154
|
- test/aws/elasti_cache_test.rb
|
151
155
|
- test/aws/elastic_beanstalk_test.rb
|
@@ -157,7 +161,6 @@ test_files:
|
|
157
161
|
- test/aws/rds_test.rb
|
158
162
|
- test/aws/s3_test.rb
|
159
163
|
- test/aws/ses.rb
|
160
|
-
- test/aws/signing/authorization_header_test.rb
|
161
164
|
- test/aws/signing/version2_test.rb
|
162
165
|
- test/aws/signing/version3.rb
|
163
166
|
- test/aws/sns_test.rb
|
@@ -1,43 +0,0 @@
|
|
1
|
-
require 'openssl'
|
2
|
-
|
3
|
-
module AWS
|
4
|
-
module Signing
|
5
|
-
##
|
6
|
-
# Implementation of signing using the Authorization header, as used by S3 and CloudFront
|
7
|
-
##
|
8
|
-
module AuthorizationHeader
|
9
|
-
|
10
|
-
##
|
11
|
-
# Build and sign the final request, as per the rules here:
|
12
|
-
# http://s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.html
|
13
|
-
##
|
14
|
-
def finish_and_sign_request(request)
|
15
|
-
request.headers["Date"] = Time.now.utc.httpdate
|
16
|
-
request.headers["Authorization"] =
|
17
|
-
"AWS #{self.access_key}:#{Base64.encode64(build_signature_for(request)).chomp}"
|
18
|
-
|
19
|
-
request
|
20
|
-
end
|
21
|
-
|
22
|
-
def build_signature_for(request)
|
23
|
-
amazon_headers = request.headers.select {|k, v|
|
24
|
-
k =~ /^x-amz/i
|
25
|
-
}.map {|k, v|
|
26
|
-
"#{k.downcase}:#{v}".chomp
|
27
|
-
}
|
28
|
-
|
29
|
-
to_sign = [
|
30
|
-
request.method.to_s.upcase,
|
31
|
-
request.headers["Content-Md5"] || "",
|
32
|
-
request.headers["Content-Type"] || "",
|
33
|
-
request.headers["Date"],
|
34
|
-
amazon_headers,
|
35
|
-
request.path
|
36
|
-
].flatten.join("\n")
|
37
|
-
|
38
|
-
OpenSSL::HMAC.digest("sha1", self.secret_key, to_sign)
|
39
|
-
end
|
40
|
-
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
require 'aws/api'
|
3
|
-
require 'aws/call_types/action_param'
|
4
|
-
require 'aws/signing/authorization_header'
|
5
|
-
|
6
|
-
describe AWS::Signing::AuthorizationHeader do
|
7
|
-
|
8
|
-
class SigningAuthHeaderTestAPI < AWS::API
|
9
|
-
endpoint "aptest"
|
10
|
-
version "2011-01-01"
|
11
|
-
use_https true
|
12
|
-
|
13
|
-
include AWS::CallTypes::ActionParam
|
14
|
-
include AWS::Signing::AuthorizationHeader
|
15
|
-
end
|
16
|
-
|
17
|
-
it "signs the given request according to Version 3 rules" do
|
18
|
-
AWS::Connection.any_instance.expects(:call).with do |request|
|
19
|
-
header = request.headers["Authorization"]
|
20
|
-
parts = header.split(":")
|
21
|
-
|
22
|
-
parts[0].must_equal "AWS key"
|
23
|
-
parts[1].wont_be_nil
|
24
|
-
|
25
|
-
Time.parse(request.headers["Date"]).wont_be_nil
|
26
|
-
true
|
27
|
-
end.returns
|
28
|
-
|
29
|
-
obj = SigningAuthHeaderTestAPI.new "key", "secret"
|
30
|
-
obj.describe_instances
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|