cloudfront-signer 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --colour
2
+ --drb
3
+ --format documentation
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
9
9
  s.email = ["tony@58bits.com"]
10
10
  s.homepage = "http://github.com/58bits/cloudfront-signer"
11
11
  s.summary = %q{A gem to sign url and stream paths for Amazon CloudFront private content.}
12
- s.description = %q{A fork of Dylan Vaughn's excellent signing gem - https://github.com/stlondemand/aws_cf_signer. The gem has been rewritten to use class methods and includes specific signing methods for both url and streaming paths, including html 'safe' escpaed versions of each.}
12
+ s.description = %q{A fork of Dylan Vaughn's signing gem - https://github.com/stlondemand/aws_cf_signer. The gem has been rewritten to use class methods and includes specific signing methods for both url and streaming paths, including html 'safe' escpaed versions of each.}
13
13
 
14
14
  s.rubyforge_project = "cloudfront-signer"
15
15
 
@@ -6,183 +6,223 @@ require 'base64'
6
6
  require "cloudfront-signer/version"
7
7
 
8
8
  module AWS
9
- module CF
10
- class Signer
11
- # Public non-inheritable class accessors
12
- #----------------------------------------------------------------------------
13
- class << self
14
- attr_accessor :key_pair_id
15
-
16
- def key_path
17
- @key_path
18
- end
19
-
20
- def key_path=(path)
21
- raise ArgumentError.new("The signing key could not be found at #{path}") unless File.exists?(path)
22
- @key_path = path
23
- @key = OpenSSL::PKey::RSA.new(File.readlines(path).join(""))
24
- end
25
-
26
- def default_expires
27
- @default_expires ||= 3600
28
- end
29
-
30
- def default_expires=(value)
31
- raise ArgumentError.new("The default expires value must be an integer") unless value.is_a?(Integer)
32
- @default_expires = value
33
- end
34
-
35
- private
36
-
37
- # Private key
38
- #----------------------------------------------------------------------------
39
- def private_key
40
- @key
41
- end
42
- end
43
-
44
- #----------------------------------------------------------------------------
45
- def self.is_configured?
46
- if self.key_path && self.key_pair_id && private_key
47
- return true
48
- else
49
- return false
50
- end
51
- end
52
-
53
-
54
- # Configure the signing class.
55
- #----------------------------------------------------------------------------
56
- def self.configure!(key_path, options = {})
57
-
58
- raise ArgumentError.new("You must supply the path to a PEM format private RSA key.") if key_path.nil?
59
- self.key_path = key_path
60
-
61
- @key_pair_id = options[:key_pair_id] || extract_key_pair_id(key_path)
62
- unless @key_pair_id
63
- raise ArgumentError.new("The Cloudfront signing key id could not be inferred from #{key_path}. Please supply the key pair id as a configuration arguemet.")
64
- end
65
-
66
- @default_expires = options[:default_expires] ? options[:default_expires] : 3600
67
- end
68
-
69
-
70
- # Signing methods
71
- #----------------------------------------------------------------------------
72
-
73
- # Sign a url - encoding any spaces in the url before signing. CloudFront
74
- # stipulates that signed URLs must not contain spaces (as opposed to stream
75
- # paths/filenames which CAN contain spaces).
76
- #----------------------------------------------------------------------------
77
- def self.sign_url(subject, policy_options = {})
78
- self.sign(subject, {:remove_spaces => true}, policy_options)
79
- end
80
-
81
- # Sign a url (as above) and HTML encode the result.
82
- #----------------------------------------------------------------------------
83
- def self.sign_url_safe(subject, policy_options = {})
84
- self.sign(subject, {:remove_spaces => true, :html_escape => true}, policy_options)
85
- end
86
-
87
- # Sign a stream path part or filename (spaces are allowed in stream paths
88
- # and so are not removed).
89
- #----------------------------------------------------------------------------
90
- def self.sign_path(subject, policy_options ={})
91
- self.sign(subject, {:remove_spaces => false}, policy_options)
92
- end
93
-
94
- # Sign a stream path or filename and HTML encode the result.
95
- #----------------------------------------------------------------------------
96
- def self.sign_path_safe(subject, policy_options ={})
97
- self.sign(subject, {:remove_spaces => false, :html_escape => true}, policy_options)
98
- end
99
-
100
-
101
- # Sign a subject url or stream resource name with optional configuration and
102
- # policy options
103
- #----------------------------------------------------------------------------
104
- def self.sign(subject, configuration_options = {}, policy_options = {})
105
-
106
- raise "Configure using AWS::CF.Signer.configure! before signing." unless self.is_configured?
107
-
108
- # If the url or stream path already has a query string parameter - append to that.
109
- separator = subject =~ /\?/ ? '&' : '?'
110
-
111
- if configuration_options[:remove_spaces]
112
- subject.gsub!(/\s/, "%20")
113
- end
114
-
115
- if policy_options[:policy_file]
116
- policy = IO.read(policy_options[:policy_file])
117
- result = "#{subject}#{separator}Policy=#{encode_policy(policy)}&Signature=#{create_signature(policy)}&Key-Pair-Id=#{@key_pair_id}"
118
- else
119
- if policy_options.keys.size <= 1
120
- # Canned Policy - shorter URL
121
- expires_at = epoch_time(policy_options[:expires] || Time.now + self.default_expires)
122
- policy = %({"Statement":[{"Resource":"#{subject}","Condition":{"DateLessThan":{"AWS:EpochTime":#{expires_at}}}}]})
123
- result = "#{subject}#{separator}Expires=#{expires_at}&Signature=#{create_signature(policy)}&Key-Pair-Id=#{@key_pair_id}"
124
- else
125
- # Custom Policy
126
- resource = policy_options[:resource] || subject
127
- policy = generate_custom_policy(resource, policy_options)
128
- result = "#{subject}#{separator}Policy=#{encode_policy(policy)}&Signature=#{create_signature(policy)}&Key-Pair-Id=#{@key_pair_id}"
129
- end
130
- end
131
-
132
- if configuration_options[:html_escape]
133
- return html_encode(result)
134
- else
135
- return result
136
- end
137
- end
138
-
139
-
140
- # Private helper methods
141
- #----------------------------------------------------------------------------
142
- private
143
-
144
-
145
- #----------------------------------------------------------------------------
146
- def self.generate_custom_policy(resource, options)
147
- conditions = ["\"DateLessThan\":{\"AWS:EpochTime\":#{epoch_time(options[:expires])}}"]
148
- conditions << "\"DateGreaterThan\":{\"AWS:EpochTime\":#{epoch_time(options[:starting])}}" if options[:starting]
149
- conditions << "\"IpAddress\":{\"AWS:SourceIp\":\"#{options[:ip_range]}\"" if options[:ip_range]
9
+ module CF
10
+ class Signer
11
+ # Public non-inheritable class accessors
12
+ class << self
13
+
14
+ # Public: Provides a configuration option to set the key_pair_id if it has not
15
+ # been inferred from the key_path
16
+ #
17
+ # Examples
18
+ #
19
+ # AWS::CF::Signer.configure do |config|
20
+ # config.key_pair_id = "XXYYZZ"
21
+ # end
22
+ #
23
+ # Returns a String value indicating the current setting
24
+ attr_accessor :key_pair_id
25
+
26
+ # Public: Provides a configuration option that sets the key_path
27
+ #
28
+ # Examples
29
+ #
30
+ # AWS::CF::Signer.configure do |config|
31
+ # config.key_path = "/path/to/your/keyfile.pem"
32
+ # end
33
+ #
34
+ # Returns nothing.
35
+ def key_path=(path)
36
+ raise ArgumentError.new("The signing key could not be found at #{path}") unless File.exists?(path)
37
+ @key_path = path
38
+ @key = OpenSSL::PKey::RSA.new(File.readlines(path).join(""))
39
+ end
40
+
41
+ # Public: Provides an accessor to the key_path
42
+ #
43
+ # Returns a String value indicating the current setting
44
+ def key_path
45
+ @key_path
46
+ end
47
+
48
+
49
+ # Public: Provides a configuration option that sets the default_expires in milliseconds
50
+ #
51
+ # Examples
52
+ #
53
+ # AWS::CF::Signer.configure do |config|
54
+ # config.default_expires = 3600
55
+ # end
56
+ #
57
+ # Returns nothing.
58
+ def default_expires=(value)
59
+ @default_expires = value
60
+ end
61
+
62
+ # Public: Provides an accessor to the default_expires value
63
+ #
64
+ # Returns an Integer value indicating the current setting
65
+ def default_expires
66
+ @default_expires ||= 3600
67
+ end
68
+
69
+
70
+ private
71
+
72
+ # Private: Provides an accessor to the RSA key value
73
+ #
74
+ # Returns an RSA key pair.
75
+ def private_key
76
+ @key
77
+ end
78
+ end
79
+
80
+ # Public: Provides a simple way to configure the signing class.
81
+ #
82
+ # Yields self.
83
+ #
84
+ # Examples
85
+ #
86
+ # AWS::CF::Signer.configure do |config|
87
+ # config.key_path = "/path/to/yourkeyfile.pem"
88
+ # config.key_pair_id = "XXYYZZ"
89
+ # config.default_expires = 3600
90
+ # end
91
+ #
92
+ # Returns nothing.
93
+ def self.configure
94
+
95
+ yield self if block_given?
96
+
97
+ raise ArgumentError.new("You must supply the path to a PEM format RSA key pair.") unless self.key_path
98
+
99
+ unless @key_pair_id
100
+ @key_pair_id = extract_key_pair_id(self.key_path)
101
+ raise ArgumentError.new("The Cloudfront signing key id could not be inferred from #{self.key_path}. Please supply the key pair id as a configuration argument.") unless @key_pair_id
102
+ end
103
+
104
+ end
105
+
106
+ # Public: Provides a configuration check method which tests to see
107
+ # that the key_path, key_pair_id and private key values have all been set.
108
+ #
109
+ # Returns a Boolean value indicating that settings are present.
110
+ def self.is_configured?
111
+ (self.key_path.nil? || self.key_pair_id.nil? || private_key.nil?) ? false : true
112
+ end
113
+
114
+ # Public: Sign a url - encoding any spaces in the url before signing. CloudFront
115
+ # stipulates that signed URLs must not contain spaces (as opposed to stream
116
+ # paths/filenames which CAN contain spaces).
117
+ #
118
+ # Returns a String
119
+ def self.sign_url(subject, policy_options = {})
120
+ self.sign(subject, {:remove_spaces => true}, policy_options)
121
+ end
122
+
123
+
124
+
125
+ # Public: Sign a url (as above) and HTML encode the result.
126
+ #
127
+ # Returns a String
128
+ def self.sign_url_safe(subject, policy_options = {})
129
+ self.sign(subject, {:remove_spaces => true, :html_escape => true}, policy_options)
130
+ end
131
+
132
+ # Public: Sign a stream path part or filename (spaces are allowed in stream paths
133
+ # and so are not removed).
134
+ #
135
+ # Returns a String
136
+ def self.sign_path(subject, policy_options ={})
137
+ self.sign(subject, {:remove_spaces => false}, policy_options)
138
+ end
139
+
140
+ # Public: Sign a stream path or filename and HTML encode the result.
141
+ #
142
+ # Returns a String
143
+ def self.sign_path_safe(subject, policy_options ={})
144
+ self.sign(subject, {:remove_spaces => false, :html_escape => true}, policy_options)
145
+ end
146
+
147
+
148
+ # Public: Sign a subject url or stream resource name with optional configuration and
149
+ # policy options
150
+ #
151
+ # Returns a String
152
+ def self.sign(subject, configuration_options = {}, policy_options = {})
153
+
154
+ raise "Configure using AWS::CF.Signer.configure! before signing." unless self.is_configured?
155
+
156
+ # If the url or stream path already has a query string parameter - append to that.
157
+ separator = subject =~ /\?/ ? '&' : '?'
158
+
159
+ if configuration_options[:remove_spaces]
160
+ subject.gsub!(/\s/, "%20")
161
+ end
162
+
163
+ if policy_options[:policy_file]
164
+ policy = IO.read(policy_options[:policy_file])
165
+ result = "#{subject}#{separator}Policy=#{encode_policy(policy)}&Signature=#{create_signature(policy)}&Key-Pair-Id=#{@key_pair_id}"
166
+ else
167
+ if policy_options.keys.size <= 1
168
+ # Canned Policy - shorter URL
169
+ expires_at = epoch_time(policy_options[:expires] || Time.now + self.default_expires)
170
+ policy = %({"Statement":[{"Resource":"#{subject}","Condition":{"DateLessThan":{"AWS:EpochTime":#{expires_at}}}}]})
171
+ result = "#{subject}#{separator}Expires=#{expires_at}&Signature=#{create_signature(policy)}&Key-Pair-Id=#{@key_pair_id}"
172
+ else
173
+ # Custom Policy
174
+ resource = policy_options[:resource] || subject
175
+ policy = generate_custom_policy(resource, policy_options)
176
+ result = "#{subject}#{separator}Policy=#{encode_policy(policy)}&Signature=#{create_signature(policy)}&Key-Pair-Id=#{@key_pair_id}"
177
+ end
178
+ end
179
+
180
+ if configuration_options[:html_escape]
181
+ return html_encode(result)
182
+ else
183
+ return result
184
+ end
185
+ end
186
+
187
+
188
+ # Private helper methods
189
+ private
190
+
191
+
192
+ def self.generate_custom_policy(resource, options)
193
+ conditions = ["\"DateLessThan\":{\"AWS:EpochTime\":#{epoch_time(options[:expires])}}"]
194
+ conditions << "\"DateGreaterThan\":{\"AWS:EpochTime\":#{epoch_time(options[:starting])}}" if options[:starting]
195
+ conditions << "\"IpAddress\":{\"AWS:SourceIp\":\"#{options[:ip_range]}\"" if options[:ip_range]
150
196
  %({"Statement":[{"Resource":"#{resource}","Condition":{#{conditions.join(',')}}}}]})
151
- end
152
-
153
- #----------------------------------------------------------------------------
154
- def self.epoch_time(timelike)
155
- case timelike
156
- when String then Time.parse(timelike).to_i
157
- when Time then timelike.to_i
158
- else raise ArgumentError.new("Invalid argument - String or Time required - #{timelike.class} passed.")
159
- end
160
- end
161
-
162
- #----------------------------------------------------------------------------
163
- def self.encode_policy(policy)
164
- url_encode(Base64.encode64(policy))
165
- end
166
-
167
- #----------------------------------------------------------------------------
168
- def self.create_signature(policy)
169
- url_encode(Base64.encode64(private_key.sign(OpenSSL::Digest::SHA1.new, (policy))))
170
- end
171
-
172
- #----------------------------------------------------------------------------
173
- def self.extract_key_pair_id(key_path)
174
- File.basename(key_path) =~ /^pk-(.*).pem$/ ? $1 : nil
175
- end
176
-
177
- #----------------------------------------------------------------------------
178
- def self.url_encode(s)
179
- s.gsub('+','-').gsub('=','_').gsub('/','~').gsub(/\n/,'').gsub(' ','')
180
- end
181
-
182
- #----------------------------------------------------------------------------
183
- def self.html_encode(s)
184
- return s.gsub('?', '%3F').gsub('=', '%3D').gsub('&', '%26')
185
- end
197
+ end
198
+
199
+ def self.epoch_time(timelike)
200
+ case timelike
201
+ when String then Time.parse(timelike).to_i
202
+ when Time then timelike.to_i
203
+ else raise ArgumentError.new("Invalid argument - String or Time required - #{timelike.class} passed.")
186
204
  end
205
+ end
206
+
207
+ def self.encode_policy(policy)
208
+ url_encode(Base64.encode64(policy))
209
+ end
210
+
211
+ def self.create_signature(policy)
212
+ url_encode(Base64.encode64(private_key.sign(OpenSSL::Digest::SHA1.new, (policy))))
213
+ end
214
+
215
+ def self.extract_key_pair_id(key_path)
216
+ File.basename(key_path) =~ /^pk-(.*).pem$/ ? $1 : nil
217
+ end
218
+
219
+ def self.url_encode(s)
220
+ s.gsub('+','-').gsub('=','_').gsub('/','~').gsub(/\n/,'').gsub(' ','')
221
+ end
222
+
223
+ def self.html_encode(s)
224
+ return s.gsub('?', '%3F').gsub('=', '%3D').gsub('&', '%26')
225
+ end
187
226
  end
227
+ end
188
228
  end
@@ -1,5 +1,5 @@
1
1
  module AWS
2
2
  module CF
3
- VERSION = "1.0.0"
3
+ VERSION = "2.0.0"
4
4
  end
5
5
  end
data/spec/signer_spec.rb CHANGED
@@ -2,73 +2,79 @@ require 'spec_helper'
2
2
 
3
3
  describe AWS::CF::Signer do
4
4
 
5
- let(:key_path) { File.expand_path(File.dirname(__FILE__) + '/keys/pk-APKAIKUROOUNR2BAFUUU.pem') }
5
+ let(:key_path) { File.expand_path(File.dirname(__FILE__) + '/keys/pk-APKAIKUROOUNR2BAFUUU.pem') }
6
6
 
7
- before(:each) do
8
- AWS::CF::Signer.configure!(key_path)
7
+ before(:each) do
8
+ AWS::CF::Signer.configure do |config|
9
+ config.key_path = key_path
10
+ #config.key_pair_id = "XXYYZZ"
11
+ #config.default_expires = 3600
9
12
  end
13
+ end
10
14
 
11
- describe "before default use" do
15
+ describe "before default use" do
12
16
 
13
- it "should be configured" do
14
- AWS::CF::Signer.is_configured?.should eql(true)
15
- end
17
+ it "should be configured" do
18
+ AWS::CF::Signer.is_configured?.should eql(true)
19
+ end
20
+
21
+ it "should expire urls and paths in one hour by default" do
22
+ AWS::CF::Signer.default_expires.should eql(3600)
23
+ end
24
+
25
+ it "should optionally be configured to expire urls and paths in ten minutes" do
26
+ AWS::CF::Signer.default_expires = 600
27
+ AWS::CF::Signer.default_expires.should eql(600)
28
+ AWS::CF::Signer.default_expires = nil
29
+ end
30
+ end
31
+
32
+ describe "when signing a url" do
16
33
 
17
- it "should expire urls and paths in one hour by default" do
18
- AWS::CF::Signer.default_expires.should eql(3600)
19
- end
34
+ it "should remove spaces from the url" do
35
+ url = "http://somedomain.com/sign me"
36
+ result = AWS::CF::Signer.sign_url(url)
37
+ (result =~ /\s/).should be_nil
38
+ end
39
+
40
+ it "should not html encode the signed url by default" do
41
+ url = "http://somedomain.com/someresource?opt1=one&opt2=two"
42
+ result = AWS::CF::Signer.sign_url(url)
43
+ (result =~ /\?/).should_not be_nil
44
+ (result =~ /=/).should_not be_nil
45
+ (result =~ /&/).should_not be_nil
46
+ end
20
47
 
21
- it "should optionally be configured to expire urls and paths in ten minutes" do
22
- AWS::CF::Signer.configure!(key_path, :default_expires => 600)
23
- AWS::CF::Signer.default_expires.should eql(600)
24
- end
48
+ it "should optionally html encode the signed url" do
49
+ url = "http://somedomain.com/someresource?opt1=one&opt2=two"
50
+ result = AWS::CF::Signer.sign_url_safe(url)
51
+ (result =~ /\?/).should be_nil
52
+ (result =~ /=/).should be_nil
53
+ (result =~ /&/).should be_nil
25
54
  end
26
55
 
27
- describe "when signing a url" do
28
-
29
- it "should remove spaces from the url" do
30
- url = "http://somedomain.com/sign me"
31
- result = AWS::CF::Signer.sign_url(url)
32
- (result =~ /\s/).should be_nil
33
- end
34
-
35
- it "should not html encode the signed url by default" do
36
- url = "http://somedomain.com/someresource?opt1=one&opt2=two"
37
- result = AWS::CF::Signer.sign_url(url)
38
- (result =~ /\?/).should_not be_nil
39
- (result =~ /=/).should_not be_nil
40
- (result =~ /&/).should_not be_nil
41
- end
42
-
43
- it "should optionally html encode the signed url" do
44
- url = "http://somedomain.com/someresource?opt1=one&opt2=two"
45
- result = AWS::CF::Signer.sign_url_safe(url)
46
- (result =~ /\?/).should be_nil
47
- (result =~ /=/).should be_nil
48
- (result =~ /&/).should be_nil
49
- end
50
-
51
- it "should expire in one hour by default" do
52
- url = "http://somedomain.com/sign me"
53
- result = AWS::CF::Signer.sign_url(url)
54
- get_query_value(result, 'Expires').to_i.should eql((Time.now + 3600).to_i)
55
- end
56
-
57
- it "should optionally expire in ten minutes" do
58
- url = "http://somedomain.com/sign me"
59
- result = AWS::CF::Signer.sign_url(url, :expires => Time.now + 600)
60
- get_query_value(result, 'Expires').to_i.should eql((Time.now + 600 ).to_i)
61
- end
56
+ it "should expire in one hour by default" do
57
+ url = "http://somedomain.com/sign me"
58
+ result = AWS::CF::Signer.sign_url(url)
59
+ get_query_value(result, 'Expires').to_i.should eql((Time.now + 3600).to_i)
60
+ end
62
61
 
62
+ it "should optionally expire in ten minutes" do
63
+ url = "http://somedomain.com/sign me"
64
+ result = AWS::CF::Signer.sign_url(url, :expires => Time.now + 600)
65
+ get_query_value(result, 'Expires').to_i.should eql((Time.now + 600 ).to_i)
63
66
  end
64
67
 
68
+ end
69
+
65
70
 
66
- describe "when signing a path" do
71
+ describe "when signing a path" do
67
72
 
68
- it "should not remove spaces from the path" do
69
- path = "/someprefix/sign me"
70
- result = AWS::CF::Signer.sign_path(path)
71
- (result =~ /\s/).should_not be_nil
72
- end
73
+ it "should not remove spaces from the path" do
74
+ path = "/someprefix/sign me"
75
+ result = AWS::CF::Signer.sign_path(path)
76
+ (result =~ /\s/).should_not be_nil
73
77
  end
78
+
79
+ end
74
80
  end
data/spec/spec_helper.rb CHANGED
@@ -5,13 +5,13 @@ require 'rspec'
5
5
  require 'cloudfront-signer'
6
6
 
7
7
  def get_query_value(url, key)
8
- query_string = url.slice((url =~ /\?/) + 1..-1)
9
- pairs = query_string.split('&')
10
- pairs.each do |item|
11
- if item.start_with?(key)
12
- return item.split('=')[1]
13
- end
8
+ query_string = url.slice((url =~ /\?/) + 1..-1)
9
+ pairs = query_string.split('&')
10
+ pairs.each do |item|
11
+ if item.start_with?(key)
12
+ return item.split('=')[1]
14
13
  end
14
+ end
15
15
  end
16
16
 
17
17
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cloudfront-signer
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-08-08 00:00:00.000000000 +07:00
13
- default_executable:
12
+ date: 2012-05-24 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: rspec
17
- requirement: &2151692620 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
18
17
  none: false
19
18
  requirements:
20
19
  - - ! '>='
@@ -22,8 +21,13 @@ dependencies:
22
21
  version: '0'
23
22
  type: :development
24
23
  prerelease: false
25
- version_requirements: *2151692620
26
- description: A fork of Dylan Vaughn's excellent signing gem - https://github.com/stlondemand/aws_cf_signer.
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ description: A fork of Dylan Vaughn's signing gem - https://github.com/stlondemand/aws_cf_signer.
27
31
  The gem has been rewritten to use class methods and includes specific signing methods
28
32
  for both url and streaming paths, including html 'safe' escpaed versions of each.
29
33
  email:
@@ -33,6 +37,7 @@ extensions: []
33
37
  extra_rdoc_files: []
34
38
  files:
35
39
  - .gitignore
40
+ - .rspec
36
41
  - Gemfile
37
42
  - LICENSE
38
43
  - README.markdown
@@ -44,7 +49,6 @@ files:
44
49
  - spec/keys/rsa-APKAIKUROOUNR2BAFUUU.pem
45
50
  - spec/signer_spec.rb
46
51
  - spec/spec_helper.rb
47
- has_rdoc: true
48
52
  homepage: http://github.com/58bits/cloudfront-signer
49
53
  licenses: []
50
54
  post_install_message:
@@ -65,7 +69,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
65
69
  version: '0'
66
70
  requirements: []
67
71
  rubyforge_project: cloudfront-signer
68
- rubygems_version: 1.6.2
72
+ rubygems_version: 1.8.23
69
73
  signing_key:
70
74
  specification_version: 3
71
75
  summary: A gem to sign url and stream paths for Amazon CloudFront private content.