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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f481ca0770aed1210888cb8be44b046d78d42e8d
4
- data.tar.gz: 2f68e7ca5f0a995c31bc3770a769a843144de8b0
3
+ metadata.gz: 552f0bd886f26d55598a1d70c64c3d67ccf0e283
4
+ data.tar.gz: c2442bc068866a0bcc44b2f3eb78c4b3be012b27
5
5
  SHA512:
6
- metadata.gz: 712bc1e5ca1c13f41703d630cc9bfbe9f0d9641bc9bb13a8d83bf41e3e6fd1d33103f0f35641d092e4bfdf81ffe85ca0bb1160b4c90861fdc144e84e72b8c556
7
- data.tar.gz: 402a885f0c1f8676eea6d5c5dcb754e0e202e754b462cf63057259b99765c83fb49bc2073ed6b592c51a023043ffb4ed4238049bbbcfb8d9b2ab5b70bc1858c9
6
+ metadata.gz: 6edb548afa51c035dadbeb90b756e246b6662f6c1f16fad9730979423408cac1b176c610498acefc596919fd02ce763e8ba1360762429e33b9b8d7ce455b447d
7
+ data.tar.gz: 5b9b46c8f65293fb56057d244247dbc2d5c28f47358326e9587fa277549ada89051b761512a400ef90f3d14828649a0d91ab5a14fb69b26b56bc357ba2f8fbbb
data/CHANGELOG.txt CHANGED
@@ -1,3 +1,12 @@
1
+ = 0.0.19
2
+ * s3 requests expire as expected
3
+ = 0.0.18
4
+ * added s3 authentification
5
+ = 0.0.17
6
+ * updated directory listing, truncated listing of 100 files each
7
+ * made the invalidation object a proxy that is only called when accessed
8
+ = 0.0.15
9
+ * changed the way directories are listed to allow direct traversal.
1
10
  = 0.0.14
2
11
  * now files are streamed instead of read internally
3
12
  * storages now require IO streams on put
data/README.md CHANGED
@@ -78,7 +78,11 @@ Check the amazon s3 specs for more information. It only supports the REST api wi
78
78
  * put file into bucket
79
79
  * delete file from bucket
80
80
 
81
- The s3 interface itself is unsecured and should not be visible to the outside.
81
+ The s3 interface can be secured with a key value pair just like the AmazonS3 store:
82
+
83
+ * Blobsterix.secret_key_store = Blobsterix::S3Auth::KeyStore.new("myID" => "myVerySecretKey")
84
+
85
+ You can also create your own key store. The only method it needs to implement is the get_key(ID) method. Simply check the example implementation.
82
86
 
83
87
  ## Blob interface
84
88
 
data/blobsterix.gemspec CHANGED
@@ -30,6 +30,7 @@ Gem::Specification.new do |gem|
30
30
  gem.add_dependency "nokogiri", "~> 1.6.1"
31
31
  gem.add_dependency "ruby-webp", "~> 0.1.0"
32
32
  gem.add_dependency "mini_magick", "~> 3.5.0"
33
+ gem.add_dependency "log4r"
33
34
 
34
35
  gem.add_development_dependency "rake","~> 0.9.6"
35
36
  gem.add_development_dependency "rspec", "~> 2.14.0"
@@ -1,6 +1,7 @@
1
1
  module Blobsterix
2
2
  class BlobApi < AppRouterBase
3
3
  include BlobUrlHelper
4
+ include UrlHelper
4
5
 
5
6
  get "/blob/v1", :not_allowed
6
7
  get "/blob", :not_allowed
@@ -1,10 +1,6 @@
1
1
  module Blobsterix
2
2
  module BlobUrlHelper
3
-
4
- def favicon
5
- @favicon ||= file.match /favicon/
6
- end
7
-
3
+
8
4
  def bucket
9
5
  if (env[nil] && env[nil][:bucket])
10
6
  env[nil][:bucket]
@@ -15,40 +11,7 @@ module Blobsterix
15
11
  end
16
12
  end
17
13
 
18
- def format
19
- @format ||= env[nil][:format]
20
- end
21
-
22
- def included_bucket
23
- if env[nil][:bucket_or_file] && env[nil][:bucket_or_file].include?("/")
24
- env[nil][:bucket] = env[nil][:bucket_or_file].split("/")[0]
25
- env[nil][:bucket_or_file] = env[nil][:bucket_or_file].gsub("#{env[nil][:bucket]}/", "")
26
- true
27
- else
28
- false
29
- end
30
- end
31
-
32
- def file
33
- if format
34
- [env[nil][:file] || env[nil][:bucket_or_file] || "", format].join(".")
35
- else
36
- env[nil][:file] || env[nil][:bucket_or_file] || ""
37
- end
38
- end
39
-
40
- #TransformationCommand
41
- def trafo(trafo_s='')
42
- trafo_a = []
43
- trafo_s.split(",").each{|command|
44
- parts = command.split("_")
45
- key = parts.delete_at(0)
46
- trafo_a << [key, parts.join("_")]
47
- }
48
- trafo_a
49
- end
50
-
51
- def transformation_string()
14
+ def transformation_string
52
15
  (env["params"] && env["params"]["trafo"]) || env[nil][:trafo] || ""
53
16
  end
54
17
  end
@@ -41,18 +41,10 @@ module Blobsterix
41
41
  if trafo.empty? || raw_trafo?
42
42
  metaData = Blobsterix.storage.get(self.bucket, self.id)
43
43
  if raw_trafo? || raw_accept_type?(metaData.accept_type)
44
- # puts "Load from storage"
45
- return metaData unless Blobsterix.cache_original?
46
- Blobsterix.cache.put_raw(BlobAccess.new(:bucket => bucket, :id => id), metaData.data) if metaData.valid?
47
- return Blobsterix.cache.get(BlobAccess.new(:bucket => bucket, :id => id)) if metaData.valid?
48
- else
49
- # puts "accept type doesn't work"
44
+ load_from_storage(metaData)
50
45
  end
51
- else
52
- # puts "trafo is not raw"
53
46
  end
54
- end
55
- Blobsterix.cache.get(self)
47
+ end || Blobsterix.cache.get(self)
56
48
  end
57
49
 
58
50
  def raw_trafo?
@@ -63,6 +55,13 @@ module Blobsterix
63
55
  @raw_accept_type||= (!accept_type || accept_type.equal?(other))
64
56
  end
65
57
 
58
+ def load_from_storage(metaData)
59
+ return metaData unless Blobsterix.cache_original?
60
+ Blobsterix.cache.put_raw(BlobAccess.new(:bucket => bucket, :id => id), metaData.data) if metaData.valid?
61
+ return Blobsterix.cache.get(BlobAccess.new(:bucket => bucket, :id => id)) if metaData.valid?
62
+ nil
63
+ end
64
+
66
65
 
67
66
  def subtype
68
67
  accept_type ? accept_type.subtype : ""
@@ -10,24 +10,16 @@ module Blobsterix
10
10
  require Blobsterix.root.join("config.rb") if (File.exist?(Blobsterix.root.join("config.rb")))
11
11
  end
12
12
 
13
- def require_transformators()
14
- trafo_dir = Blobsterix.root.join("transformators")
15
- return if not File.exist?(trafo_dir)
16
- Dir.entries(trafo_dir).each{|dir|
17
- if !File.directory? File.join(trafo_dir,dir) and !(dir =='.' || dir == '..')
18
- require "#{File.join(trafo_dir,dir)}"
19
- end
20
- }
21
- end
22
-
23
- def require_storages()
24
- storages_dir = Blobsterix.root.join("storages")
25
- return if not File.exist?(storages_dir)
26
- Dir.entries(storages_dir).each{|dir|
27
- if !File.directory? File.join(storages_dir,dir) and !(dir =='.' || dir == '..')
28
- require "#{File.join(storages_dir,dir)}"
29
- end
30
- }
13
+ ["transformators", "storages"].each do |name|
14
+ define_method "require_#{name}".to_sym do
15
+ load_dir = Blobsterix.root.join(name)
16
+ return if not File.exist?(load_dir)
17
+ Dir.entries(load_dir).each{|dir|
18
+ if !File.directory? File.join(load_dir,dir) and !(dir =='.' || dir == '..')
19
+ require "#{File.join(load_dir,dir)}"
20
+ end
21
+ }
22
+ end
31
23
  end
32
24
  end
33
25
  end
@@ -0,0 +1,131 @@
1
+ module Blobsterix
2
+ class DirectoryWalker
3
+ attr_accessor :path, :child_walker, :child_index
4
+
5
+ def initialize(base_path, opts = {})
6
+ @current_id = 0
7
+ @child_walker = nil
8
+ @path = Pathname.new base_path
9
+ @child_index = opts[:child_index]
10
+ init_path(opts[:start_path]) if opts[:start_path]
11
+ end
12
+
13
+ def init_path(start_path)
14
+ @start = Pathname.new(start_path)
15
+ myentry = path_root(@start)
16
+
17
+ entries.each_with_index do |entry,index|
18
+ @current_id=index+1 if myentry.to_s == entry.to_s
19
+ end
20
+
21
+ set_childwalker(path.join(myentry), current_id-1, @start.relative_path_from(myentry)) if path.join(myentry).directory?
22
+ end
23
+
24
+ def next
25
+ out = nil
26
+ begin
27
+ return current if @child_walker && @child_walker.next
28
+ return nil unless increment_id
29
+ out = current
30
+ end while out == nil
31
+ out
32
+ end
33
+
34
+ def entries
35
+ @entries ||= Dir.entries(path).sort
36
+ end
37
+
38
+ def current_entry
39
+ entries[@current_id-1]
40
+ end
41
+
42
+ def current_id
43
+ return @current_id if @current_id > 0
44
+ increment_id
45
+ end
46
+
47
+ def increment_id
48
+ begin
49
+ return nil if @current_id+1 > entries.size
50
+ @current_id+=1
51
+ end while (current_entry == "." || current_entry == "..")
52
+ @current_id
53
+ end
54
+
55
+ def current_path
56
+ current_(
57
+ lambda{|walker|walker.current_path},
58
+ lambda{|walker|walker.current_path},
59
+ lambda{|new_path|path}
60
+ )
61
+ end
62
+
63
+ def current_file
64
+ current_(
65
+ lambda{|walker|walker.current_file},
66
+ lambda{|walker|walker.current_file},
67
+ lambda{|new_path|entries[current_id-1]}
68
+ )
69
+ end
70
+
71
+ def current
72
+ current_(
73
+ lambda{|walker|walker.current},
74
+ lambda{|walker|walker.next},
75
+ lambda{|new_path|new_path}
76
+ )
77
+ end
78
+
79
+ private
80
+ def set_childwalker(path_, index_=nil, start_path_=nil)
81
+ options = {}
82
+ options[:child_index] = index_ if index_
83
+ options[:start_path] = start_path_ if start_path_
84
+ @child_walker = DirectoryWalker.new(path_, options)
85
+ end
86
+
87
+ def path_root(path_)
88
+ myentry = nil
89
+ path_.descend do |entry|
90
+ myentry = entry
91
+ break
92
+ end
93
+ myentry
94
+ end
95
+
96
+ def current_(on_valid, on_new, on_file)
97
+ return nil unless current_id
98
+ return on_valid.call(@child_walker) if valid_childwalker?
99
+
100
+ new_path = path.join(entries[current_id-1])
101
+ if new_path.directory?
102
+ @child_walker = DirectoryWalker.new(new_path, :child_index => current_id-1)
103
+ on_new.call(@child_walker)
104
+ else
105
+ on_file.call(new_path)
106
+ end
107
+ end
108
+
109
+ def valid_childwalker?
110
+ @child_walker && @child_walker.child_index == current_id-1
111
+ end
112
+ end
113
+ class DirectoryList
114
+ def self.each_limit(path, opts={})
115
+ used = 0
116
+ limit = opts[:limit]||0
117
+ start_path = opts[:start_path]||nil
118
+ a = DirectoryWalker.new(path, :start_path => start_path)
119
+ while (!limit || used < limit) && a.next
120
+ used +=1 if yield a.current_path, a.current_file
121
+ end
122
+ a
123
+ end
124
+ def self.each(path)
125
+ a = DirectoryWalker.new(path)
126
+ while a.next
127
+ yield a.current_path, a.current_file
128
+ end
129
+ end
130
+ end
131
+ end
@@ -1,7 +1,7 @@
1
1
  module Blobsterix
2
2
  module Http
3
3
  def self.renderer
4
- @@renderer||=(Blobsterix.respond_to?(:env) && Blobsterix.env == :production) ? TemplateRenderer.new(binding) : ReloadTemplateRenderer.new(binding)
4
+ @@renderer||=TemplateRenderer.create(binding)
5
5
  end
6
6
  def self.error_object_binding(obj)
7
7
  obj||={}
@@ -19,23 +19,22 @@ module Blobsterix
19
19
  end
20
20
  obj.get_binding
21
21
  end
22
- def self.NextApi(data="Not Found", content_type="txt")
23
- [600, {"Content-Type" => MimeMagic.by_extension(content_type).type}, data]
24
- end
25
- def self.NotFound(data="Not Found", content_type="html")
26
- [404, {"Content-Type" => MimeMagic.by_extension(content_type).type}, renderer.render("error_page", error_object_binding(:title=>"Not Found", :content=>data, :error_code => 404))]
27
- end
28
- def self.ServerError(data="Server Error", content_type="html")
29
- [500, {"Content-Type" => MimeMagic.by_extension(content_type).type}, renderer.render("error_page", error_object_binding(:title=>"Server Error", :content=>data, :error_code => 500))]
22
+
23
+ def self.error_massages
24
+ @error_massages||={"Not Found" => 404, "Server Error" => 500, "Not Allowed" => 403, "Not Authorized" => 401}
30
25
  end
31
- def self.NotAllowed(data="Not Allowed", content_type="html")
32
- [403, {"Content-Type" => MimeMagic.by_extension(content_type).type}, renderer.render("error_page", error_object_binding(:title=>"Not Allowed", :content=>data, :error_code => 403))]
26
+
27
+ error_massages.each do |error_name, error_code|
28
+ define_singleton_method error_name.gsub(" ", "").to_sym do |data=error_name, content_type="html"|
29
+ Response(error_code, renderer.render("error_page", error_object_binding(:title=>error_name, :content=>data, :error_code => 404)), content_type)
30
+ end
33
31
  end
34
- def self.NotAuthorized(data="Not Authorized", content_type="html")
35
- [401, {"Content-Type" => MimeMagic.by_extension(content_type).type}, renderer.render("error_page", error_object_binding(:title=>"Not Authorized", :content=>data, :error_code => 401))]
32
+
33
+ def self.NextApi(data="Not Found", content_type="txt")
34
+ Response(600, data, content_type)
36
35
  end
37
36
  def self.OK(data="", content_type="txt")
38
- [200, {"Content-Type" => MimeMagic.by_extension(content_type).type}, data]
37
+ Response(200, data, content_type)
39
38
  end
40
39
  def self.Response(status_code=200, data="", content_type="txt")
41
40
  [status_code, {"Content-Type" => MimeMagic.by_extension(content_type).type}, data]
@@ -0,0 +1,45 @@
1
+ module Blobsterix
2
+ module Jsonizer
3
+ def json_var(*var_names)
4
+ @json_vars = (@json_vars||[])+var_names.flatten
5
+ end
6
+
7
+ def json_vars
8
+ @json_vars||= []
9
+ end
10
+
11
+ module Methods
12
+ def render_json(obj=nil)
13
+ Http.OK (obj||self).to_json, "json"
14
+ end
15
+
16
+ def render_xml(obj=nil)
17
+ obj = Nokogiri::XML::Builder.new do |xml|
18
+ yield xml
19
+ end if block_given?
20
+ Http.OK (obj||self).to_xml, "xml"
21
+ end
22
+
23
+ def to_json
24
+ stuff = Hash.new
25
+ self.class.json_vars.each{|var_name|
26
+ stuff[var_name.to_sym]=send(var_name) if respond_to?(var_name)
27
+ }
28
+ stuff.to_json
29
+ end
30
+
31
+ def to_xml()
32
+ xml = Nokogiri::XML::Builder.new do |xml|
33
+ xml.BlobsterixStatus() {
34
+ self.class.json_vars.each{|var_name|
35
+ var = send(var_name)
36
+ var = var.to_xml if var.respond_to?(:to_xml)
37
+ xml.send(var_name, var) if respond_to?(var_name)
38
+ }
39
+ }
40
+ end
41
+ xml.to_xml
42
+ end
43
+ end
44
+ end
45
+ end
@@ -1,4 +1,24 @@
1
1
  module Blobsterix
2
+
3
+ class BlobsterixLogger
4
+ def initialize logger, req_id
5
+ @logger=logger
6
+ @req_id=req_id
7
+ end
8
+ def info msg
9
+ @logger.info "[#{@req_id}] -> #{msg}"
10
+ end
11
+ def warn msg
12
+ @logger.warn "[#{@req_id}] -> #{msg}"
13
+ end
14
+ def error msg
15
+ @logger.error "[#{@req_id}] -> #{msg}"
16
+ end
17
+ def debug msg
18
+ @logger.debug "[#{@req_id}] -> #{msg}"
19
+ end
20
+ end
21
+
2
22
  module Logable
3
23
  def logger
4
24
  @logger ||= Blobsterix.logger
@@ -7,5 +27,10 @@ module Blobsterix
7
27
  def logger=(_logger)
8
28
  @logger=_logger
9
29
  end
30
+
31
+ def self.next_id
32
+ @req_id ||= 0
33
+ @req_id+=1
34
+ end
10
35
  end
11
36
  end
@@ -134,4 +134,18 @@ class Murmur
134
134
 
135
135
  h
136
136
  end
137
+
138
+ def self.map_filename(filename, *additional)
139
+ hash = Murmur.Hash64B(filename)
140
+ bits = hash.to_s(2)
141
+ parts = []
142
+ 6.times { |index|
143
+ len = 11
144
+ len = bits.length if len >= bits.length
145
+ value = bits.slice!(0, len).to_i(2).to_s(16).rjust(3,"0")
146
+ parts.push(value)
147
+ }
148
+ parts = parts+additional
149
+ parts.join("/")
150
+ end
137
151
  end
@@ -0,0 +1,11 @@
1
+ module Blobsterix
2
+ class SimpleProxy
3
+ def initialize(init_proc)
4
+ @init_proc = init_proc
5
+ end
6
+ def method_missing(meth, *args, &block)
7
+ @proc||=@init_proc.call
8
+ @proc.send(meth, *args, &block)
9
+ end
10
+ end
11
+ end
@@ -10,6 +10,10 @@ module Blobsterix
10
10
  end
11
11
 
12
12
  class TemplateRenderer
13
+ def self.create(binding_)
14
+ (Blobsterix.respond_to?(:env) && Blobsterix.env == :production) ? TemplateRenderer.new(binding_) : ReloadTemplateRenderer.new(binding_)
15
+ end
16
+
13
17
  def initialize(controller_binding_)
14
18
  @controller_binding=controller_binding_
15
19
  end
@@ -0,0 +1,41 @@
1
+ module Blobsterix
2
+ module UrlHelper
3
+
4
+ def favicon
5
+ @favicon ||= file.match /favicon/
6
+ end
7
+
8
+ #TransformationCommand
9
+ def trafo(trafo_s='')
10
+ trafo_a = []
11
+ trafo_s.split(",").each{|command|
12
+ parts = command.split("_")
13
+ key = parts.delete_at(0)
14
+ trafo_a << [key, parts.join("_")]
15
+ }
16
+ trafo_a
17
+ end
18
+
19
+ def file
20
+ if format
21
+ [env[nil][:file] || env[nil][:bucket_or_file] || "", format].join(".")
22
+ else
23
+ env[nil][:file] || env[nil][:bucket_or_file] || ""
24
+ end
25
+ end
26
+
27
+ def included_bucket
28
+ if env[nil][:bucket_or_file] && env[nil][:bucket_or_file].include?("/")
29
+ env[nil][:bucket] = env[nil][:bucket_or_file].split("/")[0]
30
+ env[nil][:bucket_or_file] = env[nil][:bucket_or_file].gsub("#{env[nil][:bucket]}/", "")
31
+ true
32
+ else
33
+ false
34
+ end
35
+ end
36
+
37
+ def format
38
+ @format ||= env[nil][:format]
39
+ end
40
+ end
41
+ end
@@ -1,25 +1,14 @@
1
1
  module Blobsterix
2
- module Jsonizer
3
- def json_var(*var_names)
4
- @json_vars = (@json_vars||[])+var_names.flatten
5
- end
6
-
7
- def json_vars
8
- @json_vars||= []
9
- end
10
- end
11
-
12
2
  class AppRouterBase
13
3
 
14
4
  extend Jsonizer
5
+ include Jsonizer::Methods
15
6
  include Logable
16
7
 
17
- #attr_reader :logger
18
8
  attr_accessor :env
19
9
 
20
10
  def initialize(env)
21
11
  @env = env
22
- #@logger = env["rack.logger"]
23
12
  end
24
13
 
25
14
  def storage
@@ -39,7 +28,7 @@ module Blobsterix
39
28
  end
40
29
 
41
30
  def renderer
42
- @@renderer||=(Blobsterix.respond_to?(:env) && Blobsterix.env == :production) ? TemplateRenderer.new(binding) : ReloadTemplateRenderer.new(binding)
31
+ @@renderer||=TemplateRenderer.create(binding)
43
32
  end
44
33
 
45
34
  def render(template_name, status_code=200, bind=nil)
@@ -50,74 +39,35 @@ module Blobsterix
50
39
  end
51
40
  end
52
41
 
53
- def render_json(obj=nil)
54
- Http.OK (obj||self).to_json, "json"
55
- end
56
-
57
- def render_xml(obj=nil)
58
- obj = Nokogiri::XML::Builder.new do |xml|
59
- yield xml
60
- end if block_given?
61
- Http.OK (obj||self).to_xml, "xml"
62
- end
63
-
64
- def to_json
65
- stuff = Hash.new
66
- self.class.json_vars.each{|var_name|
67
- stuff[var_name.to_sym]=send(var_name) if respond_to?(var_name)
68
- }
69
- stuff.to_json
70
- end
71
- def to_xml()
72
- xml = Nokogiri::XML::Builder.new do |xml|
73
- xml.BlobsterixStatus() {
74
- self.class.json_vars.each{|var_name|
75
- var = send(var_name)
76
- var = var.to_xml if var.respond_to?(:to_xml)
77
- xml.send(var_name, var) if respond_to?(var_name)
78
- }
79
- }
80
- end
81
- xml.to_xml
82
- end
83
-
84
42
  def self.options(opt)
85
43
  opt = {:function => opt.to_sym} if opt.class != Hash
86
44
  {:controller => self.name, :function => :call}.merge(opt)
87
45
  end
88
46
 
89
- def self.get(path, opt = {})
90
- path = Journey::Path::Pattern.new path
91
- router.routes.add_route(lambda{|env| call_controller(options(opt), env)}, path, {:request_method => "GET"}, {})
92
- end
93
-
94
- def self.post(path, opt = {})
95
- path = Journey::Path::Pattern.new path
96
- router.routes.add_route(lambda{|env| call_controller(options(opt), env)}, path, {:request_method => "POST"}, {})
97
- end
98
-
99
- def self.put(path, opt = {})
100
- path = Journey::Path::Pattern.new path
101
- router.routes.add_route(lambda{|env| call_controller(options(opt), env)}, path, {:request_method => "PUT"}, {})
47
+ def self.http_verbs
48
+ @http_verbs||=["GET", "POST", "PUT", "DELETE", "HEAD"]
102
49
  end
103
50
 
104
- def self.delete(path, opt = {})
105
- path = Journey::Path::Pattern.new path
106
- router.routes.add_route(lambda{|env| call_controller(options(opt), env)}, path, {:request_method => "DELETE"}, {})
107
- end
108
-
109
- def self.head(path, opt = {})
110
- path = Journey::Path::Pattern.new path
111
- router.routes.add_route(lambda{|env| call_controller(options(opt), env)}, path, {:request_method => "HEAD"}, {})
51
+ http_verbs.each do |method|
52
+ define_singleton_method method.downcase.to_sym do |path, opt = {}|
53
+ path = Journey::Path::Pattern.new path
54
+ router.routes.add_route(lambda{|env| call_controller(options(opt), env)}, path, {:request_method => method}, {})
55
+ end
112
56
  end
113
57
 
114
58
  def self.call(env)
115
59
  Blobsterix::StatusInfo.connections+=1
60
+ print_ram_usage("RAM USAGE Before")
116
61
  result=router.call(env)
62
+ print_ram_usage("RAM USAGE After")
117
63
  Blobsterix::StatusInfo.connections-=1
118
64
  result
119
65
  end
120
66
 
67
+ def self.print_ram_usage(text)
68
+ Blobsterix.logger.info "#{text}[#{Process.pid}]: " + `pmap #{Process.pid} | tail -1`[10,40].strip
69
+ end
70
+
121
71
  def self.call_controller(options, env)
122
72
  options[:controller].respond_to?(options[:function]) ? options[:controller].send(options[:function], env) : Blobsterix.const_get(options[:controller]).new(env).send(options[:function])
123
73
  end