blobsterix 0.0.14 → 0.0.19

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.txt +9 -0
  3. data/README.md +5 -1
  4. data/blobsterix.gemspec +1 -0
  5. data/lib/blobsterix/blob/blob_api.rb +1 -0
  6. data/lib/blobsterix/blob/blob_url_helper.rb +2 -39
  7. data/lib/blobsterix/helper/blob_access.rb +9 -10
  8. data/lib/blobsterix/helper/config_loader.rb +10 -18
  9. data/lib/blobsterix/helper/directory_list.rb +131 -0
  10. data/lib/blobsterix/helper/http.rb +13 -14
  11. data/lib/blobsterix/helper/jsonizer.rb +45 -0
  12. data/lib/blobsterix/helper/logable.rb +25 -0
  13. data/lib/blobsterix/helper/murmur.rb +14 -0
  14. data/lib/blobsterix/helper/simple_proxy.rb +11 -0
  15. data/lib/blobsterix/helper/template_renderer.rb +4 -0
  16. data/lib/blobsterix/helper/url_helper.rb +41 -0
  17. data/lib/blobsterix/router/app_router.rb +15 -65
  18. data/lib/blobsterix/s3/s3_api.rb +20 -6
  19. data/lib/blobsterix/s3/s3_auth.rb +32 -0
  20. data/lib/blobsterix/s3/s3_auth_key_store.rb +14 -0
  21. data/lib/blobsterix/s3/s3_auth_v2.rb +62 -0
  22. data/lib/blobsterix/s3/s3_auth_v2_helper.rb +42 -0
  23. data/lib/blobsterix/s3/s3_auth_v2_query.rb +37 -0
  24. data/lib/blobsterix/s3/s3_auth_v4.rb +33 -0
  25. data/lib/blobsterix/s3/s3_url_helper.rb +1 -38
  26. data/lib/blobsterix/service.rb +3 -9
  27. data/lib/blobsterix/storage/bucket.rb +6 -3
  28. data/lib/blobsterix/storage/bucket_entry.rb +11 -1
  29. data/lib/blobsterix/storage/cache.rb +13 -21
  30. data/lib/blobsterix/storage/file_system.rb +37 -40
  31. data/lib/blobsterix/storage/storage.rb +2 -2
  32. data/lib/blobsterix/transformation/image_transformation.rb +134 -386
  33. data/lib/blobsterix/version.rb +1 -1
  34. data/lib/blobsterix.rb +22 -1
  35. data/spec/lib/helper/directory_list_spec.rb +51 -0
  36. data/spec/lib/s3/s3_api_spec.rb +27 -0
  37. data/spec/lib/s3/s3_auth_spec.rb +181 -0
  38. data/spec/lib/storage/file_system_spec.rb +14 -0
  39. data/spec/spec_helper.rb +1 -0
  40. data/templates/storage_template.rb +2 -2
  41. metadata +30 -2
@@ -0,0 +1,51 @@
1
+ require "spec_helper"
2
+
3
+ describe Blobsterix::DirectoryList do
4
+ include Blobsterix::SpecHelper
5
+
6
+ describe "list all" do
7
+ before :each do
8
+ 10.times do|id|
9
+ Blobsterix.cache.put_raw(Blobsterix::BlobAccess.new(:bucket => "test", :id => "#{id}"), "data")
10
+ end
11
+ end
12
+ after :each do
13
+ clear_cache
14
+ end
15
+ it "should give the same entries as glob" do
16
+ count = Dir.glob("#{Blobsterix.cache_dir}/**/*").select { |f| File.file?(f) && !f.to_s.match(/\.meta$/) }.length
17
+ Blobsterix::DirectoryList.each(Blobsterix.cache_dir) do |path, filename|
18
+ count-=1 if !filename.to_s.match(/\.meta$/)
19
+ end
20
+ count.should eql 0
21
+ end
22
+ it "should list all files in the directories" do
23
+ count = 0
24
+ Blobsterix.cache.delete(Blobsterix::BlobAccess.new(:bucket => "test", :id => "5"))
25
+ Blobsterix::DirectoryList.each(Blobsterix.cache_dir) do |path, filename|
26
+ count+=1 if !filename.to_s.match(/\.meta$/)
27
+ end
28
+ count.should eql(9)
29
+ end
30
+ it "should get the next entry" do
31
+ a = Blobsterix::DirectoryWalker.new(Blobsterix.cache_dir, :start_path => Blobsterix::DirectoryWalker.new(Blobsterix.cache_dir).next)
32
+ b = Blobsterix::DirectoryWalker.new(Blobsterix.cache_dir)
33
+ first = a.next
34
+ real_first = b.next
35
+ second = b.next
36
+ first.should eql(second)
37
+ first.should_not eql(real_first)
38
+ end
39
+ it "should just run shit" do
40
+ counter = 0
41
+ a = Blobsterix::DirectoryWalker.new(Blobsterix.cache_dir)
42
+ while a.next
43
+ counter += 1
44
+ end
45
+ Blobsterix::DirectoryList.each(Blobsterix.cache_dir) do |dir, file|
46
+ counter -= 1
47
+ end
48
+ counter.should eql(0)
49
+ end
50
+ end
51
+ end
@@ -109,6 +109,33 @@ describe Blobsterix::S3Api do
109
109
  end
110
110
  end
111
111
 
112
+ context "with two data objects" do
113
+ before :each do
114
+ Blobsterix.storage.put(bucket, key, StringIO.new(data, "r"))
115
+ Blobsterix.storage.put(bucket, "u#{key}", StringIO.new(data, "r"))
116
+ end
117
+
118
+ after :each do
119
+ clear_storage
120
+ end
121
+
122
+ describe 'list bucket truncated' do
123
+ it 'should return all files for the bucket starting at u#{key}' do
124
+ get "/#{bucket}", "", "params" => {"marker" => "u#{key}"}
125
+ expect(last_response.status).to eql(200)
126
+ response = Hash.from_xml last_response.body
127
+ expect(response).to have_key(:ListBucketResult)
128
+ expect(response[:ListBucketResult]).to have_key(:Name)
129
+ expect(response[:ListBucketResult][:Name]).to eql(bucket)
130
+ expect(response[:ListBucketResult][:Contents]).to_not be_empty
131
+ expect(response[:ListBucketResult][:Contents][:Key]).to eql(key)
132
+ expect(response[:ListBucketResult][:Contents][:MimeType]).to eql("text/plain")
133
+ expect(response[:ListBucketResult][:Contents][:Size]).to eql(data.length)
134
+ expect(response[:ListBucketResult][:Contents][:ETag]).to eql(Digest::MD5.hexdigest(data))
135
+ end
136
+ end
137
+ end
138
+
112
139
  context "with data" do
113
140
 
114
141
  before :each do
@@ -0,0 +1,181 @@
1
+ require "spec_helper"
2
+
3
+ describe Blobsterix::S3Auth do
4
+ include Blobsterix::SpecHelper
5
+ include Goliath::TestHelper
6
+
7
+ let(:v2_delete_file) {
8
+ {
9
+ :path=>"/profile_photo%2F1023066_1407492523",
10
+ :head => {
11
+ "host"=>"career.blob.localhost.local",
12
+ "date" => "Fri, 08 Aug 2014 10:09:03 +0000",
13
+ "authorization" => "AWS somethingIdid:LxTRXgW+E0SHU2xSkMI5Q62wKhU="
14
+ }
15
+ }
16
+ }
17
+
18
+ let(:v2_list_bucket) {
19
+ {
20
+ :path=>"/",
21
+ :head => {
22
+ "host"=>"johnsmith.s3.amazonaws.com",
23
+ "date" => "Tue, 27 Mar 2007 19:42:41 +0000",
24
+ "authorization" => "AWS AKIAIOSFODNN7EXAMPLE:htDYFYduRNen8P9ZfE/s9SuKy0U="
25
+ }
26
+ }
27
+ }
28
+
29
+ let(:v2_upload_photo) {
30
+ {
31
+ :path=>"/photos/puppy.jpg",
32
+ :head => {
33
+ "host"=>"johnsmith.s3.amazonaws.com",
34
+ "content-type" => "image/jpeg",
35
+ "date" => "Tue, 27 Mar 2007 21:15:45 +0000",
36
+ "authorization" => "AWS AKIAIOSFODNN7EXAMPLE:MyyxeRY7whkBe+bq8fHCL/2kKUg="
37
+ }
38
+ }
39
+ }
40
+
41
+ let(:v2_list_root_date) {
42
+ {
43
+ :path=>"/",
44
+ :head => {
45
+ "date" => "Wed, 28 Mar 2007 01:29:59 +0000",
46
+ "authorization" => "AWS AKIAIOSFODNN7EXAMPLE:qGdzdERIC03wnaRNKh6OqZehG9s="
47
+ }
48
+ }
49
+ }
50
+
51
+ let(:v2_list_root_amz_date) {
52
+ {
53
+ :path=>"/",
54
+ :head => {
55
+ "x-amz-date" => "Fri, 08 Aug 2014 10:28:22 +0000",
56
+ "authorization" => "AWS somethingIdid:CEyyoVY9bnq4Ujjgwwo5ozYXEfI="
57
+ }
58
+ }
59
+ }
60
+
61
+ let(:v2_query_download_file) {
62
+ {
63
+ :path=>"/photos/puppy.jpg",
64
+ :query=>"AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&Signature=NpgCjnDzrM%2BWFzoENXmpNDUsSn8%3D&Expires=1175139620",
65
+ :head => {
66
+ "host"=>"johnsmith.s3.amazonaws.com"
67
+ }
68
+ }
69
+ }
70
+
71
+ let(:v2_req_env) {
72
+ {
73
+ "HTTP_USER_AGENT"=>"fog/1.22.1",
74
+ "HTTP_PROXY_CONNECTION"=>"Keep-Alive",
75
+ "HTTP_DATE"=>"Fri, 08 Aug 2014 10:09:03 +0000",
76
+ "HTTP_AUTHORIZATION"=>"AWS somethingIdid:LxTRXgW+E0SHU2xSkMI5Q62wKhU=",
77
+ "HTTP_HOST"=>"career.blob.localhost.local:80",
78
+ "HTTP_TE"=>"trailers, deflate, gzip",
79
+ "HTTP_CONNECTION"=>"TE, close",
80
+ "CONTENT_LENGTH"=>"0",
81
+ "REQUEST_METHOD"=>"DELETE",
82
+ "REQUEST_URI"=>"http://career.blob.localhost.local:80/profile_photo%2F1023066_1407492523",
83
+ "QUERY_STRING"=>nil,
84
+ "HTTP_VERSION"=>"1.1",
85
+ "SCRIPT_NAME"=>"",
86
+ "REQUEST_PATH"=>"/profile_photo%2F1023066_1407492523",
87
+ "PATH_INFO"=>"/profile_photo%2F1023066_1407492523",
88
+ nil => {
89
+ :file => "profile_photo%2F1023066_1407492523"
90
+ }
91
+ }
92
+ }
93
+
94
+ let(:v4_req_env) {
95
+ {
96
+ "HTTP_USER_AGENT"=>"fog/1.22.1",
97
+ "HTTP_PROXY_CONNECTION"=>"Keep-Alive",
98
+ "HTTP_DATE"=>"Fri, 24 May 2013 00:00:00 GMT",
99
+ "HTTP_AUTHORIZATION"=>"AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;range;x-amz-content-sha256;x-amz-date,Signature=f0e8bdb87c964420e857bd35b5d6ed310bd44f0170aba48dd91039c6036bdb41",
100
+ "HTTP_HOST"=>"examplebucket.s3.amazonaws.com:80",
101
+ "HTTP_TE"=>"trailers, deflate, gzip",
102
+ "HTTP_CONNECTION"=>"TE, close",
103
+ "CONTENT_LENGTH"=>"0",
104
+ "REQUEST_METHOD"=>"GET",
105
+ "REQUEST_URI"=>"http://examplebucket.s3.amazonaws.com:80/test.txt",
106
+ "QUERY_STRING"=>nil,
107
+ "HTTP_VERSION"=>"1.1",
108
+ "SCRIPT_NAME"=>"",
109
+ "REQUEST_PATH"=>"/test.txt",
110
+ "PATH_INFO"=>"/test.txt",
111
+ "HTTP_RANGE" => "bytes=0-9",
112
+ "HTTP_X_AMZ_CONTENT_SHA256" => "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
113
+ "HTTP_X_AMZ_DATE" => "20130524T000000Z",
114
+ nil => {
115
+ :file => "test.txt"
116
+ }
117
+ }
118
+ }
119
+
120
+ before :all do
121
+ Blobsterix.secret_key_store = Blobsterix::S3Auth::KeyStore.new(
122
+ "AKIAIOSFODNN7EXAMPLE" => "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
123
+ "somethingIdid" => "somethingIdidInSecret"
124
+ )
125
+ end
126
+
127
+ after :all do
128
+ Blobsterix.secret_key_store = nil
129
+ end
130
+
131
+ def run_request(method, params, test, key)
132
+ with_api( Blobsterix::Service, :log_stdout => false) do |a|
133
+ Blobsterix.logger = a.logger
134
+ send(method, params) do |resp|
135
+ resp.response_header.status.should eql test
136
+ end
137
+ end
138
+ end
139
+
140
+ it "should work with aws v2 query" do
141
+ Blobsterix::S3Auth.current_time=lambda{Time.parse("Tue, 27 Mar 2007 21:15:45 +0000")}
142
+ run_request("put_request", v2_upload_photo, 200, "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY")
143
+ Blobsterix::S3Auth.current_time=lambda{Time.at(1175139610)}
144
+ run_request("get_request", v2_query_download_file, 200, "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY")
145
+ end
146
+
147
+ it "should work with aws v2" do
148
+ Blobsterix::S3Auth.current_time=lambda{Time.parse("Fri, 08 Aug 2014 10:28:22 +0000")}
149
+ run_request("get_request", v2_list_root_amz_date, 200, "somethingIdidInSecret")
150
+ Blobsterix::S3Auth.current_time=lambda{Time.parse("Wed, 28 Mar 2007 01:29:59 +0000")}
151
+ run_request("get_request", v2_list_root_date, 200, "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY")
152
+ Blobsterix::S3Auth.current_time=lambda{Time.parse("Tue, 27 Mar 2007 21:15:45 +0000")}
153
+ run_request("put_request", v2_upload_photo, 200, "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY")
154
+ Blobsterix::S3Auth.current_time=lambda{Time.parse("Tue, 27 Mar 2007 19:42:41 +0000")}
155
+ run_request("get_request", v2_list_bucket, 200, "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY")
156
+ Blobsterix::S3Auth.current_time=lambda{Time.parse("Fri, 08 Aug 2014 10:09:03 +0000")}
157
+ run_request("delete_request", v2_delete_file, 204, "somethingIdidInSecret")
158
+ end
159
+
160
+ it "should expire after 15 minutes" do
161
+ Blobsterix::S3Auth.current_time=lambda{Time.parse("Fri, 08 Aug 2014 10:28:22 +0000")+60*16}
162
+ run_request("get_request", v2_list_root_amz_date, 401, "somethingIdidInSecret")
163
+ end
164
+
165
+ it "should expire query when expire time is passed" do
166
+ Blobsterix::S3Auth.current_time=lambda{Time.parse("Tue, 27 Mar 2007 21:15:45 +0000")}
167
+ run_request("put_request", v2_upload_photo, 200, "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY")
168
+ Blobsterix::S3Auth.current_time=lambda{Time.at(1175139621)}
169
+ run_request("get_request", v2_query_download_file, 401, "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY")
170
+ end
171
+
172
+ it "should at least recognize aws v4" do
173
+ auth = Blobsterix::S3Auth.authenticate(v4_req_env)
174
+ auth.class.should eql Blobsterix::S3Auth::V4
175
+ end
176
+
177
+ it "should at least recognize aws v2" do
178
+ auth = Blobsterix::S3Auth.authenticate(v2_req_env)
179
+ auth.class.should eql Blobsterix::S3Auth::V2
180
+ end
181
+ end
@@ -43,6 +43,20 @@ describe Blobsterix::Storage::FileSystem do
43
43
  expect(response[:Error]).to eql("no such bucket")
44
44
  end
45
45
 
46
+ it "should not destroy bucket when files still exist" do
47
+ Blobsterix.storage.create(bucket)
48
+ Blobsterix.storage.put(bucket, key, StringIO.new(data, "r"))
49
+ response = Hash.from_xml Blobsterix.storage.list(bucket).to_xml
50
+ expect(response).to have_key(:ListBucketResult)
51
+ expect(response[:ListBucketResult]).to have_key(:Name)
52
+ expect(response[:ListBucketResult][:Name]).to eql(bucket)
53
+
54
+ Blobsterix.storage.delete(bucket)
55
+ response = Hash.from_xml Blobsterix.storage.list(bucket).to_xml
56
+ expect(response).to_not have_key(:Error)
57
+ expect(response[:Error]).to_not eql("no such bucket")
58
+ end
59
+
46
60
  it "should return the key info if it exists when listing bucket" do
47
61
  Blobsterix.storage.put(bucket, key, StringIO.new(data, "r"))
48
62
  response = Hash.from_xml Blobsterix.storage.list(bucket).to_xml
data/spec/spec_helper.rb CHANGED
@@ -9,6 +9,7 @@ Bundler.setup
9
9
  Bundler.require
10
10
 
11
11
  require 'rack/test'
12
+ require 'log4r'
12
13
  require 'goliath/test_helper'
13
14
 
14
15
  Blobsterix.storage_dir=Blobsterix.root.join("tmp/contents")
@@ -1,7 +1,7 @@
1
1
  module Blobsterix
2
2
  module Storage
3
3
  class $ClassNameStorage < Storage
4
- def list(bucket="root")
4
+ def list(bucket="root", opts={})
5
5
  Nokogiri::XML::Builder.new do |xml|
6
6
  xml.Error "no such bucket"
7
7
  end
@@ -12,7 +12,7 @@ module Blobsterix
12
12
  def get(bucket, key)
13
13
  Blobsterix::Storage::BlobMetaData.new
14
14
  end
15
- def put(bucket, key, value)
15
+ def put(bucket, key, value, opts={})
16
16
  Blobsterix::Storage::BlobMetaData.new
17
17
  end
18
18
  def create(bucket)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blobsterix
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.14
4
+ version: 0.0.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Sudmann
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-01 00:00:00.000000000 Z
11
+ date: 2014-08-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - ~>
95
95
  - !ruby/object:Gem::Version
96
96
  version: 3.5.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: log4r
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: rake
99
113
  requirement: !ruby/object:Gem::Requirement
@@ -221,16 +235,26 @@ files:
221
235
  - lib/blobsterix/helper/blob_access.rb
222
236
  - lib/blobsterix/helper/config_loader.rb
223
237
  - lib/blobsterix/helper/data_response.rb
238
+ - lib/blobsterix/helper/directory_list.rb
224
239
  - lib/blobsterix/helper/http.rb
240
+ - lib/blobsterix/helper/jsonizer.rb
225
241
  - lib/blobsterix/helper/logable.rb
226
242
  - lib/blobsterix/helper/murmur.rb
243
+ - lib/blobsterix/helper/simple_proxy.rb
227
244
  - lib/blobsterix/helper/status_info.rb
228
245
  - lib/blobsterix/helper/template_renderer.rb
246
+ - lib/blobsterix/helper/url_helper.rb
229
247
  - lib/blobsterix/mimemagic/magic.rb
230
248
  - lib/blobsterix/mimemagic/tables.rb
231
249
  - lib/blobsterix/mimemagic/version.rb
232
250
  - lib/blobsterix/router/app_router.rb
233
251
  - lib/blobsterix/s3/s3_api.rb
252
+ - lib/blobsterix/s3/s3_auth.rb
253
+ - lib/blobsterix/s3/s3_auth_key_store.rb
254
+ - lib/blobsterix/s3/s3_auth_v2.rb
255
+ - lib/blobsterix/s3/s3_auth_v2_helper.rb
256
+ - lib/blobsterix/s3/s3_auth_v2_query.rb
257
+ - lib/blobsterix/s3/s3_auth_v4.rb
234
258
  - lib/blobsterix/s3/s3_url_helper.rb
235
259
  - lib/blobsterix/service.rb
236
260
  - lib/blobsterix/status/status_api.rb
@@ -253,7 +277,9 @@ files:
253
277
  - spec/lib/blob/blob_api_spec.rb
254
278
  - spec/lib/blobsterix_spec.rb
255
279
  - spec/lib/helper/blob_access_spec.rb
280
+ - spec/lib/helper/directory_list_spec.rb
256
281
  - spec/lib/s3/s3_api_spec.rb
282
+ - spec/lib/s3/s3_auth_spec.rb
257
283
  - spec/lib/service_spec.rb
258
284
  - spec/lib/status/status_api_spec.rb
259
285
  - spec/lib/storage/cache_spec.rb
@@ -299,7 +325,9 @@ test_files:
299
325
  - spec/lib/blob/blob_api_spec.rb
300
326
  - spec/lib/blobsterix_spec.rb
301
327
  - spec/lib/helper/blob_access_spec.rb
328
+ - spec/lib/helper/directory_list_spec.rb
302
329
  - spec/lib/s3/s3_api_spec.rb
330
+ - spec/lib/s3/s3_auth_spec.rb
303
331
  - spec/lib/service_spec.rb
304
332
  - spec/lib/status/status_api_spec.rb
305
333
  - spec/lib/storage/cache_spec.rb