hayabusa 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +20 -0
  4. data/Gemfile.lock +59 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.rdoc +19 -0
  7. data/Rakefile +49 -0
  8. data/VERSION +1 -0
  9. data/bin/check_running.rb +69 -0
  10. data/bin/hayabusa_benchmark.rb +82 -0
  11. data/bin/hayabusa_cgi.rb +84 -0
  12. data/bin/hayabusa_fcgi.fcgi +159 -0
  13. data/bin/hayabusa_fcgi.rb +159 -0
  14. data/bin/knjappserver_start.rb +42 -0
  15. data/conf/apache2_cgi_rhtml_conf.conf +10 -0
  16. data/conf/apache2_fcgi_rhtml_conf.conf +22 -0
  17. data/hayabusa.gemspec +151 -0
  18. data/lib/hayabusa.rb +518 -0
  19. data/lib/hayabusa_cgi_session.rb +128 -0
  20. data/lib/hayabusa_cgi_tools.rb +102 -0
  21. data/lib/hayabusa_custom_io.rb +22 -0
  22. data/lib/hayabusa_database.rb +125 -0
  23. data/lib/hayabusa_erb_handler.rb +27 -0
  24. data/lib/hayabusa_ext/cleaner.rb +140 -0
  25. data/lib/hayabusa_ext/cmdline.rb +52 -0
  26. data/lib/hayabusa_ext/errors.rb +135 -0
  27. data/lib/hayabusa_ext/logging.rb +404 -0
  28. data/lib/hayabusa_ext/mailing.rb +158 -0
  29. data/lib/hayabusa_ext/sessions.rb +71 -0
  30. data/lib/hayabusa_ext/threadding.rb +96 -0
  31. data/lib/hayabusa_ext/threadding_timeout.rb +101 -0
  32. data/lib/hayabusa_ext/translations.rb +43 -0
  33. data/lib/hayabusa_ext/web.rb +190 -0
  34. data/lib/hayabusa_http_server.rb +102 -0
  35. data/lib/hayabusa_http_session.rb +361 -0
  36. data/lib/hayabusa_http_session_contentgroup.rb +176 -0
  37. data/lib/hayabusa_http_session_page_environment.rb +66 -0
  38. data/lib/hayabusa_http_session_post_multipart.rb +135 -0
  39. data/lib/hayabusa_http_session_request.rb +219 -0
  40. data/lib/hayabusa_http_session_response.rb +144 -0
  41. data/lib/hayabusa_models.rb +8 -0
  42. data/lib/kernel_ext/gettext_methods.rb +22 -0
  43. data/lib/kernel_ext/magic_methods.rb +61 -0
  44. data/lib/models/log.rb +130 -0
  45. data/lib/models/log_access.rb +88 -0
  46. data/lib/models/log_data.rb +27 -0
  47. data/lib/models/log_data_link.rb +3 -0
  48. data/lib/models/log_data_value.rb +21 -0
  49. data/lib/models/log_link.rb +65 -0
  50. data/lib/models/session.rb +35 -0
  51. data/pages/benchmark.rhtml +0 -0
  52. data/pages/benchmark_print.rhtml +14 -0
  53. data/pages/benchmark_simple.rhtml +3 -0
  54. data/pages/benchmark_threadded_content.rhtml +21 -0
  55. data/pages/debug_database_connections.rhtml +46 -0
  56. data/pages/debug_http_sessions.rhtml +40 -0
  57. data/pages/debug_memory_usage.rhtml +16 -0
  58. data/pages/error_notfound.rhtml +12 -0
  59. data/pages/logs_latest.rhtml +57 -0
  60. data/pages/logs_show.rhtml +32 -0
  61. data/pages/spec.rhtml +41 -0
  62. data/pages/spec_post.rhtml +3 -0
  63. data/pages/spec_test_multiple_clients.rhtml +3 -0
  64. data/pages/spec_thread_joins.rhtml +21 -0
  65. data/pages/spec_threadded_content.rhtml +40 -0
  66. data/pages/tests.rhtml +14 -0
  67. data/spec/cgi_spec.rb +47 -0
  68. data/spec/custom_urls_spec.rb +35 -0
  69. data/spec/fcgi_multiple_processes_spec.rb +32 -0
  70. data/spec/fcgi_spec.rb +69 -0
  71. data/spec/hayabusa_spec.rb +194 -0
  72. data/spec/spec_helper.rb +12 -0
  73. data/tests/cgi_test/config_cgi.rb +6 -0
  74. data/tests/cgi_test/threadded_content_test.rhtml +23 -0
  75. data/tests/cgi_test/vars_get_test.rhtml +4 -0
  76. data/tests/cgi_test/vars_header_test.rhtml +3 -0
  77. data/tests/cgi_test/vars_post_test.rhtml +4 -0
  78. data/tests/fcgi_test/config_fcgi.rb +6 -0
  79. data/tests/fcgi_test/index.rhtml +3 -0
  80. data/tests/fcgi_test/sleeper.rhtml +4 -0
  81. data/tests/fcgi_test/threadded_content_test.rhtml +23 -0
  82. data/tests/fcgi_test/vars_get_test.rhtml +4 -0
  83. data/tests/fcgi_test/vars_header_test.rhtml +3 -0
  84. data/tests/fcgi_test/vars_post_test.rhtml +4 -0
  85. metadata +257 -0
@@ -0,0 +1,144 @@
1
+ require "time"
2
+
3
+ #This object writes headers, trailing headers, status headers and more for HTTP-sessions.
4
+ class Hayabusa::Http_session::Response
5
+ attr_accessor :chunked, :cgroup, :nl, :status, :http_version, :headers, :headers_trailing, :headers_sent, :socket
6
+
7
+ STATUS_CODES = {
8
+ 100 => "Continue",
9
+ 200 => "OK",
10
+ 201 => "Created",
11
+ 202 => "Accepted",
12
+ 204 => "No Content",
13
+ 205 => "Reset Content",
14
+ 206 => "Partial Content",
15
+ 301 => "Moved Permanently",
16
+ 302 => "Found",
17
+ 303 => "See Other",
18
+ 304 => "Not Modified",
19
+ 307 => "Temporary Redirect",
20
+ 400 => "Bad Request",
21
+ 401 => "Unauthorized",
22
+ 403 => "Forbidden",
23
+ 404 => "Not Found",
24
+ 500 => "Internal Server Error"
25
+ }
26
+ NL = "\r\n"
27
+
28
+ def initialize(args)
29
+ @chunked = false
30
+ @socket = args[:socket]
31
+ end
32
+
33
+ def reset(args)
34
+ @status = 200
35
+ @http_version = args[:http_version]
36
+ @close = args[:close]
37
+ @fileobj = nil
38
+ @close = true if @http_version == "1.0"
39
+ @trailers = []
40
+ @skip_statuscode = true if args[:mode] == :cgi
41
+
42
+ @headers_sent = false
43
+ @headers_trailing = {}
44
+
45
+ @mode = args[:mode]
46
+
47
+ @headers = {
48
+ "date" => ["Date", Time.now.httpdate]
49
+ }
50
+
51
+ @headers_11 = {
52
+ "Connection" => "Keep-Alive"
53
+ }
54
+ if args[:mode] != :cgi and (!args.key?(:chunked) or args[:chunked])
55
+ @headers_11["Transfer-Encoding"] = "chunked"
56
+ end
57
+
58
+ #Socket-timeout is currently broken in JRuby.
59
+ if RUBY_ENGINE != "jruby"
60
+ @headers_11["Keep-Alive"] = "timeout=15, max=30"
61
+ end
62
+
63
+ @cookies = []
64
+ end
65
+
66
+ def header(key, val)
67
+ lines = val.to_s.count("\n") + 1
68
+ raise "Value contains more lines than 1 (#{lines})." if lines > 1
69
+
70
+ if !@headers_sent
71
+ @headers[key.to_s.downcase] = [key, val]
72
+ else
73
+ raise "Headers already sent and given header was not in trailing headers: '#{key}'." if @trailers.index(key) == nil
74
+ @headers_trailing[key.to_s.downcase] = [key, val]
75
+ end
76
+ end
77
+
78
+ def cookie(cookie)
79
+ @cookies << cookie
80
+ end
81
+
82
+ def header_str
83
+ if @skip_statuscode
84
+ res = ""
85
+ else
86
+ if @http_version == "1.0"
87
+ res = "HTTP/1.0 #{@status}"
88
+ else
89
+ res = "HTTP/1.1 #{@status}"
90
+ end
91
+
92
+ code = STATUS_CODES[@status]
93
+ res << " #{code}" if code
94
+ res << NL
95
+ end
96
+
97
+ @headers.each do |key, val|
98
+ res << "#{val[0]}: #{val[1]}#{NL}"
99
+ end
100
+
101
+ if @http_version == "1.1"
102
+ @headers_11.each do |key, val|
103
+ res << "#{key}: #{val}#{NL}"
104
+ end
105
+
106
+ @trailers.each do |trailer|
107
+ res << "Trailer: #{trailer}#{NL}"
108
+ end
109
+ end
110
+
111
+ @cookies.each do |cookie|
112
+ res << "Set-Cookie: #{Knj::Web.cookie_str(cookie)}#{NL}"
113
+ end
114
+
115
+ res << NL
116
+
117
+ return res
118
+ end
119
+
120
+ def write
121
+ @headers_sent = true
122
+ @socket.write(self.header_str)
123
+
124
+ if @status == 304
125
+ #do nothing.
126
+ else
127
+ if @chunked
128
+ @cgroup.write_to_socket
129
+ @socket.write("0#{NL}")
130
+
131
+ @headers_trailing.each do |header_id_str, header|
132
+ @socket.write("#{header[0]}: #{header[1]}#{NL}")
133
+ end
134
+
135
+ @socket.write(NL)
136
+ else
137
+ @cgroup.write_to_socket
138
+ @socket.write("#{NL}#{NL}") if @mode != :cgi
139
+ end
140
+ end
141
+
142
+ @socket.close if @close and @mode != :cgi
143
+ end
144
+ end
@@ -0,0 +1,8 @@
1
+ class Hayabusa::Models
2
+ #Autoloader for subclasses.
3
+ def self.const_missing(name)
4
+ require "#{File.dirname(__FILE__)}/models/#{name.to_s.downcase}.rb"
5
+ raise "Still not defined: '#{name}'." if !Hayabusa::Models.const_defined?(name)
6
+ return Hayabusa::Models.const_get(name)
7
+ end
8
+ end
@@ -0,0 +1,22 @@
1
+ #coding: utf-8
2
+
3
+ def _(str)
4
+ hb = _hb
5
+ session = _session
6
+ locale = nil
7
+
8
+ if Thread.current[:locale].to_s.length > 0
9
+ locale = Thread.current[:locale]
10
+ elsif session and session[:locale].to_s.strip.length > 0
11
+ locale = session[:locale]
12
+ elsif hb and hb.config[:locale_default].to_s.strip.length > 0
13
+ session[:locale] = hb.config[:locale_default] if session
14
+ locale = hb.config[:locale_default]
15
+ elsif !session and !hb
16
+ return str
17
+ else
18
+ raise "No locale set for session and ':locale_default' not set in config."
19
+ end
20
+
21
+ return hb.gettext.trans(locale, str)
22
+ end
@@ -0,0 +1,61 @@
1
+ def _cookie
2
+ return Thread.current[:hayabusa][:cookie] if Thread.current[:hayabusa]
3
+ end
4
+
5
+ def _get
6
+ return Thread.current[:hayabusa][:get] if Thread.current[:hayabusa]
7
+ end
8
+
9
+ def _post
10
+ return Thread.current[:hayabusa][:post] if Thread.current[:hayabusa]
11
+ end
12
+
13
+ def _meta
14
+ return Thread.current[:hayabusa][:meta] if Thread.current[:hayabusa]
15
+ end
16
+
17
+ def _server
18
+ return Thread.current[:hayabusa][:meta] if Thread.current[:hayabusa]
19
+ end
20
+
21
+ def _session
22
+ return Thread.current[:hayabusa][:session].sess_data if Thread.current[:hayabusa] and Thread.current[:hayabusa][:session]
23
+ end
24
+
25
+ def _session_hash
26
+ return Thread.current[:hayabusa][:session].edata if Thread.current[:hayabusa] and Thread.current[:hayabusa][:session]
27
+ end
28
+
29
+ def _session_obj
30
+ return Thread.current[:hayabusa][:session] if Thread.current[:hayabusa] and Thread.current[:hayabusa][:session]
31
+ end
32
+
33
+ def _httpsession
34
+ return Thread.current[:hayabusa][:httpsession] if Thread.current[:hayabusa]
35
+ end
36
+
37
+ def _httpsession_var
38
+ return Thread.current[:hayabusa][:httpsession].httpsession_var if Thread.current[:hayabusa]
39
+ end
40
+
41
+ def _requestdata
42
+ return Thread.current[:hayabusa] if Thread.current[:hayabusa]
43
+ end
44
+
45
+ def _hb
46
+ return Thread.current[:hayabusa][:hb] if Thread.current[:hayabusa]
47
+ end
48
+
49
+ def _vars
50
+ return Thread.current[:hayabusa][:hb].vars if Thread.current[:hayabusa]
51
+ end
52
+
53
+ def _db
54
+ return Thread.current[:hayabusa][:db] if Thread.current[:hayabusa] and Thread.current[:hayabusa][:db] #This is the default use from a .rhtml-file.
55
+ return Thread.current[:hayabusa][:hb].db_handler if Thread.current[:hayabusa] and Thread.current[:hayabusa][:hb] #This is useually used when using autoload-argument for the appserver.
56
+ end
57
+
58
+ #This function makes it possible to define methods in ERubis-parsed files (else _buf-variable wouldnt be globally available).
59
+ def _buf
60
+ return $stdout
61
+ end
@@ -0,0 +1,130 @@
1
+ class Hayabusa::Models::Log < Knj::Datarow
2
+ has_many [
3
+ {:class => :Log_link, :col => :log_id, :method => :links, :depends => true, :autodelete => true}
4
+ ]
5
+
6
+ def self.list(d, &block)
7
+ sql = "SELECT #{table}.* FROM #{table}"
8
+
9
+ if d.args["object_lookup"]
10
+ data_val = d.ob.get_by(:Log_data_value, {"value" => d.args["object_lookup"].class.name})
11
+ return [] if !data_val #if this data-value cannot be found, nothing has been logged for the object. So just return empty array here and skip the rest.
12
+
13
+ sql << "
14
+ LEFT JOIN Log_link ON
15
+ Log_link.log_id = #{table}.id AND
16
+ Log_link.object_class_value_id = '#{d.db.esc(data_val.id)}' AND
17
+ Log_link.object_id = '#{d.db.esc(d.args["object_lookup"].id)}'
18
+ "
19
+ end
20
+
21
+ q_args = nil
22
+ return_sql = false
23
+ ret = self.list_helper(d)
24
+
25
+ sql << ret[:sql_joins]
26
+ sql << " WHERE 1=1"
27
+
28
+ d.args.each do |key, val|
29
+ case key
30
+ when "object_lookup"
31
+ sql << " AND Log_link.id IS NOT NULL"
32
+ when "return_sql"
33
+ return_sql = true
34
+ when "tag"
35
+ data_val = d.ob.get_by(:Log_data_value, {"value" => val})
36
+ if !data_val
37
+ sql << " AND false"
38
+ else
39
+ sql << " AND Log.tag_data_id = '#{d.db.esc(data_val.id)}'"
40
+ end
41
+ when :cloned_ubuf
42
+ q_args = {:cloned_ubuf => true}
43
+ else
44
+ raise "Invalid key: #{key}."
45
+ end
46
+ end
47
+
48
+ sql << ret[:sql_where]
49
+ sql << ret[:sql_order]
50
+ sql << ret[:sql_limit]
51
+
52
+ return sql if return_sql
53
+
54
+ return d.ob.list_bysql(:Log, sql, q_args, &block)
55
+ end
56
+
57
+ def self.add(d)
58
+ d.data[:date_saved] = Time.now if !d.data.key?(:date_saved)
59
+ end
60
+
61
+ def text
62
+ return ob.get(:Log_data_value, self[:text_value_id])[:value]
63
+ end
64
+
65
+ def comment
66
+ return "" if self[:comment_data_id].to_i == 0
67
+ log_data = ob.get(:Log_data_value, self[:comment_data_id])
68
+ return "" if !log_data
69
+ return log_data[:value]
70
+ end
71
+
72
+ def tag
73
+ return "" if self[:tag_data_id].to_i == 0
74
+ log_data = ob.get(:Log_data_value, self[:tag_data_id])
75
+ return "" if !log_data
76
+ return log_data[:value]
77
+ end
78
+
79
+ def get
80
+ ob.args[:hayabusa].log_data_hash(self[:get_keys_data_id], self[:get_values_data_id])
81
+ end
82
+
83
+ def post
84
+ ob.args[:hayabusa].log_data_hash(self[:post_keys_data_id], self[:post_values_data_id])
85
+ end
86
+
87
+ def cookie
88
+ ob.args[:hayabusa].log_data_hash(self[:cookie_keys_data_id], self[:cookie_values_data_id])
89
+ end
90
+
91
+ def meta
92
+ ob.args[:hayabusa].log_data_hash(self[:meta_keys_data_id], self[:meta_values_data_id])
93
+ end
94
+
95
+ def session
96
+ ob.args[:hayabusa].log_data_hash(self[:session_keys_data_id], self[:session_values_data_id])
97
+ end
98
+
99
+ def ip
100
+ meta_d = self.meta
101
+
102
+ return meta_d[:HTTP_X_FORWARDED_FOR] if meta_d.has_key?(:HTTP_X_FORWARDED_FOR)
103
+ return meta_d[:REMOTE_ADDR] if meta_d.has_key?(:REMOTE_ADDR)
104
+ return "[no ip logged]"
105
+ end
106
+
107
+ def first_line
108
+ lines = self.text.to_s.split("\n").first.to_s
109
+ end
110
+
111
+ def objects_html(ob_use)
112
+ html = ""
113
+ first = true
114
+
115
+ self.links.each do |link|
116
+ obj = link.object(ob_use)
117
+
118
+ html << ", " if !first
119
+ first = false if first
120
+
121
+ if obj.respond_to?(:html)
122
+ html << obj.html
123
+ else
124
+ html << "#{obj.class.name}{#{obj.id}}"
125
+ end
126
+ end
127
+
128
+ return html
129
+ end
130
+ end
@@ -0,0 +1,88 @@
1
+ class Hayabusa::Models::Log_access < Knj::Datarow
2
+ def get
3
+ return data_hash("get")
4
+ end
5
+
6
+ def post
7
+ return data_hash("post")
8
+ end
9
+
10
+ def meta
11
+ return data_hash("meta")
12
+ end
13
+
14
+ def cookie
15
+ return data_hash("cookie")
16
+ end
17
+
18
+ def ips
19
+ return data_array(self[:ip_data_id])
20
+ end
21
+
22
+ def data_array(data_id)
23
+ sql = "
24
+ SELECT
25
+ value_value.value AS value
26
+
27
+ FROM
28
+ Log_data_link AS value_links,
29
+ Log_data_value AS value_value
30
+
31
+ WHERE
32
+ value_links.data_id = '#{data_id}' AND
33
+ value_value.id = value_links.value_id
34
+
35
+ ORDER BY
36
+ key_links.no
37
+ "
38
+
39
+ arr = []
40
+ q_array = db.query(sql)
41
+ while d_array = q_array.fetch
42
+ arr << d_array[:value]
43
+ end
44
+
45
+ return arr
46
+ end
47
+
48
+ def data_hash(type)
49
+ col_keys_id = "#{type}_keys_data_id".to_sym
50
+ col_values_id = "#{type}_values_data_id".to_sym
51
+
52
+ keys_id = self[col_keys_id]
53
+ values_id = self[col_values_id]
54
+
55
+ keys_data_obj = ob.get(:Log_data, keys_id)
56
+ values_data_obj = ob.get(:Log_data, values_id)
57
+
58
+ sql = "
59
+ SELECT
60
+ key_value.value AS `key`,
61
+ value_value.value AS value
62
+
63
+ FROM
64
+ Log_data_link AS key_links,
65
+ Log_data_link AS value_links,
66
+ Log_data_value AS key_value,
67
+ Log_data_value AS value_value
68
+
69
+ WHERE
70
+ key_links.data_id = '#{keys_id}' AND
71
+ value_links.data_id = '#{values_id}' AND
72
+ key_links.no = value_links.no AND
73
+ key_value.id = key_links.value_id AND
74
+ value_value.id = value_links.value_id
75
+
76
+ ORDER BY
77
+ key_links.no
78
+ "
79
+
80
+ hash = {}
81
+ q_hash = db.query(sql)
82
+ while d_hash = q_hash.fetch
83
+ hash[d_hash[:key].to_s] = d_hash[:value]
84
+ end
85
+
86
+ return hash
87
+ end
88
+ end