knjappserver 0.0.20 → 0.0.21

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.20
1
+ 0.0.21
data/knjappserver.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{knjappserver}
8
- s.version = "0.0.20"
8
+ s.version = "0.0.21"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Kasper Johansen"]
12
- s.date = %q{2012-03-16}
12
+ s.date = %q{2012-04-26}
13
13
  s.description = %q{Which supports a lot of undocumented stuff.}
14
14
  s.email = %q{k@spernj.org}
15
15
  s.executables = ["check_running.rb", "knjappserver_start.rb"]
@@ -42,6 +42,7 @@ Gem::Specification.new do |s|
42
42
  "lib/include/class_httpsession_contentgroup.rb",
43
43
  "lib/include/class_httpsession_http_request.rb",
44
44
  "lib/include/class_httpsession_http_response.rb",
45
+ "lib/include/class_httpsession_page_environment.rb",
45
46
  "lib/include/class_httpsession_post_multipart.rb",
46
47
  "lib/include/class_knjappserver.rb",
47
48
  "lib/include/class_knjappserver_cleaner.rb",
@@ -1,12 +1,13 @@
1
1
  class Knjappserver::Httpsession
2
2
  attr_accessor :data, :alert_sent
3
- attr_reader :session, :session_id, :session_hash, :kas, :active, :out, :eruby, :browser, :debug, :resp, :page_path, :cgroup, :meta, :httpsession_var, :handler, :working
3
+ attr_reader :get, :session, :session_id, :session_hash, :kas, :active, :out, :eruby, :browser, :debug, :resp, :page_path, :post, :cgroup, :meta, :httpsession_var, :handler, :working
4
4
 
5
5
  dir = File.dirname(__FILE__)
6
6
 
7
7
  autoload :Contentgroup, "#{dir}/class_httpsession_contentgroup.rb"
8
8
  autoload :Http_request, "#{dir}/class_httpsession_http_request.rb"
9
9
  autoload :Http_response, "#{dir}/class_httpsession_http_response.rb"
10
+ autoload :Page_environment, "#{dir}/class_httpsession_page_environment.rb"
10
11
  autoload :Post_multipart, "#{dir}/class_httpsession_post_multipart.rb"
11
12
 
12
13
  def initialize(httpserver, socket)
@@ -17,11 +18,15 @@ class Knjappserver::Httpsession
17
18
  @types = @kas.types
18
19
  @config = @kas.config
19
20
  @active = true
20
- @eruby = Knj::Eruby.new(:cache_hash => @kas.eruby_cache)
21
21
  @debug = @kas.debug
22
22
  @handlers_cache = @config[:handlers_cache]
23
23
  @httpsession_var = {}
24
24
 
25
+ @eruby = Knj::Eruby.new(
26
+ :cache_hash => @kas.eruby_cache,
27
+ :binding_callback => self.method("create_binding")
28
+ )
29
+
25
30
  #Set socket stuff.
26
31
  if RUBY_PLATFORM == "java" or RUBY_ENGINE == "rbx"
27
32
  if @kas.config[:peeraddr_static]
@@ -135,6 +140,12 @@ class Knjappserver::Httpsession
135
140
  end
136
141
  end
137
142
 
143
+ #Creates a new Knjappserver::Binding-object and returns the binding for that object.
144
+ def create_binding
145
+ binding_obj = Knjappserver::Httpsession::Page_environment.new(:httpsession => self, :kas => @kas)
146
+ return binding_obj.get_binding
147
+ end
148
+
138
149
  #Is called when content is added and begings to write the output if it goes above the limit.
139
150
  def add_size(size)
140
151
  @written_size += size
@@ -204,7 +215,7 @@ class Knjappserver::Httpsession
204
215
 
205
216
  def serve
206
217
  STDOUT.print "Generating meta, cookie, get, post and headers.\n" if @debug
207
- @meta = @handler.meta.merge!(@socket_meta)
218
+ @meta = @handler.meta.merge(@socket_meta)
208
219
  @cookie = @handler.cookie
209
220
  @get = @handler.get
210
221
  @post = @handler.post
@@ -292,49 +303,56 @@ class Knjappserver::Httpsession
292
303
  :httpsession => self
293
304
  }) if @kas.events
294
305
 
295
- if @handlers_cache.key?(@ext)
296
- STDOUT.print "Calling handler.\n" if @debug
297
- @handlers_cache[@ext].call(self)
298
- else
299
- #check if we should use a handler for this request.
300
- @config[:handlers].each do |handler_info|
301
- if handler_info.key?(:file_ext) and handler_info[:file_ext] == @ext
302
- return handler_info[:callback].call(self)
303
- elsif handler_info.key?(:path) and handler_info[:mount] and @meta["SCRIPT_NAME"].slice(0, handler_info[:path].length) == handler_info[:path]
304
- @page_path = "#{handler_info[:mount]}#{@meta["SCRIPT_NAME"].slice(handler_info[:path].length, @meta["SCRIPT_NAME"].length)}"
305
- break
306
- end
307
- end
308
-
309
- if !File.exists?(@page_path)
310
- @resp.status = 404
311
- @resp.header("Content-Type", "text/html")
312
- @cgroup.write("File you are looking for was not found: '#{@meta["REQUEST_URI"]}'.")
313
- else
314
- if @headers["cache-control"] and @headers["cache-control"][0]
315
- cache_control = {}
316
- @headers["cache-control"][0].scan(/(.+)=(.+)/) do |match|
317
- cache_control[match[1]] = match[2]
306
+ begin
307
+ Timeout.timeout(@kas.config[:timeout]) do
308
+ if @handlers_cache.key?(@ext)
309
+ STDOUT.print "Calling handler.\n" if @debug
310
+ @handlers_cache[@ext].call(self)
311
+ else
312
+ #check if we should use a handler for this request.
313
+ @config[:handlers].each do |handler_info|
314
+ if handler_info.key?(:file_ext) and handler_info[:file_ext] == @ext
315
+ return handler_info[:callback].call(self)
316
+ elsif handler_info.key?(:path) and handler_info[:mount] and @meta["SCRIPT_NAME"].slice(0, handler_info[:path].length) == handler_info[:path]
317
+ @page_path = "#{handler_info[:mount]}#{@meta["SCRIPT_NAME"].slice(handler_info[:path].length, @meta["SCRIPT_NAME"].length)}"
318
+ break
319
+ end
318
320
  end
319
- end
320
-
321
- cache_dont = true if cache_control and cache_control.key?("max-age") and cache_control["max-age"].to_i <= 0
322
- lastmod = File.mtime(@page_path)
323
-
324
- @resp.header("Last-Modified", lastmod.httpdate)
325
- @resp.header("Expires", (Time.now + 86400).httpdate) #next day.
326
-
327
- if !cache_dont and @headers["if-modified-since"] and @headers["if-modified-since"][0]
328
- request_mod = Knj::Datet.parse(@headers["if-modified-since"][0]).time
329
321
 
330
- if request_mod == lastmod
331
- @resp.status = 304
332
- return nil
322
+ if !File.exists?(@page_path)
323
+ @resp.status = 404
324
+ @resp.header("Content-Type", "text/html")
325
+ @cgroup.write("File you are looking for was not found: '#{@meta["REQUEST_URI"]}'.")
326
+ else
327
+ if @headers["cache-control"] and @headers["cache-control"][0]
328
+ cache_control = {}
329
+ @headers["cache-control"][0].scan(/(.+)=(.+)/) do |match|
330
+ cache_control[match[1]] = match[2]
331
+ end
332
+ end
333
+
334
+ cache_dont = true if cache_control and cache_control.key?("max-age") and cache_control["max-age"].to_i <= 0
335
+ lastmod = File.mtime(@page_path)
336
+
337
+ @resp.header("Last-Modified", lastmod.httpdate)
338
+ @resp.header("Expires", (Time.now + 86400).httpdate) #next day.
339
+
340
+ if !cache_dont and @headers["if-modified-since"] and @headers["if-modified-since"][0]
341
+ request_mod = Knj::Datet.parse(@headers["if-modified-since"].first).time
342
+
343
+ if request_mod == lastmod
344
+ @resp.status = 304
345
+ return nil
346
+ end
347
+ end
348
+
349
+ @cgroup.new_io(:type => :file, :path => @page_path)
333
350
  end
334
351
  end
335
-
336
- @cgroup.new_io(File.new(@page_path))
337
352
  end
353
+ rescue Timeout::Error
354
+ @resp.status = 500
355
+ print "The request timed out."
338
356
  end
339
357
 
340
358
  @cgroup.mark_done
@@ -121,24 +121,22 @@ class Knjappserver::Httpsession::Contentgroup
121
121
  if data.is_a?(Knjappserver::Httpsession::Contentgroup)
122
122
  data.write_to_socket
123
123
  elsif data.key?(:str)
124
- if data[:str].is_a?(File)
125
- file = data[:str]
126
-
127
- loop do
128
- begin
129
- buf = file.sysread(16384)
130
- rescue EOFError
131
- break
132
- end
133
-
134
- if @chunked
135
- @socket.write("#{buf.length.to_s(16)}#{NL}#{buf}#{NL}")
136
- else
137
- @socket.write(buf)
124
+ if data[:str].is_a?(Hash) and data[:str][:type] == :file
125
+ File.open(data[:str][:path], "r") do |file|
126
+ loop do
127
+ begin
128
+ buf = file.sysread(16384)
129
+ rescue EOFError
130
+ break
131
+ end
132
+
133
+ if @chunked
134
+ @socket.write("#{buf.length.to_s(16)}#{NL}#{buf}#{NL}")
135
+ else
136
+ @socket.write(buf)
137
+ end
138
138
  end
139
139
  end
140
-
141
- file.close
142
140
  else
143
141
  loop do
144
142
  break if data[:done] and data[:str].size <= 0
@@ -1,4 +1,3 @@
1
- require "uri"
2
1
  require "knj/web"
3
2
 
4
3
  #If we are running on JRuby or Rubinius this will seriously speed things up if we are behind a proxy.
@@ -18,40 +17,56 @@ class Knjappserver::Httpsession::Http_request
18
17
  end
19
18
 
20
19
  #Reads content from the socket until the end of headers. Also does various error-checks.
21
- def read_socket
20
+ def read_socket(socket, cont)
22
21
  loop do
23
- raise Errno::ECONNRESET, "Socket closed." if @socket.closed?
24
- read = @socket.gets
22
+ raise Errno::ECONNRESET, "Socket closed." if socket.closed?
23
+ read = socket.gets
25
24
  raise Errno::ECONNRESET, "Socket returned non-string: '#{read.class.name}'." if !read.is_a?(String)
26
- @cont << read
27
- break if @cont[-4..-1] == "\r\n\r\n" or @cont[-2..-1] == "\n\n"
25
+ cont << read
26
+ break if cont[-4..-1] == "\r\n\r\n" or cont[-2..-1] == "\n\n"
28
27
  end
29
28
  end
30
29
 
30
+ def reset
31
+ @modified_since = nil
32
+ @get = nil
33
+ @post = nil
34
+ @cookie = nil
35
+ @meta = nil
36
+ @page_path = nil
37
+ @headers = nil
38
+ @http_version = nil
39
+ @read = nil
40
+ @clength = nil
41
+ @speec = nil
42
+ @percent = nil
43
+ @secs_left = nil
44
+ end
45
+
31
46
  #Generates data on object from the given socket.
32
47
  def socket_parse(socket)
33
- @modified_since = nil
34
- @cont = ""
35
- @socket = socket
36
- self.read_socket
48
+ self.reset
49
+ cont = ""
50
+ self.read_socket(socket, cont)
37
51
 
38
52
  #Parse URI (page_path and get).
39
- match = @cont.match(/^(GET|POST|HEAD)\s+(.+)\s+HTTP\/1\.(\d+)\s*/)
40
- raise "Could not parse request: '#{@cont.split("\n").first}'." if !match
53
+ match = cont.match(/^(GET|POST|HEAD)\s+(.+)\s+HTTP\/1\.(\d+)\s*/)
54
+ raise "Could not parse request: '#{cont.split("\n").first}'." if !match
41
55
 
42
56
  @http_version = "1.#{match[3]}"
43
57
 
44
58
  method = match[1]
45
- @cont = @cont.gsub(match[0], "")
46
- uri = URI.parse(match[2])
59
+ cont = cont.gsub(match[0], "")
60
+
61
+ uri = Knj::Web.parse_uri(match[2])
47
62
 
48
- page_filepath = Knj::Web.urldec(uri.path)
63
+ page_filepath = Knj::Web.urldec(uri[:path])
49
64
  if page_filepath.length <= 0 or page_filepath == "/" or File.directory?("#{@kas.config[:doc_root]}/#{page_filepath}")
50
65
  page_filepath = "#{page_filepath}/#{@kas.config[:default_page]}"
51
66
  end
52
67
 
53
68
  @page_path = "#{@kas.config[:doc_root]}/#{page_filepath}"
54
- @get = Knj::Web.parse_urlquery(uri.query.to_s, {:urldecode => true, :force_utf8 => true})
69
+ @get = Knj::Web.parse_urlquery(uri[:query], {:urldecode => true, :force_utf8 => true})
55
70
 
56
71
  if @get["_kas_httpsession_id"]
57
72
  @kas.httpsessions_ids[@get["_kas_httpsession_id"]] = @args[:httpsession]
@@ -63,12 +78,12 @@ class Knjappserver::Httpsession::Http_request
63
78
  @cookie = {}
64
79
  @meta = {
65
80
  "REQUEST_METHOD" => method,
66
- "QUERY_STRING" => uri.query,
81
+ "QUERY_STRING" => uri[:query],
67
82
  "REQUEST_URI" => match[2],
68
- "SCRIPT_NAME" => uri.path
83
+ "SCRIPT_NAME" => uri[:path]
69
84
  }
70
85
 
71
- @cont.scan(/^(\S+):\s*(.+)\r\n/) do |header_match|
86
+ cont.scan(/^(\S+):\s*(.+)\r\n/) do |header_match|
72
87
  key = header_match[0].downcase
73
88
  val = header_match[1]
74
89
 
@@ -141,8 +156,8 @@ class Knjappserver::Httpsession::Http_request
141
156
  read_size = @clength - @read
142
157
  read_size = 4096 if read_size > 4096
143
158
 
144
- raise Errno::ECONNRESET, "Socket closed." if @socket.closed?
145
- read = @socket.read(read_size)
159
+ raise Errno::ECONNRESET, "Socket closed." if socket.closed?
160
+ read = socket.read(read_size)
146
161
  raise Errno::ECONNRESET, "Socket returned non-string: '#{read.class.name}'." if !read.is_a?(String)
147
162
  post_data << read
148
163
  @read += read.length
@@ -59,6 +59,9 @@ class Knjappserver::Httpsession::Http_response
59
59
  end
60
60
 
61
61
  def header(key, val)
62
+ lines = val.to_s.count("\n") + 1
63
+ raise "Value contains more lines than 1 (#{lines})." if lines > 1
64
+
62
65
  if !@headers_sent
63
66
  @headers[key.to_s.downcase] = [key, val]
64
67
  else
@@ -0,0 +1,66 @@
1
+ #This class handels all the magic-methods in a different way - by defining them as methods on the binding for the .rhtml-pages.
2
+ class Knjappserver::Httpsession::Page_environment
3
+ def initialize(args = {})
4
+ @args = args
5
+ end
6
+
7
+ def get_binding
8
+ return binding
9
+ end
10
+
11
+ def _buf
12
+ return $stdout
13
+ end
14
+
15
+ def _cookie
16
+ return @args[:httpsession].cookie
17
+ end
18
+
19
+ def _db
20
+ return @args[:kas].db_handler
21
+ end
22
+
23
+ def _get
24
+ return @args[:httpsession].get
25
+ end
26
+
27
+ def _kas
28
+ return @args[:kas]
29
+ end
30
+
31
+ alias _requestdata _kas
32
+
33
+ def _kas_vars
34
+ return @args[:kas].vars
35
+ end
36
+
37
+ def _httpsession
38
+ return @args[:httpsession]
39
+ end
40
+
41
+ def _httpsession_var
42
+ return @args[:httpsession].httpsession_var
43
+ end
44
+
45
+ def _post
46
+ return @args[:httpsession].post
47
+ end
48
+
49
+ def _meta
50
+ return @args[:httpsession].meta
51
+ end
52
+
53
+ alias _server _meta
54
+
55
+ def _session
56
+ return @args[:httpsession].session.sess_data
57
+ end
58
+
59
+ def _session_hash
60
+ return @args[:httpsession].session_hash
61
+ end
62
+
63
+ def _session_obj
64
+ return @args[:httpsession].session
65
+ end
66
+ end
@@ -5,6 +5,7 @@ class Knjappserver
5
5
  appsrv_dir = File.dirname(__FILE__)
6
6
  autoload :ERBHandler, "#{appsrv_dir}/class_erbhandler"
7
7
  autoload :Log, "#{appsrv_dir}/class_log.rb"
8
+ autoload :Log_link, "#{appsrv_dir}/class_log_link.rb"
8
9
 
9
10
  def initialize(config)
10
11
  raise "No arguments given." if !config.is_a?(Hash)
@@ -67,8 +68,6 @@ class Knjappserver
67
68
  @path_knjappserver = File.dirname(__FILE__)
68
69
  if @config[:knjrbfw_path]
69
70
  @path_knjrbfw = @config[:knjrbfw_path]
70
- elsif $knjappserver_config and $knjappserver_config["knjrbfw"]
71
- @path_knjrbfw = $knjappserver_config["knjrbfw"]
72
71
  else
73
72
  @path_knjrbfw = ""
74
73
  end
@@ -232,8 +231,7 @@ class Knjappserver
232
231
 
233
232
  #Save the PID to the run-file.
234
233
  print "Setting run-file.\n" if @debug
235
- require "tmpdir"
236
- tmpdir = "#{Dir.tmpdir}/knjappserver"
234
+ tmpdir = "#{Knj::Os.tmpdir}/knjappserver"
237
235
  tmppath = "#{tmpdir}/run_#{@config[:title]}"
238
236
 
239
237
  if !File.exists?(tmpdir)
@@ -372,8 +370,8 @@ class Knjappserver
372
370
  STDOUT.print "Threadpool startet.\n" if @debug
373
371
  @httpserv.start
374
372
  STDOUT.print "Appserver startet.\n" if @debug
375
- rescue Interrupt
376
- STDOUT.print "Got interrupt - stopping appserver.\n" if @debug
373
+ rescue Interrupt => e
374
+ STDOUT.print "Got interrupt - trying to stop appserver.\n" if @debug
377
375
  self.stop
378
376
  end
379
377
  end
@@ -392,12 +390,10 @@ class Knjappserver
392
390
  self.sessions_flush
393
391
  }
394
392
 
395
- #If we cant get a paused-execution in 10 secs - we just force the stop.
393
+ #If we cant get a paused-execution in 5 secs - we just force the stop.
396
394
  begin
397
- Timeout.timeout(10) do
398
- self.paused_exec do
399
- proc_stop.call
400
- end
395
+ Timeout.timeout(5) do
396
+ self.paused_exec(&proc_stop)
401
397
  end
402
398
  rescue Timeout::Error, SystemExit, Interrupt
403
399
  STDOUT.print "Forcing stop-appserver - couldnt get timing window.\n" if @debug
@@ -423,12 +419,15 @@ class Knjappserver
423
419
 
424
420
  #Will stop handeling any more HTTP-requests, run the proc given and return handeling HTTP-requests.
425
421
  def paused_exec
422
+ raise "No block given." if !block_given?
426
423
  self.pause
427
424
 
428
425
  begin
429
426
  sleep 0.2 while @httpserv and @httpserv.working_count and @httpserv.working_count > 0
430
427
  @paused_mutex.synchronize do
431
- yield
428
+ Timeout.timeout(15) do
429
+ yield
430
+ end
432
431
  end
433
432
  ensure
434
433
  self.unpause
@@ -8,7 +8,7 @@ class Knjappserver
8
8
 
9
9
  #This should not be runned via _kas.timeout because timeout wont run when @should_restart is true! - knj
10
10
  Thread.new do
11
- begin
11
+ begin
12
12
  loop do
13
13
  sleep time
14
14
 
@@ -91,51 +91,43 @@ class Knjappserver
91
91
  end
92
92
 
93
93
  #This flushes (writes) all session-data to the server and deletes old unused sessions from the database.
94
- self.timeout(:time => @config[:cleaner_timeout]) do
95
- self.clean
96
- end
94
+ self.timeout(:time => @config[:cleaner_timeout], &self.method("clean"))
97
95
  end
98
96
 
99
97
  #This method can be used to clean the appserver. Dont call this from a HTTP-request.
100
98
  def clean
101
- self.paused_exec do
102
- STDOUT.print "Cleaning sessions on appserver.\n" if @config[:debug]
103
-
104
- #Clean up various inactive sessions.
105
- session_not_ids = []
106
- time_check = Time.now.to_i - 300
107
- newsessions = {}
108
- @sessions.each do |session_hash, session_data|
109
- session_data[:dbobj].flush
110
-
111
- if session_data[:time_lastused].to_i > time_check
112
- newsessions[session_hash] = session_data
113
- session_not_ids << session_data[:dbobj].id
114
- end
115
- end
116
-
117
- @sessions = newsessions
99
+ STDOUT.print "Cleaning sessions on appserver.\n" if @config[:debug]
100
+
101
+ #Clean up various inactive sessions.
102
+ session_not_ids = []
103
+ time_check = Time.now.to_i - 300
104
+ newsessions = {}
105
+ @sessions.each do |session_hash, session_data|
106
+ session_data[:dbobj].flush
118
107
 
119
- STDOUT.print "Delete sessions...\n" if @config[:debug]
120
- @ob.list(:Session, {"id_not" => session_not_ids, "date_lastused_below" => (Time.now - 5356800)}) do |session|
121
- idhash = session[:idhash]
122
- STDOUT.print "Deleting session: '#{session.id}'.\n" if @config[:debug]
123
- @ob.delete(session)
124
- @sessions.delete(idhash)
108
+ if session_data[:time_lastused].to_i > time_check
109
+ newsessions[session_hash] = session_data
110
+ session_not_ids << session_data[:dbobj].id
125
111
  end
126
-
127
-
128
- #Clean database weak references from the tables-module.
129
- @db.clean
130
-
131
- #Clean the object-handler.
132
- @ob.clean_all
133
-
134
- #Run garbage-collector.
135
- GC.start
136
-
137
- #Call various user-connected methods.
138
- @events.call(:on_clean) if @events
139
112
  end
113
+
114
+ @sessions = newsessions
115
+
116
+ STDOUT.print "Delete sessions...\n" if @config[:debug]
117
+ @ob.list(:Session, {"id_not" => session_not_ids, "date_lastused_below" => (Time.now - 5356800)}) do |session|
118
+ idhash = session[:idhash]
119
+ STDOUT.print "Deleting session: '#{session.id}'.\n" if @config[:debug]
120
+ @ob.delete(session)
121
+ @sessions.delete(idhash)
122
+ end
123
+
124
+ #Clean database weak references from the tables-module.
125
+ @db.clean
126
+
127
+ #Clean the object-handler.
128
+ @ob.clean_all
129
+
130
+ #Call various user-connected methods.
131
+ @events.call(:on_clean) if @events
140
132
  end
141
133
  end
@@ -93,10 +93,10 @@ class Knjappserver
93
93
  end
94
94
 
95
95
  html = "An error occurred.<br /><br />"
96
- html << "<b>#{e.class.name.html}: #{e.message.html}</b><br /><br />"
96
+ html << "<b>#{Knj::Web.html(e.class.name)}: #{Knj::Web.html(e.message)}</b><br /><br />"
97
97
 
98
98
  e.backtrace.each do |line|
99
- html << line.html + "<br />"
99
+ html << "#{Knj::Web.html(line)}<br />"
100
100
  end
101
101
 
102
102
  html << "<br /><b>Post:</b><br /><pre>#{Knj::Php.print_r(_post, true)}</pre>" if _post
@@ -112,7 +112,27 @@ class Knjappserver
112
112
  end
113
113
  end
114
114
 
115
+ #Converts fileuploads into strings so logging wont be crazy big.
116
+ def log_hash_safe(hash)
117
+ hash_obj = {}
118
+ hash.each do |key, val|
119
+ if val.is_a?(Knjappserver::Httpsession::Post_multipart::File_upload)
120
+ hash_obj[key] = "<Fileupload>"
121
+ elsif val.is_a?(Hash)
122
+ hash_obj[key] = self.log_hash_safe(val)
123
+ else
124
+ hash_obj[key] = val
125
+ end
126
+ end
127
+
128
+ return hash_obj
129
+ end
130
+
131
+ #Handles the hashes that should be logged.
115
132
  def log_hash_ins(hash_obj)
133
+ #Sort out fileuploads - it would simply bee too big to log this.
134
+ hash_obj = self.log_hash_safe(hash_obj)
135
+
116
136
  inserts_links = []
117
137
  ret = {}
118
138
  [:keys, :values].each do |type|
@@ -269,6 +289,18 @@ class Knjappserver
269
289
  end
270
290
  end
271
291
 
292
+ #Deletes all logs for an object.
293
+ def logs_delete(obj)
294
+ @ob.list(:Log_link, {"object_class" => obj.class.name, "object_id" => obj.id}) do |log_link|
295
+ log = log_link.log
296
+ @ob.delete(log_link)
297
+
298
+ if log
299
+ @ob.delete(log) if log.links("count" => true) <= 0
300
+ end
301
+ end
302
+ end
303
+
272
304
  #Returns the HTML for a table with logs from a given object.
273
305
  def logs_table(obj, args = {})
274
306
  links = @ob.list(:Log_link, {"object_class" => obj.class.name, "object_id" => obj.id, "limit" => 500, "orderby" => [["id", "desc"]]})
@@ -48,7 +48,7 @@ class Knjappserver
48
48
  begin
49
49
  #Use subprocessing to avoid the mail-framework (activesupport and so on, also possible memory leaks in those large frameworks).
50
50
  require "knj/process_meta"
51
- subproc = Knj::Process_meta.new("debug" => @debug, "debug_err" => true)
51
+ subproc = Knj::Process_meta.new("debug" => @debug, "debug_err" => true, "id" => "knjappserver_mailing")
52
52
  subproc.static("Object", "require", "rubygems")
53
53
  subproc.static("Object", "require", "mail")
54
54
  subproc.static("Object", "require", "#{@config[:knjrbfw_path]}knjrbfw")
@@ -49,7 +49,14 @@ class Knjappserver::Threadding_timeout
49
49
 
50
50
  begin
51
51
  @running = true
52
- @args[:block].call(*@args[:args])
52
+
53
+ if @args.key?(:timeout)
54
+ Timeout.timeout(@args[:timeout]) do
55
+ @args[:block].call(*@args[:args])
56
+ end
57
+ else
58
+ @args[:block].call(*@args[:args])
59
+ end
53
60
  ensure
54
61
  @running = false
55
62
  @kas.ob.db.free_thread if @kas.ob.db.opts[:threadsafe]
@@ -1,13 +1,6 @@
1
1
  class Knjappserver
2
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
-
3
+ args[:locale] = self.trans_locale if !args[:locale]
11
4
  trans_val = @translations.get(obj, key, args).to_s
12
5
 
13
6
  if trans_val.length <= 0
@@ -17,12 +10,24 @@ class Knjappserver
17
10
  return trans_val
18
11
  end
19
12
 
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]
13
+ def trans_locale(args = {})
14
+ if args.is_a?(Hash) and args[:locale]
15
+ return args[:locale]
16
+ elsif _session and _session[:locale]
17
+ return _session[:locale]
18
+ elsif _httpsession and _httpsession.data[:locale]
19
+ return _httpsession.data[:locale]
20
+ elsif Thread.current[:locale]
21
+ return Thread.current[:locale]
22
+ elsif @config[:locale_default]
23
+ return @config[:locale_default]
24
24
  end
25
25
 
26
+ raise "Could not figure out locale."
27
+ end
28
+
29
+ def trans_set(obj, values, args = {})
30
+ args[:locale] = self.trans_locale if !args[:locale]
26
31
  @translations.set(obj, values, args)
27
32
  end
28
33
 
@@ -25,6 +25,13 @@ class Knjappserver::Log < Knj::Datarow
25
25
  case key
26
26
  when "object_lookup"
27
27
  sql << " AND Log_link.id IS NOT NULL"
28
+ when "tag"
29
+ data_val = d.ob.get_by(:Log_data_value, {"value" => val})
30
+ if !data_val
31
+ sql << " AND false"
32
+ else
33
+ sql << " AND Log.tag_data_id = '#{d.db.esc(data_val.id)}'"
34
+ end
28
35
  else
29
36
  raise "Invalid key: #{key}."
30
37
  end
@@ -4,9 +4,15 @@ class Knjappserver::Log_link < Knj::Datarow
4
4
  ]
5
5
 
6
6
  def self.list(d, &block)
7
- sql = "SELECT * FROM #{table} WHERE 1=1"
7
+ if d.args["count"]
8
+ sql = "SELECT COUNT(id) AS count FROM #{table} WHERE 1=1"
9
+ count = true
10
+ d.args.delete("count")
11
+ else
12
+ sql = "SELECT * FROM #{table} WHERE 1=1"
13
+ end
8
14
 
9
- ret = list_helper(d)
15
+ ret = self.list_helper(d)
10
16
  d.args.each do |key, val|
11
17
  case key
12
18
  when "object_class"
@@ -19,6 +25,9 @@ class Knjappserver::Log_link < Knj::Datarow
19
25
  end
20
26
 
21
27
  sql << ret[:sql_where]
28
+
29
+ return d.db.query(sql).fetch[:count].to_i if count
30
+
22
31
  sql << ret[:sql_order]
23
32
  sql << ret[:sql_limit]
24
33
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knjappserver
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.20
4
+ version: 0.0.21
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,12 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-03-16 00:00:00.000000000 +01:00
12
+ date: 2012-04-26 00:00:00.000000000 +02:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: knjrbfw
17
- requirement: &12366780 !ruby/object:Gem::Requirement
17
+ requirement: &10828140 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: '0'
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *12366780
25
+ version_requirements: *10828140
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: erubis
28
- requirement: &12365600 !ruby/object:Gem::Requirement
28
+ requirement: &10827060 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
- version_requirements: *12365600
36
+ version_requirements: *10827060
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: mail
39
- requirement: &12365060 !ruby/object:Gem::Requirement
39
+ requirement: &10826360 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ! '>='
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: '0'
45
45
  type: :runtime
46
46
  prerelease: false
47
- version_requirements: *12365060
47
+ version_requirements: *10826360
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: rspec
50
- requirement: &12364340 !ruby/object:Gem::Requirement
50
+ requirement: &10825400 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ~>
@@ -55,10 +55,10 @@ dependencies:
55
55
  version: 2.3.0
56
56
  type: :development
57
57
  prerelease: false
58
- version_requirements: *12364340
58
+ version_requirements: *10825400
59
59
  - !ruby/object:Gem::Dependency
60
60
  name: bundler
61
- requirement: &12363160 !ruby/object:Gem::Requirement
61
+ requirement: &10824260 !ruby/object:Gem::Requirement
62
62
  none: false
63
63
  requirements:
64
64
  - - ~>
@@ -66,10 +66,10 @@ dependencies:
66
66
  version: 1.0.0
67
67
  type: :development
68
68
  prerelease: false
69
- version_requirements: *12363160
69
+ version_requirements: *10824260
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: jeweler
72
- requirement: &12362140 !ruby/object:Gem::Requirement
72
+ requirement: &10822320 !ruby/object:Gem::Requirement
73
73
  none: false
74
74
  requirements:
75
75
  - - ~>
@@ -77,10 +77,10 @@ dependencies:
77
77
  version: 1.6.3
78
78
  type: :development
79
79
  prerelease: false
80
- version_requirements: *12362140
80
+ version_requirements: *10822320
81
81
  - !ruby/object:Gem::Dependency
82
82
  name: rcov
83
- requirement: &12352800 !ruby/object:Gem::Requirement
83
+ requirement: &10821260 !ruby/object:Gem::Requirement
84
84
  none: false
85
85
  requirements:
86
86
  - - ! '>='
@@ -88,10 +88,10 @@ dependencies:
88
88
  version: '0'
89
89
  type: :development
90
90
  prerelease: false
91
- version_requirements: *12352800
91
+ version_requirements: *10821260
92
92
  - !ruby/object:Gem::Dependency
93
93
  name: sqlite3
94
- requirement: &12352260 !ruby/object:Gem::Requirement
94
+ requirement: &10820300 !ruby/object:Gem::Requirement
95
95
  none: false
96
96
  requirements:
97
97
  - - ! '>='
@@ -99,10 +99,10 @@ dependencies:
99
99
  version: '0'
100
100
  type: :development
101
101
  prerelease: false
102
- version_requirements: *12352260
102
+ version_requirements: *10820300
103
103
  - !ruby/object:Gem::Dependency
104
104
  name: json
105
- requirement: &12351520 !ruby/object:Gem::Requirement
105
+ requirement: &10819440 !ruby/object:Gem::Requirement
106
106
  none: false
107
107
  requirements:
108
108
  - - ! '>='
@@ -110,7 +110,7 @@ dependencies:
110
110
  version: '0'
111
111
  type: :development
112
112
  prerelease: false
113
- version_requirements: *12351520
113
+ version_requirements: *10819440
114
114
  description: Which supports a lot of undocumented stuff.
115
115
  email: k@spernj.org
116
116
  executables:
@@ -145,6 +145,7 @@ files:
145
145
  - lib/include/class_httpsession_contentgroup.rb
146
146
  - lib/include/class_httpsession_http_request.rb
147
147
  - lib/include/class_httpsession_http_response.rb
148
+ - lib/include/class_httpsession_page_environment.rb
148
149
  - lib/include/class_httpsession_post_multipart.rb
149
150
  - lib/include/class_knjappserver.rb
150
151
  - lib/include/class_knjappserver_cleaner.rb
@@ -207,7 +208,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
207
208
  version: '0'
208
209
  segments:
209
210
  - 0
210
- hash: 894779464839235539
211
+ hash: -1162266061337157012
211
212
  required_rubygems_version: !ruby/object:Gem::Requirement
212
213
  none: false
213
214
  requirements: