simple_aws 0.0.1c → 0.0.1d
Sign up to get free protection for your applications and to get access to all the features.
- 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
|