knjappserver 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +18 -0
  4. data/Gemfile.lock +39 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.rdoc +19 -0
  7. data/Rakefile +49 -0
  8. data/VERSION +1 -0
  9. data/bin/check_running.rb +71 -0
  10. data/bin/knjappserver_start.rb +50 -0
  11. data/knjappserver.gemspec +107 -0
  12. data/lib/conf/README +1 -0
  13. data/lib/conf/conf_example.rb +109 -0
  14. data/lib/conf/conf_vars_example.rb +3 -0
  15. data/lib/files/database_schema.rb +111 -0
  16. data/lib/files/run/README +1 -0
  17. data/lib/include/class_customio.rb +21 -0
  18. data/lib/include/class_erbhandler.rb +36 -0
  19. data/lib/include/class_httpresp.rb +91 -0
  20. data/lib/include/class_httpserver.rb +91 -0
  21. data/lib/include/class_httpsession.rb +350 -0
  22. data/lib/include/class_httpsession_knjengine.rb +189 -0
  23. data/lib/include/class_httpsession_mongrel.rb +75 -0
  24. data/lib/include/class_httpsession_webrick.rb +75 -0
  25. data/lib/include/class_knjappserver.rb +455 -0
  26. data/lib/include/class_knjappserver_cleaner.rb +109 -0
  27. data/lib/include/class_knjappserver_errors.rb +117 -0
  28. data/lib/include/class_knjappserver_logging.rb +272 -0
  29. data/lib/include/class_knjappserver_mailing.rb +97 -0
  30. data/lib/include/class_knjappserver_threadding.rb +87 -0
  31. data/lib/include/class_knjappserver_web.rb +23 -0
  32. data/lib/include/class_log.rb +81 -0
  33. data/lib/include/class_log_access.rb +103 -0
  34. data/lib/include/class_log_data.rb +42 -0
  35. data/lib/include/class_log_data_link.rb +16 -0
  36. data/lib/include/class_log_data_value.rb +34 -0
  37. data/lib/include/class_log_link.rb +51 -0
  38. data/lib/include/class_session.rb +43 -0
  39. data/lib/include/gettext_funcs.rb +10 -0
  40. data/lib/include/magic_methods.rb +59 -0
  41. data/lib/knjappserver.rb +1 -0
  42. data/lib/pages/logs_latest.rhtml +57 -0
  43. data/lib/pages/logs_show.rhtml +32 -0
  44. data/lib/pages/spec.rhtml +10 -0
  45. data/spec/knjappserver_spec.rb +110 -0
  46. data/spec/spec_helper.rb +12 -0
  47. metadata +188 -0
@@ -0,0 +1,16 @@
1
+ class Knjappserver::Log_data_link < Knj::Datarow
2
+ def self.list(d)
3
+ sql = "SELECT * FROM #{table} WHERE 1=1"
4
+
5
+ ret = list_helper(d)
6
+ d.args.each do |key, val|
7
+ raise "Invalid key: #{key}."
8
+ end
9
+
10
+ sql += ret[:sql_where]
11
+ sql += ret[:sql_order]
12
+ sql += ret[:sql_limit]
13
+
14
+ return d.ob.list_bysql(:Log_data_link, sql)
15
+ end
16
+ end
@@ -0,0 +1,34 @@
1
+ class Knjappserver::Log_data_value < Knj::Datarow
2
+ def self.list(d)
3
+ sql = "SELECT * FROM #{table} WHERE 1=1"
4
+
5
+ ret = list_helper(d)
6
+ d.args.each do |key, val|
7
+ raise "Invalid key: #{key}."
8
+ end
9
+
10
+ sql += ret[:sql_where]
11
+ sql += ret[:sql_order]
12
+ sql += ret[:sql_limit]
13
+
14
+ return d.ob.list_bysql(:Log_data_value, sql)
15
+ end
16
+
17
+ def self.force(d, value)
18
+ value_obj = d.ob.get_by(:Log_data_value, {
19
+ "value" => value.to_s
20
+ })
21
+
22
+ if !value_obj
23
+ value_obj = d.ob.add(:Log_data_value, {"value" => value})
24
+ end
25
+
26
+ return value_obj
27
+ end
28
+
29
+ def self.force_id(d, value)
30
+ value_obj = d.db.query("SELECT * FROM Log_data_value WHERE value = '#{d.db.esc(value)}' LIMIT 1").fetch
31
+ return value_obj[:id].to_i if value_obj
32
+ return d.db.insert(:Log_data_value, {:value => value}, {:return_id => true}).to_i
33
+ end
34
+ end
@@ -0,0 +1,51 @@
1
+ class Knjappserver::Log_link < Knj::Datarow
2
+ has_one [
3
+ {:class => :Log, :col => :log_id}
4
+ ]
5
+
6
+ def self.list(d)
7
+ sql = "SELECT * FROM #{table} WHERE 1=1"
8
+
9
+ ret = list_helper(d)
10
+ d.args.each do |key, val|
11
+ case key
12
+ when "object_class"
13
+ data_val = d.db.single(:Log_data_value, {"value" => val})
14
+ return [] if !data_val #if this data-value cannot be found, nothing has been logged for the object. So just return empty array here and skip the rest.
15
+ sql += " AND object_class_value_id = '#{d.db.esc(data_val[:id])}'"
16
+ else
17
+ raise "Invalid key: #{key}."
18
+ end
19
+ end
20
+
21
+ sql += ret[:sql_where]
22
+ sql += ret[:sql_order]
23
+ sql += ret[:sql_limit]
24
+
25
+ return d.ob.list_bysql(:Log_link, sql)
26
+ end
27
+
28
+ def self.add(d)
29
+ if d.data.has_key?(:object)
30
+ class_data_id = d.ob.static(:Log_data_value, :force, d.data[:object].class.name)
31
+ d.data[:object_class_value_id] = class_data_id.id
32
+ d.data[:object_id] = d.data[:object].id
33
+ d.data.delete(:object)
34
+ end
35
+
36
+ log = d.ob.get(:Log, d.data[:log_id]) #throws exception if it doesnt exist.
37
+ end
38
+
39
+ def object(ob_use)
40
+ begin
41
+ class_name = ob.get(:Log_data_value, self[:object_class_value_id])[:value].split("::").last
42
+ return ob_use.get(class_name, self[:object_id])
43
+ rescue Knj::Errors::NotFound
44
+ return false
45
+ end
46
+ end
47
+
48
+ def object_class
49
+ return ob.get(:Log_data_value, self[:object_class_value_id])[:value]
50
+ end
51
+ end
@@ -0,0 +1,43 @@
1
+ class Knjappserver::Session < Knj::Datarow
2
+ attr_reader :edata
3
+ attr_accessor :sess_data
4
+
5
+ def initialize(d)
6
+ @edata = {}
7
+ super(d)
8
+
9
+ if self[:sess_data].to_s.length > 0
10
+ begin
11
+ @sess_data = Marshal.load(Base64.decode64(self[:sess_data]))
12
+ rescue ArgumentError
13
+ @sess_data = {}
14
+ end
15
+ else
16
+ @sess_data = {}
17
+ end
18
+ end
19
+
20
+ def self.list(d)
21
+ sql = "SELECT * FROM #{table} WHERE 1=1"
22
+
23
+ ret = list_helper(d)
24
+ d.args.each do |key, val|
25
+ raise "Invalid key: #{key}."
26
+ end
27
+
28
+ sql += ret[:sql_where]
29
+ sql += ret[:sql_order]
30
+ sql += ret[:sql_limit]
31
+
32
+ return d.ob.list_bysql(:Session, sql)
33
+ end
34
+
35
+ def self.add(d)
36
+ d.data[:date_added] = Knj::Datet.new.dbstr if !d.data[:date_added]
37
+ end
38
+
39
+ def flush
40
+ m_newdata = Base64.encode64(Marshal.dump(@sess_data))
41
+ self[:sess_data] = m_newdata
42
+ end
43
+ end
@@ -0,0 +1,10 @@
1
+ # coding: utf-8
2
+
3
+ def _(str)
4
+ kas = _kas
5
+ return str if !kas or !_session
6
+ _session[:locale] = _kas.config[:locale_default] if !_session[:locale] and _kas.config[:locale_default]
7
+ raise "No locale set for session and ':locale_default' not set in config." if !_session[:locale]
8
+ str = kas.gettext.trans(_session[:locale], str)
9
+ return str
10
+ end
@@ -0,0 +1,59 @@
1
+ def _cookie
2
+ return Thread.current[:knjappserver][:cookie] if Thread.current[:knjappserver]
3
+ end
4
+
5
+ def _get
6
+ return Thread.current[:knjappserver][:get] if Thread.current[:knjappserver]
7
+ end
8
+
9
+ def _post
10
+ return Thread.current[:knjappserver][:post] if Thread.current[:knjappserver]
11
+ end
12
+
13
+ def _session
14
+ return Thread.current[:knjappserver][:session].sess_data if Thread.current[:knjappserver] and Thread.current[:knjappserver][:session]
15
+ end
16
+
17
+ def _session_hash
18
+ return Thread.current[:knjappserver][:session_hash] if Thread.current[:knjappserver]
19
+ end
20
+
21
+ def _session_obj
22
+ return Thread.current[:knjappserver][:session] if Thread.current[:knjappserver]
23
+ end
24
+
25
+ def _server
26
+ return Thread.current[:knjappserver][:meta] if Thread.current[:knjappserver]
27
+ end
28
+
29
+ def _httpsession
30
+ return Thread.current[:knjappserver][:httpsession] if Thread.current[:knjappserver]
31
+ end
32
+
33
+ def _requestdata
34
+ return Thread.current[:knjappserver] if Thread.current[:knjappserver]
35
+ end
36
+
37
+ def _meta
38
+ return Thread.current[:knjappserver][:meta] if Thread.current[:knjappserver]
39
+ end
40
+
41
+ def _kas
42
+ return Thread.current[:knjappserver][:kas] if Thread.current[:knjappserver]
43
+ return $knjappserver[:knjappserver] if $knjappserver and $knjappserver[:knjappserver]
44
+ end
45
+
46
+ def _vars
47
+ return Thread.current[:knjappserver][:kas].vars if Thread.current[:knjappserver]
48
+ return $knjappserver[:knjappserver].vars if $knjappserver and $knjappserver[:knjappserver]
49
+ end
50
+
51
+ def _db
52
+ return Thread.current[:knjappserver][:db] if Thread.current[:knjappserver]
53
+ return $db if $db #return the global database object, if we are not running in a thread with one.
54
+ end
55
+
56
+ #This function makes it possible to define methods in ERubis-parsed files (else _buf-variable wouldnt be globally available).
57
+ def _buf
58
+ return $stdout
59
+ end
@@ -0,0 +1 @@
1
+ require "#{File.dirname(__FILE__)}/include/class_knjappserver"
@@ -0,0 +1,57 @@
1
+ <%
2
+ access = _kas.events.call(:check_page_access, {:page => :logs_latest})
3
+ if !access
4
+ print _("You do not have access to this page.")
5
+ exit
6
+ end
7
+
8
+ ob = _kas.events.call(:ob)
9
+ %>
10
+
11
+ <table class="list">
12
+ <thead>
13
+ <tr>
14
+ <th><%=_("ID")%></th>
15
+ <th><%=_("Log")%></th>
16
+ <%if ob%>
17
+ <th><%=_("Object")%></th>
18
+ <%end%>
19
+ </tr>
20
+ </thead>
21
+ <tbody>
22
+ <%
23
+ logs = _kas.ob.list(:Log, {
24
+ "orderby" => [["date_saved", "desc"]],
25
+ "limit" => 200
26
+ })
27
+
28
+ logs.each do |log|
29
+ %>
30
+ <tr>
31
+ <td>
32
+ <a href="logs_show.rhtml?log_id=<%=log.id%>"><%=log.id%></a>
33
+ </td>
34
+ <td>
35
+ <%=log.first_line%>
36
+ </td>
37
+ <%if ob%>
38
+ <td>
39
+ <%=log.objects_html(ob)%>
40
+ </td>
41
+ <%end%>
42
+ </tr>
43
+ <%
44
+ end
45
+
46
+ if logs.empty?
47
+ %>
48
+ <tr>
49
+ <td class="error">
50
+ <%=_("No logs were found.")%>
51
+ </td>
52
+ </tr>
53
+ <%
54
+ end
55
+ %>
56
+ </tbody>
57
+ </table>
@@ -0,0 +1,32 @@
1
+ <%
2
+ access = _kas.events.call(:check_page_access, {:page => :logs_show})
3
+ if !access
4
+ print _("You do not have access to this page.")
5
+ exit
6
+ end
7
+
8
+ ob = _kas.events.call(:ob)
9
+ log = _kas.ob.get(:Log, _get["log_id"])
10
+ %>
11
+
12
+ <table class="form">
13
+ <%
14
+ print Knj::Web.inputs([{
15
+ :title => _("Date"),
16
+ :type => :info,
17
+ :value => Knj::Datet.in(log[:date_saved]).out
18
+ }])
19
+
20
+ if ob
21
+ print Knj::Web.input(
22
+ :title => _("Objects"),
23
+ :type => :info,
24
+ :value => log.objects_html(ob)
25
+ )
26
+ end
27
+ %>
28
+ </table>
29
+
30
+ <div style="padding-top: 10px;">
31
+ <%=log.text%>
32
+ </div>
@@ -0,0 +1,10 @@
1
+ <%
2
+ _kas.header("TestHeader", "NormalHeader")
3
+ _kas.header_raw("TestRaw: RawHeader")
4
+
5
+ if _meta["REQUEST_METHOD"] == "POST"
6
+ print _post["postdata"]
7
+ else
8
+ print "Test"
9
+ end
10
+ %>
@@ -0,0 +1,110 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Knjappserver" do
4
+ it "should be able to start a sample-server" do
5
+ require "rubygems"
6
+ require "knjappserver"
7
+ require "knjrbfw"
8
+ require "knj/autoload"
9
+ require "tmpdir"
10
+
11
+ db_path = "#{Dir.tmpdir}/knjappserver_rspec.sqlite3"
12
+ File.unlink(db_path) if File.exists?(db_path)
13
+
14
+ db = Knj::Db.new(
15
+ :type => "sqlite3",
16
+ :path => db_path,
17
+ :return_keys => "symbols"
18
+ )
19
+
20
+ erbhandler = Knjappserver::ERBHandler.new
21
+
22
+ $appserver = Knjappserver.new(
23
+ :debug => false,
24
+ :autorestart => false,
25
+ :autoload => false,
26
+ :verbose => false,
27
+ :title => "knjTasks",
28
+ :port => 1515,
29
+ :host => "0.0.0.0",
30
+ :default_page => "index.rhtml",
31
+ :doc_root => "#{File.dirname(__FILE__)}/../lib/pages",
32
+ :hostname => false,
33
+ :default_filetype => "text/html",
34
+ :engine_knjengine => true,
35
+ :locales_gettext_funcs => true,
36
+ :locale_default => "da_DK",
37
+ :max_requests_working => 5,
38
+ :filetypes => {
39
+ :jpg => "image/jpeg",
40
+ :gif => "image/gif",
41
+ :png => "image/png",
42
+ :html => "text/html",
43
+ :htm => "text/html",
44
+ :rhtml => "text/html",
45
+ :css => "text/css",
46
+ :xml => "text/xml",
47
+ :js => "text/javascript"
48
+ },
49
+ :handlers => [
50
+ {
51
+ :file_ext => "rhtml",
52
+ :callback => erbhandler.method(:erb_handler)
53
+ },{
54
+ :path => "/fckeditor",
55
+ :mount => "/usr/share/fckeditor"
56
+ }
57
+ ],
58
+ :db => db
59
+ )
60
+
61
+ $appserver.vars[:test] = "kasper"
62
+ $appserver.define_magic_var(:_testvar1, "Kasper")
63
+ $appserver.define_magic_var(:_testvar2, "Johansen")
64
+ $appserver.update_db
65
+ $appserver.start
66
+ end
67
+
68
+ it "should be able to mount FCKeditor dir to /usr/share/fckeditor" do
69
+
70
+ end
71
+
72
+ it "should be able to handle a GET-request." do
73
+ $http = Knj::Http.new("host" => "localhost", "port" => 1515)
74
+ data = $http.get("/spec.rhtml")
75
+ raise "Unexpected HTML: '#{data["data"]}'." if data["data"].to_s.strip != "Test"
76
+ end
77
+
78
+ it "should be able to handle a HEAD-request." do
79
+ data = $http.head("/spec.rhtml")
80
+ raise "HEAD-request returned content - it shouldnt?" if data["data"].to_s.length > 0
81
+ end
82
+
83
+ it "should be able to handle a POST-request." do
84
+ data = $http.post("/spec.rhtml", {
85
+ "postdata" => "Test post"
86
+ })
87
+ raise "POST-request did not return expected data: '#{data["data"]}'." if data["data"].to_s.strip != "Test post"
88
+ end
89
+
90
+ it "should be able to join the server so other tests can be made manually." do
91
+ begin
92
+ Timeout.timeout(1) do
93
+ $appserver.join
94
+ raise "Appserver didnt join."
95
+ end
96
+ rescue Timeout::Error
97
+ #ignore.
98
+ end
99
+ end
100
+
101
+ it "it should be able to use the header-methods." do
102
+ data = $http.get("/spec.rhtml")
103
+ raise "Normal header data could not be detected." if data["response"].header["testheader"] != "NormalHeader"
104
+ raise "Raw header data could not be detected." if data["response"].header["testraw"]!= "RawHeader"
105
+ end
106
+
107
+ it "should be able to stop." do
108
+ $appserver.stop
109
+ end
110
+ end
@@ -0,0 +1,12 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+ require 'knjappserver'
5
+
6
+ # Requires supporting files with custom matchers and macros, etc,
7
+ # in ./support/ and its subdirectories.
8
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
9
+
10
+ RSpec.configure do |config|
11
+
12
+ end
metadata ADDED
@@ -0,0 +1,188 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: knjappserver
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.6
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Kasper Johansen
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-08-03 00:00:00.000000000 +02:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: knjrbfw
17
+ requirement: &15241340 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: 0.0.3
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *15241340
26
+ - !ruby/object:Gem::Dependency
27
+ name: erubis
28
+ requirement: &15240780 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: *15240780
37
+ - !ruby/object:Gem::Dependency
38
+ name: knjdbrevision
39
+ requirement: &15240140 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: 0.0.2
45
+ type: :runtime
46
+ prerelease: false
47
+ version_requirements: *15240140
48
+ - !ruby/object:Gem::Dependency
49
+ name: rspec
50
+ requirement: &15239540 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ version: 2.3.0
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: *15239540
59
+ - !ruby/object:Gem::Dependency
60
+ name: bundler
61
+ requirement: &15238940 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ~>
65
+ - !ruby/object:Gem::Version
66
+ version: 1.0.0
67
+ type: :development
68
+ prerelease: false
69
+ version_requirements: *15238940
70
+ - !ruby/object:Gem::Dependency
71
+ name: jeweler
72
+ requirement: &15238220 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 1.6.3
78
+ type: :development
79
+ prerelease: false
80
+ version_requirements: *15238220
81
+ - !ruby/object:Gem::Dependency
82
+ name: rcov
83
+ requirement: &15237440 !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ! '>='
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: *15237440
92
+ - !ruby/object:Gem::Dependency
93
+ name: sqlite3
94
+ requirement: &15233840 !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ! '>='
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ type: :development
101
+ prerelease: false
102
+ version_requirements: *15233840
103
+ description: Which supports a lot of undocumented stuff.
104
+ email: k@spernj.org
105
+ executables:
106
+ - check_running.rb
107
+ - knjappserver_start.rb
108
+ extensions: []
109
+ extra_rdoc_files:
110
+ - LICENSE.txt
111
+ - README.rdoc
112
+ files:
113
+ - .document
114
+ - .rspec
115
+ - Gemfile
116
+ - Gemfile.lock
117
+ - LICENSE.txt
118
+ - README.rdoc
119
+ - Rakefile
120
+ - VERSION
121
+ - bin/check_running.rb
122
+ - bin/knjappserver_start.rb
123
+ - knjappserver.gemspec
124
+ - lib/conf/README
125
+ - lib/conf/conf_example.rb
126
+ - lib/conf/conf_vars_example.rb
127
+ - lib/files/database_schema.rb
128
+ - lib/files/run/README
129
+ - lib/include/class_customio.rb
130
+ - lib/include/class_erbhandler.rb
131
+ - lib/include/class_httpresp.rb
132
+ - lib/include/class_httpserver.rb
133
+ - lib/include/class_httpsession.rb
134
+ - lib/include/class_httpsession_knjengine.rb
135
+ - lib/include/class_httpsession_mongrel.rb
136
+ - lib/include/class_httpsession_webrick.rb
137
+ - lib/include/class_knjappserver.rb
138
+ - lib/include/class_knjappserver_cleaner.rb
139
+ - lib/include/class_knjappserver_errors.rb
140
+ - lib/include/class_knjappserver_logging.rb
141
+ - lib/include/class_knjappserver_mailing.rb
142
+ - lib/include/class_knjappserver_threadding.rb
143
+ - lib/include/class_knjappserver_web.rb
144
+ - lib/include/class_log.rb
145
+ - lib/include/class_log_access.rb
146
+ - lib/include/class_log_data.rb
147
+ - lib/include/class_log_data_link.rb
148
+ - lib/include/class_log_data_value.rb
149
+ - lib/include/class_log_link.rb
150
+ - lib/include/class_session.rb
151
+ - lib/include/gettext_funcs.rb
152
+ - lib/include/magic_methods.rb
153
+ - lib/knjappserver.rb
154
+ - lib/pages/logs_latest.rhtml
155
+ - lib/pages/logs_show.rhtml
156
+ - lib/pages/spec.rhtml
157
+ - spec/knjappserver_spec.rb
158
+ - spec/spec_helper.rb
159
+ has_rdoc: true
160
+ homepage: http://github.com/kaspernj/knjappserver
161
+ licenses:
162
+ - MIT
163
+ post_install_message:
164
+ rdoc_options: []
165
+ require_paths:
166
+ - lib
167
+ required_ruby_version: !ruby/object:Gem::Requirement
168
+ none: false
169
+ requirements:
170
+ - - ! '>='
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
173
+ segments:
174
+ - 0
175
+ hash: -3661152369845667563
176
+ required_rubygems_version: !ruby/object:Gem::Requirement
177
+ none: false
178
+ requirements:
179
+ - - ! '>='
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ requirements: []
183
+ rubyforge_project:
184
+ rubygems_version: 1.6.2
185
+ signing_key:
186
+ specification_version: 3
187
+ summary: A multi-threadded app-web-server.
188
+ test_files: []