happening 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md ADDED
@@ -0,0 +1,10 @@
1
+ Changelog
2
+ =============
3
+
4
+ 0.2.1
5
+
6
+ - Return the response object on get so that the data can be streamed [carlism]
7
+
8
+ 0.2.0
9
+
10
+ - Initial release
data/README.md CHANGED
@@ -139,6 +139,20 @@ You can also just load the headers of an S3 item:
139
139
  end
140
140
 
141
141
 
142
+
143
+ Streaming
144
+ =============
145
+
146
+ The response data can also be streamed:
147
+
148
+ EM.run do
149
+ item = Happening::S3::Item.new( bucket...
150
+ item.get(:on_error => on_error, :on_success => on_success ).stream do |chunk|
151
+ # .. handle the individual chunk
152
+ end
153
+ end
154
+
155
+
142
156
  SSL Support
143
157
  =============
144
158
 
@@ -33,7 +33,7 @@ module Happening
33
33
 
34
34
  @response.errback { error_callback }
35
35
  @response.callback { success_callback }
36
- nil
36
+ @response
37
37
  end
38
38
 
39
39
  def http_class
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: happening
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
5
- prerelease: false
4
+ hash: 21
5
+ prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 0
10
- version: 0.2.0
9
+ - 1
10
+ version: 0.2.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jonathan Weiss
@@ -15,13 +15,10 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-05-20 00:00:00 +02:00
19
- default_executable:
18
+ date: 2011-08-07 00:00:00 Z
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
22
- name: em-http-request
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
21
+ version_requirements: &id001 !ruby/object:Gem::Requirement
25
22
  none: false
26
23
  requirements:
27
24
  - - ">="
@@ -30,12 +27,26 @@ dependencies:
30
27
  segments:
31
28
  - 0
32
29
  version: "0"
30
+ name: happening
31
+ prerelease: false
33
32
  type: :runtime
34
- version_requirements: *id001
33
+ requirement: *id001
35
34
  - !ruby/object:Gem::Dependency
35
+ version_requirements: &id002 !ruby/object:Gem::Requirement
36
+ none: false
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ hash: 3
41
+ segments:
42
+ - 0
43
+ version: "0"
36
44
  name: jeweler
37
45
  prerelease: false
38
- requirement: &id002 !ruby/object:Gem::Requirement
46
+ type: :development
47
+ requirement: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ version_requirements: &id003 !ruby/object:Gem::Requirement
39
50
  none: false
40
51
  requirements:
41
52
  - - ">="
@@ -44,12 +55,26 @@ dependencies:
44
55
  segments:
45
56
  - 0
46
57
  version: "0"
58
+ name: shoulda
59
+ prerelease: false
47
60
  type: :development
48
- version_requirements: *id002
61
+ requirement: *id003
49
62
  - !ruby/object:Gem::Dependency
50
- name: shoulda
63
+ version_requirements: &id004 !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ hash: 3
69
+ segments:
70
+ - 0
71
+ version: "0"
72
+ name: mocha
51
73
  prerelease: false
52
- requirement: &id003 !ruby/object:Gem::Requirement
74
+ type: :development
75
+ requirement: *id004
76
+ - !ruby/object:Gem::Dependency
77
+ version_requirements: &id005 !ruby/object:Gem::Requirement
53
78
  none: false
54
79
  requirements:
55
80
  - - ">="
@@ -58,12 +83,40 @@ dependencies:
58
83
  segments:
59
84
  - 0
60
85
  version: "0"
86
+ name: em-http-request
87
+ prerelease: false
88
+ type: :runtime
89
+ requirement: *id005
90
+ - !ruby/object:Gem::Dependency
91
+ version_requirements: &id006 !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ hash: 3
97
+ segments:
98
+ - 0
99
+ version: "0"
100
+ name: jeweler
101
+ prerelease: false
61
102
  type: :development
62
- version_requirements: *id003
103
+ requirement: *id006
63
104
  - !ruby/object:Gem::Dependency
64
- name: mocha
105
+ version_requirements: &id007 !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ hash: 3
111
+ segments:
112
+ - 0
113
+ version: "0"
114
+ name: shoulda
65
115
  prerelease: false
66
- requirement: &id004 !ruby/object:Gem::Requirement
116
+ type: :development
117
+ requirement: *id007
118
+ - !ruby/object:Gem::Dependency
119
+ version_requirements: &id008 !ruby/object:Gem::Requirement
67
120
  none: false
68
121
  requirements:
69
122
  - - ">="
@@ -72,8 +125,10 @@ dependencies:
72
125
  segments:
73
126
  - 0
74
127
  version: "0"
128
+ name: mocha
129
+ prerelease: false
75
130
  type: :development
76
- version_requirements: *id004
131
+ requirement: *id008
77
132
  description: An EventMachine based S3 client - using em-http-request
78
133
  email: info@peritor.com
79
134
  executables: []
@@ -84,6 +139,7 @@ extra_rdoc_files:
84
139
  - LICENSE.txt
85
140
  - README.md
86
141
  files:
142
+ - CHANGELOG.md
87
143
  - LICENSE.txt
88
144
  - README.md
89
145
  - lib/happening.rb
@@ -93,18 +149,12 @@ files:
93
149
  - lib/happening/s3/item.rb
94
150
  - lib/happening/s3/request.rb
95
151
  - lib/happening/utils.rb
96
- - test/aws_test.rb
97
- - test/s3/item_test.rb
98
- - test/s3/request_test.rb
99
- - test/s3_test.rb
100
- - test/test_helper.rb
101
- has_rdoc: true
102
152
  homepage: http://github.com/peritor/happening
103
153
  licenses: []
104
154
 
105
155
  post_install_message:
106
- rdoc_options:
107
- - --charset=UTF-8
156
+ rdoc_options: []
157
+
108
158
  require_paths:
109
159
  - lib
110
160
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -128,13 +178,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
128
178
  requirements: []
129
179
 
130
180
  rubyforge_project:
131
- rubygems_version: 1.3.7
181
+ rubygems_version: 1.8.7
132
182
  signing_key:
133
183
  specification_version: 3
134
184
  summary: An EventMachine based S3 client
135
- test_files:
136
- - test/aws_test.rb
137
- - test/s3/item_test.rb
138
- - test/s3/request_test.rb
139
- - test/s3_test.rb
140
- - test/test_helper.rb
185
+ test_files: []
186
+
data/test/aws_test.rb DELETED
@@ -1,41 +0,0 @@
1
- require File.expand_path('../test_helper', __FILE__)
2
-
3
- class ItemTest < Test::Unit::TestCase
4
- context "An Happening::AWS instance" do
5
-
6
- setup do
7
- @aws = Happening::AWS.new('the-aws-access-key', 'the-aws-secret-key')
8
- end
9
-
10
- context "when constructing" do
11
- should "require Access Key and Secret Key" do
12
- assert_raise(ArgumentError) do
13
- Happening::AWS.new(nil, nil)
14
- end
15
-
16
- assert_raise(ArgumentError) do
17
- Happening::AWS.new('', '')
18
- end
19
-
20
- assert_nothing_raised do
21
- Happening::AWS.new('abc', 'abc')
22
- end
23
- end
24
- end
25
-
26
- context "when signing parameters" do
27
- should "return a header hash" do
28
- assert_not_nil @aws.sign("GET", '/')['Authorization']
29
- end
30
-
31
- should "include the current date" do
32
- assert_not_nil @aws.sign("GET", '/')['date']
33
- end
34
-
35
- should "keep given headers" do
36
- assert_equal 'bar', @aws.sign("GET", '/', {'foo' => 'bar'})['foo']
37
- end
38
- end
39
-
40
- end
41
- end
data/test/s3/item_test.rb DELETED
@@ -1,507 +0,0 @@
1
- require File.expand_path('../../test_helper', __FILE__)
2
-
3
- class ItemTest < Test::Unit::TestCase
4
- context "An Happening::S3::Item instance" do
5
-
6
- setup do
7
- Happening::Log.level = Logger::ERROR
8
- @item = Happening::S3::Item.new('the-bucket', 'the-key', :aws_access_key_id => '123', :aws_secret_access_key => 'secret', :server => '127.0.0.1')
9
-
10
- @time = "Thu, 25 Feb 2010 10:00:00 GMT"
11
- Time.stubs(:now).returns(Time.parse(@time))
12
- #stub(:utc_httpdate => @time, :to_i => 99, :usec => 88))
13
- end
14
-
15
- context "validation" do
16
- should "require a bucket and a key" do
17
- assert_raise(ArgumentError) do
18
- item = Happening::S3::Item.new()
19
- end
20
-
21
- assert_raise(ArgumentError) do
22
- item = Happening::S3::Item.new('the-key')
23
- end
24
-
25
- assert_nothing_raised(ArgumentError) do
26
- item = Happening::S3::Item.new('the-bucket', 'the-key')
27
- end
28
-
29
- end
30
-
31
- should "not allow unknown options" do
32
- assert_raise(ArgumentError) do
33
- item = Happening::S3::Item.new('the-bucket', 'the-key', :aws_access_key_id => '123', :aws_secret_access_key => 'secret', :lala => 'lulul')
34
- end
35
- end
36
-
37
- should "check valid protocol" do
38
- assert_raise(ArgumentError) do
39
- item = Happening::S3::Item.new('the-bucket', 'the-key', :aws_access_key_id => '123', :aws_secret_access_key => 'secret', :protocol => 'lulul')
40
- end
41
-
42
- assert_nothing_raised do
43
- item = Happening::S3::Item.new('the-bucket', 'the-key', :aws_access_key_id => '123', :aws_secret_access_key => 'secret', :protocol => 'http')
44
- end
45
-
46
- assert_nothing_raised do
47
- item = Happening::S3::Item.new('the-bucket', 'the-key', :aws_access_key_id => '123', :aws_secret_access_key => 'secret', :protocol => 'https')
48
- end
49
- end
50
- end
51
-
52
- context "when building the item url" do
53
- should "build the full path out of the server, bucket, and key" do
54
- @item = Happening::S3::Item.new('the-bucketissoooooooooooooooooooooooooooooooooooooolonggggggggggggggggggggggggggggggggggg', 'the-key', :aws_access_key_id => '123', :aws_secret_access_key => 'secret', :server => '127.0.0.1')
55
- assert_equal "https://127.0.0.1:443/the-bucketissoooooooooooooooooooooooooooooooooooooolonggggggggggggggggggggggggggggggggggg/the-key", @item.url
56
- end
57
-
58
- should "use the DNS bucket name where possible" do
59
- @item = Happening::S3::Item.new('bucket', 'the-key', :aws_access_key_id => '123', :aws_secret_access_key => 'secret')
60
- assert_equal "https://bucket.s3.amazonaws.com:443/the-key", @item.url
61
- end
62
- end
63
-
64
- context "when getting an item" do
65
-
66
- should "call the on success callback" do
67
- EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :get, {}, fake_response("data-here"))
68
-
69
- called = false
70
- data = nil
71
- on_success = Proc.new {|http| called = true, data = http.response}
72
- @item = Happening::S3::Item.new('bucket', 'the-key')
73
- run_in_em_loop do
74
- @item.get(:on_success => on_success)
75
-
76
- EM.add_timer(1) {
77
- assert called
78
- assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :get, {})
79
- assert_equal "data-here\n", data
80
- EM.stop_event_loop
81
- }
82
-
83
- end
84
- end
85
-
86
- should "support direct blocks" do
87
- EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :get, {}, fake_response("data-here"))
88
-
89
- called = false
90
- data = nil
91
- @item = Happening::S3::Item.new('bucket', 'the-key')
92
- run_in_em_loop do
93
- @item.get do |http|
94
- called = true
95
- data = http.response
96
- end
97
-
98
- EM.add_timer(1) {
99
- assert called
100
- assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :get, {})
101
- assert_equal "data-here\n", data
102
- EM.stop_event_loop
103
- }
104
-
105
- end
106
- end
107
-
108
- should "sign requests if AWS credentials are passend" do
109
- time = "Thu, 25 Feb 2010 12:06:33 GMT"
110
- Time.stubs(:now).returns(Time.parse(time))
111
- EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :get, {"Authorization"=>"AWS abc:3OEcVbE//maUUmqh3A5ETEcr9TE=", 'date' => time}, fake_response("data-here"))
112
-
113
- @item = Happening::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
114
- run_in_em_loop do
115
- @item.get
116
-
117
- EM.add_timer(1) {
118
- EM.stop_event_loop
119
- assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :get, {"Authorization"=>"AWS abc:3OEcVbE//maUUmqh3A5ETEcr9TE=", 'date' => time})
120
- }
121
-
122
- end
123
- end
124
-
125
- should "retry on error" do
126
- EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :get, {}, error_response(400))
127
-
128
- @item = Happening::S3::Item.new('bucket', 'the-key')
129
- run_in_em_loop do
130
- @item.get(:on_error => Proc.new{} ) #ignore error
131
-
132
- EM.add_timer(1) {
133
- EM.stop_event_loop
134
- assert_equal 5, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :get, {})
135
- }
136
-
137
- end
138
- end
139
-
140
- should "handle re-direct" do
141
- EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :get, {}, redirect_response('https://bucket.s3-external-3.amazonaws.com/the-key'))
142
- EventMachine::MockHttpRequest.register('https://bucket.s3-external-3.amazonaws.com:443/the-key', :get, {}, fake_response('hy there'))
143
-
144
- @item = Happening::S3::Item.new('bucket', 'the-key')
145
- run_in_em_loop do
146
- @item.get
147
-
148
- EM.add_timer(1) {
149
- EM.stop_event_loop
150
- assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :get, {})
151
- assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3-external-3.amazonaws.com:443/the-key', :get, {})
152
- }
153
-
154
- end
155
- end
156
- end
157
-
158
- context "when deleting an item" do
159
- should "send a DELETE to the items location" do
160
- EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :delete, {
161
- "Authorization"=>"AWS abc:nvkrlq4wor1qbFXZh6rHnAbiRjk=",
162
- 'date' => @time,
163
- 'url' => "/bucket/the-key"}, fake_response("data-here"))
164
-
165
- @item = Happening::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
166
- run_in_em_loop do
167
- @item.delete
168
-
169
- EM.add_timer(1) {
170
- EM.stop_event_loop
171
- assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :delete, {
172
- "Authorization"=>"AWS abc:nvkrlq4wor1qbFXZh6rHnAbiRjk=",
173
- 'date' => @time,
174
- 'url' => "/bucket/the-key"})
175
- }
176
-
177
- end
178
- end
179
-
180
- should "support direct blocks" do
181
- EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :delete, {
182
- "Authorization"=>"AWS abc:nvkrlq4wor1qbFXZh6rHnAbiRjk=",
183
- 'date' => @time,
184
- 'url' => "/bucket/the-key"}, fake_response("data-here"))
185
-
186
- called = false
187
- data = nil
188
- @item = Happening::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
189
- run_in_em_loop do
190
- @item.delete do |http|
191
- called = true
192
- data = http.response
193
- end
194
-
195
- EM.add_timer(1) {
196
- assert called
197
- assert_equal "data-here\n", data
198
- EM.stop_event_loop
199
- assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :delete, {
200
- "Authorization"=>"AWS abc:nvkrlq4wor1qbFXZh6rHnAbiRjk=",
201
- 'date' => @time,
202
- 'url' => "/bucket/the-key"})
203
- }
204
-
205
- end
206
- end
207
-
208
- should "handle re-direct" do
209
- EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :delete, {
210
- "Authorization"=>"AWS abc:nvkrlq4wor1qbFXZh6rHnAbiRjk=",
211
- 'date' => @time,
212
- 'url' => "/bucket/the-key"}, redirect_response('https://bucket.s3-external-3.amazonaws.com/the-key'))
213
- EventMachine::MockHttpRequest.register('https://bucket.s3-external-3.amazonaws.com:443/the-key', :delete, {
214
- "Authorization"=>"AWS abc:nvkrlq4wor1qbFXZh6rHnAbiRjk=",
215
- 'date' => @time,
216
- 'url' => "/bucket/the-key"}, fake_response("success!"))
217
-
218
- @item = Happening::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
219
- run_in_em_loop do
220
- @item.delete
221
-
222
- EM.add_timer(1) {
223
- EM.stop_event_loop
224
- assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :delete, {
225
- "Authorization"=>"AWS abc:nvkrlq4wor1qbFXZh6rHnAbiRjk=",
226
- 'date' => @time,
227
- 'url' => "/bucket/the-key"})
228
- assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3-external-3.amazonaws.com:443/the-key', :delete, {
229
- "Authorization"=>"AWS abc:nvkrlq4wor1qbFXZh6rHnAbiRjk=",
230
- 'date' => @time,
231
- 'url' => "/bucket/the-key"})
232
- }
233
-
234
- end
235
- end
236
-
237
- should "handle retry" do
238
- EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :delete, {
239
- "Authorization"=>"AWS abc:nvkrlq4wor1qbFXZh6rHnAbiRjk=",
240
- 'date' => @time,
241
- 'url' => "/bucket/the-key"}, error_response(400))
242
-
243
- @item = Happening::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
244
- run_in_em_loop do
245
- @item.delete(:on_error => Proc.new{} ) #ignore error
246
-
247
- EM.add_timer(1) {
248
- EM.stop_event_loop
249
- assert_equal 5, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :delete, {
250
- "Authorization"=>"AWS abc:nvkrlq4wor1qbFXZh6rHnAbiRjk=",
251
- 'date' => @time,
252
- 'url' => "/bucket/the-key"})
253
- }
254
-
255
- end
256
- end
257
- end
258
-
259
- context "when loading the headers" do
260
- should "request via HEAD" do
261
- EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :head, {}, fake_response('hy there'))
262
-
263
- @item = Happening::S3::Item.new('bucket', 'the-key')
264
- run_in_em_loop do
265
- @item.head
266
-
267
- EM.add_timer(1) {
268
- EM.stop_event_loop
269
- assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :head, {})
270
- }
271
-
272
- end
273
- end
274
- end
275
-
276
- context "when saving an item" do
277
-
278
- should "post to the desired location" do
279
- EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :put, {
280
- "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
281
- 'date' => @time,
282
- 'url' => "/bucket/the-key"}, fake_response("data-here"))
283
-
284
- @item = Happening::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
285
- run_in_em_loop do
286
- @item.put('content')
287
-
288
- EM.add_timer(1) {
289
- EM.stop_event_loop
290
- assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :put, {
291
- "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
292
- 'date' => @time,
293
- 'url' => "/bucket/the-key"})
294
- }
295
-
296
- end
297
- end
298
-
299
- should "support direct blocks" do
300
- EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :put, {
301
- "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
302
- 'date' => @time,
303
- 'url' => "/bucket/the-key"}, fake_response("data-here"))
304
-
305
- called = false
306
- data = nil
307
- @item = Happening::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
308
- run_in_em_loop do
309
- @item.put('upload me') do |http|
310
- called = true
311
- data = http.response
312
- end
313
-
314
- EM.add_timer(1) {
315
- assert called
316
- assert_equal "data-here\n", data
317
- EM.stop_event_loop
318
- assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :put, {
319
- "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
320
- 'date' => @time,
321
- 'url' => "/bucket/the-key"})
322
- }
323
-
324
- end
325
- end
326
-
327
- should "set the desired permissions" do
328
- EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :put, {
329
- "Authorization"=>"AWS abc:cqkfX+nC7WIkYD+yWaUFuoRuePA=",
330
- 'date' => @time,
331
- 'url' => "/bucket/the-key",
332
- "x-amz-acl" => 'public-read'}, fake_response("data-here"))
333
-
334
- @item = Happening::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123' , :permissions => 'public-read')
335
- run_in_em_loop do
336
- @item.put('content')
337
-
338
- EM.add_timer(1) {
339
- EM.stop_event_loop
340
- assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :put, {
341
- "Authorization"=>"AWS abc:cqkfX+nC7WIkYD+yWaUFuoRuePA=",
342
- 'date' => @time,
343
- 'url' => "/bucket/the-key",
344
- 'x-amz-acl' => 'public-read'})
345
- }
346
-
347
- end
348
- end
349
-
350
- should "allow to set custom headers" do
351
- EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :put, {
352
- "Authorization"=>"AWS abc:wrPkGKrlwH2AtNzBVS80vU73TDc=",
353
- 'date' => @time,
354
- 'url' => "/bucket/the-key",
355
- "x-amz-acl" => 'public-read',
356
- 'Cache-Control' => "max-age=252460800",
357
- 'Expires' => 'Fri, 16 Nov 2018 22:09:29 GMT',
358
- 'x-amz-meta-abc' => 'ABC'}, fake_response("data-here"))
359
-
360
- @item = Happening::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc',
361
- :aws_secret_access_key => '123' ,
362
- :permissions => 'public-read')
363
- run_in_em_loop do
364
- @item.put('content', :headers => {
365
- 'Expires' => 'Fri, 16 Nov 2018 22:09:29 GMT',
366
- 'Cache-Control' => "max-age=252460800",
367
- 'x-amz-meta-abc' => 'ABC'})
368
-
369
- EM.add_timer(1) {
370
- EM.stop_event_loop
371
- assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :put, {
372
- "Authorization"=>"AWS abc:wrPkGKrlwH2AtNzBVS80vU73TDc=",
373
- 'date' => @time,
374
- 'url' => "/bucket/the-key",
375
- 'x-amz-acl' => 'public-read',
376
- 'Cache-Control' => "max-age=252460800",
377
- 'Expires' => 'Fri, 16 Nov 2018 22:09:29 GMT',
378
- 'x-amz-meta-abc' => 'ABC'})
379
- }
380
-
381
- end
382
- end
383
-
384
- should "validate the headers" do
385
-
386
- @item = Happening::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc',
387
- :aws_secret_access_key => '123' ,
388
- :permissions => 'public-read')
389
-
390
- assert_raise(ArgumentError) do
391
- @item.put('content', :headers => {
392
- 'expires' => 'Fri, 16 Nov 2018 22:09:29 GMT',
393
- 'cache_control' => "max-age=252460800"})
394
- end
395
- end
396
-
397
- should "re-post to a new location" do
398
- EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :put, {
399
- "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
400
- 'date' => @time,
401
- 'url' => "/bucket/the-key"}, redirect_response('https://bucket.s3-external-3.amazonaws.com/the-key'))
402
- EventMachine::MockHttpRequest.register('https://bucket.s3-external-3.amazonaws.com:443/the-key', :put, {
403
- "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
404
- 'date' => @time,
405
- 'url' => "/bucket/the-key"}, fake_response('Thanks!'))
406
-
407
- @item = Happening::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
408
- run_in_em_loop do
409
- @item.put('content')
410
-
411
- EM.add_timer(1) {
412
- EM.stop_event_loop
413
- assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :put, {
414
- "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
415
- 'date' => @time,
416
- 'url' => "/bucket/the-key"})
417
-
418
- assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3-external-3.amazonaws.com:443/the-key', :put, {
419
- "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
420
- 'date' => @time,
421
- 'url' => "/bucket/the-key"})
422
- }
423
-
424
- end
425
- end
426
-
427
- should "retry on error" do
428
- EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :put, {
429
- "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
430
- 'date' => @time,
431
- 'url' => "/bucket/the-key"}, error_response(400))
432
-
433
- @item = Happening::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
434
- run_in_em_loop do
435
- @item.put('content', :on_error => Proc.new{} )
436
-
437
- EM.add_timer(1) {
438
- EM.stop_event_loop
439
- assert_equal 5, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :put, {
440
- "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
441
- 'date' => @time,
442
- 'url' => "/bucket/the-key"})
443
- }
444
-
445
- end
446
- end
447
-
448
- should "call error handler after retry reached" do
449
- EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :put, {
450
- "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
451
- 'date' => @time,
452
- 'url' => "/bucket/the-key"}, error_response(400))
453
-
454
- called = false
455
- on_error = Proc.new {|http| called = true}
456
-
457
- @item = Happening::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
458
- run_in_em_loop do
459
- @item.put('content', :on_error => on_error, :retry_count => 1)
460
-
461
- EM.add_timer(1) {
462
- EM.stop_event_loop
463
- assert called
464
- assert_equal 2, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :put, {
465
- "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
466
- 'date' => @time,
467
- 'url' => "/bucket/the-key"})
468
- }
469
-
470
- end
471
- end
472
-
473
- end
474
-
475
- context "SSL options" do
476
- setup do
477
- Happening::S3.ssl_options[:verify_peer] = true
478
- Happening::S3.ssl_options[:cert_chain_file] = '/etc/foo.ca'
479
- end
480
-
481
- should "re-use the global options" do
482
- item = Happening::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
483
- assert item.options[:ssl][:verify_peer]
484
- assert_equal '/etc/foo.ca', item.options[:ssl][:cert_chain_file]
485
- end
486
-
487
- should "allow to override global options" do
488
- 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})
489
- assert !item.options[:ssl][:verify_peer]
490
- assert_nil item.options[:ssl][:cert_chain_file]
491
- end
492
-
493
- should "pass the options to the Request" do
494
- item = Happening::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
495
- 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))
496
- item.get
497
- end
498
-
499
- should "allow to override the options per request" do
500
- item = Happening::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
501
- 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))
502
- item.get(:ssl => {:foo => :bar})
503
- end
504
- end
505
-
506
- end
507
- end
@@ -1,102 +0,0 @@
1
- require File.expand_path('../../test_helper', __FILE__)
2
-
3
- class ItemTest < Test::Unit::TestCase
4
- context "An Happening::S3::Request instance" do
5
-
6
- setup do
7
- Happening::Log.level = Logger::ERROR
8
- @response_stub = stub()
9
- @response_stub.stubs(:errback)
10
- @response_stub.stubs(:callback)
11
- end
12
-
13
- context "validation" do
14
- should "check HTTP method" do
15
- assert_raise(ArgumentError) do
16
- Happening::S3::Request.new(:foo, 'https://www.example.com')
17
- end
18
-
19
- assert_nothing_raised do
20
- Happening::S3::Request.new(:get, 'https://www.example.com')
21
- end
22
- end
23
-
24
- should "check the options" do
25
- assert_raise(ArgumentError) do
26
- Happening::S3::Request.new(:get, 'https://www.example.com', {:foo => :bar})
27
- end
28
-
29
- assert_nothing_raised do
30
- Happening::S3::Request.new(:get, 'https://www.example.com', {:timeout => 4})
31
- end
32
- end
33
- end
34
-
35
- context "when executing" do
36
- should "have no response before executing" do
37
- assert_nil Happening::S3::Request.new(:get, 'https://www.example.com').response
38
- end
39
-
40
- should "call em-http-request" do
41
- request = mock(:get => @response_stub)
42
- EventMachine::MockHttpRequest.expects(:new).with('https://www.example.com').returns(request)
43
- Happening::S3::Request.new(:get, 'https://www.example.com').execute
44
- end
45
-
46
- should "pass the given headers and options" do
47
- request = mock('em-http-request')
48
- request.expects(:get).with(:timeout => 10, :head => {'a' => 'b'}, :body => nil, :ssl => {:verify_peer => false, :cert_chain_file => nil}).returns(@response_stub)
49
- EventMachine::MockHttpRequest.expects(:new).with('https://www.example.com').returns(request)
50
- Happening::S3::Request.new(:get, 'https://www.example.com', :headers => {'a' => 'b'}).execute
51
- end
52
-
53
- should "post any given data" do
54
- request = mock('em-http-request')
55
- request.expects(:put).with(:timeout => 10, :body => 'the-data', :head => {}, :ssl => {:verify_peer => false, :cert_chain_file => nil}).returns(@response_stub)
56
- EventMachine::MockHttpRequest.expects(:new).with('https://www.example.com').returns(request)
57
- Happening::S3::Request.new(:put, 'https://www.example.com', :data => 'the-data').execute
58
- end
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
-
67
- context "when handling errors" do
68
- should "call the user error handler" do
69
- EventMachine::MockHttpRequest.register('http://www.example.com:80/', :get, {}, error_response(400))
70
-
71
- called = false
72
- on_error = Proc.new {|http| called = true}
73
-
74
- run_in_em_loop do
75
- Happening::S3::Request.new(:get, 'http://www.example.com/', :on_error => on_error).execute
76
-
77
- EM.add_timer(1) {
78
- EM.stop_event_loop
79
- assert called
80
- assert_equal 5, EventMachine::MockHttpRequest.count('http://www.example.com:80/', :get, {})
81
- }
82
-
83
- end
84
- end
85
-
86
- should "use a default error handler if there is no user handler" do
87
- EventMachine::MockHttpRequest.register('http://www.example.com:80/', :get, {}, error_response(400))
88
-
89
- assert_raise(Happening::Error) do
90
- run_in_em_loop do
91
- Happening::S3::Request.new(:get, 'http://www.example.com/').execute
92
- end
93
- end
94
- EM.stop_event_loop if EM.reactor_running?
95
- end
96
-
97
- end
98
-
99
- end
100
-
101
- end
102
- end
data/test/s3_test.rb DELETED
@@ -1,32 +0,0 @@
1
- require File.expand_path('../test_helper', __FILE__)
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
data/test/test_helper.rb DELETED
@@ -1,94 +0,0 @@
1
- require 'rubygems'
2
-
3
- require 'test/unit'
4
- require 'shoulda'
5
- require 'mocha'
6
-
7
- $:.unshift(File.dirname(__FILE__) + "/../")
8
-
9
- require 'happening'
10
-
11
- require 'em-http/mock'
12
-
13
- EventMachine.instance_eval do
14
- # Switching out EM's defer since it makes tests just a tad more unreliable
15
- alias :defer_original :defer
16
- def defer
17
- yield
18
- end
19
- end unless EM.respond_to?(:defer_original)
20
-
21
- class Test::Unit::TestCase
22
- def setup
23
- EventMachine::MockHttpRequest.reset_counts!
24
- EventMachine::MockHttpRequest.reset_registry!
25
- end
26
-
27
- def run_in_em_loop
28
- EM.run {
29
- yield
30
- }
31
- end
32
- end
33
-
34
- module Happening
35
- module S3
36
- class Request
37
- def http_class
38
- EventMachine::MockHttpRequest
39
- end
40
- end
41
- end
42
- end
43
-
44
- def fake_response(data)
45
- <<-HEREDOC
46
- HTTP/1.0 200 OK
47
- Date: Mon, 16 Nov 2009 20:39:15 GMT
48
- Expires: -1
49
- Cache-Control: private, max-age=0
50
- Content-Type: text/html; charset=ISO-8859-1
51
- Set-Cookie: PREF=ID=9454187d21c4a6a6:TM=1258403955:LM=1258403955:S=2-mf1n5oV5yAeT9-; expires=Wed, 16-Nov-2011 20:39:15 GMT; path=/; domain=.google.ca
52
- Set-Cookie: NID=28=lvxxVdiBQkCetu_WFaUxLyB7qPlHXS5OdAGYTqge_laVlCKVN8VYYeVBh4bNZiK_Oan2gm8oP9GA-FrZfMPC3ZMHeNq37MG2JH8AIW9LYucU8brOeuggMEbLNNXuiWg4; expires=Tue, 18-May-2010 20:39:15 GMT; path=/; domain=.google.ca; HttpOnly
53
- Server: gws
54
- X-XSS-Protection: 0
55
- X-Cache: MISS from .
56
- Via: 1.0 .:80 (squid)
57
- Connection: close
58
-
59
- #{data}
60
- HEREDOC
61
- end
62
-
63
- # amazon tells us to upload to another location, e.g. happening-benchmark.s3-external-3.amazonaws.com instead of happening-benchmark.s3.amazonaws.com
64
- def redirect_response(location)
65
- <<-HEREDOC
66
- HTTP/1.0 301 Moved Permanently
67
- Date: Mon, 16 Nov 2009 20:39:15 GMT
68
- Expires: -1
69
- Cache-Control: private, max-age=0
70
- Content-Type: text/html; charset=ISO-8859-1
71
- Via: 1.0 .:80 (squid)
72
- Connection: close
73
- Location: #{location}
74
-
75
- <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Error><Code>TemporaryRedirect</Code><Message>Please re-send this request to the specified temporary endpoint. Continue to use the original request endpoint for future requests.</Message><RequestId>137D5486D66095AE</RequestId><Bucket>happening-benchmark</Bucket><HostId>Nyk+Zq9GbtxcspdbKDWyGhsZhyUZquZP55tteYef4QVodsn73HUUad0xrIeD09lF</HostId><Endpoint>#{location}</Endpoint></Error>
76
- HEREDOC
77
- end
78
-
79
- def error_response(error_code)
80
- <<-HEREDOC
81
- HTTP/1.0 #{error_code} OK
82
- Date: Mon, 16 Nov 2009 20:39:15 GMT
83
- Content-Type: text/html; charset=ISO-8859-1
84
- Connection: close
85
-
86
- <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Error><Code>TemporaryRedirect</Code><Message>Please re-send this request to the specified temporary endpoint. Continue to use the original request endpoint for future requests.</Message><RequestId>137D5486D66095AE</RequestId><Bucket>happening-benchmark</Bucket><HostId>Nyk+Zq9GbtxcspdbKDWyGhsZhyUZquZP55tteYef4QVodsn73HUUad0xrIeD09lF</HostId><Endpoint>https://s3.amazonaws.com</Endpoint></Error>
87
- HEREDOC
88
- end
89
-
90
- module EventMachine
91
- class MockHttpRequest
92
- @@pass_through_requests = false
93
- end
94
- end