knjappserver 0.0.15 → 0.0.16
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +4 -2
- data/Gemfile.lock +24 -10
- data/README.rdoc +298 -1
- data/VERSION +1 -1
- data/bin/check_running.rb +2 -2
- data/knjappserver.gemspec +23 -5
- data/lib/files/database_schema.rb +124 -111
- data/lib/include/class_customio.rb +19 -5
- data/lib/include/class_erbhandler.rb +5 -22
- data/lib/include/class_httpresp.rb +66 -28
- data/lib/include/class_httpserver.rb +27 -14
- data/lib/include/class_httpsession.rb +161 -212
- data/lib/include/class_httpsession_contentgroup.rb +144 -0
- data/lib/include/class_httpsession_knjengine.rb +33 -68
- data/lib/include/class_httpsession_mongrel.rb +1 -1
- data/lib/include/class_httpsession_webrick.rb +1 -1
- data/lib/include/class_knjappserver.rb +105 -130
- data/lib/include/class_knjappserver_cleaner.rb +20 -13
- data/lib/include/class_knjappserver_cmdline.rb +44 -0
- data/lib/include/class_knjappserver_errors.rb +4 -1
- data/lib/include/class_knjappserver_logging.rb +48 -8
- data/lib/include/class_knjappserver_mailing.rb +36 -14
- data/lib/include/class_knjappserver_sessions.rb +78 -0
- data/lib/include/class_knjappserver_threadding.rb +18 -45
- data/lib/include/class_knjappserver_threadding_timeout.rb +78 -0
- data/lib/include/class_knjappserver_translations.rb +30 -0
- data/lib/include/class_knjappserver_web.rb +55 -3
- data/lib/include/class_log.rb +31 -3
- data/lib/include/class_log_access.rb +0 -15
- data/lib/include/class_log_data.rb +0 -15
- data/lib/include/class_log_data_link.rb +1 -14
- data/lib/include/class_log_data_value.rb +5 -17
- data/lib/include/class_session.rb +6 -18
- data/lib/include/magic_methods.rb +12 -14
- data/lib/pages/benchmark.rhtml +0 -0
- data/lib/pages/benchmark_print.rhtml +14 -0
- data/lib/pages/benchmark_simple.rhtml +3 -0
- data/lib/pages/benchmark_threadded_content.rhtml +21 -0
- data/lib/pages/spec.rhtml +26 -0
- data/lib/pages/spec_test_multiple_clients.rhtml +3 -0
- data/lib/pages/spec_threadded_content.rhtml +38 -0
- data/lib/scripts/benchmark.rb +65 -0
- data/spec/knjappserver_spec.rb +87 -43
- metadata +54 -20
@@ -0,0 +1,78 @@
|
|
1
|
+
class Knjappserver::Threadding_timeout
|
2
|
+
def initialize(args)
|
3
|
+
@args = args
|
4
|
+
@kas = @args[:kas]
|
5
|
+
raise "No time given." if !@args[:args].key?(:time)
|
6
|
+
@args[:time] = @args[:args][:time].to_s.to_i
|
7
|
+
@args[:args] = [] if !@args[:args]
|
8
|
+
@mutex = Mutex.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def time=(newtime)
|
12
|
+
@args[:time] = newtime.to_s.to_i
|
13
|
+
end
|
14
|
+
|
15
|
+
def time
|
16
|
+
return @args[:time]
|
17
|
+
end
|
18
|
+
|
19
|
+
#Starts the timeout.
|
20
|
+
def start
|
21
|
+
@run = true
|
22
|
+
@thread = Thread.new do
|
23
|
+
loop do
|
24
|
+
begin
|
25
|
+
if @args[:counting]
|
26
|
+
@timeout = @args[:time]
|
27
|
+
|
28
|
+
while @timeout > 0
|
29
|
+
@timeout += -1
|
30
|
+
break if @kas.should_restart or !@run
|
31
|
+
sleep 1
|
32
|
+
end
|
33
|
+
else
|
34
|
+
sleep @args[:time]
|
35
|
+
end
|
36
|
+
|
37
|
+
break if @kas.should_restart or !@run
|
38
|
+
|
39
|
+
@mutex.synchronize do
|
40
|
+
@kas.threadpool.run do
|
41
|
+
@kas.ob.db.get_and_register_thread if @kas.ob.db.opts[:threadsafe]
|
42
|
+
@kas.db_handler.get_and_register_thread if @kas.db_handler.opts[:threadsafe]
|
43
|
+
|
44
|
+
Thread.current[:knjappserver] = {
|
45
|
+
:kas => self,
|
46
|
+
:db => @kas.db_handler
|
47
|
+
}
|
48
|
+
|
49
|
+
begin
|
50
|
+
@args[:block].call(*@args[:args])
|
51
|
+
ensure
|
52
|
+
@kas.ob.db.free_thread if @kas.ob.db.opts[:threadsafe]
|
53
|
+
@kas.db_handler.free_thread if @kas.db_handler.opts[:threadsafe]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
rescue Exception => e
|
58
|
+
@kas.handle_error(e)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
#Stops the timeout.
|
65
|
+
def stop
|
66
|
+
@run = false
|
67
|
+
@mutex.synchronize do
|
68
|
+
@thread.kill if @thread.alive?
|
69
|
+
@thread = nil
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
#Returns various data.
|
74
|
+
def [](key)
|
75
|
+
return @timeout if key == :knjappserver_timeout
|
76
|
+
raise "No such key: '#{key}'."
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class Knjappserver
|
2
|
+
def trans(obj, key, args = {})
|
3
|
+
if !args.key?(:locale)
|
4
|
+
if _session[:locale]
|
5
|
+
args[:locale] = _session[:locale]
|
6
|
+
elsif _httpsession.data[:locale]
|
7
|
+
args[:locale] = _httpsession.data[:locale]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
trans_val = @translations.get(obj, key, args).to_s
|
12
|
+
|
13
|
+
if trans_val.length <= 0
|
14
|
+
trans_val = @events.call(:trans_no_str, {:obj => obj, :key => key, :args => args})
|
15
|
+
end
|
16
|
+
|
17
|
+
return trans_val
|
18
|
+
end
|
19
|
+
|
20
|
+
def trans_set(obj, values)
|
21
|
+
args = {}
|
22
|
+
args[:locale] = _session[:locale] if _session[:locale] and !args[:locale]
|
23
|
+
args[:locale] = _httpsession.data[:locale] if _httpsession.data[:locale] and !args[:locale]
|
24
|
+
@translations.set(obj, values, args)
|
25
|
+
end
|
26
|
+
|
27
|
+
def trans_del(obj)
|
28
|
+
@translations.delete(obj)
|
29
|
+
end
|
30
|
+
end
|
@@ -1,23 +1,75 @@
|
|
1
1
|
class Knjappserver
|
2
|
+
#Imports a .rhtml-file and executes it.
|
3
|
+
def import(filepath)
|
4
|
+
_httpsession.eruby.import(filepath)
|
5
|
+
end
|
6
|
+
|
7
|
+
#Redirects to another URL.
|
2
8
|
def redirect(url, args = {})
|
3
|
-
|
9
|
+
#Header way
|
10
|
+
if !_httpsession.alert_sent and !self.headers_sent?
|
11
|
+
if args[:perm]
|
12
|
+
_httpsession.resp.status = 301 if !self.headers_sent?
|
13
|
+
else
|
14
|
+
_httpsession.resp.status = 303 if !self.headers_sent?
|
15
|
+
end
|
16
|
+
|
17
|
+
self.header("Location", url) if !self.headers_sent?
|
18
|
+
end
|
19
|
+
|
20
|
+
print "<script type=\"text/javascript\">location.href=\"#{url}\";</script>"
|
21
|
+
exit
|
4
22
|
end
|
5
23
|
|
24
|
+
#Sends a javascript-alert to the HTML.
|
6
25
|
def alert(msg)
|
26
|
+
_httpsession.alert_sent = true
|
7
27
|
Knj::Web.alert(msg)
|
8
28
|
return self
|
9
29
|
end
|
10
30
|
|
31
|
+
#Define a cookies in the clients browser.
|
32
|
+
def cookie(cookie)
|
33
|
+
raise "No HTTP-session attached to this thread." if !_httpsession
|
34
|
+
raise "HTTP-session not active." if !_httpsession.resp
|
35
|
+
raise "Not a hash: '#{cookie.class.name}', '#{cookie}'." unless cookie.is_a?(Hash)
|
36
|
+
_httpsession.resp.cookie(cookie)
|
37
|
+
end
|
38
|
+
|
39
|
+
#Sends a header to the clients browser.
|
11
40
|
def header(key, val)
|
12
|
-
|
41
|
+
raise "No HTTP-session attached to this thread." if !_httpsession
|
42
|
+
raise "HTTP-session not active." if !_httpsession.resp
|
43
|
+
_httpsession.resp.header(key, val)
|
13
44
|
end
|
14
45
|
|
46
|
+
#Sends a raw header-line to the clients browser.
|
15
47
|
def header_raw(str)
|
48
|
+
raise "No HTTP-session attached to this thread." if !_httpsession
|
49
|
+
raise "HTTP-session not active." if !_httpsession.resp
|
16
50
|
Knj::Php.header(str)
|
17
51
|
end
|
18
52
|
|
53
|
+
def headers_sent?
|
54
|
+
return true if _httpsession.resp.headers_sent
|
55
|
+
return false
|
56
|
+
end
|
57
|
+
|
58
|
+
def headers_send_size=(newsize)
|
59
|
+
if self.headers_sent?
|
60
|
+
raise "The headers are already sent and you cannot modify the send-size any more."
|
61
|
+
end
|
62
|
+
|
63
|
+
_httpsession.size_send = newsize.to_i
|
64
|
+
end
|
65
|
+
|
66
|
+
#Sends a javascript back to the browser and exits.
|
19
67
|
def back
|
20
68
|
Knj::Web.back
|
21
|
-
|
69
|
+
end
|
70
|
+
|
71
|
+
#Draw a input in a table.
|
72
|
+
def inputs(*args)
|
73
|
+
return Knj::Web.inputs(args)
|
22
74
|
end
|
23
75
|
end
|
data/lib/include/class_log.rb
CHANGED
@@ -34,15 +34,27 @@ class Knjappserver::Log < Knj::Datarow
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def self.add(d)
|
37
|
-
if !d.data.
|
38
|
-
d.data[:date_saved] = d.db.date_out(Knj::Datet.new)
|
39
|
-
end
|
37
|
+
d.data[:date_saved] = Time.now if !d.data.key?(:date_saved)
|
40
38
|
end
|
41
39
|
|
42
40
|
def text
|
43
41
|
return ob.get(:Log_data_value, self[:text_value_id])[:value]
|
44
42
|
end
|
45
43
|
|
44
|
+
def comment
|
45
|
+
return "" if self[:comment_data_id].to_i == 0
|
46
|
+
log_data = ob.get(:Log_data_value, self[:comment_data_id])
|
47
|
+
return "" if !log_data
|
48
|
+
return log_data[:value]
|
49
|
+
end
|
50
|
+
|
51
|
+
def tag
|
52
|
+
return "" if self[:tag_data_id].to_i == 0
|
53
|
+
log_data = ob.get(:Log_data_value, self[:tag_data_id])
|
54
|
+
return "" if !log_data
|
55
|
+
return log_data[:value]
|
56
|
+
end
|
57
|
+
|
46
58
|
def get
|
47
59
|
ob.args[:knjappserver].log_data_hash(self[:get_keys_data_id], self[:get_values_data_id])
|
48
60
|
end
|
@@ -51,6 +63,22 @@ class Knjappserver::Log < Knj::Datarow
|
|
51
63
|
ob.args[:knjappserver].log_data_hash(self[:post_keys_data_id], self[:post_values_data_id])
|
52
64
|
end
|
53
65
|
|
66
|
+
def cookie
|
67
|
+
ob.args[:knjappserver].log_data_hash(self[:cookie_keys_data_id], self[:cookie_values_data_id])
|
68
|
+
end
|
69
|
+
|
70
|
+
def meta
|
71
|
+
ob.args[:knjappserver].log_data_hash(self[:meta_keys_data_id], self[:meta_values_data_id])
|
72
|
+
end
|
73
|
+
|
74
|
+
def ip
|
75
|
+
meta_d = self.meta
|
76
|
+
|
77
|
+
return meta_d[:HTTP_X_FORWARDED_FOR] if meta_d.has_key?(:HTTP_X_FORWARDED_FOR)
|
78
|
+
return meta_d[:REMOTE_ADDR] if meta_d.has_key?(:REMOTE_ADDR)
|
79
|
+
return "[no ip logged]"
|
80
|
+
end
|
81
|
+
|
54
82
|
def first_line
|
55
83
|
lines = self.text.to_s.split("\n").first.to_s
|
56
84
|
end
|
@@ -1,19 +1,4 @@
|
|
1
1
|
class Knjappserver::Log_access < 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_access, sql)
|
15
|
-
end
|
16
|
-
|
17
2
|
def get
|
18
3
|
return data_hash("get")
|
19
4
|
end
|
@@ -1,19 +1,4 @@
|
|
1
1
|
class Knjappserver::Log_data < 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, sql)
|
15
|
-
end
|
16
|
-
|
17
2
|
def self.force(d, id_hash)
|
18
3
|
data_obj = d.ob.get_by(:Log_data, {"id_hash" => id_hash})
|
19
4
|
|
@@ -1,16 +1,3 @@
|
|
1
1
|
class Knjappserver::Log_data_link < Knj::Datarow
|
2
|
-
|
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
|
2
|
+
|
16
3
|
end
|
@@ -1,19 +1,4 @@
|
|
1
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
2
|
def self.force(d, value)
|
18
3
|
value_obj = d.ob.get_by(:Log_data_value, {
|
19
4
|
"value" => value.to_s
|
@@ -27,8 +12,11 @@ class Knjappserver::Log_data_value < Knj::Datarow
|
|
27
12
|
end
|
28
13
|
|
29
14
|
def self.force_id(d, value)
|
30
|
-
|
31
|
-
|
15
|
+
q_val = d.db.select(:Log_data_value, {"value" => value})
|
16
|
+
while d_val = q_val.fetch
|
17
|
+
return d_val[:id].to_i if d_val[:value].to_s == value.to_s #MySQL doesnt take upper/lower-case into consideration because value is a text-column... lame! - knj
|
18
|
+
end
|
19
|
+
|
32
20
|
return d.db.insert(:Log_data_value, {:value => value}, {:return_id => true}).to_i
|
33
21
|
end
|
34
22
|
end
|
@@ -17,27 +17,15 @@ class Knjappserver::Session < Knj::Datarow
|
|
17
17
|
end
|
18
18
|
end
|
19
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
20
|
def self.add(d)
|
36
|
-
d.data[:date_added] =
|
21
|
+
d.data[:date_added] = Time.now if !d.data[:date_added]
|
22
|
+
d.data[:date_lastused] = Time.now if !d.data[:date_lastused]
|
37
23
|
end
|
38
24
|
|
39
25
|
def flush
|
40
|
-
|
41
|
-
|
26
|
+
self.update(
|
27
|
+
:sess_data => Base64.encode64(Marshal.dump(@sess_data)),
|
28
|
+
:date_lastused => Time.now
|
29
|
+
)
|
42
30
|
end
|
43
31
|
end
|
@@ -10,20 +10,24 @@ def _post
|
|
10
10
|
return Thread.current[:knjappserver][:post] if Thread.current[:knjappserver]
|
11
11
|
end
|
12
12
|
|
13
|
+
def _meta
|
14
|
+
return Thread.current[:knjappserver][:meta] if Thread.current[:knjappserver]
|
15
|
+
end
|
16
|
+
|
17
|
+
def _server
|
18
|
+
return Thread.current[:knjappserver][:meta] if Thread.current[:knjappserver]
|
19
|
+
end
|
20
|
+
|
13
21
|
def _session
|
14
22
|
return Thread.current[:knjappserver][:session].sess_data if Thread.current[:knjappserver] and Thread.current[:knjappserver][:session]
|
15
23
|
end
|
16
24
|
|
17
25
|
def _session_hash
|
18
|
-
return Thread.current[:knjappserver][:
|
26
|
+
return Thread.current[:knjappserver][:session].edata if Thread.current[:knjappserver] and Thread.current[:knjappserver][:session]
|
19
27
|
end
|
20
28
|
|
21
29
|
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]
|
30
|
+
return Thread.current[:knjappserver][:session] if Thread.current[:knjappserver] and Thread.current[:knjappserver][:session]
|
27
31
|
end
|
28
32
|
|
29
33
|
def _httpsession
|
@@ -34,23 +38,17 @@ def _requestdata
|
|
34
38
|
return Thread.current[:knjappserver] if Thread.current[:knjappserver]
|
35
39
|
end
|
36
40
|
|
37
|
-
def _meta
|
38
|
-
return Thread.current[:knjappserver][:meta] if Thread.current[:knjappserver]
|
39
|
-
end
|
40
|
-
|
41
41
|
def _kas
|
42
42
|
return Thread.current[:knjappserver][:kas] if Thread.current[:knjappserver]
|
43
|
-
return $knjappserver[:knjappserver] if $knjappserver and $knjappserver[:knjappserver]
|
44
43
|
end
|
45
44
|
|
46
45
|
def _vars
|
47
46
|
return Thread.current[:knjappserver][:kas].vars if Thread.current[:knjappserver]
|
48
|
-
return $knjappserver[:knjappserver].vars if $knjappserver and $knjappserver[:knjappserver]
|
49
47
|
end
|
50
48
|
|
51
49
|
def _db
|
52
|
-
return Thread.current[:knjappserver][:db] if Thread.current[:knjappserver]
|
53
|
-
return
|
50
|
+
return Thread.current[:knjappserver][:db] if Thread.current[:knjappserver] and Thread.current[:knjappserver][:db] #This is the default use from a .rhtml-file.
|
51
|
+
return Thread.current[:knjappserver][:kas].db_handler if Thread.current[:knjappserver] and Thread.current[:knjappserver][:kas] #This is useually used when using autoload-argument for the appserver.
|
54
52
|
end
|
55
53
|
|
56
54
|
#This function makes it possible to define methods in ERubis-parsed files (else _buf-variable wouldnt be globally available).
|
File without changes
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<%
|
2
|
+
0.upto(100) do
|
3
|
+
print "Test 1<br />\n"
|
4
|
+
print "Test 2<br />\n"
|
5
|
+
print "Test 3<br />\n"
|
6
|
+
print "Test 4<br />\n"
|
7
|
+
print "Test 5<br />\n"
|
8
|
+
print "Test 6<br />\n"
|
9
|
+
print "Test 7<br />\n"
|
10
|
+
print "Test 8<br />\n"
|
11
|
+
print "Test 9<br />\n"
|
12
|
+
print "Test 10<br />\n"
|
13
|
+
end
|
14
|
+
%>
|