knjappserver 0.0.15 → 0.0.16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/Gemfile +4 -2
  2. data/Gemfile.lock +24 -10
  3. data/README.rdoc +298 -1
  4. data/VERSION +1 -1
  5. data/bin/check_running.rb +2 -2
  6. data/knjappserver.gemspec +23 -5
  7. data/lib/files/database_schema.rb +124 -111
  8. data/lib/include/class_customio.rb +19 -5
  9. data/lib/include/class_erbhandler.rb +5 -22
  10. data/lib/include/class_httpresp.rb +66 -28
  11. data/lib/include/class_httpserver.rb +27 -14
  12. data/lib/include/class_httpsession.rb +161 -212
  13. data/lib/include/class_httpsession_contentgroup.rb +144 -0
  14. data/lib/include/class_httpsession_knjengine.rb +33 -68
  15. data/lib/include/class_httpsession_mongrel.rb +1 -1
  16. data/lib/include/class_httpsession_webrick.rb +1 -1
  17. data/lib/include/class_knjappserver.rb +105 -130
  18. data/lib/include/class_knjappserver_cleaner.rb +20 -13
  19. data/lib/include/class_knjappserver_cmdline.rb +44 -0
  20. data/lib/include/class_knjappserver_errors.rb +4 -1
  21. data/lib/include/class_knjappserver_logging.rb +48 -8
  22. data/lib/include/class_knjappserver_mailing.rb +36 -14
  23. data/lib/include/class_knjappserver_sessions.rb +78 -0
  24. data/lib/include/class_knjappserver_threadding.rb +18 -45
  25. data/lib/include/class_knjappserver_threadding_timeout.rb +78 -0
  26. data/lib/include/class_knjappserver_translations.rb +30 -0
  27. data/lib/include/class_knjappserver_web.rb +55 -3
  28. data/lib/include/class_log.rb +31 -3
  29. data/lib/include/class_log_access.rb +0 -15
  30. data/lib/include/class_log_data.rb +0 -15
  31. data/lib/include/class_log_data_link.rb +1 -14
  32. data/lib/include/class_log_data_value.rb +5 -17
  33. data/lib/include/class_session.rb +6 -18
  34. data/lib/include/magic_methods.rb +12 -14
  35. data/lib/pages/benchmark.rhtml +0 -0
  36. data/lib/pages/benchmark_print.rhtml +14 -0
  37. data/lib/pages/benchmark_simple.rhtml +3 -0
  38. data/lib/pages/benchmark_threadded_content.rhtml +21 -0
  39. data/lib/pages/spec.rhtml +26 -0
  40. data/lib/pages/spec_test_multiple_clients.rhtml +3 -0
  41. data/lib/pages/spec_threadded_content.rhtml +38 -0
  42. data/lib/scripts/benchmark.rb +65 -0
  43. data/spec/knjappserver_spec.rb +87 -43
  44. metadata +54 -20
@@ -1,111 +1,124 @@
1
- $tables = {
2
- "tables" => {
3
- "Session" => {
4
- "columns" => [
5
- {"name" => "id", "type" => "bigint", "autoincr" => true, "primarykey" => true},
6
- {"name" => "idhash", "type" => "varchar"},
7
- {"name" => "sess_data", "type" => "text"},
8
- {"name" => "date_added", "type" => "datetime"},
9
- {"name" => "ip", "type" => "varchar", "maxlength" => 15}
10
- ],
11
- "indexes" => [
12
- {"name" => "date_added", "columns" => ["date_added"]},
13
- {"name" => "idhash", "columns" => ["idhash"]}
14
- ],
15
- "renames" => ["sessions"]
16
- },
17
- "Translation" => {
18
- "columns" => [
19
- {"name" => "id", "type" => "bigint", "autoincr" => true, "primarykey" => true},
20
- {"name" => "object_class", "type" => "varchar", "maxlength" => 50},
21
- {"name" => "object_id", "type" => "bigint"},
22
- {"name" => "key", "type" => "varchar", "maxlength" => 50},
23
- {"name" => "locale", "type" => "varchar", "maxlength" => 5},
24
- {"name" => "value", "type" => "text"}
25
- ],
26
- "indexes" => [
27
- {"name" => "lookup", "columns" => ["object_class", "object_id", "key", "locale"]}
28
- ],
29
- "indexes_remove" => {
30
- "object_class" => true
31
- },
32
- "renames" => ["translations"]
33
- },
34
- "Log" => {
35
- "columns" => [
36
- {"name" => "id", "type" => "bigint", "autoincr" => true, "primarykey" => true},
37
- {"name" => "text_value_id", "type" => "bigint"},
38
- {"name" => "date_saved", "type" => "datetime"},
39
- {"name" => "get_keys_data_id", "type" => "bigint"},
40
- {"name" => "get_values_data_id", "type" => "bigint"},
41
- {"name" => "post_keys_data_id", "type" => "bigint"},
42
- {"name" => "post_values_data_id", "type" => "bigint"}
43
- ],
44
- "indexes" => [
45
- {"name" => "text_value_id", "columns" => ["text_value_id"]}
46
- ]
47
- },
48
- "Log_access" => {
49
- "columns" => [
50
- {"name" => "id", "type" => "bigint", "autoincr" => true, "primarykey" => true},
51
- {"name" => "session_id", "type" => "bigint"},
52
- {"name" => "date_request", "type" => "datetime"},
53
- {"name" => "ip_data_id", "type" => "bigint"},
54
- {"name" => "get_keys_data_id", "type" => "bigint"},
55
- {"name" => "get_values_data_id", "type" => "bigint"},
56
- {"name" => "post_keys_data_id", "type" => "bigint"},
57
- {"name" => "post_values_data_id", "type" => "bigint"},
58
- {"name" => "cookie_keys_data_id", "type" => "bigint"},
59
- {"name" => "cookie_values_data_id", "type" => "bigint"},
60
- {"name" => "meta_keys_data_id", "type" => "bigint"},
61
- {"name" => "meta_values_data_id", "type" => "bigint"}
62
- ],
63
- "indexes" => [
64
- {"name" => "session_id", "columns" => ["session_id"]},
65
- {"name" => "date_request", "columns" => ["date_request"]}
66
- ]
67
- },
68
- "Log_data" => {
69
- "columns" => [
70
- {"name" => "id", "type" => "bigint", "autoincr" => true, "primarykey" => true},
71
- {"name" => "id_hash", "type" => "varchar"}
72
- ],
73
- "indexes" => [
74
- {"name" => "id_hash", "columns" => ["id_hash"]}
75
- ]
76
- },
77
- "Log_data_link" => {
78
- "columns" => [
79
- {"name" => "id", "type" => "bigint", "autoincr" => true, "primarykey" => true},
80
- {"name" => "no", "type" => "int"},
81
- {"name" => "data_id", "type" => "bigint"},
82
- {"name" => "value_id", "type" => "bigint"}
83
- ],
84
- "indexes" => [
85
- {"name" => "data_id", "columns" => ["data_id"]},
86
- {"name" => "value_id", "columns" => ["value_id"]}
87
- ]
88
- },
89
- "Log_data_value" => {
90
- "columns" => [
91
- {"name" => "id", "type" => "bigint", "autoincr" => true, "primarykey" => true},
92
- {"name" => "value", "type" => "text"}
93
- ]
94
- },
95
- "Log_link" => {
96
- "columns" => [
97
- {"name" => "id", "type" => "bigint", "autoincr" => true, "primarykey" => true},
98
- {"name" => "log_id", "type" => "bigint"},
99
- {"name" => "object_class_value_id", "type" => "bigint"},
100
- {"name" => "object_id", "type" => "bigint"}
101
- ],
102
- "indexes" => [
103
- {"name" => "log_id", "columns" => ["log_id"]},
104
- {"name" => "object_id", "columns" => ["object_id"]},
105
- {"name" => "object_class_value_id", "columns" => ["object_class_value_id"]},
106
- {"name" => "object_lookup", "columns" => ["object_class_value_id", "object_id"]},
107
- {"name" => "log_lookup", "columns" => ["object_class_value_id", "object_id", "log_id"]}
108
- ]
109
- }
110
- }
111
- }
1
+ class Knjappserver
2
+ DATABASE_SCHEMA = {
3
+ "tables" => {
4
+ "Log" => {
5
+ "columns" => [
6
+ {"name" => "id", "type" => "bigint", "autoincr" => true, "primarykey" => true},
7
+ {"name" => "text_value_id", "type" => "bigint"},
8
+ {"name" => "date_saved", "type" => "datetime"},
9
+ {"name" => "get_keys_data_id", "type" => "bigint"},
10
+ {"name" => "get_values_data_id", "type" => "bigint"},
11
+ {"name" => "post_keys_data_id", "type" => "bigint"},
12
+ {"name" => "post_values_data_id", "type" => "bigint"},
13
+ {"name" => "cookie_keys_data_id", "type" => "bigint"},
14
+ {"name" => "cookie_values_data_id", "type" => "bigint"},
15
+ {"name" => "meta_keys_data_id", "type" => "bigint"},
16
+ {"name" => "meta_values_data_id", "type" => "bigint"},
17
+ {"name" => "tag_data_id", "type" => "bigint"},
18
+ {"name" => "comment_data_id", "type" => "bigint"}
19
+ ],
20
+ "indexes" => [
21
+ {"name" => "text_value_id", "columns" => ["text_value_id"]},
22
+ {"name" => "tag_data_id", "columns" => ["tag_data_id"]},
23
+ {"name" => "comment_data_id", "columns" => ["comment_data_id"]}
24
+ ]
25
+ },
26
+ "Log_access" => {
27
+ "columns" => [
28
+ {"name" => "id", "type" => "bigint", "autoincr" => true, "primarykey" => true},
29
+ {"name" => "session_id", "type" => "bigint"},
30
+ {"name" => "date_request", "type" => "datetime"},
31
+ {"name" => "ip_data_id", "type" => "bigint"},
32
+ {"name" => "get_keys_data_id", "type" => "bigint"},
33
+ {"name" => "get_values_data_id", "type" => "bigint"},
34
+ {"name" => "post_keys_data_id", "type" => "bigint"},
35
+ {"name" => "post_values_data_id", "type" => "bigint"},
36
+ {"name" => "cookie_keys_data_id", "type" => "bigint"},
37
+ {"name" => "cookie_values_data_id", "type" => "bigint"},
38
+ {"name" => "meta_keys_data_id", "type" => "bigint"},
39
+ {"name" => "meta_values_data_id", "type" => "bigint"}
40
+ ],
41
+ "indexes" => [
42
+ {"name" => "session_id", "columns" => ["session_id"]},
43
+ {"name" => "date_request", "columns" => ["date_request"]}
44
+ ]
45
+ },
46
+ "Log_data" => {
47
+ "columns" => [
48
+ {"name" => "id", "type" => "bigint", "autoincr" => true, "primarykey" => true},
49
+ {"name" => "id_hash", "type" => "varchar"}
50
+ ],
51
+ "indexes" => [
52
+ {"name" => "id_hash", "columns" => ["id_hash"]}
53
+ ]
54
+ },
55
+ "Log_data_link" => {
56
+ "columns" => [
57
+ {"name" => "id", "type" => "bigint", "autoincr" => true, "primarykey" => true},
58
+ {"name" => "no", "type" => "int"},
59
+ {"name" => "data_id", "type" => "bigint"},
60
+ {"name" => "value_id", "type" => "bigint"}
61
+ ],
62
+ "indexes" => [
63
+ {"name" => "data_id", "columns" => ["data_id"]},
64
+ {"name" => "value_id", "columns" => ["value_id"]}
65
+ ]
66
+ },
67
+ "Log_data_value" => {
68
+ "columns" => [
69
+ {"name" => "id", "type" => "bigint", "autoincr" => true, "primarykey" => true},
70
+ {"name" => "value", "type" => "text"}
71
+ ]
72
+ },
73
+ "Log_link" => {
74
+ "columns" => [
75
+ {"name" => "id", "type" => "bigint", "autoincr" => true, "primarykey" => true},
76
+ {"name" => "log_id", "type" => "bigint"},
77
+ {"name" => "object_class_value_id", "type" => "bigint"},
78
+ {"name" => "object_id", "type" => "bigint"}
79
+ ],
80
+ "indexes" => [
81
+ {"name" => "log_id", "columns" => ["log_id"]},
82
+ {"name" => "object_id", "columns" => ["object_id"]},
83
+ {"name" => "object_class_value_id", "columns" => ["object_class_value_id"]},
84
+ {"name" => "object_lookup", "columns" => ["object_class_value_id", "object_id"]},
85
+ {"name" => "log_lookup", "columns" => ["object_class_value_id", "object_id", "log_id"]}
86
+ ]
87
+ },
88
+ "Session" => {
89
+ "columns" => [
90
+ {"name" => "id", "type" => "bigint", "autoincr" => true, "primarykey" => true},
91
+ {"name" => "idhash", "type" => "varchar"},
92
+ {"name" => "sess_data", "type" => "text"},
93
+ {"name" => "date_added", "type" => "datetime"},
94
+ {"name" => "date_lastused", "type" => "datetime", "on_created" => proc{|d| d["db"].query("UPDATE Session SET date_lastused = '#{Knj::Datet.new.dbstr}")}},
95
+ {"name" => "ip", "type" => "varchar", "maxlength" => 15},
96
+ {"name" => "user_agent", "type" => "text"},
97
+ {"name" => "remember", "type" => "enum", "maxlength" => "'0','1'", "default" => 0, "comment" => "If the session should be remembered or not."}
98
+ ],
99
+ "indexes" => [
100
+ {"name" => "date_added", "columns" => ["date_added"]},
101
+ {"name" => "idhash", "columns" => ["idhash"]}
102
+ ],
103
+ "renames" => ["sessions"]
104
+ },
105
+ "Translation" => {
106
+ "columns" => [
107
+ {"name" => "id", "type" => "bigint", "autoincr" => true, "primarykey" => true},
108
+ {"name" => "object_class", "type" => "varchar", "maxlength" => 50},
109
+ {"name" => "object_id", "type" => "bigint"},
110
+ {"name" => "key", "type" => "varchar", "maxlength" => 50},
111
+ {"name" => "locale", "type" => "varchar", "maxlength" => 5},
112
+ {"name" => "value", "type" => "text"}
113
+ ],
114
+ "indexes" => [
115
+ {"name" => "lookup", "columns" => ["object_class", "object_id", "key", "locale"]}
116
+ ],
117
+ "indexes_remove" => {
118
+ "object_class" => true
119
+ },
120
+ "renames" => ["translations"]
121
+ }
122
+ }
123
+ }
124
+ end
@@ -1,13 +1,23 @@
1
1
  class Knjappserver::CustomIO < StringIO
2
2
  def print(str)
3
3
  thread = Thread.current
4
+ str = str.to_s
4
5
 
5
- if thread and thread[:knjappserver] and thread[:knjappserver][:stringio] and !thread[:knjappserver][:stringio].closed?
6
- return thread[:knjappserver][:stringio].print(str)
7
- elsif thread and thread[:knjappserver] and thread[:knjappserver][:httpsession] and thread[:knjappserver][:httpsession].out and !thread[:knjappserver][:httpsession].out.closed?
8
- return thread[:knjappserver][:httpsession].out.print(str)
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)
9
19
  else
10
- return STDOUT.print(str) if !STDOUT.closed?
20
+ STDOUT.print(str) if !STDOUT.closed?
11
21
  end
12
22
  end
13
23
 
@@ -18,4 +28,8 @@ class Knjappserver::CustomIO < StringIO
18
28
  def write(str)
19
29
  self.print(str)
20
30
  end
31
+
32
+ def p(str)
33
+ self.print(str)
34
+ end
21
35
  end
@@ -3,12 +3,10 @@ class Knjappserver::ERBHandler
3
3
  @connected = {}
4
4
  end
5
5
 
6
- def erb_handler(data)
7
- #Hack the Knj::Thread to accept data - this is how get, post and etc. are set.
8
- Thread.current[:knjappserver] = data
9
- eruby = data[:httpsession].eruby
10
-
11
- if !@connected[eruby.__id__]
6
+ def erb_handler(httpsess)
7
+ eruby = httpsess.eruby
8
+
9
+ if !@connected.key?(eruby.__id__)
12
10
  eruby.connect("error") do |e|
13
11
  _kas.handle_error(e)
14
12
  end
@@ -16,21 +14,6 @@ class Knjappserver::ERBHandler
16
14
  @connected[eruby.__id__] = true
17
15
  end
18
16
 
19
- cont = eruby.load_return(data[:filepath], {
20
- :with_headers => false,
21
- :custom_io => true
22
- })
23
- headers = eruby.headers
24
- eruby.reset_headers
25
-
26
- headers_ret = {}
27
- headers.each do |header|
28
- headers_ret[header[0]] = [header[1]]
29
- end
30
-
31
- Thread.current[:knjappserver].clear
32
- Thread.current[:knjappserver] = nil
33
-
34
- return {:headers => headers}
17
+ eruby.import(httpsess.page_path)
35
18
  end
36
19
  end
@@ -1,7 +1,7 @@
1
1
  require "time"
2
2
 
3
3
  class Knjappserver::Httpresp
4
- attr_accessor :body, :nl, :status
4
+ attr_accessor :nl, :status, :http_version, :headers, :headers_trailing, :headers_sent
5
5
 
6
6
  STATUS_CODES = {
7
7
  100 => "Continue",
@@ -24,20 +24,41 @@ class Knjappserver::Httpresp
24
24
  }
25
25
  NL = "\r\n"
26
26
 
27
- def initialize
27
+ def initialize(args)
28
+ @cgroup = args[:cgroup]
29
+ end
30
+
31
+ def reset(args)
28
32
  @status = 200
33
+ @http_version = args[:http_version]
34
+ @close = args[:close]
35
+ @fileobj = nil
36
+ @close = true if @http_version == "1.0"
37
+ @trailers = []
38
+
39
+ @headers_sent = false
40
+ @headers_trailing = {}
41
+
29
42
  @headers = {
30
- "Content-Type" => "text/html",
31
- "Date" => Time.now.httpdate,
43
+ "date" => ["Date", Time.now.httpdate]
44
+ }
45
+
46
+ @headers_11 = {
32
47
  "Connection" => "Keep-Alive",
33
48
  "Transfer-Encoding" => "chunked",
34
- "Keep-Alive" => "timeout=30, max=100"
49
+ "Keep-Alive" => "timeout=15, max=30"
35
50
  }
51
+
36
52
  @cookies = []
37
53
  end
38
54
 
39
55
  def header(key, val)
40
- @headers[key] = val
56
+ if !@headers_sent
57
+ @headers[key.to_s.downcase] = [key, val]
58
+ else
59
+ raise "Headers already sent and given header was not in trailing headers: '#{key}'." if @trailers.index(key) == nil
60
+ @headers_trailing[key.to_s.downcase] = [key, val]
61
+ end
41
62
  end
42
63
 
43
64
  def cookie(cookie)
@@ -45,18 +66,32 @@ class Knjappserver::Httpresp
45
66
  end
46
67
 
47
68
  def header_str
48
- res = "HTTP/1.1 #{@status}"
69
+ if @http_version == "1.0"
70
+ res = "HTTP/1.0 #{@status}"
71
+ else
72
+ res = "HTTP/1.1 #{@status}"
73
+ end
74
+
49
75
  code = STATUS_CODES[@status]
50
76
  res += " #{code}" if code
51
77
  res += NL
52
- #res += "Content-Length: #{@body.length}#{NL}"
53
78
 
54
79
  @headers.each do |key, val|
55
- res += "#{key}: #{val}#{NL}"
80
+ res += "#{val[0]}: #{val[1]}#{NL}"
81
+ end
82
+
83
+ if @http_version == "1.1"
84
+ @headers_11.each do |key, val|
85
+ res += "#{key}: #{val}#{NL}"
86
+ end
87
+
88
+ @trailers.each do |trailer|
89
+ res += "Trailer: #{trailer}#{NL}"
90
+ end
56
91
  end
57
92
 
58
93
  @cookies.each do |cookie|
59
- res += "Set-Cookie: #{cookie}#{NL}"
94
+ res += "Set-Cookie: #{Knj::Web.cookie_str(cookie)}#{NL}"
60
95
  end
61
96
 
62
97
  res += NL
@@ -64,28 +99,31 @@ class Knjappserver::Httpresp
64
99
  return res
65
100
  end
66
101
 
67
- def write_chunked(socket)
102
+ def write(socket)
103
+ @headers_sent = true
68
104
  socket.write(self.header_str)
69
105
 
70
- @body.each do |part|
71
- while buf = part.read(1024)
72
- next if buf.empty?
73
- socket.write("#{format("%x", buf.bytesize)}#{NL}#{buf}#{NL}")
106
+ if @status == 304
107
+ #do nothing.
108
+ else
109
+ case @http_version
110
+ when "1.0"
111
+ @cgroup.write_to_socket
112
+ socket.write("#{NL}#{NL}")
113
+ when "1.1"
114
+ @cgroup.write_to_socket
115
+ socket.write("0#{NL}")
116
+
117
+ @headers_trailing.each do |header_id_str, header|
118
+ socket.write("#{header[0]}: #{header[1]}#{NL}")
119
+ end
120
+
121
+ socket.write(NL)
122
+ else
123
+ raise "Could not figure out of HTTP version: '#{@http_version}'."
74
124
  end
75
125
  end
76
126
 
77
- socket.write("0#{NL}#{NL}")
78
- end
79
-
80
- def content
81
- str = self.header_str + @body.string + "\n\n"
82
- end
83
-
84
- def destroy
85
- @status = nil
86
- @status_codes = nil
87
- @body = nil
88
- @cookies = nil
89
- @headers = nil
127
+ socket.close if @close
90
128
  end
91
129
  end