knjappserver 0.0.16 → 0.0.17

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 (49) hide show
  1. data/VERSION +1 -1
  2. data/bin/knjappserver_start.rb +17 -25
  3. data/knjappserver.gemspec +17 -6
  4. data/lib/conf/conf_example.rb +3 -3
  5. data/lib/files/database_schema.rb +1 -2
  6. data/lib/include/class_customio.rb +8 -25
  7. data/lib/include/class_erbhandler.rb +7 -1
  8. data/lib/include/class_httpserver.rb +50 -34
  9. data/lib/include/class_httpsession.rb +138 -101
  10. data/lib/include/class_httpsession_contentgroup.rb +52 -24
  11. data/lib/include/class_httpsession_http_request.rb +203 -0
  12. data/lib/include/{class_httpresp.rb → class_httpsession_http_response.rb} +27 -28
  13. data/lib/include/class_httpsession_post_multipart.rb +117 -0
  14. data/lib/include/class_knjappserver.rb +146 -96
  15. data/lib/include/class_knjappserver_cleaner.rb +74 -68
  16. data/lib/include/class_knjappserver_cmdline.rb +23 -17
  17. data/lib/include/class_knjappserver_errors.rb +121 -104
  18. data/lib/include/class_knjappserver_leakproxy_client.rb +6 -0
  19. data/lib/include/class_knjappserver_leakproxy_server.rb +56 -0
  20. data/lib/include/class_knjappserver_logging.rb +25 -25
  21. data/lib/include/class_knjappserver_mailing.rb +84 -56
  22. data/lib/include/class_knjappserver_sessions.rb +15 -22
  23. data/lib/include/class_knjappserver_threadding.rb +70 -43
  24. data/lib/include/class_knjappserver_threadding_timeout.rb +20 -4
  25. data/lib/include/class_knjappserver_translations.rb +6 -4
  26. data/lib/include/class_knjappserver_web.rb +87 -35
  27. data/lib/include/class_log.rb +9 -9
  28. data/lib/include/class_log_link.rb +4 -4
  29. data/lib/include/class_session.rb +8 -4
  30. data/lib/include/gettext_funcs.rb +8 -6
  31. data/lib/include/magic_methods.rb +4 -0
  32. data/lib/pages/debug_database_connections.rhtml +46 -0
  33. data/lib/pages/debug_http_sessions.rhtml +40 -0
  34. data/lib/pages/error_notfound.rhtml +12 -0
  35. data/lib/pages/spec.rhtml +1 -1
  36. data/lib/pages/spec_post.rhtml +3 -0
  37. data/lib/pages/spec_thread_joins.rhtml +21 -0
  38. data/lib/pages/spec_threadded_content.rhtml +2 -0
  39. data/lib/pages/tests.rhtml +14 -0
  40. data/lib/scripts/benchmark.rb +25 -8
  41. data/lib/scripts/knjappserver_cgi.rb +60 -0
  42. data/lib/scripts/knjappserver_fcgi.rb +135 -0
  43. data/lib/scripts/leakproxy.rb +27 -0
  44. data/spec/knjappserver_spec.rb +16 -5
  45. data/spec/leakproxy_spec.rb +56 -0
  46. metadata +38 -27
  47. data/lib/include/class_httpsession_knjengine.rb +0 -154
  48. data/lib/include/class_httpsession_mongrel.rb +0 -75
  49. data/lib/include/class_httpsession_webrick.rb +0 -75
@@ -1,11 +1,12 @@
1
1
  class Knjappserver::Threadding_timeout
2
+ attr_reader :timeout
3
+
2
4
  def initialize(args)
3
5
  @args = args
4
6
  @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]
7
+ raise "No time given." if !@args.key?(:time)
8
8
  @mutex = Mutex.new
9
+ @running = false
9
10
  end
10
11
 
11
12
  def time=(newtime)
@@ -42,13 +43,15 @@ class Knjappserver::Threadding_timeout
42
43
  @kas.db_handler.get_and_register_thread if @kas.db_handler.opts[:threadsafe]
43
44
 
44
45
  Thread.current[:knjappserver] = {
45
- :kas => self,
46
+ :kas => @kas,
46
47
  :db => @kas.db_handler
47
48
  }
48
49
 
49
50
  begin
51
+ @running = true
50
52
  @args[:block].call(*@args[:args])
51
53
  ensure
54
+ @running = false
52
55
  @kas.ob.db.free_thread if @kas.ob.db.opts[:threadsafe]
53
56
  @kas.db_handler.free_thread if @kas.db_handler.opts[:threadsafe]
54
57
  end
@@ -59,6 +62,8 @@ class Knjappserver::Threadding_timeout
59
62
  end
60
63
  end
61
64
  end
65
+
66
+ return self
62
67
  end
63
68
 
64
69
  #Stops the timeout.
@@ -75,4 +80,15 @@ class Knjappserver::Threadding_timeout
75
80
  return @timeout if key == :knjappserver_timeout
76
81
  raise "No such key: '#{key}'."
77
82
  end
83
+
84
+ #Returns true if the thread is alive or not.
85
+ def alive?
86
+ return @thread.alive? if @thread
87
+ return false
88
+ end
89
+
90
+ #Returns true if the timeout is running or not.
91
+ def running?
92
+ return @running
93
+ end
78
94
  end
@@ -17,10 +17,12 @@ class Knjappserver
17
17
  return trans_val
18
18
  end
19
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]
20
+ def trans_set(obj, values, args = {})
21
+ if !args[:locale]
22
+ args[:locale] = _session[:locale] if _session[:locale]
23
+ args[:locale] = _httpsession.data[:locale] if _httpsession.data[:locale] and !args[:locale]
24
+ end
25
+
24
26
  @translations.set(obj, values, args)
25
27
  end
26
28
 
@@ -5,7 +5,7 @@ class Knjappserver
5
5
  end
6
6
 
7
7
  #Redirects to another URL.
8
- def redirect(url, args = {})
8
+ def redirect(url, args = {})
9
9
  #Header way
10
10
  if !_httpsession.alert_sent and !self.headers_sent?
11
11
  if args[:perm]
@@ -19,57 +19,109 @@ class Knjappserver
19
19
 
20
20
  print "<script type=\"text/javascript\">location.href=\"#{url}\";</script>"
21
21
  exit
22
- end
23
-
24
- #Sends a javascript-alert to the HTML.
25
- def alert(msg)
22
+ end
23
+
24
+ #Sends a javascript-alert to the HTML.
25
+ def alert(msg)
26
26
  _httpsession.alert_sent = true
27
- Knj::Web.alert(msg)
28
- return self
29
- end
30
-
31
- #Define a cookies in the clients browser.
32
- def cookie(cookie)
27
+ Knj::Web.alert(msg)
28
+ return self
29
+ end
30
+
31
+ #Define a cookies in the clients browser.
32
+ def cookie(cookie)
33
33
  raise "No HTTP-session attached to this thread." if !_httpsession
34
34
  raise "HTTP-session not active." if !_httpsession.resp
35
35
  raise "Not a hash: '#{cookie.class.name}', '#{cookie}'." unless cookie.is_a?(Hash)
36
36
  _httpsession.resp.cookie(cookie)
37
- end
38
-
39
- #Sends a header to the clients browser.
40
- def header(key, val)
37
+ end
38
+
39
+ #Sends a header to the clients browser.
40
+ def header(key, val)
41
41
  raise "No HTTP-session attached to this thread." if !_httpsession
42
42
  raise "HTTP-session not active." if !_httpsession.resp
43
43
  _httpsession.resp.header(key, val)
44
- end
45
-
46
- #Sends a raw header-line to the clients browser.
47
- def header_raw(str)
44
+ end
45
+
46
+ #Sends a raw header-line to the clients browser.
47
+ def header_raw(str)
48
48
  raise "No HTTP-session attached to this thread." if !_httpsession
49
49
  raise "HTTP-session not active." if !_httpsession.resp
50
50
  Knj::Php.header(str)
51
- end
52
-
53
- def headers_sent?
51
+ end
52
+
53
+ def headers_sent?
54
54
  return true if _httpsession.resp.headers_sent
55
55
  return false
56
- end
57
-
58
- def headers_send_size=(newsize)
56
+ end
57
+
58
+ def headers_send_size=(newsize)
59
59
  if self.headers_sent?
60
60
  raise "The headers are already sent and you cannot modify the send-size any more."
61
61
  end
62
62
 
63
63
  _httpsession.size_send = newsize.to_i
64
- end
65
-
66
- #Sends a javascript back to the browser and exits.
67
- def back
68
- Knj::Web.back
69
- end
70
-
71
- #Draw a input in a table.
72
- def inputs(*args)
64
+ end
65
+
66
+ #Sends a javascript back to the browser and exits.
67
+ def back
68
+ Knj::Web.back
69
+ end
70
+
71
+ #Draw a input in a table.
72
+ def inputs(*args)
73
73
  return Knj::Web.inputs(args)
74
- end
74
+ end
75
+
76
+ #Urlencodes a string.
77
+ def urlenc(str)
78
+ return Knj::Web.urlenc(str)
79
+ end
80
+
81
+ #Urldecodes a string.
82
+ def urldec(str)
83
+ return Knj::Web.urldec(str)
84
+ end
85
+
86
+ #Returns a number localized as a string.
87
+ def num(*args)
88
+ return Knj::Locales.number_out(*args)
89
+ end
90
+
91
+ def get_parse_arrays(arg = nil, ob = nil)
92
+ arg = _get.clone if !arg
93
+
94
+ #Parses key-numeric-hashes into arrays and converts special model-strings into actual models.
95
+ if arg.is_a?(Hash) and Knj::ArrayExt.hash_numeric_keys?(arg)
96
+ arr = []
97
+
98
+ arg.each do |key, val|
99
+ arr << val
100
+ end
101
+
102
+ return self.get_parse_arrays(arr, ob)
103
+ elsif arg.is_a?(Hash)
104
+ arg.each do |key, val|
105
+ arg[key] = self.get_parse_arrays(val, ob)
106
+ end
107
+
108
+ return arg
109
+ elsif arg.is_a?(Array)
110
+ arg.each_index do |key|
111
+ arg[key] = self.get_parse_arrays(arg[key], ob)
112
+ end
113
+
114
+ return arg
115
+ elsif arg.is_a?(String) and match = arg.match(/^#<Model::(.+?)::(\d+)>$/)
116
+ ob = @ob if !ob
117
+ return ob.get(match[1], match[2])
118
+ else
119
+ return arg
120
+ end
121
+ end
122
+
123
+ #Returns the socket-port the appserver is currently running on.
124
+ def port
125
+ return @httpserv.server.addr[1]
126
+ end
75
127
  end
@@ -6,7 +6,7 @@ class Knjappserver::Log < Knj::Datarow
6
6
  data_val = d.ob.get_by(:Log_data_value, {"value" => d.args["object_lookup"].class.name})
7
7
  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.
8
8
 
9
- sql += "
9
+ sql << "
10
10
  LEFT JOIN Log_link ON
11
11
  Log_link.log_id = #{table}.id AND
12
12
  Log_link.object_class_value_id = '#{d.db.esc(data_val.id)}' AND
@@ -14,21 +14,21 @@ class Knjappserver::Log < Knj::Datarow
14
14
  "
15
15
  end
16
16
 
17
- sql += " WHERE 1=1"
17
+ sql << " WHERE 1=1"
18
18
 
19
19
  ret = list_helper(d)
20
20
  d.args.each do |key, val|
21
21
  case key
22
22
  when "object_lookup"
23
- sql += " AND Log_link.id IS NOT NULL"
23
+ sql << " AND Log_link.id IS NOT NULL"
24
24
  else
25
25
  raise "Invalid key: #{key}."
26
26
  end
27
27
  end
28
28
 
29
- sql += ret[:sql_where]
30
- sql += ret[:sql_order]
31
- sql += ret[:sql_limit]
29
+ sql << ret[:sql_where]
30
+ sql << ret[:sql_order]
31
+ sql << ret[:sql_limit]
32
32
 
33
33
  return d.ob.list_bysql(:Log, sql)
34
34
  end
@@ -94,13 +94,13 @@ class Knjappserver::Log < Knj::Datarow
94
94
  self.links.each do |link|
95
95
  obj = link.object(ob_use)
96
96
 
97
- html += ", " if !first
97
+ html << ", " if !first
98
98
  first = false if first
99
99
 
100
100
  if obj.respond_to?(:html)
101
- html += obj.html
101
+ html << obj.html
102
102
  else
103
- html += "#{obj.class.name}{#{obj.id}}"
103
+ html << "#{obj.class.name}{#{obj.id}}"
104
104
  end
105
105
  end
106
106
 
@@ -12,15 +12,15 @@ class Knjappserver::Log_link < Knj::Datarow
12
12
  when "object_class"
13
13
  data_val = d.db.single(:Log_data_value, {"value" => val})
14
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])}'"
15
+ sql << " AND object_class_value_id = '#{d.db.esc(data_val[:id])}'"
16
16
  else
17
17
  raise "Invalid key: #{key}."
18
18
  end
19
19
  end
20
20
 
21
- sql += ret[:sql_where]
22
- sql += ret[:sql_order]
23
- sql += ret[:sql_limit]
21
+ sql << ret[:sql_where]
22
+ sql << ret[:sql_order]
23
+ sql << ret[:sql_limit]
24
24
 
25
25
  return d.ob.list_bysql(:Log_link, sql)
26
26
  end
@@ -23,9 +23,13 @@ class Knjappserver::Session < Knj::Datarow
23
23
  end
24
24
 
25
25
  def flush
26
- self.update(
27
- :sess_data => Base64.encode64(Marshal.dump(@sess_data)),
28
- :date_lastused => Time.now
29
- )
26
+ flush_data = Base64.encode64(Marshal.dump(@sess_data))
27
+
28
+ if self[:sess_data] != flush_data
29
+ self.update(
30
+ :sess_data => flush_data,
31
+ :date_lastused => Time.now
32
+ )
33
+ end
30
34
  end
31
35
  end
@@ -1,10 +1,12 @@
1
- # coding: utf-8
1
+ #coding: utf-8
2
2
 
3
3
  def _(str)
4
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
5
+ session = _session
6
+
7
+ return str.to_s.encode("utf-8") if !kas or !session
8
+ session[:locale] = kas.config[:locale_default] if !session[:locale] and kas.config[:locale_default]
9
+ raise "No locale set for session and ':locale_default' not set in config." if !session[:locale]
10
+ str = kas.gettext.trans(session[:locale], str)
11
+ return str.to_s.encode("utf-8")
10
12
  end
@@ -34,6 +34,10 @@ def _httpsession
34
34
  return Thread.current[:knjappserver][:httpsession] if Thread.current[:knjappserver]
35
35
  end
36
36
 
37
+ def _httpsession_var
38
+ return Thread.current[:knjappserver][:httpsession].httpsession_var if Thread.current[:knjappserver]
39
+ end
40
+
37
41
  def _requestdata
38
42
  return Thread.current[:knjappserver] if Thread.current[:knjappserver]
39
43
  end
@@ -0,0 +1,46 @@
1
+ <h1>Database connections</h1>
2
+
3
+ <table>
4
+ <thead>
5
+ <tr>
6
+ <th>Key</th>
7
+ <th>Free</th>
8
+ </tr>
9
+ </thead>
10
+ <tbody>
11
+ <%
12
+ thread_handler = _kas.db_handler.conns
13
+ if !thread_handler.is_a?(Knj::Threadhandler)
14
+ print "A threadhandler has not been spawned for this instance."
15
+ exit
16
+ end
17
+
18
+ objects = thread_handler.objects.clone
19
+
20
+ objects.each_index do |key|
21
+ val = objects[key]
22
+
23
+ %>
24
+ <tr>
25
+ <td>
26
+ <%=key%>
27
+ </td>
28
+ <td>
29
+ <%=Knj::Strings.yn_str(val[:free])%>
30
+ </td>
31
+ </tr>
32
+ <%
33
+ end
34
+
35
+ if objects.empty?
36
+ %>
37
+ <tr>
38
+ <td colspan="2">
39
+ Thread handler was spawned but no active connections was spawned?
40
+ </td>
41
+ </tr>
42
+ <%
43
+ end
44
+ %>
45
+ </tbody>
46
+ </table>
@@ -0,0 +1,40 @@
1
+ <h1>HTTP sessions</h1>
2
+
3
+ <table>
4
+ <thead>
5
+ <tr>
6
+ <th>Key</th>
7
+ <th>Working</th>
8
+ </tr>
9
+ </thead>
10
+ <tbody>
11
+ <%
12
+ sessions = _kas.httpserv.http_sessions.clone
13
+
14
+ sessions.each_index do |key|
15
+ http_session = sessions[key]
16
+
17
+ %>
18
+ <tr>
19
+ <td>
20
+ <%=key%>
21
+ </td>
22
+ <td>
23
+ <%=Knj::Strings.yn_str(http_session.working)%>
24
+ </td>
25
+ </tr>
26
+ <%
27
+ end
28
+
29
+ if sessions.empty?
30
+ %>
31
+ <tr>
32
+ <td colspan="2">
33
+ No HTTP-sessions has been spawned.
34
+ </td>
35
+ </tr>
36
+ <%
37
+ end
38
+ %>
39
+ </tbody>
40
+ </table>
@@ -0,0 +1,12 @@
1
+ <%
2
+ _httpsession.resp.status = 404
3
+ %>
4
+ <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
5
+ <html><head>
6
+ <title>404 Not Found</title>
7
+ </head><body>
8
+ <h1>Not Found</h1>
9
+ <p>The requested URL <%=_meta["REQUEST_URI"]%> was not found on this server.</p>
10
+ <hr>
11
+ <address>Knjappserver at <%=_meta["HTTP_HOST"]%></address>
12
+ </body></html>