hayabusa 0.0.24 → 0.0.29
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +363 -0
- data/Rakefile +0 -14
- data/bin/hayabusa_fcgi.fcgi +1 -0
- data/bin/hayabusa_fcgi_server.rb +0 -1
- data/lib/hayabusa.rb +124 -118
- data/lib/hayabusa_cgi_tools.rb +4 -2
- data/lib/hayabusa_client_session.rb +3 -1
- data/lib/hayabusa_database.rb +84 -84
- data/lib/hayabusa_datarow.rb +873 -0
- data/lib/hayabusa_ext/mailing.rb +8 -7
- data/lib/hayabusa_ext/web.rb +5 -0
- data/lib/hayabusa_fcgi.rb +13 -4
- data/lib/hayabusa_http_session.rb +2 -0
- data/lib/hayabusa_http_session_contentgroup.rb +7 -1
- data/lib/hayabusa_http_session_request.rb +7 -1
- data/lib/hayabusa_http_session_response.rb +30 -29
- data/lib/hayabusa_objects.rb +1455 -0
- data/lib/hayabusa_revision.rb +347 -0
- data/lib/kernel_ext/magic_methods.rb +4 -0
- data/lib/models/log.rb +27 -27
- data/lib/models/log_access.rb +20 -20
- data/lib/models/log_data.rb +6 -6
- data/lib/models/log_data_link.rb +2 -2
- data/lib/models/log_data_value.rb +5 -5
- data/lib/models/log_link.rb +12 -12
- data/lib/models/session.rb +6 -6
- metadata +125 -126
- data/.document +0 -5
- data/.rspec +0 -1
- data/Gemfile +0 -24
- data/Gemfile.lock +0 -70
- data/README.rdoc +0 -315
- data/VERSION +0 -1
- data/bin/hayabusa_fcgi.fcgi +0 -42
- data/conf/apache2_cgi_rhtml_conf.conf +0 -10
- data/conf/apache2_fcgi_rhtml_conf.conf +0 -22
- data/conf/apache2_hayabusa_conf.conf +0 -15
- data/hayabusa.gemspec +0 -167
- data/pages/benchmark.rhtml +0 -0
- data/pages/benchmark_print.rhtml +0 -14
- data/pages/benchmark_simple.rhtml +0 -3
- data/pages/benchmark_threadded_content.rhtml +0 -21
- data/pages/config_cgi.rb +0 -22
- data/pages/config_fcgi.rb +0 -22
- data/pages/debug_database_connections.rhtml +0 -46
- data/pages/debug_http_sessions.rhtml +0 -40
- data/pages/debug_memory_usage.rhtml +0 -39
- data/pages/error_notfound.rhtml +0 -12
- data/pages/image.png +0 -0
- data/pages/logs_latest.rhtml +0 -57
- data/pages/logs_show.rhtml +0 -32
- data/pages/spec.rhtml +0 -41
- data/pages/spec_exit.rhtml +0 -5
- data/pages/spec_multiple_threads.rhtml +0 -18
- data/pages/spec_sleeper.rhtml +0 -4
- data/pages/spec_test_multiple_clients.rhtml +0 -3
- data/pages/spec_thread_joins.rhtml +0 -29
- data/pages/spec_threadded_content.rhtml +0 -40
- data/pages/spec_vars_get.rhtml +0 -4
- data/pages/spec_vars_header.rhtml +0 -3
- data/pages/spec_vars_post.rhtml +0 -4
- data/pages/spec_vars_post_fileupload.rhtml +0 -19
- data/pages/testpic.jpeg +0 -0
- data/pages/tests.rhtml +0 -14
- data/pages/threadded_content_test.rhtml +0 -23
- data/spec/fcgi_multiple_processes_spec.rb +0 -104
- data/spec/hayabusa_spec.rb +0 -423
- data/spec/spec_helper.rb +0 -12
- data/spec/test_upload.xlsx +0 -0
data/lib/hayabusa_ext/mailing.rb
CHANGED
@@ -7,8 +7,8 @@ class Hayabusa
|
|
7
7
|
require "knj/autoload/ping"
|
8
8
|
|
9
9
|
@mails_waiting = []
|
10
|
-
@mails_mutex = Monitor.new
|
11
|
-
@mails_queue_mutex = Monitor.new
|
10
|
+
@mails_mutex = ::Monitor.new
|
11
|
+
@mails_queue_mutex = ::Monitor.new
|
12
12
|
@mails_timeout = self.timeout(:time => @config[:mailing_time], &self.method(:mail_flush))
|
13
13
|
end
|
14
14
|
|
@@ -60,7 +60,8 @@ class Hayabusa
|
|
60
60
|
|
61
61
|
#Use subprocessing to avoid the mail-framework (activesupport and so on, also possible memory leaks in those large frameworks).
|
62
62
|
self.log_puts("Starting subprocess for mailing.") if @debug
|
63
|
-
|
63
|
+
require "ruby_process"
|
64
|
+
::Ruby_process::Cproxy.run do |data|
|
64
65
|
subproc = data[:subproc]
|
65
66
|
subproc.static(:Object, :require, "rubygems")
|
66
67
|
subproc.static(:Object, :require, "mail")
|
@@ -78,7 +79,7 @@ class Hayabusa
|
|
78
79
|
#ignore -
|
79
80
|
rescue => e
|
80
81
|
@mails_waiting.delete(mail)
|
81
|
-
self.handle_error(e,
|
82
|
+
self.handle_error(e, :email => false)
|
82
83
|
end
|
83
84
|
|
84
85
|
sleep 1 #sleep so we dont take up too much bandwidth.
|
@@ -122,13 +123,13 @@ class Hayabusa
|
|
122
123
|
if args[:proc]
|
123
124
|
mail = args[:proc].new("Knj::Mailobj", @args[:hb].config[:smtp_args])
|
124
125
|
else
|
125
|
-
mail = Knj::Mailobj.new(@args[:hb].config[:smtp_args])
|
126
|
+
mail = ::Knj::Mailobj.new(@args[:hb].config[:smtp_args])
|
126
127
|
end
|
127
128
|
|
128
129
|
mail.to = @args[:to]
|
129
130
|
mail.subject = @args[:subject] if @args[:subject]
|
130
|
-
mail.html = Knj::Strings.email_str_safe(@args[:html]) if @args[:html]
|
131
|
-
mail.text = Knj::Strings.email_str_safe(@args[:text]) if @args[:text]
|
131
|
+
mail.html = ::Knj::Strings.email_str_safe(@args[:html]) if @args[:html]
|
132
|
+
mail.text = ::Knj::Strings.email_str_safe(@args[:text]) if @args[:text]
|
132
133
|
mail.from = @args[:from]
|
133
134
|
mail.send
|
134
135
|
|
data/lib/hayabusa_ext/web.rb
CHANGED
data/lib/hayabusa_fcgi.rb
CHANGED
@@ -13,6 +13,17 @@ class Hayabusa::Fcgi
|
|
13
13
|
@debug = false
|
14
14
|
end
|
15
15
|
|
16
|
+
def conf_path
|
17
|
+
#Parse the configuration-header and generate Hayabusa-config-hash.
|
18
|
+
if @cgi.env["HAYABUSA_FCGI_CONFIG"].to_s.length > 0
|
19
|
+
return @cgi.env["HAYABUSA_FCGI_CONFIG"]
|
20
|
+
elsif @cgi.env["HTTP_HAYABUSA_FCGI_CONFIG"].to_s.length > 0
|
21
|
+
return @cgi.env["HTTP_HAYABUSA_FCGI_CONFIG"]
|
22
|
+
else
|
23
|
+
raise "No HTTP_HAYABUSA_FCGI_CONFIG-header was given or HAYABUSA_FCGI_CONFIG environment variable."
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
16
27
|
#Evaluates if a new host-process should be started or we should proxy calls to an existing one.
|
17
28
|
def evaluate_mode
|
18
29
|
#If this is a FCGI-proxy-instance then the HTTP-connection should be checked if it is working.
|
@@ -25,9 +36,7 @@ class Hayabusa::Fcgi
|
|
25
36
|
#Skip the actual check if Hayabusa is spawned or this is a working FCGI-proxy-instance.
|
26
37
|
return nil if @hayabusa or @fcgi_proxy
|
27
38
|
|
28
|
-
|
29
|
-
raise "No HTTP_HAYABUSA_FCGI_CONFIG-header was given." if !@cgi.env["HTTP_HAYABUSA_FCGI_CONFIG"]
|
30
|
-
@hayabusa_fcgi_conf_path = @cgi.env["HTTP_HAYABUSA_FCGI_CONFIG"]
|
39
|
+
@hayabusa_fcgi_conf_path = conf_path
|
31
40
|
require @hayabusa_fcgi_conf_path
|
32
41
|
raise "No 'Hayabusa::FCGI_CONF'-constant was spawned by '#{@cgi.env["HTTP_HAYABUSA_FCGI_CONFIG"]}'." if !Hayabusa.const_defined?(:FCGI_CONF)
|
33
42
|
conf = Hayabusa::FCGI_CONF
|
@@ -148,7 +157,7 @@ class Hayabusa::Fcgi
|
|
148
157
|
end
|
149
158
|
|
150
159
|
#Ensure the same FCGI-process isnt active for more than one website.
|
151
|
-
raise "Expected 'HTTP_HAYABUSA_FCGI_CONFIG' to be '#{@hayabusa_fcgi_conf_path}' but it wasnt: '#{cgi.env
|
160
|
+
raise "Expected 'HTTP_HAYABUSA_FCGI_CONFIG' to be '#{@hayabusa_fcgi_conf_path}' but it wasnt: '#{conf_path}' #{@cgi.env}" if @hayabusa_fcgi_conf_path != conf_path
|
152
161
|
|
153
162
|
#Proxy request to the host-FCGI-process.
|
154
163
|
raise "No proxy spawned." unless @fcgi_proxy
|
@@ -179,6 +179,8 @@ class Hayabusa::Http_session < Hayabusa::Client_session
|
|
179
179
|
end
|
180
180
|
|
181
181
|
@page_path = @handler.page_path
|
182
|
+
@hb.log_puts "Hayabusa: Page path: #{@page_path}" if @debug
|
183
|
+
|
182
184
|
@ext = File.extname(@page_path).downcase[1..-1].to_s
|
183
185
|
|
184
186
|
@ctype = @types[@ext.to_sym] if @ext.length > 0 and @types.key?(@ext.to_sym)
|
@@ -79,8 +79,14 @@ class Hayabusa::Http_session::Contentgroup
|
|
79
79
|
end
|
80
80
|
|
81
81
|
def write(cont)
|
82
|
+
return if cont.empty?
|
83
|
+
|
82
84
|
@mutex.synchronize do
|
83
|
-
@cur_data[:str]
|
85
|
+
unless @cur_data[:str].is_a?(String)
|
86
|
+
raise "Couldnt add to string with a length of #{cont.length} to str, because str was a #{@cur_data[:str].class.name}. Cont: #{cont}"
|
87
|
+
else
|
88
|
+
@cur_data[:str] << cont
|
89
|
+
end
|
84
90
|
end
|
85
91
|
end
|
86
92
|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require "tempfile"
|
2
|
+
require "uri"
|
2
3
|
|
3
4
|
#If we are running on JRuby or Rubinius this will seriously speed things up if we are behind a proxy.
|
4
5
|
if RUBY_PLATFORM == "java" or RUBY_ENGINE == "rbx"
|
@@ -70,9 +71,14 @@ class Hayabusa::Http_session::Request
|
|
70
71
|
uri_raw = match[2]
|
71
72
|
uri_raw = "index.rhtml" if uri_raw == ""
|
72
73
|
|
73
|
-
uri =
|
74
|
+
if uri = URI.parse(match[2]) rescue nil
|
75
|
+
uri = {:path => uri.path.slice(1, 999), :query => uri.query}
|
76
|
+
else
|
77
|
+
uri = {:path => match[2], :query => ""}
|
78
|
+
end
|
74
79
|
|
75
80
|
page_filepath = Knj::Web.urldec(uri[:path])
|
81
|
+
|
76
82
|
if page_filepath.empty? or page_filepath == "/" or File.directory?("#{@hb.config[:doc_root]}/#{page_filepath}")
|
77
83
|
page_filepath = "#{page_filepath}/#{@hb.config[:default_page]}"
|
78
84
|
end
|
@@ -3,7 +3,7 @@ require "time"
|
|
3
3
|
#This object writes headers, trailing headers, status headers and more for HTTP-sessions.
|
4
4
|
class Hayabusa::Http_session::Response
|
5
5
|
attr_accessor :chunked, :cgroup, :nl, :status, :http_version, :headers, :headers_trailing, :headers_sent, :socket
|
6
|
-
|
6
|
+
|
7
7
|
STATUS_CODES = {
|
8
8
|
100 => "Continue",
|
9
9
|
200 => "OK",
|
@@ -22,16 +22,17 @@ class Hayabusa::Http_session::Response
|
|
22
22
|
403 => "Forbidden",
|
23
23
|
404 => "Not Found",
|
24
24
|
408 => "Request Timeout",
|
25
|
+
415 => "Unsupported media type",
|
25
26
|
500 => "Internal Server Error"
|
26
27
|
}
|
27
28
|
NL = "\r\n"
|
28
|
-
|
29
|
+
|
29
30
|
def initialize(args)
|
30
31
|
@chunked = false
|
31
32
|
@socket = args[:socket]
|
32
33
|
@hb = args[:hb]
|
33
34
|
end
|
34
|
-
|
35
|
+
|
35
36
|
def reset(args)
|
36
37
|
@status = 200
|
37
38
|
@http_version = args[:http_version]
|
@@ -45,20 +46,20 @@ class Hayabusa::Http_session::Response
|
|
45
46
|
@headers_trailing = {}
|
46
47
|
@mode = args[:mode]
|
47
48
|
@cookies = []
|
48
|
-
|
49
|
+
|
49
50
|
@headers = {
|
50
51
|
"date" => ["Date", Time.now.httpdate]
|
51
52
|
}
|
52
|
-
|
53
|
+
|
53
54
|
if args[:mode] != :cgi and (!args.key?(:chunked) or args[:chunked])
|
54
55
|
@chunked = true
|
55
56
|
end
|
56
57
|
end
|
57
|
-
|
58
|
+
|
58
59
|
def header(key, val)
|
59
60
|
lines = val.to_s.count("\n") + 1
|
60
61
|
raise "Value contains more lines than 1 (#{lines})." if lines > 1
|
61
|
-
|
62
|
+
|
62
63
|
if !@headers_sent
|
63
64
|
@headers[key.to_s.downcase.strip] = [key, val]
|
64
65
|
else
|
@@ -66,32 +67,32 @@ class Hayabusa::Http_session::Response
|
|
66
67
|
@headers_trailing[key.to_s.downcase.strip] = [key, val]
|
67
68
|
end
|
68
69
|
end
|
69
|
-
|
70
|
+
|
70
71
|
# Returns the value of a header.
|
71
72
|
def get_header_value(header)
|
72
73
|
header_p = header.to_s.downcase.strip
|
73
|
-
|
74
|
+
|
74
75
|
gothrough = [@headers, @headers_trailing]
|
75
76
|
gothrough.each do |headers|
|
76
77
|
headers.each do |key, val|
|
77
78
|
return val[1] if header_p == key
|
78
79
|
end
|
79
80
|
end
|
80
|
-
|
81
|
+
|
81
82
|
return nil
|
82
83
|
end
|
83
|
-
|
84
|
+
|
84
85
|
# Returns true if the given header-name is sat.
|
85
86
|
def has_header?(header)
|
86
87
|
header_p = header.to_s.downcase.strip
|
87
88
|
return @headers.key?(header_p) || @headers_trailing.key?(header_p)
|
88
89
|
end
|
89
|
-
|
90
|
+
|
90
91
|
def cookie(cookie)
|
91
92
|
@cookies << cookie
|
92
93
|
@session_cookie[cookie["name"]] = cookie["value"]
|
93
94
|
end
|
94
|
-
|
95
|
+
|
95
96
|
def header_str
|
96
97
|
if @http_version == "1.1" && @chunked
|
97
98
|
self.header("Connection", "Keep-Alive")
|
@@ -99,9 +100,9 @@ class Hayabusa::Http_session::Response
|
|
99
100
|
elsif @http_version == "1.1" && get_header_value("content-length").to_i > 0
|
100
101
|
self.header("Connection", "Keep-Alive")
|
101
102
|
end
|
102
|
-
|
103
|
+
|
103
104
|
self.header("Keep-Alive", "timeout=15, max=30") if self.get_header_value("connection") == "Keep-Alive"
|
104
|
-
|
105
|
+
|
105
106
|
if @skip_statuscode
|
106
107
|
res = ""
|
107
108
|
else
|
@@ -110,67 +111,67 @@ class Hayabusa::Http_session::Response
|
|
110
111
|
else
|
111
112
|
res = "HTTP/1.1 #{@status}"
|
112
113
|
end
|
113
|
-
|
114
|
+
|
114
115
|
code = STATUS_CODES[@status]
|
115
116
|
res << " #{code}" if code
|
116
117
|
res << NL
|
117
118
|
end
|
118
|
-
|
119
|
+
|
119
120
|
# The status header is used to make CGI or FCGI use the correct status-code.
|
120
121
|
self.header("Status", "#{@status} #{STATUS_CODES[@status]}")
|
121
|
-
|
122
|
+
|
122
123
|
@headers.each do |key, val|
|
123
124
|
res << "#{val[0]}: #{val[1]}#{NL}"
|
124
125
|
end
|
125
|
-
|
126
|
+
|
126
127
|
if @http_version == "1.1"
|
127
128
|
@trailers.each do |trailer|
|
128
129
|
res << "Trailer: #{trailer}#{NL}"
|
129
130
|
end
|
130
131
|
end
|
131
|
-
|
132
|
+
|
132
133
|
@cookies.each do |cookie|
|
133
134
|
res << "Set-Cookie: #{Knj::Web.cookie_str(cookie)}#{NL}"
|
134
135
|
end
|
135
|
-
|
136
|
+
|
136
137
|
res << NL
|
137
|
-
|
138
|
+
|
138
139
|
return res
|
139
140
|
end
|
140
|
-
|
141
|
+
|
141
142
|
def write
|
142
143
|
# Write headers to socket.
|
143
144
|
@socket.write(self.header_str)
|
144
145
|
@headers_sent = true
|
145
146
|
@cgroup.chunked = @chunked
|
146
|
-
|
147
|
+
|
147
148
|
# Set the content-length on the content-group to enable write-lenght-validation.
|
148
149
|
if self.has_header?("content-length")
|
149
150
|
@cgroup.content_length = self.get_header_value("content-length").to_i
|
150
151
|
else
|
151
152
|
@cgroup.content_length = nil
|
152
153
|
end
|
153
|
-
|
154
|
+
|
154
155
|
if @chunked
|
155
156
|
@cgroup.write_to_socket
|
156
157
|
@socket.write("0#{NL}")
|
157
|
-
|
158
|
+
|
158
159
|
@headers_trailing.each do |header_id_str, header|
|
159
160
|
@socket.write("#{header[0]}: #{header[1]}#{NL}")
|
160
161
|
end
|
161
|
-
|
162
|
+
|
162
163
|
@socket.write(NL)
|
163
164
|
else
|
164
165
|
@cgroup.write_to_socket
|
165
166
|
end
|
166
|
-
|
167
|
+
|
167
168
|
# Validate that no more has been written than given in content-length, since that will corrupt the client.
|
168
169
|
if self.has_header?("content-length")
|
169
170
|
length = cgroup.length_written
|
170
171
|
content_length = self.get_header_value("content-length").to_i
|
171
172
|
raise "More written than given in content-length: #{length}, #{content_length}" if length != content_length
|
172
173
|
end
|
173
|
-
|
174
|
+
|
174
175
|
# Close socket if that should be done.
|
175
176
|
if @close and @mode != :cgi
|
176
177
|
@hb.log_puts("Hauabusa: Closing socket.")
|