happening 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
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
 
@@ -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
@@ -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 }
@@ -0,0 +1,16 @@
1
+ module Happening
2
+ module S3
3
+
4
+ def self.ssl_options
5
+ @_ssl_options ||= {
6
+ :cert_chain_file => nil,
7
+ :verify_peer => false
8
+ }
9
+ end
10
+
11
+ def self.ssl_options=(val)
12
+ @_ssl_options = val
13
+ end
14
+
15
+ end
16
+ end
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
@@ -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
- - 7
9
- version: 0.0.7
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-23 00:00:00 +02:00
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