knjappserver 0.0.16 → 0.0.17

Sign up to get free protection for your applications and to get access to all the features.
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