hayabusa 0.0.5 → 0.0.6
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.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"
|