hayabusa 0.0.20 → 0.0.22
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/Gemfile +2 -0
- data/Gemfile.lock +30 -23
- data/VERSION +1 -1
- data/hayabusa.gemspec +15 -8
- data/lib/hayabusa.rb +8 -8
- data/lib/hayabusa_cgi_session.rb +1 -2
- data/lib/hayabusa_client_session.rb +14 -8
- data/lib/hayabusa_erb_handler.rb +1 -1
- data/lib/hayabusa_ext/cleaner.rb +5 -7
- data/lib/hayabusa_ext/errors.rb +1 -1
- data/lib/hayabusa_ext/mailing.rb +15 -21
- data/lib/hayabusa_ext/sessions.rb +6 -3
- data/lib/hayabusa_ext/threadding.rb +3 -3
- data/lib/hayabusa_ext/web.rb +1 -1
- data/lib/hayabusa_fcgi.rb +1 -1
- data/lib/hayabusa_http_session.rb +32 -28
- data/lib/hayabusa_http_session_contentgroup.rb +21 -2
- data/lib/hayabusa_http_session_post_multipart.rb +10 -1
- data/lib/hayabusa_http_session_request.rb +12 -2
- data/lib/hayabusa_http_session_response.rb +53 -22
- data/pages/debug_memory_usage.rhtml +24 -1
- data/pages/testpic.jpeg +0 -0
- data/spec/hayabusa_spec.rb +45 -14
- metadata +121 -30
data/Gemfile
CHANGED
|
@@ -10,6 +10,7 @@ gem "datet"
|
|
|
10
10
|
gem "http2"
|
|
11
11
|
gem "tpool"
|
|
12
12
|
gem "fcgi"
|
|
13
|
+
gem "ruby_process"
|
|
13
14
|
|
|
14
15
|
# Add dependencies to develop your gem here.
|
|
15
16
|
# Include everything needed to run rake, tests, features, etc.
|
|
@@ -18,5 +19,6 @@ group :development do
|
|
|
18
19
|
gem "rspec", ">= 2.3.0"
|
|
19
20
|
gem "bundler", ">= 1.0.0"
|
|
20
21
|
gem "jeweler", "~> 1.6.3"
|
|
22
|
+
gem "rmagick"
|
|
21
23
|
gem "sqlite3" if RUBY_ENGINE != "jruby"
|
|
22
24
|
end
|
data/Gemfile.lock
CHANGED
|
@@ -1,49 +1,54 @@
|
|
|
1
1
|
GEM
|
|
2
2
|
remote: http://rubygems.org/
|
|
3
3
|
specs:
|
|
4
|
-
datet (0.0.
|
|
5
|
-
diff-lcs (1.
|
|
4
|
+
datet (0.0.25)
|
|
5
|
+
diff-lcs (1.2.4)
|
|
6
6
|
erubis (2.7.0)
|
|
7
|
-
fcgi (0.
|
|
7
|
+
fcgi (0.9.1)
|
|
8
8
|
git (1.2.5)
|
|
9
|
-
http2 (0.0.
|
|
10
|
-
i18n (0.6.1)
|
|
9
|
+
http2 (0.0.21)
|
|
11
10
|
jeweler (1.6.4)
|
|
12
11
|
bundler (~> 1.0)
|
|
13
12
|
git (>= 1.2.5)
|
|
14
13
|
rake
|
|
15
|
-
json (1.
|
|
16
|
-
knjrbfw (0.0.
|
|
14
|
+
json (1.8.0)
|
|
15
|
+
knjrbfw (0.0.105)
|
|
17
16
|
datet
|
|
18
17
|
http2
|
|
19
18
|
php4r
|
|
19
|
+
ruby_process
|
|
20
20
|
tsafe
|
|
21
21
|
wref
|
|
22
|
-
mail (2.
|
|
23
|
-
i18n (>= 0.4.0)
|
|
22
|
+
mail (2.5.4)
|
|
24
23
|
mime-types (~> 1.16)
|
|
25
24
|
treetop (~> 1.4.8)
|
|
26
|
-
mime-types (1.
|
|
27
|
-
php4r (0.0.
|
|
25
|
+
mime-types (1.23)
|
|
26
|
+
php4r (0.0.4)
|
|
28
27
|
datet
|
|
29
28
|
http2
|
|
29
|
+
string-strtr
|
|
30
30
|
polyglot (0.3.3)
|
|
31
|
-
rake (
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
rspec-
|
|
35
|
-
rspec-
|
|
36
|
-
|
|
37
|
-
rspec-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
31
|
+
rake (10.1.0)
|
|
32
|
+
rmagick (2.13.2)
|
|
33
|
+
rspec (2.13.0)
|
|
34
|
+
rspec-core (~> 2.13.0)
|
|
35
|
+
rspec-expectations (~> 2.13.0)
|
|
36
|
+
rspec-mocks (~> 2.13.0)
|
|
37
|
+
rspec-core (2.13.1)
|
|
38
|
+
rspec-expectations (2.13.0)
|
|
39
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
|
40
|
+
rspec-mocks (2.13.1)
|
|
41
|
+
ruby_process (0.0.8)
|
|
42
|
+
tsafe
|
|
43
|
+
wref
|
|
44
|
+
sqlite3 (1.3.7)
|
|
45
|
+
string-strtr (0.0.3)
|
|
41
46
|
tpool (0.0.4)
|
|
42
|
-
treetop (1.4.
|
|
47
|
+
treetop (1.4.14)
|
|
43
48
|
polyglot
|
|
44
49
|
polyglot (>= 0.3.1)
|
|
45
50
|
tsafe (0.0.11)
|
|
46
|
-
wref (0.0.
|
|
51
|
+
wref (0.0.6)
|
|
47
52
|
|
|
48
53
|
PLATFORMS
|
|
49
54
|
ruby
|
|
@@ -58,6 +63,8 @@ DEPENDENCIES
|
|
|
58
63
|
json
|
|
59
64
|
knjrbfw
|
|
60
65
|
mail
|
|
66
|
+
rmagick
|
|
61
67
|
rspec (>= 2.3.0)
|
|
68
|
+
ruby_process
|
|
62
69
|
sqlite3
|
|
63
70
|
tpool
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.0.
|
|
1
|
+
0.0.22
|
data/hayabusa.gemspec
CHANGED
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
# -*- encoding: utf-8 -*-
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |s|
|
|
7
|
-
s.name =
|
|
8
|
-
s.version = "0.0.
|
|
7
|
+
s.name = "hayabusa"
|
|
8
|
+
s.version = "0.0.22"
|
|
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 =
|
|
13
|
-
s.description =
|
|
14
|
-
s.email =
|
|
12
|
+
s.date = "2013-06-28"
|
|
13
|
+
s.description = "A threadded web/app-server that focuses on threadding, shared ressources, speed and more."
|
|
14
|
+
s.email = "k@spernj.org"
|
|
15
15
|
s.executables = ["check_running.rb", "hayabusa_benchmark.rb", "hayabusa_cgi.rb", "hayabusa_fcgi.fcgi", "hayabusa_fcgi.rb", "hayabusa_fcgi_server.rb", "hayabusa_spec_restart.rb", "knjappserver_start.rb"]
|
|
16
16
|
s.extra_rdoc_files = [
|
|
17
17
|
"LICENSE.txt",
|
|
@@ -96,6 +96,7 @@ Gem::Specification.new do |s|
|
|
|
96
96
|
"pages/spec_vars_header.rhtml",
|
|
97
97
|
"pages/spec_vars_post.rhtml",
|
|
98
98
|
"pages/spec_vars_post_fileupload.rhtml",
|
|
99
|
+
"pages/testpic.jpeg",
|
|
99
100
|
"pages/tests.rhtml",
|
|
100
101
|
"pages/threadded_content_test.rhtml",
|
|
101
102
|
"spec/fcgi_multiple_processes_spec.rb",
|
|
@@ -103,11 +104,11 @@ Gem::Specification.new do |s|
|
|
|
103
104
|
"spec/spec_helper.rb",
|
|
104
105
|
"spec/test_upload.xlsx"
|
|
105
106
|
]
|
|
106
|
-
s.homepage =
|
|
107
|
+
s.homepage = "http://github.com/kaspernj/hayabusa"
|
|
107
108
|
s.licenses = ["MIT"]
|
|
108
109
|
s.require_paths = ["lib"]
|
|
109
|
-
s.rubygems_version =
|
|
110
|
-
s.summary =
|
|
110
|
+
s.rubygems_version = "1.8.23"
|
|
111
|
+
s.summary = "A threadded web/app-server that supports stand-alone, CGI and FCGI-modes."
|
|
111
112
|
|
|
112
113
|
if s.respond_to? :specification_version then
|
|
113
114
|
s.specification_version = 3
|
|
@@ -120,10 +121,12 @@ Gem::Specification.new do |s|
|
|
|
120
121
|
s.add_runtime_dependency(%q<http2>, [">= 0"])
|
|
121
122
|
s.add_runtime_dependency(%q<tpool>, [">= 0"])
|
|
122
123
|
s.add_runtime_dependency(%q<fcgi>, [">= 0"])
|
|
124
|
+
s.add_runtime_dependency(%q<ruby_process>, [">= 0"])
|
|
123
125
|
s.add_development_dependency(%q<json>, [">= 0"])
|
|
124
126
|
s.add_development_dependency(%q<rspec>, [">= 2.3.0"])
|
|
125
127
|
s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
|
|
126
128
|
s.add_development_dependency(%q<jeweler>, ["~> 1.6.3"])
|
|
129
|
+
s.add_development_dependency(%q<rmagick>, [">= 0"])
|
|
127
130
|
s.add_development_dependency(%q<sqlite3>, [">= 0"])
|
|
128
131
|
else
|
|
129
132
|
s.add_dependency(%q<knjrbfw>, [">= 0"])
|
|
@@ -133,10 +136,12 @@ Gem::Specification.new do |s|
|
|
|
133
136
|
s.add_dependency(%q<http2>, [">= 0"])
|
|
134
137
|
s.add_dependency(%q<tpool>, [">= 0"])
|
|
135
138
|
s.add_dependency(%q<fcgi>, [">= 0"])
|
|
139
|
+
s.add_dependency(%q<ruby_process>, [">= 0"])
|
|
136
140
|
s.add_dependency(%q<json>, [">= 0"])
|
|
137
141
|
s.add_dependency(%q<rspec>, [">= 2.3.0"])
|
|
138
142
|
s.add_dependency(%q<bundler>, [">= 1.0.0"])
|
|
139
143
|
s.add_dependency(%q<jeweler>, ["~> 1.6.3"])
|
|
144
|
+
s.add_dependency(%q<rmagick>, [">= 0"])
|
|
140
145
|
s.add_dependency(%q<sqlite3>, [">= 0"])
|
|
141
146
|
end
|
|
142
147
|
else
|
|
@@ -147,10 +152,12 @@ Gem::Specification.new do |s|
|
|
|
147
152
|
s.add_dependency(%q<http2>, [">= 0"])
|
|
148
153
|
s.add_dependency(%q<tpool>, [">= 0"])
|
|
149
154
|
s.add_dependency(%q<fcgi>, [">= 0"])
|
|
155
|
+
s.add_dependency(%q<ruby_process>, [">= 0"])
|
|
150
156
|
s.add_dependency(%q<json>, [">= 0"])
|
|
151
157
|
s.add_dependency(%q<rspec>, [">= 2.3.0"])
|
|
152
158
|
s.add_dependency(%q<bundler>, [">= 1.0.0"])
|
|
153
159
|
s.add_dependency(%q<jeweler>, ["~> 1.6.3"])
|
|
160
|
+
s.add_dependency(%q<rmagick>, [">= 0"])
|
|
154
161
|
s.add_dependency(%q<sqlite3>, [">= 0"])
|
|
155
162
|
end
|
|
156
163
|
end
|
data/lib/hayabusa.rb
CHANGED
|
@@ -34,7 +34,7 @@ class Hayabusa
|
|
|
34
34
|
:default_filetype => "text/html",
|
|
35
35
|
:max_requests_working => 20,
|
|
36
36
|
:size_send => 1024,
|
|
37
|
-
:cleaner_timeout =>
|
|
37
|
+
:cleaner_timeout => 60,
|
|
38
38
|
:mailing_time => 30
|
|
39
39
|
}.merge(config)
|
|
40
40
|
|
|
@@ -52,20 +52,20 @@ class Hayabusa
|
|
|
52
52
|
[:Tpool, "tpool"]
|
|
53
53
|
]
|
|
54
54
|
|
|
55
|
-
gems.each do |
|
|
56
|
-
if Kernel.const_defined?(
|
|
57
|
-
puts "Gem already loaded: '#{
|
|
55
|
+
gems.each do |gem_i|
|
|
56
|
+
if Kernel.const_defined?(gem_i[0])
|
|
57
|
+
puts "Gem already loaded: '#{gem_i[1]}'." if @debug
|
|
58
58
|
next
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
-
fpath = "#{@@path}/../../#{
|
|
61
|
+
fpath = "#{@@path}/../../#{gem_i[1]}/lib/#{gem_i[1]}.rb"
|
|
62
62
|
|
|
63
63
|
if File.exists?(fpath)
|
|
64
64
|
puts "Loading custom gem-path: '#{fpath}'." if @debug
|
|
65
65
|
require fpath
|
|
66
66
|
else
|
|
67
|
-
puts "Loading gem: '#{
|
|
68
|
-
require
|
|
67
|
+
puts "Loading gem: '#{gem_i[1]}'." if @debug
|
|
68
|
+
require gem_i[1]
|
|
69
69
|
end
|
|
70
70
|
end
|
|
71
71
|
|
|
@@ -544,4 +544,4 @@ class Hayabusa
|
|
|
544
544
|
|
|
545
545
|
return @translations
|
|
546
546
|
end
|
|
547
|
-
end
|
|
547
|
+
end
|
data/lib/hayabusa_cgi_session.rb
CHANGED
|
@@ -22,6 +22,14 @@ class Hayabusa::Client_session
|
|
|
22
22
|
@cgroup.force_content(newcont)
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
#Forces the output to be read from a file.
|
|
26
|
+
def force_fileread(fpath)
|
|
27
|
+
raise "Invalid filepath given: '#{fpath}'." if !fpath || !File.exists?(fpath)
|
|
28
|
+
@resp.chunked = false
|
|
29
|
+
@resp.header("Content-Length", File.size(fpath))
|
|
30
|
+
@cgroup.new_io(:type => :file, :path => fpath)
|
|
31
|
+
end
|
|
32
|
+
|
|
25
33
|
#Creates a new Hayabusa::Binding-object and returns the binding for that object.
|
|
26
34
|
def create_binding
|
|
27
35
|
return Hayabusa::Http_session::Page_environment.new(:httpsession => self, :hb => @hb).get_binding
|
|
@@ -82,6 +90,7 @@ class Hayabusa::Client_session
|
|
|
82
90
|
if @handlers_cache.key?(@ext)
|
|
83
91
|
@hb.log_puts("Calling handler.") if @debug
|
|
84
92
|
@handlers_cache[@ext].call(self)
|
|
93
|
+
@hb.log_puts("Called handler.") if @debug
|
|
85
94
|
else
|
|
86
95
|
#check if we should use a handler for this request.
|
|
87
96
|
@config[:handlers].each do |handler_info|
|
|
@@ -125,7 +134,7 @@ class Hayabusa::Client_session
|
|
|
125
134
|
end
|
|
126
135
|
end
|
|
127
136
|
|
|
128
|
-
|
|
137
|
+
self.force_fileread(@page_path)
|
|
129
138
|
end
|
|
130
139
|
end
|
|
131
140
|
end
|
|
@@ -133,8 +142,8 @@ class Hayabusa::Client_session
|
|
|
133
142
|
rescue SystemExit
|
|
134
143
|
#do nothing - ignore.
|
|
135
144
|
rescue Timeout::Error
|
|
136
|
-
@resp.status =
|
|
137
|
-
|
|
145
|
+
@resp.status = 408
|
|
146
|
+
@hb.log_puts "The request timed out."
|
|
138
147
|
end
|
|
139
148
|
end
|
|
140
149
|
|
|
@@ -144,10 +153,7 @@ class Hayabusa::Client_session
|
|
|
144
153
|
@hb.log_puts "#{__id__} - Served '#{@meta["REQUEST_URI"]}' in #{Time.now.to_f - @time_start} secs (#{@resp.status})." if @debug
|
|
145
154
|
@time_start = nil
|
|
146
155
|
@cgroup.join
|
|
147
|
-
|
|
148
|
-
@hb.events.call(:request_done, {
|
|
149
|
-
:httpsession => self
|
|
150
|
-
}) if @hb.events
|
|
156
|
+
@hb.events.call(:request_done, :httpsession => self) if @hb.events
|
|
151
157
|
@httpsession_var = {}
|
|
152
158
|
end
|
|
153
|
-
end
|
|
159
|
+
end
|
data/lib/hayabusa_erb_handler.rb
CHANGED
|
@@ -20,7 +20,7 @@ class Hayabusa::Erb_handler
|
|
|
20
20
|
httpsess.resp.status = 500 if eruby.error
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
#Handels the event when an error in the eruby-instance occurs.
|
|
23
|
+
# Handels the event when an error in the eruby-instance occurs.
|
|
24
24
|
def on_error(e)
|
|
25
25
|
_hb.handle_error(e)
|
|
26
26
|
end
|
data/lib/hayabusa_ext/cleaner.rb
CHANGED
|
@@ -9,7 +9,6 @@ class Hayabusa
|
|
|
9
9
|
|
|
10
10
|
def clean
|
|
11
11
|
self.clean_sessions
|
|
12
|
-
self.clean_autorestart
|
|
13
12
|
end
|
|
14
13
|
|
|
15
14
|
def clean_autorestart
|
|
@@ -108,18 +107,17 @@ class Hayabusa
|
|
|
108
107
|
#Clean up various inactive sessions.
|
|
109
108
|
session_not_ids = []
|
|
110
109
|
time_check = Time.now.to_i - 300
|
|
111
|
-
|
|
112
|
-
@sessions.each do |session_hash, session_data|
|
|
110
|
+
@sessions.delete_if do |session_hash, session_data|
|
|
113
111
|
session_data[:dbobj].flush
|
|
114
112
|
|
|
115
|
-
if session_data[:
|
|
116
|
-
newsessions[session_hash] = session_data
|
|
113
|
+
if session_data[:dbobj].date_lastused.to_i > time_check
|
|
117
114
|
session_not_ids << session_data[:dbobj].id
|
|
115
|
+
false
|
|
116
|
+
else
|
|
117
|
+
true
|
|
118
118
|
end
|
|
119
119
|
end
|
|
120
120
|
|
|
121
|
-
@sessions = newsessions
|
|
122
|
-
|
|
123
121
|
self.log_puts("Delete sessions...") if @debug
|
|
124
122
|
@ob.list(:Session, {"id_not" => session_not_ids, "date_lastused_below" => (Time.now - 5356800)}) do |session|
|
|
125
123
|
idhash = session[:idhash]
|
data/lib/hayabusa_ext/errors.rb
CHANGED
data/lib/hayabusa_ext/mailing.rb
CHANGED
|
@@ -60,17 +60,17 @@ 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
|
-
|
|
64
|
-
subproc
|
|
65
|
-
subproc.static(
|
|
66
|
-
subproc.static(
|
|
67
|
-
subproc.static(
|
|
63
|
+
Ruby_process::Cproxy.run do |data|
|
|
64
|
+
subproc = data[:subproc]
|
|
65
|
+
subproc.static(:Object, :require, "rubygems")
|
|
66
|
+
subproc.static(:Object, :require, "mail")
|
|
67
|
+
subproc.static(:Object, :require, "#{Knj.knjrbfw_path}/../knjrbfw.rb")
|
|
68
68
|
|
|
69
69
|
self.log_puts("Flushing emails.") if @debug
|
|
70
70
|
@mails_waiting.each do |mail|
|
|
71
71
|
begin
|
|
72
72
|
self.log_puts("Sending email: #{mail.__id__}") if @debug
|
|
73
|
-
if mail.send(
|
|
73
|
+
if mail.send(:proc => subproc)
|
|
74
74
|
self.log_puts("Email sent: #{mail.__id__}") if @debug
|
|
75
75
|
@mails_waiting.delete(mail)
|
|
76
76
|
end
|
|
@@ -119,25 +119,19 @@ class Hayabusa
|
|
|
119
119
|
def send(args = {})
|
|
120
120
|
@args[:hb].log_puts("Sending mail '#{__id__}'.") if @args[:hb].debug
|
|
121
121
|
|
|
122
|
-
if args[
|
|
123
|
-
args[
|
|
124
|
-
mail = args["proc"].new("Knj::Mailobj", @args[:hb].config[:smtp_args])
|
|
125
|
-
mail._pm_send_noret("to=", @args[:to])
|
|
126
|
-
mail._pm_send_noret("subject=", @args[:subject]) if @args[:subject]
|
|
127
|
-
mail._pm_send_noret("html=", Knj::Strings.email_str_safe(@args[:html])) if @args[:html]
|
|
128
|
-
mail._pm_send_noret("text=", Knj::Strings.email_str_safe(@args[:text])) if @args[:text]
|
|
129
|
-
mail._pm_send_noret("from=", @args[:from])
|
|
130
|
-
mail._pm_send_noret("send")
|
|
122
|
+
if args[:proc]
|
|
123
|
+
mail = args[:proc].new("Knj::Mailobj", @args[:hb].config[:smtp_args])
|
|
131
124
|
else
|
|
132
125
|
mail = Knj::Mailobj.new(@args[:hb].config[:smtp_args])
|
|
133
|
-
mail.to = @args[:to]
|
|
134
|
-
mail.subject = @args[:subject] if @args[:subject]
|
|
135
|
-
mail.html = Knj::Strings.email_str_safe(@args[:html]) if @args[:html]
|
|
136
|
-
mail.text = Knj::Strings.email_str_safe(@args[:text]) if @args[:text]
|
|
137
|
-
mail.from = @args[:from]
|
|
138
|
-
mail.send
|
|
139
126
|
end
|
|
140
127
|
|
|
128
|
+
mail.to = @args[:to]
|
|
129
|
+
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]
|
|
132
|
+
mail.from = @args[:from]
|
|
133
|
+
mail.send
|
|
134
|
+
|
|
141
135
|
@args[:status] = :sent
|
|
142
136
|
@args[:hb].log_puts("Sent email #{self.__id__}") if @args[:hb].debug
|
|
143
137
|
return true
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
class Hayabusa
|
|
2
|
+
attr_reader :sessions
|
|
3
|
+
|
|
2
4
|
def initialize_sessions
|
|
3
5
|
@sessions = Tsafe::MonHash.new
|
|
4
6
|
end
|
|
@@ -13,8 +15,11 @@ class Hayabusa
|
|
|
13
15
|
session = @ob.add(:Session, {
|
|
14
16
|
:idhash => idhash,
|
|
15
17
|
:user_agent => meta["HTTP_USER_AGENT"],
|
|
16
|
-
:ip => ip
|
|
18
|
+
:ip => ip,
|
|
19
|
+
:date_lastused => Time.now
|
|
17
20
|
})
|
|
21
|
+
else
|
|
22
|
+
session[:date_lastused] = Time.now
|
|
18
23
|
end
|
|
19
24
|
|
|
20
25
|
hash = {}
|
|
@@ -28,8 +33,6 @@ class Hayabusa
|
|
|
28
33
|
end
|
|
29
34
|
|
|
30
35
|
raise ArgumentError, "Invalid IP." if ip != "bot" and !session.remember? and ip.to_s != session[:ip].to_s
|
|
31
|
-
|
|
32
|
-
@sessions[idhash][:time_lastused] = Time.now
|
|
33
36
|
return [session, hash]
|
|
34
37
|
end
|
|
35
38
|
|
|
@@ -16,10 +16,10 @@ class Hayabusa
|
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
#Inits the thread so it has access to the appserver and various magic methods can be used.
|
|
19
|
-
def thread_init(thread =
|
|
20
|
-
thread = Thread.current if thread == nil
|
|
19
|
+
def thread_init(thread = Thread.current)
|
|
21
20
|
thread[:hayabusa] = {} if !thread[:hayabusa]
|
|
22
21
|
thread[:hayabusa][:hb] = self
|
|
22
|
+
return nil
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
#Spawns a new thread with access to magic methods, _db-method and various other stuff in the appserver.
|
|
@@ -72,7 +72,7 @@ class Hayabusa
|
|
|
72
72
|
thread[:hayabusa][:hb] = self
|
|
73
73
|
|
|
74
74
|
begin
|
|
75
|
-
block.call
|
|
75
|
+
return block.call
|
|
76
76
|
ensure
|
|
77
77
|
@ob.db.free_thread if @ob.db.opts[:threadsafe]
|
|
78
78
|
@db_handler.free_thread if @db_handler.opts[:threadsafe]
|
data/lib/hayabusa_ext/web.rb
CHANGED
|
@@ -100,7 +100,7 @@ class Hayabusa
|
|
|
100
100
|
|
|
101
101
|
#Urlencodes a string.
|
|
102
102
|
#===Examples
|
|
103
|
-
#
|
|
103
|
+
# Knj::Web.redirect("mypage.rhtml?arg=#{_hb.urlenc(value_variable)}")
|
|
104
104
|
def urlenc(str)
|
|
105
105
|
return Knj::Web.urlenc(str)
|
|
106
106
|
end
|
data/lib/hayabusa_fcgi.rb
CHANGED
|
@@ -64,7 +64,7 @@ class Hayabusa::Fcgi
|
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
if hayabusa_conf[:debug]
|
|
67
|
-
@fcgi_proxy[:fp_log] = File.open("/tmp/hayabusa_#{hayabusa_conf[:
|
|
67
|
+
@fcgi_proxy[:fp_log] = File.open("/tmp/hayabusa_#{hayabusa_conf[:title]}_#{Process.pid}.log", "w")
|
|
68
68
|
@fcgi_proxy[:fp_log].sync = true
|
|
69
69
|
end
|
|
70
70
|
rescue
|
|
@@ -82,31 +82,35 @@ class Hayabusa::Http_session < Hayabusa::Client_session
|
|
|
82
82
|
@handler.socket_parse(@socket)
|
|
83
83
|
end
|
|
84
84
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
@hb.
|
|
89
|
-
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
break if @hb.should_restart
|
|
93
|
-
|
|
94
|
-
if max_requests_working and @httpserver
|
|
95
|
-
while @httpserver.working_count.to_i >= max_requests_working
|
|
96
|
-
@hb.log_puts "#{__id__} - Maximum amounts of requests are working (#{@httpserver.working_count}, #{max_requests_working}) - sleeping." if @debug
|
|
85
|
+
begin
|
|
86
|
+
@hb.log_puts "#{__id__} - Done parsing from socket." if @debug
|
|
87
|
+
|
|
88
|
+
while @hb.paused? #Check if we should be waiting with executing the pending request.
|
|
89
|
+
@hb.log_puts "#{__id__} - Paused! (#{@hb.paused}) - sleeping." if @debug
|
|
97
90
|
sleep 0.1
|
|
98
91
|
end
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
92
|
+
|
|
93
|
+
break if @hb.should_restart
|
|
94
|
+
|
|
95
|
+
if max_requests_working and @httpserver
|
|
96
|
+
while @httpserver.working_count.to_i >= max_requests_working
|
|
97
|
+
@hb.log_puts "#{__id__} - Maximum amounts of requests are working (#{@httpserver.working_count}, #{max_requests_working}) - sleeping." if @debug
|
|
98
|
+
sleep 0.1
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
#Reserve database connections.
|
|
103
|
+
@hb.db_handler.get_and_register_thread if @hb.db_handler.opts[:threadsafe]
|
|
104
|
+
@hb.ob.db.get_and_register_thread if @hb.ob.db.opts[:threadsafe]
|
|
105
|
+
|
|
106
|
+
@working = true
|
|
107
|
+
@hb.log_puts "#{__id__} - Serving." if @debug
|
|
108
|
+
|
|
109
|
+
@httpserver.count_block do
|
|
110
|
+
self.serve
|
|
111
|
+
end
|
|
112
|
+
ensure
|
|
113
|
+
@handler.delete_tempfiles
|
|
110
114
|
end
|
|
111
115
|
ensure
|
|
112
116
|
@hb.log_puts "#{__id__} - Closing request." if @debug
|
|
@@ -132,11 +136,11 @@ class Hayabusa::Http_session < Hayabusa::Client_session
|
|
|
132
136
|
end
|
|
133
137
|
|
|
134
138
|
def self.finalize(id)
|
|
135
|
-
@hb.log_puts "Http_session finalize #{id}." if @debug
|
|
139
|
+
@hb.log_puts "Hayabusa: Http_session finalize #{id}." if @debug
|
|
136
140
|
end
|
|
137
141
|
|
|
138
142
|
def destruct
|
|
139
|
-
@hb.log_puts "Http_session destruct (#{@httpserver.http_sessions.length})" if @debug and @httpserver and @httpserver.http_sessions
|
|
143
|
+
@hb.log_puts "Hayabusa: Http_session destruct (#{@httpserver.http_sessions.length})" if @debug and @httpserver and @httpserver.http_sessions
|
|
140
144
|
|
|
141
145
|
begin
|
|
142
146
|
@socket.close if !@socket.closed?
|
|
@@ -153,7 +157,7 @@ class Hayabusa::Http_session < Hayabusa::Client_session
|
|
|
153
157
|
end
|
|
154
158
|
|
|
155
159
|
def serve
|
|
156
|
-
@hb.log_puts "Generating meta, cookie, get, post and headers." if @debug
|
|
160
|
+
@hb.log_puts "Hayabusa: Generating meta, cookie, get, post and headers." if @debug
|
|
157
161
|
@meta = @handler.meta.merge(@socket_meta)
|
|
158
162
|
@cookie = @handler.cookie
|
|
159
163
|
@get = @handler.get
|
|
@@ -184,7 +188,7 @@ class Hayabusa::Http_session < Hayabusa::Client_session
|
|
|
184
188
|
@browser = Knj::Web.browser(@meta)
|
|
185
189
|
@ip = @hb.ip(:meta => @meta)
|
|
186
190
|
|
|
187
|
-
@hb.log_puts "Figuring out session-ID, session-object and more." if @debug
|
|
191
|
+
@hb.log_puts "Hayabusa: Figuring out session-ID, session-object and more." if @debug
|
|
188
192
|
if @cookie["HayabusaSession"].to_s.length > 0
|
|
189
193
|
@session_id = @cookie["HayabusaSession"]
|
|
190
194
|
elsif @browser["browser"] == "bot"
|
|
@@ -213,7 +217,7 @@ class Hayabusa::Http_session < Hayabusa::Client_session
|
|
|
213
217
|
end
|
|
214
218
|
|
|
215
219
|
if @config.key?(:logging) and @config[:logging][:access_db]
|
|
216
|
-
@hb.log_puts "Doing access-logging." if @debug
|
|
220
|
+
@hb.log_puts "Hayabusa: Doing access-logging." if @debug
|
|
217
221
|
@ips = [@meta["REMOTE_ADDR"]]
|
|
218
222
|
@ips << @meta["HTTP_X_FORWARDED_FOR"].split(",")[0].strip if @meta["HTTP_X_FORWARDED_FOR"]
|
|
219
223
|
@hb.logs_access_pending << {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
#This class handels the adding of content and writing to socket. Since this can be done with multiple threads and multiple IO's it can get complicated.
|
|
4
4
|
class Hayabusa::Http_session::Contentgroup
|
|
5
5
|
attr_reader :done, :cur_data
|
|
6
|
-
attr_accessor :chunked, :socket
|
|
6
|
+
attr_accessor :chunked, :socket, :content_length, :length_written
|
|
7
7
|
NL = "\r\n"
|
|
8
8
|
|
|
9
9
|
def initialize(args = {})
|
|
@@ -13,6 +13,8 @@ class Hayabusa::Http_session::Contentgroup
|
|
|
13
13
|
@httpsession = args[:httpsession]
|
|
14
14
|
@mutex = Mutex.new
|
|
15
15
|
@debug = false
|
|
16
|
+
@length_written = args[:length_written] ? args[:length_written] : 0
|
|
17
|
+
@content_length = args[:content_length]
|
|
16
18
|
end
|
|
17
19
|
|
|
18
20
|
def init
|
|
@@ -30,6 +32,7 @@ class Hayabusa::Http_session::Contentgroup
|
|
|
30
32
|
@done = false
|
|
31
33
|
@thread = nil
|
|
32
34
|
@forced = false
|
|
35
|
+
@length_written = 0
|
|
33
36
|
|
|
34
37
|
@mutex.synchronize do
|
|
35
38
|
self.new_io
|
|
@@ -55,7 +58,7 @@ class Hayabusa::Http_session::Contentgroup
|
|
|
55
58
|
end
|
|
56
59
|
|
|
57
60
|
def new_thread
|
|
58
|
-
cgroup = Hayabusa::Http_session::Contentgroup.new(:socket => @socket, :chunked => @chunked)
|
|
61
|
+
cgroup = Hayabusa::Http_session::Contentgroup.new(:socket => @socket, :chunked => @chunked, :content_length => @content_length)
|
|
59
62
|
cgroup.init
|
|
60
63
|
|
|
61
64
|
@mutex.synchronize do
|
|
@@ -92,6 +95,8 @@ class Hayabusa::Http_session::Contentgroup
|
|
|
92
95
|
STDERR.puts "Error while writing."
|
|
93
96
|
STDERR.puts e.inspect
|
|
94
97
|
STDERR.puts e.backtrace
|
|
98
|
+
|
|
99
|
+
raise e
|
|
95
100
|
end
|
|
96
101
|
end
|
|
97
102
|
end
|
|
@@ -125,7 +130,12 @@ class Hayabusa::Http_session::Contentgroup
|
|
|
125
130
|
|
|
126
131
|
@ios.each do |data|
|
|
127
132
|
if data.is_a?(Hayabusa::Http_session::Contentgroup)
|
|
133
|
+
data.length_written = @length_written
|
|
134
|
+
data.content_length = @content_length
|
|
135
|
+
data.chunked = @chunked
|
|
128
136
|
data.write_to_socket
|
|
137
|
+
|
|
138
|
+
@length_written += data.length_written
|
|
129
139
|
elsif data.key?(:str)
|
|
130
140
|
if data[:str].is_a?(Hash) and data[:str][:type] == :file
|
|
131
141
|
File.open(data[:str][:path], "r") do |file|
|
|
@@ -136,6 +146,8 @@ class Hayabusa::Http_session::Contentgroup
|
|
|
136
146
|
break
|
|
137
147
|
end
|
|
138
148
|
|
|
149
|
+
add_to_length_written(buf.bytesize)
|
|
150
|
+
|
|
139
151
|
if @chunked
|
|
140
152
|
@socket.write("#{buf.length.to_s(16)}#{NL}#{buf}#{NL}")
|
|
141
153
|
else
|
|
@@ -157,6 +169,7 @@ class Hayabusa::Http_session::Contentgroup
|
|
|
157
169
|
#512 could take a long time for big pages. 16384 seems to be an optimal number.
|
|
158
170
|
str.each_slice(16384) do |slice|
|
|
159
171
|
buf = slice.pack("C*")
|
|
172
|
+
add_to_length_written(buf.bytesize)
|
|
160
173
|
|
|
161
174
|
if @chunked
|
|
162
175
|
@socket.write("#{buf.length.to_s(16)}#{NL}#{buf}#{NL}")
|
|
@@ -173,4 +186,10 @@ class Hayabusa::Http_session::Contentgroup
|
|
|
173
186
|
|
|
174
187
|
count += 1
|
|
175
188
|
end
|
|
189
|
+
|
|
190
|
+
# Adds the given size to the length written and raises an exception if it exceeds the sat content-length.
|
|
191
|
+
def add_to_length_written(size)
|
|
192
|
+
@length_written += size
|
|
193
|
+
raise "Content-Length overwritten: #{@length_written}, #{@content_length}" if @content_length != nil && @length_written > @content_length
|
|
194
|
+
end
|
|
176
195
|
end
|
|
@@ -17,6 +17,7 @@ class Hayabusa::Http_session::Post_multipart
|
|
|
17
17
|
@clength = 0
|
|
18
18
|
@headers = {}
|
|
19
19
|
@counts = {}
|
|
20
|
+
@files_arr = args[:files_arr]
|
|
20
21
|
str_crlf = nil
|
|
21
22
|
|
|
22
23
|
@args[:io].each do |line|
|
|
@@ -112,7 +113,11 @@ class Hayabusa::Http_session::Post_multipart
|
|
|
112
113
|
return nil
|
|
113
114
|
end
|
|
114
115
|
|
|
115
|
-
|
|
116
|
+
if @data.is_a?(Tempfile)
|
|
117
|
+
@data.close(false)
|
|
118
|
+
@files_arr << @data.path if @data.respond_to?(:path)
|
|
119
|
+
end
|
|
120
|
+
|
|
116
121
|
raise "No 'content-disposition' was given (#{@headers}) (#{@data})." if !@name
|
|
117
122
|
|
|
118
123
|
if @fname
|
|
@@ -203,4 +208,8 @@ class Hayabusa::Http_session::Post_multipart::File_upload
|
|
|
203
208
|
def to_json(*args)
|
|
204
209
|
raise "File_upload-objects should not be converted to json."
|
|
205
210
|
end
|
|
211
|
+
|
|
212
|
+
def unset
|
|
213
|
+
|
|
214
|
+
end
|
|
206
215
|
end
|
|
@@ -7,7 +7,7 @@ end
|
|
|
7
7
|
|
|
8
8
|
#This class parses the various HTTP requests into easy programmable objects. Get, post, cookie, meta and so on...
|
|
9
9
|
class Hayabusa::Http_session::Request
|
|
10
|
-
attr_reader :get, :post, :cookie, :meta, :page_path, :headers, :http_version, :read, :clength, :speed, :percent, :secs_left
|
|
10
|
+
attr_reader :get, :post, :cookie, :files_arr, :meta, :page_path, :headers, :http_version, :read, :clength, :speed, :percent, :secs_left
|
|
11
11
|
|
|
12
12
|
#Sets the various required data on the object. Hayabusa, crlf and arguments.
|
|
13
13
|
def initialize(args)
|
|
@@ -79,6 +79,7 @@ class Hayabusa::Http_session::Request
|
|
|
79
79
|
|
|
80
80
|
@page_path = "#{@hb.config[:doc_root]}/#{page_filepath}"
|
|
81
81
|
@get = Knj::Web.parse_urlquery(uri[:query], :urldecode => true, :force_utf8 => true)
|
|
82
|
+
@files_arr = []
|
|
82
83
|
|
|
83
84
|
if @get["_hb_httpsession_id"]
|
|
84
85
|
@hb.httpsessions_ids[@get["_hb_httpsession_id"]] = @args[:httpsession]
|
|
@@ -187,7 +188,8 @@ class Hayabusa::Http_session::Request
|
|
|
187
188
|
post_treated = Hayabusa::Http_session::Post_multipart.new(
|
|
188
189
|
:io => post_data,
|
|
189
190
|
:boundary => match[1],
|
|
190
|
-
:crlf => @crlf
|
|
191
|
+
:crlf => @crlf,
|
|
192
|
+
:files_arr => @files_arr
|
|
191
193
|
).return
|
|
192
194
|
post_data.close(true)
|
|
193
195
|
|
|
@@ -237,4 +239,12 @@ class Hayabusa::Http_session::Request
|
|
|
237
239
|
Knj::Web.parse_name(seton, varname, value, args)
|
|
238
240
|
end
|
|
239
241
|
end
|
|
242
|
+
|
|
243
|
+
#Deletes all tempfiles created by this object. This is useually called from Http_session at the end of a request.
|
|
244
|
+
def delete_tempfiles
|
|
245
|
+
@files_arr.delete_if do |tempfile_path|
|
|
246
|
+
File.unlink(tempfile_path) if File.exists?(tempfile_path)
|
|
247
|
+
true
|
|
248
|
+
end
|
|
249
|
+
end
|
|
240
250
|
end
|
|
@@ -21,6 +21,7 @@ class Hayabusa::Http_session::Response
|
|
|
21
21
|
401 => "Unauthorized",
|
|
22
22
|
403 => "Forbidden",
|
|
23
23
|
404 => "Not Found",
|
|
24
|
+
408 => "Request Timeout",
|
|
24
25
|
500 => "Internal Server Error"
|
|
25
26
|
}
|
|
26
27
|
NL = "\r\n"
|
|
@@ -40,29 +41,18 @@ class Hayabusa::Http_session::Response
|
|
|
40
41
|
@trailers = []
|
|
41
42
|
@skip_statuscode = true if args[:mode] == :cgi
|
|
42
43
|
@session_cookie = args[:cookie]
|
|
43
|
-
|
|
44
44
|
@headers_sent = false
|
|
45
45
|
@headers_trailing = {}
|
|
46
|
-
|
|
47
46
|
@mode = args[:mode]
|
|
47
|
+
@cookies = []
|
|
48
48
|
|
|
49
49
|
@headers = {
|
|
50
50
|
"date" => ["Date", Time.now.httpdate]
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
@headers_11 = {
|
|
54
|
-
"Connection" => "Keep-Alive"
|
|
55
|
-
}
|
|
56
53
|
if args[:mode] != :cgi and (!args.key?(:chunked) or args[:chunked])
|
|
57
|
-
@
|
|
54
|
+
@chunked = true
|
|
58
55
|
end
|
|
59
|
-
|
|
60
|
-
#Socket-timeout is currently broken in JRuby.
|
|
61
|
-
if RUBY_ENGINE != "jruby"
|
|
62
|
-
@headers_11["Keep-Alive"] = "timeout=15, max=30"
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
@cookies = []
|
|
66
56
|
end
|
|
67
57
|
|
|
68
58
|
def header(key, val)
|
|
@@ -70,19 +60,48 @@ class Hayabusa::Http_session::Response
|
|
|
70
60
|
raise "Value contains more lines than 1 (#{lines})." if lines > 1
|
|
71
61
|
|
|
72
62
|
if !@headers_sent
|
|
73
|
-
@headers[key.to_s.downcase] = [key, val]
|
|
63
|
+
@headers[key.to_s.downcase.strip] = [key, val]
|
|
74
64
|
else
|
|
75
65
|
raise "Headers already sent and given header was not in trailing headers: '#{key}'." if @trailers.index(key) == nil
|
|
76
|
-
@headers_trailing[key.to_s.downcase] = [key, val]
|
|
66
|
+
@headers_trailing[key.to_s.downcase.strip] = [key, val]
|
|
77
67
|
end
|
|
78
68
|
end
|
|
79
69
|
|
|
70
|
+
# Returns the value of a header.
|
|
71
|
+
def get_header_value(header)
|
|
72
|
+
header_p = header.to_s.downcase.strip
|
|
73
|
+
|
|
74
|
+
gothrough = [@headers, @headers_trailing]
|
|
75
|
+
gothrough.each do |headers|
|
|
76
|
+
headers.each do |key, val|
|
|
77
|
+
return val[1] if header_p == key
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
return nil
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Returns true if the given header-name is sat.
|
|
85
|
+
def has_header?(header)
|
|
86
|
+
header_p = header.to_s.downcase.strip
|
|
87
|
+
return @headers.key?(header_p) || @headers_trailing.key?(header_p)
|
|
88
|
+
end
|
|
89
|
+
|
|
80
90
|
def cookie(cookie)
|
|
81
91
|
@cookies << cookie
|
|
82
92
|
@session_cookie[cookie["name"]] = cookie["value"]
|
|
83
93
|
end
|
|
84
94
|
|
|
85
95
|
def header_str
|
|
96
|
+
if @http_version == "1.1" && @chunked
|
|
97
|
+
self.header("Connection", "Keep-Alive")
|
|
98
|
+
self.header("Transfer-Encoding", "chunked")
|
|
99
|
+
elsif @http_version == "1.1" && get_header_value("content-length").to_i > 0
|
|
100
|
+
self.header("Connection", "Keep-Alive")
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
self.header("Keep-Alive", "timeout=15, max=30") if self.get_header_value("connection") == "Keep-Alive"
|
|
104
|
+
|
|
86
105
|
if @skip_statuscode
|
|
87
106
|
res = ""
|
|
88
107
|
else
|
|
@@ -102,10 +121,6 @@ class Hayabusa::Http_session::Response
|
|
|
102
121
|
end
|
|
103
122
|
|
|
104
123
|
if @http_version == "1.1"
|
|
105
|
-
@headers_11.each do |key, val|
|
|
106
|
-
res << "#{key}: #{val}#{NL}"
|
|
107
|
-
end
|
|
108
|
-
|
|
109
124
|
@trailers.each do |trailer|
|
|
110
125
|
res << "Trailer: #{trailer}#{NL}"
|
|
111
126
|
end
|
|
@@ -121,8 +136,17 @@ class Hayabusa::Http_session::Response
|
|
|
121
136
|
end
|
|
122
137
|
|
|
123
138
|
def write
|
|
124
|
-
|
|
139
|
+
# Write headers to socket.
|
|
125
140
|
@socket.write(self.header_str)
|
|
141
|
+
@headers_sent = true
|
|
142
|
+
@cgroup.chunked = @chunked
|
|
143
|
+
|
|
144
|
+
# Set the content-length on the content-group to enable write-lenght-validation.
|
|
145
|
+
if self.has_header?("content-length")
|
|
146
|
+
@cgroup.content_length = self.get_header_value("content-length").to_i
|
|
147
|
+
else
|
|
148
|
+
@cgroup.content_length = nil
|
|
149
|
+
end
|
|
126
150
|
|
|
127
151
|
if @status == 304
|
|
128
152
|
#do nothing.
|
|
@@ -138,12 +162,19 @@ class Hayabusa::Http_session::Response
|
|
|
138
162
|
@socket.write(NL)
|
|
139
163
|
else
|
|
140
164
|
@cgroup.write_to_socket
|
|
141
|
-
@socket.write("#{NL}#{NL}") if @mode != :cgi
|
|
142
165
|
end
|
|
143
166
|
end
|
|
144
167
|
|
|
168
|
+
# Validate that no more has been written than given in content-length, since that will corrupt the client.
|
|
169
|
+
if self.has_header?("content-length")
|
|
170
|
+
length = cgroup.length_written
|
|
171
|
+
content_length = self.get_header_value("content-length").to_i
|
|
172
|
+
raise "More written than given in content-length: #{length}, #{content_length}" if length != content_length
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
# Close socket if that should be done.
|
|
145
176
|
if @close and @mode != :cgi
|
|
146
|
-
@hb.log_puts("Closing socket.")
|
|
177
|
+
@hb.log_puts("Hauabusa: Closing socket.")
|
|
147
178
|
@socket.close
|
|
148
179
|
end
|
|
149
180
|
end
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
<%
|
|
2
2
|
if _get["choice"] == "dogarbagecollect"
|
|
3
|
+
_hb.clean
|
|
3
4
|
GC.start
|
|
4
|
-
|
|
5
|
+
|
|
6
|
+
#Clean all Knj::Objects used in the application.
|
|
7
|
+
ObjectSpace.each_object(Knj::Objects) do |objects|
|
|
8
|
+
objects.clean_all
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
Knj::Web.redirect("?show=debug_memory_usage")
|
|
5
12
|
end
|
|
6
13
|
%>
|
|
7
14
|
|
|
@@ -11,6 +18,22 @@
|
|
|
11
18
|
<input type="button" value="Garbage collect" onclick="location.href='?show=debug_memory_usage&choice=dogarbagecollect';" />
|
|
12
19
|
</div>
|
|
13
20
|
|
|
21
|
+
<h1>Hayabusa sessions</h1>
|
|
22
|
+
<table style="width: 600px;">
|
|
23
|
+
<tbody>
|
|
24
|
+
<tr>
|
|
25
|
+
<td>Active sessions</td>
|
|
26
|
+
<td><%=_hb.num(_hb.sessions.length, 0)%></td>
|
|
27
|
+
</tr>
|
|
28
|
+
<tr>
|
|
29
|
+
<td>Total sessions</td>
|
|
30
|
+
<td><%=_hb.num(_hb.ob.list(:Session, "count" => true), 0)%>
|
|
31
|
+
</tr>
|
|
32
|
+
</tbody>
|
|
33
|
+
</table>
|
|
34
|
+
|
|
35
|
+
<br />
|
|
36
|
+
|
|
14
37
|
<%
|
|
15
38
|
Knj::Memory_analyzer.new.write
|
|
16
39
|
%>
|
data/pages/testpic.jpeg
ADDED
|
Binary file
|
data/spec/hayabusa_spec.rb
CHANGED
|
@@ -63,21 +63,56 @@ describe "Hayabusa" do
|
|
|
63
63
|
|
|
64
64
|
raise "Expected thread-pool-priority to be '-3' but it wasnt: '#{$appserver.threadpool.args[:priority]}'." if $appserver.threadpool.args[:priority] != -3
|
|
65
65
|
|
|
66
|
-
http = Http2.new(:host => "localhost", :port => 80, :encoding_gzip => false, :debug => false)
|
|
66
|
+
http = Http2.new(:host => "localhost", :port => 80, :encoding_gzip => false, :debug => false) rescue nil
|
|
67
67
|
|
|
68
68
|
$testmodes = [{
|
|
69
69
|
:name => :standalone,
|
|
70
70
|
:path_pre => "",
|
|
71
|
-
:http => Http2.new(:host => "localhost", :port => 1515)
|
|
72
|
-
},{
|
|
73
|
-
:name => :cgi,
|
|
74
|
-
:path_pre => "hayabusa_cgi_test/",
|
|
75
|
-
:http => http
|
|
76
|
-
},{
|
|
77
|
-
:name => :fcgi,
|
|
78
|
-
:path_pre => "hayabusa_fcgi_test/",
|
|
79
|
-
:http => http
|
|
71
|
+
:http => Http2.new(:host => "localhost", :port => 1515, :debug => false)
|
|
80
72
|
}]
|
|
73
|
+
|
|
74
|
+
if http
|
|
75
|
+
$testmodes += [{
|
|
76
|
+
:name => :cgi,
|
|
77
|
+
:path_pre => "hayabusa_cgi_test/",
|
|
78
|
+
:http => http
|
|
79
|
+
},{
|
|
80
|
+
:name => :fcgi,
|
|
81
|
+
:path_pre => "hayabusa_fcgi_test/",
|
|
82
|
+
:http => http
|
|
83
|
+
}]
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it "should be able to get multiple pictures" do
|
|
88
|
+
require "base64"
|
|
89
|
+
require "RMagick"
|
|
90
|
+
|
|
91
|
+
# Symlink 'image.rhtml' first.
|
|
92
|
+
img_from_path = "#{Knj.knjrbfw_path}/webscripts/image.rhtml"
|
|
93
|
+
img_to_path = "#{File.realpath("#{File.dirname(__FILE__)}/../pages")}/image.rhtml"
|
|
94
|
+
|
|
95
|
+
raise "Invalid from path: '#{img_from_path}'." unless File.exists?(img_from_path)
|
|
96
|
+
|
|
97
|
+
File.unlink(img_to_path) if File.symlink?(img_to_path)
|
|
98
|
+
File.symlink(img_from_path, img_to_path)
|
|
99
|
+
|
|
100
|
+
begin
|
|
101
|
+
$testmodes.each do |tdata|
|
|
102
|
+
5.times do
|
|
103
|
+
path = "#{File.dirname(__FILE__)}/../pages/testpic.jpeg"
|
|
104
|
+
|
|
105
|
+
res = tdata[:http].get("#{tdata[:path_pre]}testpic.jpeg")
|
|
106
|
+
res.body.bytesize.should eql(File.size(path))
|
|
107
|
+
|
|
108
|
+
res.body.bytes.to_a.should eql(File.read(path).bytes.to_a)
|
|
109
|
+
|
|
110
|
+
res = tdata[:http].get("#{tdata[:path_pre]}image.rhtml?force=true&path64=#{Base64.encode64("testpic.jpeg").to_s.strip}")
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
ensure
|
|
114
|
+
File.unlink(img_to_path) if File.exists?(img_to_path)
|
|
115
|
+
end
|
|
81
116
|
end
|
|
82
117
|
|
|
83
118
|
#it "should be able to handle custom urls" do
|
|
@@ -128,8 +163,6 @@ describe "Hayabusa" do
|
|
|
128
163
|
end
|
|
129
164
|
end
|
|
130
165
|
|
|
131
|
-
if false
|
|
132
|
-
|
|
133
166
|
it "should be able to handle a GET-request." do
|
|
134
167
|
$testmodes.each do |tdata|
|
|
135
168
|
res = tdata[:http].get("#{tdata[:path_pre]}spec.rhtml")
|
|
@@ -356,8 +389,6 @@ describe "Hayabusa" do
|
|
|
356
389
|
end
|
|
357
390
|
end
|
|
358
391
|
|
|
359
|
-
end
|
|
360
|
-
|
|
361
392
|
it "should be able to stop." do
|
|
362
393
|
$appserver.stop
|
|
363
394
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hayabusa
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.22
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -9,12 +9,11 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
13
|
-
default_executable:
|
|
12
|
+
date: 2013-06-28 00:00:00.000000000 Z
|
|
14
13
|
dependencies:
|
|
15
14
|
- !ruby/object:Gem::Dependency
|
|
16
15
|
name: knjrbfw
|
|
17
|
-
requirement:
|
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
|
18
17
|
none: false
|
|
19
18
|
requirements:
|
|
20
19
|
- - ! '>='
|
|
@@ -22,10 +21,15 @@ dependencies:
|
|
|
22
21
|
version: '0'
|
|
23
22
|
type: :runtime
|
|
24
23
|
prerelease: false
|
|
25
|
-
version_requirements:
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
26
|
+
requirements:
|
|
27
|
+
- - ! '>='
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: '0'
|
|
26
30
|
- !ruby/object:Gem::Dependency
|
|
27
31
|
name: erubis
|
|
28
|
-
requirement:
|
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
33
|
none: false
|
|
30
34
|
requirements:
|
|
31
35
|
- - ! '>='
|
|
@@ -33,10 +37,15 @@ dependencies:
|
|
|
33
37
|
version: '0'
|
|
34
38
|
type: :runtime
|
|
35
39
|
prerelease: false
|
|
36
|
-
version_requirements:
|
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
41
|
+
none: false
|
|
42
|
+
requirements:
|
|
43
|
+
- - ! '>='
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '0'
|
|
37
46
|
- !ruby/object:Gem::Dependency
|
|
38
47
|
name: mail
|
|
39
|
-
requirement:
|
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
|
40
49
|
none: false
|
|
41
50
|
requirements:
|
|
42
51
|
- - ! '>='
|
|
@@ -44,10 +53,15 @@ dependencies:
|
|
|
44
53
|
version: '0'
|
|
45
54
|
type: :runtime
|
|
46
55
|
prerelease: false
|
|
47
|
-
version_requirements:
|
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
+
none: false
|
|
58
|
+
requirements:
|
|
59
|
+
- - ! '>='
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
48
62
|
- !ruby/object:Gem::Dependency
|
|
49
63
|
name: datet
|
|
50
|
-
requirement:
|
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
|
51
65
|
none: false
|
|
52
66
|
requirements:
|
|
53
67
|
- - ! '>='
|
|
@@ -55,10 +69,15 @@ dependencies:
|
|
|
55
69
|
version: '0'
|
|
56
70
|
type: :runtime
|
|
57
71
|
prerelease: false
|
|
58
|
-
version_requirements:
|
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
73
|
+
none: false
|
|
74
|
+
requirements:
|
|
75
|
+
- - ! '>='
|
|
76
|
+
- !ruby/object:Gem::Version
|
|
77
|
+
version: '0'
|
|
59
78
|
- !ruby/object:Gem::Dependency
|
|
60
79
|
name: http2
|
|
61
|
-
requirement:
|
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
|
62
81
|
none: false
|
|
63
82
|
requirements:
|
|
64
83
|
- - ! '>='
|
|
@@ -66,10 +85,15 @@ dependencies:
|
|
|
66
85
|
version: '0'
|
|
67
86
|
type: :runtime
|
|
68
87
|
prerelease: false
|
|
69
|
-
version_requirements:
|
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
89
|
+
none: false
|
|
90
|
+
requirements:
|
|
91
|
+
- - ! '>='
|
|
92
|
+
- !ruby/object:Gem::Version
|
|
93
|
+
version: '0'
|
|
70
94
|
- !ruby/object:Gem::Dependency
|
|
71
95
|
name: tpool
|
|
72
|
-
requirement:
|
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
|
73
97
|
none: false
|
|
74
98
|
requirements:
|
|
75
99
|
- - ! '>='
|
|
@@ -77,10 +101,31 @@ dependencies:
|
|
|
77
101
|
version: '0'
|
|
78
102
|
type: :runtime
|
|
79
103
|
prerelease: false
|
|
80
|
-
version_requirements:
|
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
105
|
+
none: false
|
|
106
|
+
requirements:
|
|
107
|
+
- - ! '>='
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '0'
|
|
81
110
|
- !ruby/object:Gem::Dependency
|
|
82
111
|
name: fcgi
|
|
83
|
-
requirement:
|
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
|
113
|
+
none: false
|
|
114
|
+
requirements:
|
|
115
|
+
- - ! '>='
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: '0'
|
|
118
|
+
type: :runtime
|
|
119
|
+
prerelease: false
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
none: false
|
|
122
|
+
requirements:
|
|
123
|
+
- - ! '>='
|
|
124
|
+
- !ruby/object:Gem::Version
|
|
125
|
+
version: '0'
|
|
126
|
+
- !ruby/object:Gem::Dependency
|
|
127
|
+
name: ruby_process
|
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
|
84
129
|
none: false
|
|
85
130
|
requirements:
|
|
86
131
|
- - ! '>='
|
|
@@ -88,10 +133,15 @@ dependencies:
|
|
|
88
133
|
version: '0'
|
|
89
134
|
type: :runtime
|
|
90
135
|
prerelease: false
|
|
91
|
-
version_requirements:
|
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
137
|
+
none: false
|
|
138
|
+
requirements:
|
|
139
|
+
- - ! '>='
|
|
140
|
+
- !ruby/object:Gem::Version
|
|
141
|
+
version: '0'
|
|
92
142
|
- !ruby/object:Gem::Dependency
|
|
93
143
|
name: json
|
|
94
|
-
requirement:
|
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
|
95
145
|
none: false
|
|
96
146
|
requirements:
|
|
97
147
|
- - ! '>='
|
|
@@ -99,10 +149,15 @@ dependencies:
|
|
|
99
149
|
version: '0'
|
|
100
150
|
type: :development
|
|
101
151
|
prerelease: false
|
|
102
|
-
version_requirements:
|
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
153
|
+
none: false
|
|
154
|
+
requirements:
|
|
155
|
+
- - ! '>='
|
|
156
|
+
- !ruby/object:Gem::Version
|
|
157
|
+
version: '0'
|
|
103
158
|
- !ruby/object:Gem::Dependency
|
|
104
159
|
name: rspec
|
|
105
|
-
requirement:
|
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
|
106
161
|
none: false
|
|
107
162
|
requirements:
|
|
108
163
|
- - ! '>='
|
|
@@ -110,10 +165,15 @@ dependencies:
|
|
|
110
165
|
version: 2.3.0
|
|
111
166
|
type: :development
|
|
112
167
|
prerelease: false
|
|
113
|
-
version_requirements:
|
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
169
|
+
none: false
|
|
170
|
+
requirements:
|
|
171
|
+
- - ! '>='
|
|
172
|
+
- !ruby/object:Gem::Version
|
|
173
|
+
version: 2.3.0
|
|
114
174
|
- !ruby/object:Gem::Dependency
|
|
115
175
|
name: bundler
|
|
116
|
-
requirement:
|
|
176
|
+
requirement: !ruby/object:Gem::Requirement
|
|
117
177
|
none: false
|
|
118
178
|
requirements:
|
|
119
179
|
- - ! '>='
|
|
@@ -121,10 +181,15 @@ dependencies:
|
|
|
121
181
|
version: 1.0.0
|
|
122
182
|
type: :development
|
|
123
183
|
prerelease: false
|
|
124
|
-
version_requirements:
|
|
184
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
185
|
+
none: false
|
|
186
|
+
requirements:
|
|
187
|
+
- - ! '>='
|
|
188
|
+
- !ruby/object:Gem::Version
|
|
189
|
+
version: 1.0.0
|
|
125
190
|
- !ruby/object:Gem::Dependency
|
|
126
191
|
name: jeweler
|
|
127
|
-
requirement:
|
|
192
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
193
|
none: false
|
|
129
194
|
requirements:
|
|
130
195
|
- - ~>
|
|
@@ -132,10 +197,31 @@ dependencies:
|
|
|
132
197
|
version: 1.6.3
|
|
133
198
|
type: :development
|
|
134
199
|
prerelease: false
|
|
135
|
-
version_requirements:
|
|
200
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
201
|
+
none: false
|
|
202
|
+
requirements:
|
|
203
|
+
- - ~>
|
|
204
|
+
- !ruby/object:Gem::Version
|
|
205
|
+
version: 1.6.3
|
|
206
|
+
- !ruby/object:Gem::Dependency
|
|
207
|
+
name: rmagick
|
|
208
|
+
requirement: !ruby/object:Gem::Requirement
|
|
209
|
+
none: false
|
|
210
|
+
requirements:
|
|
211
|
+
- - ! '>='
|
|
212
|
+
- !ruby/object:Gem::Version
|
|
213
|
+
version: '0'
|
|
214
|
+
type: :development
|
|
215
|
+
prerelease: false
|
|
216
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
217
|
+
none: false
|
|
218
|
+
requirements:
|
|
219
|
+
- - ! '>='
|
|
220
|
+
- !ruby/object:Gem::Version
|
|
221
|
+
version: '0'
|
|
136
222
|
- !ruby/object:Gem::Dependency
|
|
137
223
|
name: sqlite3
|
|
138
|
-
requirement:
|
|
224
|
+
requirement: !ruby/object:Gem::Requirement
|
|
139
225
|
none: false
|
|
140
226
|
requirements:
|
|
141
227
|
- - ! '>='
|
|
@@ -143,7 +229,12 @@ dependencies:
|
|
|
143
229
|
version: '0'
|
|
144
230
|
type: :development
|
|
145
231
|
prerelease: false
|
|
146
|
-
version_requirements:
|
|
232
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
233
|
+
none: false
|
|
234
|
+
requirements:
|
|
235
|
+
- - ! '>='
|
|
236
|
+
- !ruby/object:Gem::Version
|
|
237
|
+
version: '0'
|
|
147
238
|
description: A threadded web/app-server that focuses on threadding, shared ressources,
|
|
148
239
|
speed and more.
|
|
149
240
|
email: k@spernj.org
|
|
@@ -239,13 +330,13 @@ files:
|
|
|
239
330
|
- pages/spec_vars_header.rhtml
|
|
240
331
|
- pages/spec_vars_post.rhtml
|
|
241
332
|
- pages/spec_vars_post_fileupload.rhtml
|
|
333
|
+
- pages/testpic.jpeg
|
|
242
334
|
- pages/tests.rhtml
|
|
243
335
|
- pages/threadded_content_test.rhtml
|
|
244
336
|
- spec/fcgi_multiple_processes_spec.rb
|
|
245
337
|
- spec/hayabusa_spec.rb
|
|
246
338
|
- spec/spec_helper.rb
|
|
247
339
|
- spec/test_upload.xlsx
|
|
248
|
-
has_rdoc: true
|
|
249
340
|
homepage: http://github.com/kaspernj/hayabusa
|
|
250
341
|
licenses:
|
|
251
342
|
- MIT
|
|
@@ -261,7 +352,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
261
352
|
version: '0'
|
|
262
353
|
segments:
|
|
263
354
|
- 0
|
|
264
|
-
hash:
|
|
355
|
+
hash: 4203364333015306411
|
|
265
356
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
266
357
|
none: false
|
|
267
358
|
requirements:
|
|
@@ -270,7 +361,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
270
361
|
version: '0'
|
|
271
362
|
requirements: []
|
|
272
363
|
rubyforge_project:
|
|
273
|
-
rubygems_version: 1.
|
|
364
|
+
rubygems_version: 1.8.23
|
|
274
365
|
signing_key:
|
|
275
366
|
specification_version: 3
|
|
276
367
|
summary: A threadded web/app-server that supports stand-alone, CGI and FCGI-modes.
|