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.
- data/VERSION +1 -1
- data/bin/knjappserver_start.rb +17 -25
- data/knjappserver.gemspec +17 -6
- data/lib/conf/conf_example.rb +3 -3
- data/lib/files/database_schema.rb +1 -2
- data/lib/include/class_customio.rb +8 -25
- data/lib/include/class_erbhandler.rb +7 -1
- data/lib/include/class_httpserver.rb +50 -34
- data/lib/include/class_httpsession.rb +138 -101
- data/lib/include/class_httpsession_contentgroup.rb +52 -24
- data/lib/include/class_httpsession_http_request.rb +203 -0
- data/lib/include/{class_httpresp.rb → class_httpsession_http_response.rb} +27 -28
- data/lib/include/class_httpsession_post_multipart.rb +117 -0
- data/lib/include/class_knjappserver.rb +146 -96
- data/lib/include/class_knjappserver_cleaner.rb +74 -68
- data/lib/include/class_knjappserver_cmdline.rb +23 -17
- data/lib/include/class_knjappserver_errors.rb +121 -104
- data/lib/include/class_knjappserver_leakproxy_client.rb +6 -0
- data/lib/include/class_knjappserver_leakproxy_server.rb +56 -0
- data/lib/include/class_knjappserver_logging.rb +25 -25
- data/lib/include/class_knjappserver_mailing.rb +84 -56
- data/lib/include/class_knjappserver_sessions.rb +15 -22
- data/lib/include/class_knjappserver_threadding.rb +70 -43
- data/lib/include/class_knjappserver_threadding_timeout.rb +20 -4
- data/lib/include/class_knjappserver_translations.rb +6 -4
- data/lib/include/class_knjappserver_web.rb +87 -35
- data/lib/include/class_log.rb +9 -9
- data/lib/include/class_log_link.rb +4 -4
- data/lib/include/class_session.rb +8 -4
- data/lib/include/gettext_funcs.rb +8 -6
- data/lib/include/magic_methods.rb +4 -0
- data/lib/pages/debug_database_connections.rhtml +46 -0
- data/lib/pages/debug_http_sessions.rhtml +40 -0
- data/lib/pages/error_notfound.rhtml +12 -0
- data/lib/pages/spec.rhtml +1 -1
- data/lib/pages/spec_post.rhtml +3 -0
- data/lib/pages/spec_thread_joins.rhtml +21 -0
- data/lib/pages/spec_threadded_content.rhtml +2 -0
- data/lib/pages/tests.rhtml +14 -0
- data/lib/scripts/benchmark.rb +25 -8
- data/lib/scripts/knjappserver_cgi.rb +60 -0
- data/lib/scripts/knjappserver_fcgi.rb +135 -0
- data/lib/scripts/leakproxy.rb +27 -0
- data/spec/knjappserver_spec.rb +16 -5
- data/spec/leakproxy_spec.rb +56 -0
- metadata +38 -27
- data/lib/include/class_httpsession_knjengine.rb +0 -154
- data/lib/include/class_httpsession_mongrel.rb +0 -75
- data/lib/include/class_httpsession_webrick.rb +0 -75
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.17
|
data/bin/knjappserver_start.rb
CHANGED
@@ -1,16 +1,25 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require "#{File.dirname(__FILE__)}/../lib/knjappserver.rb"
|
4
|
-
|
4
|
+
|
5
|
+
knjrbfw_path = ""
|
5
6
|
|
6
7
|
ARGV.each do |arg|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
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 =>
|
35
|
+
:path => File.realpath(File.dirname(__FILE__))
|
29
36
|
}
|
30
37
|
|
31
|
-
Knj::Os.chdir_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"
|
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.
|
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{
|
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/
|
44
|
-
"lib/include/
|
45
|
-
"lib/include/
|
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}
|
data/lib/conf/conf_example.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
rpath =
|
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
|
-
|
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]",
|
@@ -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
|
7
|
-
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
|
-
|
25
|
-
|
26
|
-
|
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
|
-
|
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 =
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
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 =
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
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
|
97
|
-
@
|
98
|
-
|
99
|
-
|
100
|
-
|
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, :
|
5
|
-
attr_reader :session, :session_id, :session_hash, :kas, :active, :out, :eruby, :browser, :debug, :resp, :page_path, :cgroup, :
|
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
|
-
:
|
21
|
-
|
22
|
-
|
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 =
|
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(
|
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
|
-
|
69
|
-
|
70
|
-
|
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
|
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
|
-
|
132
|
+
cgroup = Thread.current[:knjappserver][:contentgroup].new_thread
|
95
133
|
|
96
|
-
|
134
|
+
Thread.new do
|
97
135
|
begin
|
98
136
|
self.init_thread
|
99
|
-
|
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
|
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
|
-
@
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
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
|
-
|
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(
|
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(
|
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(
|
215
|
-
session = @kas.session_fromid(
|
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
|
-
|
270
|
-
|
271
|
-
|
272
|
-
end
|
273
|
-
end
|
277
|
+
@kas.events.call(:request_begin, {
|
278
|
+
:httpsession => self
|
279
|
+
}) if @kas.events
|
274
280
|
|
275
|
-
|
276
|
-
|
277
|
-
|
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
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
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
|
288
|
-
|
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
|
-
|
291
|
-
|
292
|
-
|
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
|