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
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.16
1
+ 0.0.17
@@ -1,16 +1,25 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require "#{File.dirname(__FILE__)}/../lib/knjappserver.rb"
4
- require "knjrbfw"
4
+
5
+ knjrbfw_path = ""
5
6
 
6
7
  ARGV.each do |arg|
7
- if arg == "--active_support"
8
- ARGV.delete(arg)
9
- require "active_support"
10
- require "active_support/core_ext"
11
- end
8
+ if arg == "--active_support"
9
+ ARGV.delete(arg)
10
+ require "active_support"
11
+ require "active_support/core_ext"
12
+ elsif match = arg.match(/--knjrbfw_path=(.+)/)
13
+ knjrbfw_path = match[1]
14
+ ARGV.delete(arg)
15
+ else
16
+ print "Unknown argument: '#{arg}'.\n"
17
+ exit
18
+ end
12
19
  end
13
20
 
21
+ require "#{knjrbfw_path}knjrbfw"
22
+
14
23
  filepath = File.dirname(__FILE__) + "/../lib/"
15
24
 
16
25
  if File.exists?($0)
@@ -20,31 +29,14 @@ else
20
29
  end
21
30
 
22
31
  require "#{conf_path}conf/conf_vars"
23
- require "webrick"
24
32
  require "#{$knjappserver_config["knjrbfw"]}knj/autoload"
25
- require "#{$knjappserver_config["knjrbfw"]}knj/ext/webrick"
26
33
 
27
34
  $knjappserver = {
28
- :path => Knj::Php.realpath(File.dirname(__FILE__))
35
+ :path => File.realpath(File.dirname(__FILE__))
29
36
  }
30
37
 
31
- Knj::Os.chdir_file(Knj::Php.realpath(__FILE__))
38
+ Knj::Os.chdir_file(File.realpath(__FILE__))
32
39
  require "#{filepath}include/class_knjappserver.rb"
33
40
 
34
- #Lets hack the $stdout to make it possible to have many running threads that all uses print.
35
- require "#{filepath}include/class_customio.rb"
36
- cio = Knjappserver::CustomIO.new
37
- $stdout = cio
38
-
39
- Thread.new do
40
- loop do
41
- sleep 30
42
- GC.enable if RUBY_ENGINE != "jruby"
43
- GC.enable
44
- GC.start
45
- ObjectSpace.garbage_collect
46
- end
47
- end
48
-
49
41
  print "Starting knjAppServer.\n"
50
42
  require "#{conf_path}conf/conf"
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{knjappserver}
8
- s.version = "0.0.16"
8
+ s.version = "0.0.17"
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{2011-11-15}
12
+ s.date = %q{2012-02-21}
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"]
@@ -36,17 +36,18 @@ Gem::Specification.new do |s|
36
36
  "lib/files/run/README",
37
37
  "lib/include/class_customio.rb",
38
38
  "lib/include/class_erbhandler.rb",
39
- "lib/include/class_httpresp.rb",
40
39
  "lib/include/class_httpserver.rb",
41
40
  "lib/include/class_httpsession.rb",
42
41
  "lib/include/class_httpsession_contentgroup.rb",
43
- "lib/include/class_httpsession_knjengine.rb",
44
- "lib/include/class_httpsession_mongrel.rb",
45
- "lib/include/class_httpsession_webrick.rb",
42
+ "lib/include/class_httpsession_http_request.rb",
43
+ "lib/include/class_httpsession_http_response.rb",
44
+ "lib/include/class_httpsession_post_multipart.rb",
46
45
  "lib/include/class_knjappserver.rb",
47
46
  "lib/include/class_knjappserver_cleaner.rb",
48
47
  "lib/include/class_knjappserver_cmdline.rb",
49
48
  "lib/include/class_knjappserver_errors.rb",
49
+ "lib/include/class_knjappserver_leakproxy_client.rb",
50
+ "lib/include/class_knjappserver_leakproxy_server.rb",
50
51
  "lib/include/class_knjappserver_logging.rb",
51
52
  "lib/include/class_knjappserver_mailing.rb",
52
53
  "lib/include/class_knjappserver_sessions.rb",
@@ -68,13 +69,23 @@ Gem::Specification.new do |s|
68
69
  "lib/pages/benchmark_print.rhtml",
69
70
  "lib/pages/benchmark_simple.rhtml",
70
71
  "lib/pages/benchmark_threadded_content.rhtml",
72
+ "lib/pages/debug_database_connections.rhtml",
73
+ "lib/pages/debug_http_sessions.rhtml",
74
+ "lib/pages/error_notfound.rhtml",
71
75
  "lib/pages/logs_latest.rhtml",
72
76
  "lib/pages/logs_show.rhtml",
73
77
  "lib/pages/spec.rhtml",
78
+ "lib/pages/spec_post.rhtml",
74
79
  "lib/pages/spec_test_multiple_clients.rhtml",
80
+ "lib/pages/spec_thread_joins.rhtml",
75
81
  "lib/pages/spec_threadded_content.rhtml",
82
+ "lib/pages/tests.rhtml",
76
83
  "lib/scripts/benchmark.rb",
84
+ "lib/scripts/knjappserver_cgi.rb",
85
+ "lib/scripts/knjappserver_fcgi.rb",
86
+ "lib/scripts/leakproxy.rb",
77
87
  "spec/knjappserver_spec.rb",
88
+ "spec/leakproxy_spec.rb",
78
89
  "spec/spec_helper.rb"
79
90
  ]
80
91
  s.homepage = %q{http://github.com/kaspernj/knjappserver}
@@ -1,4 +1,4 @@
1
- rpath = Knj::Php.realpath(File.dirname(__FILE__) + "/../include/class_erbhandler.rb")
1
+ rpath = File.realpath(File.dirname(__FILE__) + "/../include/class_erbhandler.rb")
2
2
  require rpath
3
3
  erbhandler = Knjappserver::ERBHandler.new
4
4
 
@@ -38,7 +38,8 @@ begin
38
38
  end
39
39
  end.parse!
40
40
  rescue OptionParser::InvalidOption => e
41
- Knj::Php.die(e.message + "\n")
41
+ print "#{e.message}\n"
42
+ exit
42
43
  end
43
44
 
44
45
  $knjappserver[:knjappserver] = Knjappserver.new(
@@ -52,7 +53,6 @@ $knjappserver[:knjappserver] = Knjappserver.new(
52
53
  :doc_root => "[path to rhtml files]",
53
54
  :hostname => false,
54
55
  :default_filetype => "text/html",
55
- :engine_webrick => true,
56
56
  :error_report_emails => ["admin_email"],
57
57
  :error_report_from => "robot_email",
58
58
  :locales_root => "[path to locale files]",
@@ -116,8 +116,7 @@ class Knjappserver
116
116
  ],
117
117
  "indexes_remove" => {
118
118
  "object_class" => true
119
- },
120
- "renames" => ["translations"]
119
+ }
121
120
  }
122
121
  }
123
122
  }
@@ -1,35 +1,18 @@
1
1
  class Knjappserver::CustomIO < StringIO
2
2
  def print(str)
3
- thread = Thread.current
4
3
  str = str.to_s
4
+ appsrv = Thread.current[:knjappserver]
5
5
 
6
- if thread and thread[:knjappserver] and thread[:knjappserver][:contentgroup]
7
- httpsession = thread[:knjappserver][:httpsession]
8
-
9
- if httpsession
10
- wsize = httpsession.written_size
11
- wsize += str.size
12
-
13
- if wsize >= httpsession.size_send
14
- httpsession.cgroup.write_output
15
- end
16
- end
17
-
18
- thread[:knjappserver][:contentgroup].write(str)
6
+ if appsrv and cgroup = appsrv[:contentgroup] and httpsession = appsrv[:httpsession]
7
+ httpsession.add_size(str.size)
8
+ cgroup.write(str)
19
9
  else
20
10
  STDOUT.print(str) if !STDOUT.closed?
21
11
  end
22
12
  end
23
13
 
24
- def <<(str)
25
- self.print(str)
26
- end
27
-
28
- def write(str)
29
- self.print(str)
30
- end
31
-
32
- def p(str)
33
- self.print(str)
34
- end
14
+ alias << print
15
+ alias write print
16
+ alias p print
17
+ alias puts print
35
18
  end
@@ -14,6 +14,12 @@ class Knjappserver::ERBHandler
14
14
  @connected[eruby.__id__] = true
15
15
  end
16
16
 
17
- eruby.import(httpsess.page_path)
17
+ if !File.exists?(httpsess.page_path)
18
+ eruby.import("#{File.dirname(__FILE__)}/../pages/error_notfound.rhtml")
19
+ else
20
+ eruby.import(httpsess.page_path)
21
+ end
22
+
23
+ httpsess.resp.status = 500 if eruby.error
18
24
  end
19
25
  end
@@ -5,45 +5,58 @@ class Knjappserver::Httpserver
5
5
  def initialize(kas)
6
6
  @kas = kas
7
7
  @debug = @kas.config[:debug]
8
+ @mutex_count = Mutex.new
8
9
  end
9
10
 
10
11
  def start
11
12
  @http_sessions = []
12
13
  @working_count = 0
13
14
 
14
- raise "No host was given." if !@kas.config.has_key?(:host)
15
- raise "No port was given." if !@kas.config.has_key?(:port)
15
+ raise "No host was given." if @kas and !@kas.config.has_key?(:host)
16
+ raise "No port was given." if @kas and !@kas.config.has_key?(:port)
16
17
  @server = TCPServer.new(@kas.config[:host], @kas.config[:port])
17
18
 
18
- @thread_accept = Knj::Thread.new do
19
- loop do
20
- if !@server or @server.closed?
21
- sleep 1
22
- next
23
- end
24
-
25
- begin
26
- self.spawn_httpsession(@server.accept)
27
- STDOUT.print "Starting new HTTP-request.\n" if @debug
28
- rescue => e
29
- STDOUT.puts e.inspect
30
- STDOUT.puts e.backtrace
31
- STDOUT.print "\n"
32
- STDOUT.print "Could not accept HTTP-request - waiting 1 sec and then trying again.\n"
33
- sleep 1
34
- end
35
- end
19
+ @thread_accept = Thread.new do
20
+ begin
21
+ loop do
22
+ if !@server or @server.closed?
23
+ sleep 1
24
+ next
25
+ end
26
+
27
+ begin
28
+ self.spawn_httpsession(@server.accept)
29
+ STDOUT.print "Starting new HTTP-request.\n" if @debug
30
+ rescue => e
31
+ STDOUT.puts e.inspect
32
+ STDOUT.puts e.backtrace
33
+ STDOUT.print "\n"
34
+ STDOUT.print "Could not accept HTTP-request - waiting 1 sec and then trying again.\n"
35
+ sleep 1
36
+ end
37
+ end
38
+ rescue => e
39
+ STDOUT.print Knj::Errors.error_str(e)
40
+ end
36
41
  end
37
42
 
38
- @thread_restart = Knj::Thread.new do
39
- loop do
40
- sleep 10
41
- break if @kas.should_restart and @kas.should_restart_done
42
-
43
- if !@kas.should_restart and (!@server or @server.closed?)
44
- STDOUT.print "Socket does not exist or is closed - restarting HTTP-server!\n"
45
- @server = TCPServer.new(@kas.config[:host], @kas.config[:port])
46
- STDOUT.print "Done.\n"
43
+ @thread_restart = Thread.new do
44
+ begin
45
+ loop do
46
+ sleep 10
47
+ break if @kas.should_restart and @kas.should_restart_done
48
+
49
+ if !@kas.should_restart and (!@server or @server.closed?)
50
+ STDOUT.print "Socket does not exist or is closed - restarting HTTP-server!\n"
51
+ @server = TCPServer.new(@kas.config[:host], @kas.config[:port])
52
+ STDOUT.print "Done.\n"
53
+ end
54
+ end
55
+ rescue => e
56
+ if @kas
57
+ @kas.handle_error(e)
58
+ else
59
+ STDOUT.print Knj::Errors.error_str(e)
47
60
  end
48
61
  end
49
62
  end
@@ -93,11 +106,14 @@ class Knjappserver::Httpserver
93
106
  @http_sessions << Knjappserver::Httpsession.new(self, socket)
94
107
  end
95
108
 
96
- def handle_request(&block)
97
- @working_count += 1 if @working_count
98
- begin
99
- block.call
100
- ensure
109
+ def count_add
110
+ @mutex_count.synchronize do
111
+ @working_count += 1 if @working_count
112
+ end
113
+ end
114
+
115
+ def count_remove
116
+ @mutex_count.synchronize do
101
117
  @working_count -= 1 if @working_count
102
118
  end
103
119
  end
@@ -1,8 +1,13 @@
1
- require "digest"
2
-
3
1
  class Knjappserver::Httpsession
4
- attr_accessor :data, :size_send, :alert_sent
5
- attr_reader :session, :session_id, :session_hash, :kas, :active, :out, :eruby, :browser, :debug, :resp, :page_path, :cgroup, :written_size
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
4
+
5
+ dir = File.dirname(__FILE__)
6
+
7
+ autoload :Contentgroup, "#{dir}/class_httpsession_contentgroup.rb"
8
+ autoload :Http_request, "#{dir}/class_httpsession_http_request.rb"
9
+ autoload :Http_response, "#{dir}/class_httpsession_http_response.rb"
10
+ autoload :Post_multipart, "#{dir}/class_httpsession_post_multipart.rb"
6
11
 
7
12
  def initialize(httpserver, socket)
8
13
  @data = {}
@@ -14,33 +19,48 @@ class Knjappserver::Httpsession
14
19
  @active = true
15
20
  @eruby = Knj::Eruby.new(:cache_hash => @kas.eruby_cache)
16
21
  @debug = @kas.debug
22
+ @handlers_cache = @config[:handlers_cache]
23
+ @httpsession_var = {}
24
+
25
+ #Set socket stuff.
26
+ if RUBY_PLATFORM == "java" or RUBY_ENGINE == "rbx"
27
+ if @kas.config[:peeraddr_static]
28
+ addr_peer = [0, 0, @kas.config[:peeraddr_static]]
29
+ else
30
+ addr_peer = @socket.peeraddr
31
+ end
32
+
33
+ addr = @socket.addr
34
+ else
35
+ addr = @socket.addr(false)
36
+ addr_peer = @socket.peeraddr(false)
37
+ end
38
+
39
+ @socket_meta = {
40
+ "REMOTE_ADDR" => addr[2],
41
+ "REMOTE_PORT" => addr[1],
42
+ "SERVER_ADDR" => addr_peer[2],
43
+ "SERVER_PORT" => addr_peer[1]
44
+ }
45
+
46
+ @resp = Knjappserver::Httpsession::Http_response.new(:socket => @socket)
47
+ @handler = Knjappserver::Httpsession::Http_request.new(:kas => @kas, :httpsession => self)
17
48
 
18
49
  @cgroup = Knjappserver::Httpsession::Contentgroup.new(
19
50
  :socket => @socket,
20
- :restart_proc => proc{
21
- begin
22
- @resp.write(@socket) if @meta["METHOD"] != "HEAD"
23
- rescue Errno::ECONNRESET, Errno::ENOTCONN, Errno::EPIPE, Timeout::Error
24
- #Ignore - the user probaly left.
25
- end
26
- }
51
+ :kas => @kas,
52
+ :resp => @resp,
53
+ :httpsession => self
27
54
  )
28
-
29
- @resp = Knjappserver::Httpresp.new(:cgroup => @cgroup)
30
-
31
- require "#{File.dirname(__FILE__)}/class_httpsession_knjengine"
32
- @handler = Knjappserver::Httpsession::Knjengine.new(:kas => @kas)
55
+ @resp.cgroup = @cgroup
33
56
 
34
57
  Dir.chdir(@config[:doc_root])
35
58
  ObjectSpace.define_finalizer(self, self.class.method(:finalize).to_proc) if @debug
36
59
  STDOUT.print "New httpsession #{self.__id__} (total: #{@httpserver.http_sessions.count}).\n" if @debug
37
60
 
38
- @thread_request = Knj::Thread.new do
61
+ @thread_request = Thread.new do
39
62
  Thread.current[:knjappserver] = {} if !Thread.current[:knjappserver]
40
63
 
41
- @kas.db_handler.get_and_register_thread if @kas.db_handler.opts[:threadsafe]
42
- @kas.ob.db.get_and_register_thread if @kas.ob.db.opts[:threadsafe]
43
-
44
64
  begin
45
65
  while @active
46
66
  begin
@@ -48,8 +68,9 @@ class Knjappserver::Httpsession
48
68
  @written_size = 0
49
69
  @size_send = @config[:size_send]
50
70
  @alert_sent = false
71
+ @working = false
51
72
 
52
- Timeout.timeout(30) do
73
+ Timeout.timeout(1500) do
53
74
  @handler.socket_parse(@socket)
54
75
  end
55
76
 
@@ -58,18 +79,31 @@ class Knjappserver::Httpsession
58
79
  sleep 0.1
59
80
  end
60
81
 
82
+ break if @kas.should_restart
83
+
61
84
  if @config.key?(:max_requests_working)
62
- while @httpserver.working_count >= @config[:max_requests_working]
85
+ while @httpserver and @config and @httpserver.working_count.to_i >= @config[:max_requests_working].to_i
63
86
  STDOUT.print "Maximum amounts of requests are working (#{@httpserver.working_count}, #{@config[:max_requests_working]}) - sleeping.\n" if @debug
64
87
  sleep 0.1
65
88
  end
66
89
  end
67
90
 
68
- @httpserver.handle_request do
69
- self.serve
70
- end
91
+ #Reserve database connections.
92
+ @kas.db_handler.get_and_register_thread if @kas.db_handler.opts[:threadsafe]
93
+ @kas.ob.db.get_and_register_thread if @kas.ob.db.opts[:threadsafe]
94
+
95
+ @httpserver.count_add
96
+ @working = true
97
+ STDOUT.print "Serving.\n" if @debug
98
+ self.serve
71
99
  ensure
100
+ @httpserver.count_remove
72
101
  @kas.served += 1 if @kas
102
+ @working = false
103
+
104
+ #Free reserved database-connections.
105
+ @kas.db_handler.free_thread if @kas and @kas.db_handler.opts[:threadsafe]
106
+ @kas.ob.db.free_thread if @kas and @kas.ob.db.opts[:threadsafe]
73
107
  end
74
108
  end
75
109
  rescue Errno::ECONNRESET, Errno::ENOTCONN, Errno::EPIPE, Timeout::Error => e
@@ -78,25 +112,29 @@ class Knjappserver::Httpsession
78
112
  #STDOUT.puts e.backtrace
79
113
  rescue SystemExit, Interrupt => e
80
114
  raise e
81
- rescue RuntimeError, Exception => e
115
+ rescue Exception => e
82
116
  STDOUT.puts e.inspect
83
117
  STDOUT.puts e.backtrace
84
118
  ensure
85
- @kas.db_handler.free_thread if @kas and @kas.db_handler.opts[:threadsafe]
86
- @kas.ob.db.free_thread if @kas and @kas.ob.db.opts[:threadsafe]
87
119
  self.destruct
88
120
  end
89
121
  end
90
122
  end
91
123
 
124
+ #Is called when content is added and begings to write the output if it goes above the limit.
125
+ def add_size(size)
126
+ @written_size += size
127
+ @cgroup.write_output if @written_size >= @size_send
128
+ end
129
+
92
130
  def threadded_content(block)
93
131
  raise "No block was given." if !block
94
- cgroup_data = Thread.current[:knjappserver][:contentgroup].new_thread
132
+ cgroup = Thread.current[:knjappserver][:contentgroup].new_thread
95
133
 
96
- cgroup_data[:thread] = Thread.new(Thread.current[:knjappserver].clone) do |data|
134
+ Thread.new do
97
135
  begin
98
136
  self.init_thread
99
- cgroup_data[:cgroup].register_thread
137
+ cgroup.register_thread
100
138
 
101
139
  @kas.db_handler.get_and_register_thread if @kas and @kas.db_handler.opts[:threadsafe]
102
140
  @kas.ob.db.get_and_register_thread if @kas and @kas.ob.db.opts[:threadsafe]
@@ -132,7 +170,7 @@ class Knjappserver::Httpsession
132
170
  STDOUT.print "Httpsession destruct (#{@httpserver.http_sessions.length})\n" if @debug and @httpserver and @httpserver.http_sessions
133
171
 
134
172
  begin
135
- @socket.close if @socket and !@socket.closed?
173
+ @socket.close if !@socket.closed?
136
174
  rescue => e
137
175
  STDOUT.puts e.inspect
138
176
  STDOUT.puts e.backtrace
@@ -140,31 +178,19 @@ class Knjappserver::Httpsession
140
178
  end
141
179
 
142
180
  @httpserver.http_sessions.delete(self) if @httpserver and @httpserver.http_sessions
143
- @httpserver = nil
144
-
145
- @data = nil
146
- @kas = nil
147
- @active = nil
148
- @session = nil
149
- @session_id = nil
150
- @session_hash = nil
151
- @out = nil
152
- @socket = nil
153
- @browser = nil
154
- @resp = nil
155
- @cgroup = nil
156
- @handler = nil
157
181
 
158
182
  @eruby.destroy if @eruby
159
- @eruby = nil
160
-
161
- thread = @thread_request
162
- @thread_request = nil
163
- thread.kill if thread and thread.alive?
183
+ @thread_request.kill if @thread_request.alive?
184
+ end
185
+
186
+ #Forces the content to be the input - nothing else can be added after calling this.
187
+ def force_content(newcont)
188
+ @cgroup.force_content(newcont)
164
189
  end
165
190
 
166
191
  def serve
167
- @meta = @handler.meta
192
+ STDOUT.print "Generating meta, cookie, get, post and headers.\n" if @debug
193
+ @meta = @handler.meta.merge!(@socket_meta)
168
194
  @cookie = @handler.cookie
169
195
  @get = @handler.get
170
196
  @post = @handler.post
@@ -177,8 +203,10 @@ class Knjappserver::Httpsession
177
203
  )
178
204
  if @handler.http_version == "1.1"
179
205
  @cgroup.chunked = true
206
+ @resp.chunked = true
180
207
  else
181
208
  @cgroup.chunked = false
209
+ @resp.chunked = false
182
210
  end
183
211
 
184
212
  @page_path = @handler.page_path
@@ -198,21 +226,22 @@ class Knjappserver::Httpsession
198
226
  raise "Could not figure out the IP of the session."
199
227
  end
200
228
 
229
+ STDOUT.print "Figuring out session-ID, session-object and more.\n" if @debug
201
230
  if @cookie["KnjappserverSession"].to_s.length > 0
202
231
  @session_id = @cookie["KnjappserverSession"]
203
232
  elsif @browser["browser"] == "bot"
204
233
  @session_id = "bot"
205
234
  else
206
- @session_id = @kas.session_generate_id(:meta => @meta)
235
+ @session_id = @kas.session_generate_id(@meta)
207
236
  send_cookie = true
208
237
  end
209
238
 
210
239
  begin
211
- session = @kas.session_fromid(:idhash => @session_id, :ip => @ip, :meta => @meta)
240
+ @session, @session_hash = @kas.session_fromid(@ip, @session_id, @meta)
212
241
  rescue Knj::Errors::InvalidData => e
213
242
  #User should not have the session he asked for because of invalid user-agent or invalid IP.
214
- @session_id = @kas.session_generate_id(:meta => meta)
215
- session = @kas.session_fromid(:idhash => @session_id, :ip => @ip, :meta => meta)
243
+ @session_id = @kas.session_generate_id(@meta)
244
+ @session, @session_hash = @kas.session_fromid(@ip, @session_id, @meta)
216
245
  send_cookie = true
217
246
  end
218
247
 
@@ -225,10 +254,8 @@ class Knjappserver::Httpsession
225
254
  )
226
255
  end
227
256
 
228
- @session = session[:dbobj]
229
- @session_hash = session[:hash]
230
-
231
257
  if @config.key?(:logging) and @config[:logging][:access_db]
258
+ STDOUT.print "Doing access-logging.\n" if @debug
232
259
  @ips = [@meta["REMOTE_ADDR"]]
233
260
  @ips << @meta["HTTP_X_FORWARDED_FOR"].split(",")[0].strip if @meta["HTTP_X_FORWARDED_FOR"]
234
261
  @kas.logs_access_pending << {
@@ -242,58 +269,68 @@ class Knjappserver::Httpsession
242
269
  }
243
270
  end
244
271
 
272
+ STDOUT.print "Initializing thread and content-group.\n" if @debug
245
273
  self.init_thread
246
274
  Thread.current[:knjappserver][:contentgroup] = @cgroup
247
275
  time_start = Time.now.to_f if @debug
248
- self.serve_real
249
- @cgroup.mark_done
250
- @cgroup.write_output
251
- STDOUT.print "#{__id__} - Served '#{@meta["REQUEST_URI"]}' in #{Time.now.to_f - time_start} secs (#{@resp.status}).\n" if @debug
252
- @cgroup.join
253
- end
254
-
255
- def serve_real
256
- #check if we should use a handler for this request.
257
- @config[:handlers].each do |handler_info|
258
- if handler_info.key?(:file_ext) and handler_info[:file_ext] == @ext
259
- return handler_info[:callback].call(self)
260
- elsif handler_info.key?(:path) and handler_info[:mount] and @meta["SCRIPT_NAME"].slice(0, handler_info[:path].length) == handler_info[:path]
261
- @page_path = "#{handler_info[:mount]}#{@meta["SCRIPT_NAME"].slice(handler_info[:path].length, @meta["SCRIPT_NAME"].length)}"
262
- break
263
- end
264
- end
265
-
266
- cache_control = {}
267
- cache_use = true
268
276
 
269
- if @headers["cache-control"] and @headers["cache-control"][0]
270
- @headers["cache-control"][0].scan(/(.+)=(.+)/) do |match|
271
- cache_control[match[1]] = match[2]
272
- end
273
- end
277
+ @kas.events.call(:request_begin, {
278
+ :httpsession => self
279
+ }) if @kas.events
274
280
 
275
- cache_use = false if cache_control.key?("max-age") and cache_control["max-age"].to_i <= 0
276
-
277
- if !File.exists?(@page_path)
278
- @resp.status = 404
279
- @resp.header("Content-Type", "text/html")
280
- @cgroup.write("File you are looking for was not found: '#{@meta["REQUEST_URI"]}'.")
281
+ if @handlers_cache.key?(@ext)
282
+ STDOUT.print "Calling handler.\n" if @debug
283
+ @handlers_cache[@ext].call(self)
281
284
  else
282
- lastmod = File.mtime(@page_path)
283
-
284
- @resp.header("Last-Modified", lastmod.httpdate)
285
- @resp.header("Expires", (Time.now + 86400).httpdate) #next day.
285
+ #check if we should use a handler for this request.
286
+ @config[:handlers].each do |handler_info|
287
+ if handler_info.key?(:file_ext) and handler_info[:file_ext] == @ext
288
+ return handler_info[:callback].call(self)
289
+ elsif handler_info.key?(:path) and handler_info[:mount] and @meta["SCRIPT_NAME"].slice(0, handler_info[:path].length) == handler_info[:path]
290
+ @page_path = "#{handler_info[:mount]}#{@meta["SCRIPT_NAME"].slice(handler_info[:path].length, @meta["SCRIPT_NAME"].length)}"
291
+ break
292
+ end
293
+ end
286
294
 
287
- if cache_use and @headers["if-modified-since"] and @headers["if-modified-since"][0]
288
- request_mod = Knj::Datet.parse(@headers["if-modified-since"][0]).time
295
+ if !File.exists?(@page_path)
296
+ @resp.status = 404
297
+ @resp.header("Content-Type", "text/html")
298
+ @cgroup.write("File you are looking for was not found: '#{@meta["REQUEST_URI"]}'.")
299
+ else
300
+ if @headers["cache-control"] and @headers["cache-control"][0]
301
+ cache_control = {}
302
+ @headers["cache-control"][0].scan(/(.+)=(.+)/) do |match|
303
+ cache_control[match[1]] = match[2]
304
+ end
305
+ end
306
+
307
+ cache_dont = true if cache_control and cache_control.key?("max-age") and cache_control["max-age"].to_i <= 0
308
+ lastmod = File.mtime(@page_path)
289
309
 
290
- if request_mod == lastmod
291
- @resp.status = 304
292
- return nil
310
+ @resp.header("Last-Modified", lastmod.httpdate)
311
+ @resp.header("Expires", (Time.now + 86400).httpdate) #next day.
312
+
313
+ if !cache_dont and @headers["if-modified-since"] and @headers["if-modified-since"][0]
314
+ request_mod = Knj::Datet.parse(@headers["if-modified-since"][0]).time
315
+
316
+ if request_mod == lastmod
317
+ @resp.status = 304
318
+ return nil
319
+ end
293
320
  end
321
+
322
+ @cgroup.new_io(File.new(@page_path))
294
323
  end
295
-
296
- @cgroup.new_io(File.new(@page_path))
297
324
  end
325
+
326
+ @cgroup.mark_done
327
+ @cgroup.write_output
328
+ STDOUT.print "#{__id__} - Served '#{@meta["REQUEST_URI"]}' in #{Time.now.to_f - time_start} secs (#{@resp.status}).\n" if @debug
329
+ @cgroup.join
330
+
331
+ @kas.events.call(:request_done, {
332
+ :httpsession => self
333
+ }) if @kas.events
334
+ @httpsession_var = {}
298
335
  end
299
336
  end