happening 0.0.7 → 0.0.8
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 +25 -0
- data/lib/happening/s3/item.rb +6 -5
- data/lib/happening/s3/request.rb +7 -3
- data/lib/happening/s3.rb +16 -0
- data/lib/happening.rb +1 -0
- data/test/s3/item_test.rb +31 -0
- data/test/s3/request_test.rb +9 -2
- data/test/s3_test.rb +32 -0
- metadata +5 -3
data/README.md
CHANGED
@@ -124,6 +124,31 @@ Happening support the simple S3 PUT upload:
|
|
124
124
|
|
125
125
|
Amazon returns no content on delete, so having a success handler is usually not needed for delete operations.
|
126
126
|
|
127
|
+
SSL Support
|
128
|
+
=============
|
129
|
+
|
130
|
+
Happening will use SSL/HTTPS by default. What it cannot do by default is verify the SSL certificate. This means
|
131
|
+
that traffic is encrypted but nobody can say if the SSL-endpoint is the one you except. In order to verify the
|
132
|
+
SSL certificate you need to provide Happening with the path to a certificate CA collection in PEM format:
|
133
|
+
|
134
|
+
Happening::S3.ssl_options[:cert_chain_file] = '/etc/ca-bundle.crt'
|
135
|
+
|
136
|
+
You can also set this option on each item:
|
137
|
+
|
138
|
+
Happening::S3::Item.new('bucket', 'item_id',
|
139
|
+
:aws_access_key_id => 'A',
|
140
|
+
:aws_secret_access_key => 'B',
|
141
|
+
:ssl => {
|
142
|
+
:cert_chain_file => '/etc/ca-bundle.crt'
|
143
|
+
}
|
144
|
+
|
145
|
+
Or even on the request:
|
146
|
+
|
147
|
+
item.get(:ssl => {:cert_chain_file => '/etc/ca-bundle.crt'})
|
148
|
+
|
149
|
+
The SSL options are directly passed to EventMachine, see the [EventMachine documentation](http://eventmachine.rubyforge.org/EventMachine/Connection.html#M000296) for more information on the SSL support.
|
150
|
+
|
151
|
+
|
127
152
|
Credits
|
128
153
|
=============
|
129
154
|
|
data/lib/happening/s3/item.rb
CHANGED
@@ -18,9 +18,10 @@ module Happening
|
|
18
18
|
:aws_access_key_id => nil,
|
19
19
|
:aws_secret_access_key => nil,
|
20
20
|
:retry_count => 4,
|
21
|
-
:permissions => 'private'
|
21
|
+
:permissions => 'private',
|
22
|
+
:ssl => Happening::S3.ssl_options
|
22
23
|
}.update(options.symbolize_keys)
|
23
|
-
options.assert_valid_keys(:timeout, :server, :protocol, :aws_access_key_id, :aws_secret_access_key, :retry_count, :permissions)
|
24
|
+
options.assert_valid_keys(:timeout, :server, :protocol, :aws_access_key_id, :aws_secret_access_key, :retry_count, :permissions, :ssl)
|
24
25
|
@aws_id = aws_id.to_s
|
25
26
|
@bucket = bucket.to_s
|
26
27
|
|
@@ -31,21 +32,21 @@ module Happening
|
|
31
32
|
headers = needs_to_sign? ? aws.sign("GET", path) : {}
|
32
33
|
request_options[:on_success] = blk if blk
|
33
34
|
request_options.update(:headers => headers)
|
34
|
-
Happening::S3::Request.new(:get, url, request_options).execute
|
35
|
+
Happening::S3::Request.new(:get, url, {:ssl => options[:ssl]}.update(request_options)).execute
|
35
36
|
end
|
36
37
|
|
37
38
|
def put(data, request_options = {}, &blk)
|
38
39
|
headers = construct_aws_headers('PUT', request_options.delete(:headers) || {})
|
39
40
|
request_options[:on_success] = blk if blk
|
40
41
|
request_options.update(:headers => headers, :data => data)
|
41
|
-
Happening::S3::Request.new(:put, url, request_options).execute
|
42
|
+
Happening::S3::Request.new(:put, url, {:ssl => options[:ssl]}.update(request_options)).execute
|
42
43
|
end
|
43
44
|
|
44
45
|
def delete(request_options = {}, &blk)
|
45
46
|
headers = needs_to_sign? ? aws.sign("DELETE", path, {'url' => path}) : {}
|
46
47
|
request_options[:on_success] = blk if blk
|
47
48
|
request_options.update(:headers => headers)
|
48
|
-
Happening::S3::Request.new(:delete, url, request_options).execute
|
49
|
+
Happening::S3::Request.new(:delete, url, {:ssl => options[:ssl]}.update(request_options)).execute
|
49
50
|
end
|
50
51
|
|
51
52
|
def url
|
data/lib/happening/s3/request.rb
CHANGED
@@ -13,9 +13,13 @@ module Happening
|
|
13
13
|
:headers => {},
|
14
14
|
:on_error => nil,
|
15
15
|
:on_success => nil,
|
16
|
-
:data => nil
|
16
|
+
:data => nil,
|
17
|
+
:ssl => {
|
18
|
+
:cert_chain_file => nil,
|
19
|
+
:verify_peer => false
|
20
|
+
}
|
17
21
|
}.update(options)
|
18
|
-
options.assert_valid_keys(:timeout, :on_success, :on_error, :retry_count, :headers, :data)
|
22
|
+
options.assert_valid_keys(:timeout, :on_success, :on_error, :retry_count, :headers, :data, :ssl)
|
19
23
|
@http_method = http_method
|
20
24
|
@url = url
|
21
25
|
|
@@ -24,7 +28,7 @@ module Happening
|
|
24
28
|
|
25
29
|
def execute
|
26
30
|
Happening::Log.debug "#{http_method.to_s.upcase} #{url}"
|
27
|
-
@response = http_class.new(url).send(http_method, :timeout => options[:timeout], :head => options[:headers], :body => options[:data])
|
31
|
+
@response = http_class.new(url).send(http_method, :timeout => options[:timeout], :head => options[:headers], :body => options[:data], :ssl => options[:ssl])
|
28
32
|
|
29
33
|
@response.errback { error_callback }
|
30
34
|
@response.callback { success_callback }
|
data/lib/happening/s3.rb
ADDED
data/lib/happening.rb
CHANGED
@@ -5,6 +5,7 @@ require 'active_support'
|
|
5
5
|
|
6
6
|
require File.dirname(__FILE__) + '/happening/log'
|
7
7
|
require File.dirname(__FILE__) + '/happening/aws'
|
8
|
+
require File.dirname(__FILE__) + '/happening/s3'
|
8
9
|
require File.dirname(__FILE__) + '/happening/s3/request'
|
9
10
|
require File.dirname(__FILE__) + '/happening/s3/item'
|
10
11
|
|
data/test/s3/item_test.rb
CHANGED
@@ -454,5 +454,36 @@ class ItemTest < Test::Unit::TestCase
|
|
454
454
|
|
455
455
|
end
|
456
456
|
|
457
|
+
context "SSL options" do
|
458
|
+
setup do
|
459
|
+
Happening::S3.ssl_options[:verify_peer] = true
|
460
|
+
Happening::S3.ssl_options[:cert_chain_file] = '/etc/foo.ca'
|
461
|
+
end
|
462
|
+
|
463
|
+
should "re-use the global options" do
|
464
|
+
item = Happening::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
|
465
|
+
assert item.options[:ssl][:verify_peer]
|
466
|
+
assert_equal '/etc/foo.ca', item.options[:ssl][:cert_chain_file]
|
467
|
+
end
|
468
|
+
|
469
|
+
should "allow to override global options" do
|
470
|
+
item = Happening::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123', :ssl => {:cert_chain_file => nil, :verify_peer => false})
|
471
|
+
assert !item.options[:ssl][:verify_peer]
|
472
|
+
assert_nil item.options[:ssl][:cert_chain_file]
|
473
|
+
end
|
474
|
+
|
475
|
+
should "pass the options to the Request" do
|
476
|
+
item = Happening::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
|
477
|
+
Happening::S3::Request.expects(:new).with(:get, anything, {:ssl => {:cert_chain_file => '/etc/foo.ca', :verify_peer => true}, :headers => {'Authorization' => 'AWS abc:LGLdCdGTuLAHs+InbMWEnQR6djc=', 'date' => 'Thu, 25 Feb 2010 10:00:00 GMT'}}).returns(stub(:execute => nil))
|
478
|
+
item.get
|
479
|
+
end
|
480
|
+
|
481
|
+
should "allow to override the options per request" do
|
482
|
+
item = Happening::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
|
483
|
+
Happening::S3::Request.expects(:new).with(:get, anything, {:ssl => {:foo => :bar}, :headers => {'Authorization' => 'AWS abc:LGLdCdGTuLAHs+InbMWEnQR6djc=', 'date' => 'Thu, 25 Feb 2010 10:00:00 GMT'}}).returns(stub(:execute => nil))
|
484
|
+
item.get(:ssl => {:foo => :bar})
|
485
|
+
end
|
486
|
+
end
|
487
|
+
|
457
488
|
end
|
458
489
|
end
|
data/test/s3/request_test.rb
CHANGED
@@ -45,18 +45,25 @@ class ItemTest < Test::Unit::TestCase
|
|
45
45
|
|
46
46
|
should "pass the given headers and options" do
|
47
47
|
request = mock('em-http-request')
|
48
|
-
request.expects(:get).with(:timeout => 10, :head => {'a' => 'b'}, :body => nil).returns(@response_stub)
|
48
|
+
request.expects(:get).with(:timeout => 10, :head => {'a' => 'b'}, :body => nil, :ssl => {:verify_peer => false, :cert_chain_file => nil}).returns(@response_stub)
|
49
49
|
EventMachine::MockHttpRequest.expects(:new).with('https://www.example.com').returns(request)
|
50
50
|
Happening::S3::Request.new(:get, 'https://www.example.com', :headers => {'a' => 'b'}).execute
|
51
51
|
end
|
52
52
|
|
53
53
|
should "post any given data" do
|
54
54
|
request = mock('em-http-request')
|
55
|
-
request.expects(:put).with(:timeout => 10, :body => 'the-data', :head => {}).returns(@response_stub)
|
55
|
+
request.expects(:put).with(:timeout => 10, :body => 'the-data', :head => {}, :ssl => {:verify_peer => false, :cert_chain_file => nil}).returns(@response_stub)
|
56
56
|
EventMachine::MockHttpRequest.expects(:new).with('https://www.example.com').returns(request)
|
57
57
|
Happening::S3::Request.new(:put, 'https://www.example.com', :data => 'the-data').execute
|
58
58
|
end
|
59
59
|
|
60
|
+
should "pass SSL options to em-http-request" do
|
61
|
+
request = mock('em-http-request')
|
62
|
+
request.expects(:put).with(:timeout => 10, :body => 'the-data', :head => {}, :ssl => {:verfiy_peer => true, :cert_chain_file => '/tmp/server.crt'}).returns(@response_stub)
|
63
|
+
EventMachine::MockHttpRequest.expects(:new).with('https://www.example.com').returns(request)
|
64
|
+
Happening::S3::Request.new(:put, 'https://www.example.com', :data => 'the-data', :ssl => {:verfiy_peer => true, :cert_chain_file => '/tmp/server.crt'}).execute
|
65
|
+
end
|
66
|
+
|
60
67
|
context "when handling errors" do
|
61
68
|
should "call the user error handler" do
|
62
69
|
EventMachine::MockHttpRequest.register('http://www.example.com:80/', :get, {}, error_response(400))
|
data/test/s3_test.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/test_helper"
|
2
|
+
|
3
|
+
class S3Test < Test::Unit::TestCase
|
4
|
+
context "The Happening::S3 module" do
|
5
|
+
|
6
|
+
should "allow to set global SSL options" do
|
7
|
+
assert Happening::S3.respond_to?(:ssl_options)
|
8
|
+
assert Happening::S3.respond_to?(:ssl_options=)
|
9
|
+
end
|
10
|
+
|
11
|
+
should "set and get verify_peer" do
|
12
|
+
Happening::S3.ssl_options[:verify_peer] = true
|
13
|
+
assert Happening::S3.ssl_options[:verify_peer]
|
14
|
+
Happening::S3.ssl_options[:verify_peer] = false
|
15
|
+
assert !Happening::S3.ssl_options[:verify_peer]
|
16
|
+
end
|
17
|
+
|
18
|
+
should "set and get cert_chain_file" do
|
19
|
+
Happening::S3.ssl_options[:cert_chain_file] = '/etc/cacert'
|
20
|
+
assert_equal '/etc/cacert', Happening::S3.ssl_options[:cert_chain_file]
|
21
|
+
Happening::S3.ssl_options[:cert_chain_file] = nil
|
22
|
+
assert_nil Happening::S3.ssl_options[:cert_chain_file]
|
23
|
+
end
|
24
|
+
|
25
|
+
should "default to no certificate file and no verification" do
|
26
|
+
Happening::S3.instance_variable_set("@_ssl_options", nil)
|
27
|
+
assert !Happening::S3.ssl_options[:verify_peer]
|
28
|
+
assert_nil Happening::S3.ssl_options[:cert_chain_file]
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 8
|
9
|
+
version: 0.0.8
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Jonathan Weiss
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-04-
|
17
|
+
date: 2010-04-30 00:00:00 +02:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -56,6 +56,7 @@ files:
|
|
56
56
|
- lib/happening.rb
|
57
57
|
- lib/happening/aws.rb
|
58
58
|
- lib/happening/log.rb
|
59
|
+
- lib/happening/s3.rb
|
59
60
|
- lib/happening/s3/item.rb
|
60
61
|
- lib/happening/s3/request.rb
|
61
62
|
has_rdoc: true
|
@@ -92,4 +93,5 @@ test_files:
|
|
92
93
|
- test/aws_test.rb
|
93
94
|
- test/s3/item_test.rb
|
94
95
|
- test/s3/request_test.rb
|
96
|
+
- test/s3_test.rb
|
95
97
|
- test/test_helper.rb
|