blobsterix 0.0.14 → 0.0.19

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.
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