hayabusa 0.0.20 → 0.0.22
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|