hayabusa 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- datet (0.0.15)
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.87)
15
+ knjrbfw (0.0.90)
16
16
  datet
17
17
  http2
18
18
  php4r
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.5
1
+ 0.0.6
@@ -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
@@ -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
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{hayabusa}
8
- s.version = "0.0.5"
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-22}
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",
@@ -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 @cookie["HayabusaSession"].to_s.length > 0
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, {"idhash" => idhash})
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]
@@ -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
- require "http2"
57
- @fcgi_proxy[:http] = Http2.new(:host => "localhost", :port => @fcgi_proxy[:port].to_i)
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
- self.evaluate_mode
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
- require "rubygems"
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
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-22 00:00:00 +02:00
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: -1836290877562781605
253
+ hash: 1153147131949596081
253
254
  segments:
254
255
  - 0
255
256
  version: "0"