hayabusa 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +2 -2
- data/VERSION +1 -1
- data/bin/hayabusa_fcgi.fcgi +12 -6
- data/bin/hayabusa_fcgi.rb +12 -6
- data/hayabusa.gemspec +3 -2
- data/lib/hayabusa_cgi_session.rb +7 -2
- data/lib/hayabusa_ext/sessions.rb +2 -4
- data/lib/hayabusa_fcgi.rb +13 -3
- data/lib/hayabusa_http_session.rb +2 -1
- data/lib/hayabusa_http_session_response.rb +2 -0
- data/spec/fcgi_multiple_processes_spec.rb +74 -2
- data/tests/fcgi_test/multiple_threads.rhtml +18 -0
- metadata +4 -3
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
-
datet (0.0.
|
4
|
+
datet (0.0.17)
|
5
5
|
diff-lcs (1.1.3)
|
6
6
|
erubis (2.7.0)
|
7
7
|
git (1.2.5)
|
@@ -12,7 +12,7 @@ GEM
|
|
12
12
|
git (>= 1.2.5)
|
13
13
|
rake
|
14
14
|
json (1.7.5)
|
15
|
-
knjrbfw (0.0.
|
15
|
+
knjrbfw (0.0.90)
|
16
16
|
datet
|
17
17
|
http2
|
18
18
|
php4r
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.6
|
data/bin/hayabusa_fcgi.fcgi
CHANGED
@@ -3,9 +3,6 @@
|
|
3
3
|
#This scripts start an appserver, executes a CGI-request for every FCGI-request and terminates when FCGI terminates.
|
4
4
|
#Good for programming appserver-supported projects that doesnt need threadding without running an appserver all the time.
|
5
5
|
|
6
|
-
debug = false
|
7
|
-
|
8
|
-
$stderr.puts "[hayabusa] Starting up!" if debug
|
9
6
|
error_log_file = "/tmp/hayabusa_fcgi.log"
|
10
7
|
|
11
8
|
begin
|
@@ -15,17 +12,25 @@ rescue Errno::ENOENT
|
|
15
12
|
end
|
16
13
|
|
17
14
|
begin
|
18
|
-
$stderr.puts "[hayabusa] Loading libs." if debug
|
19
15
|
require "rubygems"
|
20
|
-
require "knjrbfw"
|
21
16
|
require "fcgi"
|
22
17
|
require "fileutils"
|
23
|
-
require "#{File.dirname(Knj::Os.realpath(__FILE__))}/../lib/hayabusa.rb"
|
24
18
|
|
19
|
+
#Try to load development-version to enable debugging without doing constant gem-installations.
|
20
|
+
path = "/home/kaspernj/Ruby/knjrbfw/lib/knjrbfw.rb"
|
21
|
+
if File.exists?(path)
|
22
|
+
require path
|
23
|
+
else
|
24
|
+
require "knjrbfw"
|
25
|
+
end
|
26
|
+
|
27
|
+
#Load 'Hayabusa' and start the FCGI-loop to begin handeling requests.
|
28
|
+
require "#{File.dirname(Knj::Os.realpath(__FILE__))}/../lib/hayabusa.rb"
|
25
29
|
fcgi = Hayabusa::Fcgi.new
|
26
30
|
fcgi.fcgi_loop
|
27
31
|
rescue Exception => e
|
28
32
|
if !e.is_a?(Interrupt)
|
33
|
+
#Log error to the log-file if something happened.
|
29
34
|
File.open(error_log_file, "w") do |fp|
|
30
35
|
fp.puts e.inspect
|
31
36
|
fp.puts e.backtrace
|
@@ -33,5 +38,6 @@ rescue Exception => e
|
|
33
38
|
end
|
34
39
|
end
|
35
40
|
|
41
|
+
#Just raise it normally as if a normal error occurred.
|
36
42
|
raise e
|
37
43
|
end
|
data/bin/hayabusa_fcgi.rb
CHANGED
@@ -3,9 +3,6 @@
|
|
3
3
|
#This scripts start an appserver, executes a CGI-request for every FCGI-request and terminates when FCGI terminates.
|
4
4
|
#Good for programming appserver-supported projects that doesnt need threadding without running an appserver all the time.
|
5
5
|
|
6
|
-
debug = false
|
7
|
-
|
8
|
-
$stderr.puts "[hayabusa] Starting up!" if debug
|
9
6
|
error_log_file = "/tmp/hayabusa_fcgi.log"
|
10
7
|
|
11
8
|
begin
|
@@ -15,17 +12,25 @@ rescue Errno::ENOENT
|
|
15
12
|
end
|
16
13
|
|
17
14
|
begin
|
18
|
-
$stderr.puts "[hayabusa] Loading libs." if debug
|
19
15
|
require "rubygems"
|
20
|
-
require "knjrbfw"
|
21
16
|
require "fcgi"
|
22
17
|
require "fileutils"
|
23
|
-
require "#{File.dirname(Knj::Os.realpath(__FILE__))}/../lib/hayabusa.rb"
|
24
18
|
|
19
|
+
#Try to load development-version to enable debugging without doing constant gem-installations.
|
20
|
+
path = "/home/kaspernj/Ruby/knjrbfw/lib/knjrbfw.rb"
|
21
|
+
if File.exists?(path)
|
22
|
+
require path
|
23
|
+
else
|
24
|
+
require "knjrbfw"
|
25
|
+
end
|
26
|
+
|
27
|
+
#Load 'Hayabusa' and start the FCGI-loop to begin handeling requests.
|
28
|
+
require "#{File.dirname(Knj::Os.realpath(__FILE__))}/../lib/hayabusa.rb"
|
25
29
|
fcgi = Hayabusa::Fcgi.new
|
26
30
|
fcgi.fcgi_loop
|
27
31
|
rescue Exception => e
|
28
32
|
if !e.is_a?(Interrupt)
|
33
|
+
#Log error to the log-file if something happened.
|
29
34
|
File.open(error_log_file, "w") do |fp|
|
30
35
|
fp.puts e.inspect
|
31
36
|
fp.puts e.backtrace
|
@@ -33,5 +38,6 @@ rescue Exception => e
|
|
33
38
|
end
|
34
39
|
end
|
35
40
|
|
41
|
+
#Just raise it normally as if a normal error occurred.
|
36
42
|
raise e
|
37
43
|
end
|
data/hayabusa.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{hayabusa}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.6"
|
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 = %q{2012-08-
|
12
|
+
s.date = %q{2012-08-24}
|
13
13
|
s.description = %q{A threadded web/app-server that focuses on threadding, shared ressources, speed and more.}
|
14
14
|
s.email = %q{k@spernj.org}
|
15
15
|
s.executables = ["check_running.rb", "hayabusa_benchmark.rb", "hayabusa_cgi.rb", "hayabusa_fcgi.fcgi", "hayabusa_fcgi.rb", "knjappserver_start.rb"]
|
@@ -99,6 +99,7 @@ Gem::Specification.new do |s|
|
|
99
99
|
"tests/cgi_test/vars_post_test.rhtml",
|
100
100
|
"tests/fcgi_test/config_fcgi.rb",
|
101
101
|
"tests/fcgi_test/index.rhtml",
|
102
|
+
"tests/fcgi_test/multiple_threads.rhtml",
|
102
103
|
"tests/fcgi_test/sleeper.rhtml",
|
103
104
|
"tests/fcgi_test/threadded_content_test.rhtml",
|
104
105
|
"tests/fcgi_test/vars_get_test.rhtml",
|
data/lib/hayabusa_cgi_session.rb
CHANGED
@@ -57,7 +57,7 @@ class Hayabusa::Cgi_session
|
|
57
57
|
@ext = File.extname(@page_path).downcase[1..-1].to_s
|
58
58
|
|
59
59
|
@resp = Hayabusa::Http_session::Response.new(:socket => self)
|
60
|
-
@resp.reset(:http_version => http_version, :mode => :cgi)
|
60
|
+
@resp.reset(:http_version => http_version, :mode => :cgi, :cookie => @cookie)
|
61
61
|
|
62
62
|
@cgroup = Hayabusa::Http_session::Contentgroup.new(:socket => self, :hb => @hb, :resp => @resp, :httpsession => self)
|
63
63
|
@cgroup.reset
|
@@ -67,7 +67,7 @@ class Hayabusa::Cgi_session
|
|
67
67
|
|
68
68
|
|
69
69
|
#Set up session-variables.
|
70
|
-
if
|
70
|
+
if !@cookie["HayabusaSession"].to_s.empty?
|
71
71
|
@session_id = @cookie["HayabusaSession"]
|
72
72
|
elsif @browser["browser"] == "bot"
|
73
73
|
@session_id = "bot"
|
@@ -76,6 +76,11 @@ class Hayabusa::Cgi_session
|
|
76
76
|
send_cookie = true
|
77
77
|
end
|
78
78
|
|
79
|
+
#Set the 'ip'-variable which is required for sessions.
|
80
|
+
@ip = @meta["REMOTE_ADDR"]
|
81
|
+
raise "No 'ip'-variable was set: '#{@meta}'." if !@ip
|
82
|
+
raise "'session_id' was not valid." if @session_id.to_s.strip.empty?
|
83
|
+
|
79
84
|
begin
|
80
85
|
@session, @session_hash = @hb.session_fromid(@ip, @session_id, @meta)
|
81
86
|
rescue ArgumentError => e
|
@@ -8,7 +8,7 @@ class Hayabusa
|
|
8
8
|
ip = "bot" if idhash == "bot"
|
9
9
|
|
10
10
|
if !@sessions.key?(idhash)
|
11
|
-
session = @ob.get_by(:Session,
|
11
|
+
session = @ob.get_by(:Session, "idhash" => idhash)
|
12
12
|
if !session
|
13
13
|
session = @ob.add(:Session, {
|
14
14
|
:idhash => idhash,
|
@@ -27,9 +27,7 @@ class Hayabusa
|
|
27
27
|
hash = @sessions[idhash][:hash]
|
28
28
|
end
|
29
29
|
|
30
|
-
if ip != "bot" and !session.remember? and ip.to_s != session[:ip].to_s
|
31
|
-
raise ArgumentError, "Invalid IP."
|
32
|
-
end
|
30
|
+
raise ArgumentError, "Invalid IP." if ip != "bot" and !session.remember? and ip.to_s != session[:ip].to_s
|
33
31
|
|
34
32
|
@sessions[idhash][:time_lastused] = Time.now
|
35
33
|
return [session, hash]
|
data/lib/hayabusa_fcgi.rb
CHANGED
@@ -53,8 +53,14 @@ class Hayabusa::Fcgi
|
|
53
53
|
#Set this instance to run in proxy-mode.
|
54
54
|
begin
|
55
55
|
@fcgi_proxy = fcgi_config
|
56
|
-
|
57
|
-
|
56
|
+
Knj.gem_require(:Http2, "http2")
|
57
|
+
|
58
|
+
begin
|
59
|
+
@fcgi_proxy[:http] = Http2.new(:host => "localhost", :port => @fcgi_proxy[:port].to_i)
|
60
|
+
rescue Errno::ECONNREFUSED
|
61
|
+
#The host-process has properly closed - evaluate mode again.
|
62
|
+
raise Errno::EAGAIN
|
63
|
+
end
|
58
64
|
|
59
65
|
if hayabusa_conf[:debug]
|
60
66
|
@fcgi_proxy[:fp_log] = File.open("/tmp/hayabusa_#{hayabusa_conf[:hayabusa][:title]}_#{Process.pid}.log", "w")
|
@@ -98,7 +104,11 @@ class Hayabusa::Fcgi
|
|
98
104
|
@cgi = cgi
|
99
105
|
|
100
106
|
#Evaluate the mode of this instance.
|
101
|
-
|
107
|
+
begin
|
108
|
+
self.evaluate_mode
|
109
|
+
rescue Errno::EAGAIN
|
110
|
+
retry
|
111
|
+
end
|
102
112
|
|
103
113
|
#Ensure the same FCGI-process isnt active for more than one website.
|
104
114
|
raise "Expected 'HTTP_HAYABUSA_FCGI_CONFIG' to be '#{@hayabusa_fcgi_conf_path}' but it wasnt: '#{cgi.env_table["HTTP_HAYABUSA_FCGI_CONFIG"]}'." if @hayabusa_fcgi_conf_path and @hayabusa_fcgi_conf_path != cgi.env_table["HTTP_HAYABUSA_FCGI_CONFIG"]
|
@@ -218,7 +218,8 @@ class Hayabusa::Http_session
|
|
218
218
|
close = true if @meta["HTTP_CONNECTION"] == "close"
|
219
219
|
@resp.reset(
|
220
220
|
:http_version => @handler.http_version,
|
221
|
-
:close => close
|
221
|
+
:close => close,
|
222
|
+
:cookie => @cookie
|
222
223
|
)
|
223
224
|
if @handler.http_version == "1.1"
|
224
225
|
@cgroup.chunked = true
|
@@ -38,6 +38,7 @@ class Hayabusa::Http_session::Response
|
|
38
38
|
@close = true if @http_version == "1.0"
|
39
39
|
@trailers = []
|
40
40
|
@skip_statuscode = true if args[:mode] == :cgi
|
41
|
+
@session_cookie = args[:cookie]
|
41
42
|
|
42
43
|
@headers_sent = false
|
43
44
|
@headers_trailing = {}
|
@@ -77,6 +78,7 @@ class Hayabusa::Http_session::Response
|
|
77
78
|
|
78
79
|
def cookie(cookie)
|
79
80
|
@cookies << cookie
|
81
|
+
@session_cookie[cookie["name"]] = cookie["value"]
|
80
82
|
end
|
81
83
|
|
82
84
|
def header_str
|
@@ -1,9 +1,81 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
|
3
3
|
describe "Hayabusa" do
|
4
|
+
it "should handle sessions correctly under stressed conditions" do
|
5
|
+
require "knjrbfw"
|
6
|
+
Knj.gem_require(:Http2, "http2")
|
7
|
+
require "json"
|
8
|
+
|
9
|
+
ts = []
|
10
|
+
errs = []
|
11
|
+
|
12
|
+
1.upto(10) do |t_i|
|
13
|
+
ts << Thread.new do
|
14
|
+
if t_i == 1
|
15
|
+
debug = true
|
16
|
+
else
|
17
|
+
debug = false
|
18
|
+
end
|
19
|
+
|
20
|
+
begin
|
21
|
+
session_id = nil
|
22
|
+
hayabusa_session_id = nil
|
23
|
+
session_hash_obj_id = nil
|
24
|
+
|
25
|
+
Http2.new(:host => "localhost", :user_agent => "Client#{t_i}", :debug => false) do |http|
|
26
|
+
1.upto(25) do |request_i|
|
27
|
+
res = http.get(:url => "hayabusa_fcgi_test/multiple_threads.rhtml")
|
28
|
+
|
29
|
+
begin
|
30
|
+
data_json = JSON.parse(res.body)
|
31
|
+
rescue => e
|
32
|
+
raise "Could not parse result as JSON: '#{res.body}'."
|
33
|
+
end
|
34
|
+
|
35
|
+
data = {}
|
36
|
+
data_json.each do |key, val|
|
37
|
+
data["#{key.to_s}"] = "#{val.to_s}"
|
38
|
+
end
|
39
|
+
|
40
|
+
if request_i == 1
|
41
|
+
hayabusa_session_id = data["cookie"]["HayabusaSession"]
|
42
|
+
session_hash_obj_id = data["session_hash_id"]
|
43
|
+
session_id = data["session_id"]
|
44
|
+
end
|
45
|
+
|
46
|
+
#puts "request-i: #{request_i}, data-request-count: #{data["request_count"]}, hash-id: #{data["session_hash_id"]}" if debug
|
47
|
+
|
48
|
+
#Check 'HayabusaSession'-cookie.
|
49
|
+
raise "No 'HayabusaSession'-cookie?" if !data["cookie"]["HayabusaSession"]
|
50
|
+
raise "Expected 'HayabusaSession'-cookie to be '#{hayabusa_session_id}' but it wasnt: '#{data["cookie"]["HayabusaSession"]}' (#{data["cookie"]})." if hayabusa_session_id != data["cookie"]["HayabusaSession"]
|
51
|
+
|
52
|
+
#Check session-hash-object-ID.
|
53
|
+
raise "No 'session_hash_id' from request: '#{data}'." if data["session_hash_id"].to_s.strip.empty?
|
54
|
+
raise "Expected session-hash-object-ID to be '#{session_hash_obj_id}' but it wasnt: '#{data["session_hash_id"]}'." if session_hash_obj_id != data["session_hash_id"] or !session_hash_obj_id
|
55
|
+
|
56
|
+
|
57
|
+
#Check session-object-ID.
|
58
|
+
raise "Expected session-ID to be '#{session_id}' but it wasnt: '#{data["session_id"]}' for request '#{request_i}'." if session_id != data["session_id"]
|
59
|
+
raise "Expected request-count for session to be the same as on the client: '#{request_i}' but it wasnt: '#{data["request_count"]}'." if data["request_count"].to_i != request_i
|
60
|
+
end
|
61
|
+
end
|
62
|
+
rescue => e
|
63
|
+
errs << e
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
ts.each do |t|
|
69
|
+
t.join
|
70
|
+
end
|
71
|
+
|
72
|
+
errs.each do |e|
|
73
|
+
raise e
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
4
77
|
it "two simultanious request should be handeled by the same process - one should proxy the request" do
|
5
|
-
|
6
|
-
require "http2"
|
78
|
+
Knj.gem_require(:Http2, "http2")
|
7
79
|
require "json"
|
8
80
|
|
9
81
|
Http2.new(:host => "localhost") do |http1|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<%
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
if !_session.key?(:request_count)
|
5
|
+
_session[:request_count] = 1
|
6
|
+
else
|
7
|
+
_session[:request_count] = _session[:request_count].to_i + 1
|
8
|
+
end
|
9
|
+
|
10
|
+
print JSON.generate(
|
11
|
+
:pid => Process.pid,
|
12
|
+
:session_id => _session_obj.id,
|
13
|
+
:session_hash_id => _session.__id__,
|
14
|
+
:request_count => _session[:request_count],
|
15
|
+
:cookie => _cookie,
|
16
|
+
:meta => _meta
|
17
|
+
)
|
18
|
+
%>
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: hayabusa
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Kasper Johansen
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2012-08-
|
13
|
+
date: 2012-08-24 00:00:00 +02:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -230,6 +230,7 @@ files:
|
|
230
230
|
- tests/cgi_test/vars_post_test.rhtml
|
231
231
|
- tests/fcgi_test/config_fcgi.rb
|
232
232
|
- tests/fcgi_test/index.rhtml
|
233
|
+
- tests/fcgi_test/multiple_threads.rhtml
|
233
234
|
- tests/fcgi_test/sleeper.rhtml
|
234
235
|
- tests/fcgi_test/threadded_content_test.rhtml
|
235
236
|
- tests/fcgi_test/vars_get_test.rhtml
|
@@ -249,7 +250,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
249
250
|
requirements:
|
250
251
|
- - ">="
|
251
252
|
- !ruby/object:Gem::Version
|
252
|
-
hash:
|
253
|
+
hash: 1153147131949596081
|
253
254
|
segments:
|
254
255
|
- 0
|
255
256
|
version: "0"
|