hayabusa 0.0.9 → 0.0.10

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.
@@ -1,18 +1,18 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- datet (0.0.17)
4
+ datet (0.0.20)
5
5
  diff-lcs (1.1.3)
6
6
  erubis (2.7.0)
7
7
  git (1.2.5)
8
8
  http2 (0.0.10)
9
- i18n (0.6.0)
9
+ i18n (0.6.1)
10
10
  jeweler (1.6.4)
11
11
  bundler (~> 1.0)
12
12
  git (>= 1.2.5)
13
13
  rake
14
14
  json (1.7.5)
15
- knjrbfw (0.0.90)
15
+ knjrbfw (0.0.94)
16
16
  datet
17
17
  http2
18
18
  php4r
@@ -37,7 +37,7 @@ GEM
37
37
  diff-lcs (~> 1.1.2)
38
38
  rspec-mocks (2.3.0)
39
39
  sqlite3 (1.3.6)
40
- tpool (0.0.1)
40
+ tpool (0.0.3)
41
41
  treetop (1.4.10)
42
42
  polyglot
43
43
  polyglot (>= 0.3.1)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.9
1
+ 0.0.10
@@ -4,14 +4,14 @@
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
- s.name = %q{hayabusa}
8
- s.version = "0.0.9"
7
+ s.name = "hayabusa"
8
+ s.version = "0.0.10"
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-29}
13
- s.description = %q{A threadded web/app-server that focuses on threadding, shared ressources, speed and more.}
14
- s.email = %q{k@spernj.org}
12
+ s.date = "2012-09-11"
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", "knjappserver_start.rb"]
16
16
  s.extra_rdoc_files = [
17
17
  "LICENSE.txt",
@@ -106,11 +106,11 @@ Gem::Specification.new do |s|
106
106
  "tests/fcgi_test/vars_header_test.rhtml",
107
107
  "tests/fcgi_test/vars_post_test.rhtml"
108
108
  ]
109
- s.homepage = %q{http://github.com/kaspernj/hayabusa}
109
+ s.homepage = "http://github.com/kaspernj/hayabusa"
110
110
  s.licenses = ["MIT"]
111
111
  s.require_paths = ["lib"]
112
- s.rubygems_version = %q{1.6.2}
113
- s.summary = %q{A threadded web/app-server that supports stand-alone, CGI and FCGI-modes.}
112
+ s.rubygems_version = "1.8.24"
113
+ s.summary = "A threadded web/app-server that supports stand-alone, CGI and FCGI-modes."
114
114
 
115
115
  if s.respond_to? :specification_version then
116
116
  s.specification_version = 3
@@ -400,13 +400,7 @@ class Hayabusa
400
400
  require @config[:autoload]
401
401
  end
402
402
 
403
- begin
404
- self.log_puts "Appserver startet." if @debug
405
- rescue Interrupt => e
406
- self.log_puts "Got interrupt - trying to stop appserver." if @debug
407
- self.stop
408
- raise e
409
- end
403
+ self.log_puts "Appserver startet." if @debug
410
404
  end
411
405
 
412
406
  #Stops the entire app and releases join.
@@ -414,32 +408,21 @@ class Hayabusa
414
408
  return nil if @stop_called
415
409
  @stop_called = true
416
410
 
417
- proc_stop = proc{
418
- self.log_puts "Stopping appserver." if @debug
419
- @httpserv.stop if @httpserv and @httpserv.respond_to?(:stop)
420
-
421
- self.log_puts "Stopping threadpool." if @debug
422
- @threadpool.stop if @threadpool
423
-
424
- #This should be done first to be sure it finishes (else we have a serious bug).
425
- self.log_puts "Flush out loaded sessions." if @debug
426
-
427
- #Flush sessions and mails (only if the modules are loaded).
428
- self.sessions_flush if self.respond_to?(:sessions_flush)
429
- self.mail_flush if self.respond_to?(:mail_flush)
430
-
431
- self.log_puts "Stopping done..." if @debug
432
- }
411
+ self.log_puts "Stopping appserver." if @debug
412
+ @httpserv.stop if @httpserv and @httpserv.respond_to?(:stop)
433
413
 
434
- #If we cant get a paused-execution in 5 secs - we just force the stop.
435
- begin
436
- Timeout.timeout(7) do
437
- self.paused_exec(&proc_stop)
438
- end
439
- rescue Timeout::Error, SystemExit, Interrupt
440
- self.log_puts "Forcing stop-appserver - couldnt get timing window." if @debug
441
- proc_stop.call
442
- end
414
+ self.log_puts "Stopping threadpool." if @debug
415
+ @threadpool.stop if @threadpool
416
+
417
+ #This should be done first to be sure it finishes (else we have a serious bug).
418
+ self.log_puts "Flush out loaded sessions." if @debug
419
+
420
+ #Flush sessions and mails (only if the modules are loaded).
421
+ self.flush_error_emails(:ignore_time => true) if self.respond_to?(:flush_error_emails)
422
+ self.sessions_flush if self.respond_to?(:sessions_flush)
423
+ self.mail_flush if self.respond_to?(:mail_flush)
424
+
425
+ self.log_puts "Stopping done..." if @debug
443
426
  end
444
427
 
445
428
  #Stop running any more HTTP-requests - make them wait.
@@ -494,6 +477,7 @@ class Hayabusa
494
477
  @httpserv.thread_accept.join
495
478
  @httpserv.thread_restart.join if @httpserv and @httpserv.thread_restart
496
479
  rescue Interrupt => e
480
+ STDOUT.puts "Trying to stop because of interrupt - please wait while various data is beging flushed."
497
481
  self.stop
498
482
  end
499
483
 
@@ -1,6 +1,6 @@
1
1
  class Hayabusa::Cgi_session
2
2
  attr_accessor :data, :alert_sent
3
- attr_reader :cookie, :get, :headers, :session, :session_id, :session_hash, :hb, :active, :out, :eruby, :browser, :debug, :resp, :page_path, :post, :cgroup, :meta, :httpsession_var, :working
3
+ attr_reader :cookie, :get, :headers, :ip, :session, :session_id, :session_hash, :hb, :active, :out, :eruby, :browser, :debug, :resp, :page_path, :post, :cgroup, :meta, :httpsession_var, :working
4
4
 
5
5
  def initialize(args)
6
6
  @args = args
@@ -77,7 +77,7 @@ class Hayabusa::Cgi_session
77
77
  end
78
78
 
79
79
  #Set the 'ip'-variable which is required for sessions.
80
- @ip = @meta["REMOTE_ADDR"]
80
+ @ip = @hb.ip(:meta => @meta)
81
81
  raise "No 'ip'-variable was set: '#{@meta}'." if !@ip
82
82
  raise "'session_id' was not valid." if @session_id.to_s.strip.empty?
83
83
 
@@ -1,6 +1,7 @@
1
1
  class Hayabusa::Cgi_tools
2
2
  attr_accessor :cgi
3
3
 
4
+ #Converts CGI-like-post hashes to the normal Hayabusa-type hash.
4
5
  def convert_fcgi_post(params)
5
6
  post_hash = {}
6
7
 
@@ -10,7 +11,7 @@ class Hayabusa::Cgi_tools
10
11
 
11
12
  post_ret = {}
12
13
  post_hash.each do |varname, value|
13
- Knj::Web.parse_name(post_ret, varname, value, :urldecode => true)
14
+ Knj::Web.parse_name(post_ret, varname, value)
14
15
  end
15
16
 
16
17
  return post_ret
@@ -17,12 +17,12 @@ class Hayabusa
17
17
  end
18
18
 
19
19
  #Send error-emails based on error-emails-cache (cached so the same error isnt send out every time it occurrs to prevent spamming).
20
- def flush_error_emails
20
+ def flush_error_emails(args = {})
21
21
  @error_emails_pending_mutex.synchronize do
22
22
  send_time_older_than = Time.new.to_i - @error_emails_time
23
23
 
24
24
  @error_emails_pending.each do |backtrace_hash, error_email|
25
- if send_time_older_than < error_email[:last_time].to_i and error_email[:messages].length < 1000
25
+ if !args[:ignore_time] and send_time_older_than < error_email[:last_time].to_i and error_email[:messages].length < 1000
26
26
  next
27
27
  end
28
28
 
@@ -35,12 +35,14 @@ class Hayabusa
35
35
 
36
36
  #Generates a new session-ID by the meta data.
37
37
  def session_generate_id(meta)
38
- return Digest::MD5.hexdigest("#{Time.now.to_f}_#{meta["HTTP_HOST"]}_#{meta["REMOTE_HOST"]}_#{meta["HTTP_X_FORWARDED_SERVER"]}_#{meta["HTTP_X_FORWARDED_FOR"]}_#{meta["HTTP_X_FORWARDED_HOST"]}_#{meta["REMOTE_ADDR"]}_#{meta["HTTP_USER_AGENT"]}")
38
+ return Digest::MD5.hexdigest("#{Time.now.to_f}_#{meta["HTTP_HOST"]}_#{self.ip(:meta => meta)}_#{meta["HTTP_USER_AGENT"]}")
39
39
  end
40
40
 
41
41
  #Will make the session rememberable for a year. IP wont be checked any more.
42
42
  def session_remember
43
- session = _httpsession.session
43
+ httpsession = Thread.current[:hayabusa][:httpsession]
44
+ raise "Could not figure out HTTP-session." if !httpsession
45
+ session = httpsession.session
44
46
  raise "Could not get session-variable from HTTP-session." if !session
45
47
  session[:remember] = 1
46
48
 
@@ -52,6 +54,21 @@ class Hayabusa
52
54
  )
53
55
  end
54
56
 
57
+ #Will make the session run out as soon as the user closes his browser.
58
+ def session_dont_remember
59
+ httpsession = Thread.current[:hayabusa][:httpsession]
60
+ raise "Could not figure out HTTP-session." if !httpsession
61
+ session = httpsession.session
62
+ raise "Could not get session-variable from HTTP-session." if !session
63
+ session[:remember] = 0
64
+
65
+ self.cookie(
66
+ "name" => "HayabusaSession",
67
+ "value" => _httpsession.session_id,
68
+ "path" => "/"
69
+ )
70
+ end
71
+
55
72
  #Writes all session-data to the database (normally it is cached in memory and not updated on change).
56
73
  def sessions_flush
57
74
  if @sessions
@@ -11,7 +11,7 @@ class Hayabusa
11
11
  end
12
12
 
13
13
  #Callback for when an error occurs in the threadpool.
14
- def threadpool_on_error(event, error)
14
+ def threadpool_on_error(error)
15
15
  self.handle_error(error)
16
16
  end
17
17
 
@@ -187,4 +187,23 @@ class Hayabusa
187
187
  raise "Http-server not spawned yet. Call Hayabusa#start to spawn it." if !@httpserv
188
188
  return @httpserv.server.addr[1]
189
189
  end
190
+
191
+ #Returns the real IP of the client. Even if it has been proxied through multiple proxies.
192
+ def ip(args = nil)
193
+ if args and args[:meta]
194
+ meta = args[:meta]
195
+ elsif httpsession = Thread.current[:hayabusa][:httpsession]
196
+ meta = httpsession.meta
197
+ else
198
+ raise "Could not figure out meta-data."
199
+ end
200
+
201
+ if !meta["HTTP_X_FORWARDED_FOR"].to_s.strip.empty? and ips = meta["HTTP_X_FORWARDED_FOR"].split(/\s*,\s*/)
202
+ return ips.first.to_s.strip
203
+ elsif ip = meta["REMOTE_ADDR"].to_s.strip and !ip.empty?
204
+ return ip
205
+ else
206
+ raise "Could not figure out IP from meta-data."
207
+ end
208
+ end
190
209
  end
@@ -31,8 +31,7 @@ class Hayabusa::Fcgi
31
31
  hayabusa_conf = Hayabusa::FCGI_CONF[:hayabusa]
32
32
  hayabusa_conf.merge!(
33
33
  :cmdline => false,
34
- :mailing_timeout => 1,
35
- :mailing_instant => true,
34
+ :mailing_timeout => 1, #Since FCGI might terminate at any time, try to send out mails almost instantly in the background.
36
35
  :port => 0 #Ruby picks random port and we get the actual port after starting the appserver.
37
36
  )
38
37
 
@@ -116,15 +115,14 @@ class Hayabusa::Fcgi
116
115
  if @fcgi_proxy
117
116
  #Proxy request to the host-FCGI-process.
118
117
  $stderr.puts "[hayabusa] Proxying request." if @debug
119
- begin
120
- @cgi_tools.proxy_request_to(:cgi => cgi, :http => @fcgi_proxy[:http], :fp_log => @fcgi_proxy[:fp_log])
121
- rescue Errno::ECONNABORTED
122
- @fcgi_proxy = nil #Force re-evaluate if this process should be host or proxy.
123
- raise
124
- end
118
+ @cgi_tools.proxy_request_to(:cgi => cgi, :http => @fcgi_proxy[:http], :fp_log => @fcgi_proxy[:fp_log])
125
119
  else
126
120
  self.handle_fcgi_request(:cgi => cgi)
127
121
  end
122
+ rescue Errno::ECONNABORTED
123
+ $stderr.puts "[hayabusa] Connection to server was interrupted - trying again."
124
+ @fcgi_proxy = nil #Force re-evaluate if this process should be host or proxy.
125
+ retry
128
126
  rescue Exception => e
129
127
  cgi.print "Content-Type: text/html\r\n"
130
128
  cgi.print "\r\n"
@@ -1,7 +1,7 @@
1
1
  #This class handels the HTTP-sessions.
2
2
  class Hayabusa::Http_session
3
3
  attr_accessor :data, :alert_sent
4
- attr_reader :cookie, :get, :headers, :session, :session_id, :session_hash, :hb, :active, :out, :eruby, :browser, :debug, :resp, :page_path, :post, :cgroup, :meta, :httpsession_var, :handler, :working
4
+ attr_reader :cookie, :get, :headers, :ip, :session, :session_id, :session_hash, :hb, :active, :out, :eruby, :browser, :debug, :resp, :page_path, :post, :cgroup, :meta, :httpsession_var, :handler, :working
5
5
 
6
6
  #Autoloader for subclasses.
7
7
  def self.const_missing(name)
@@ -237,14 +237,7 @@ class Hayabusa::Http_session
237
237
  @resp.header("Content-Type", @ctype)
238
238
 
239
239
  @browser = Knj::Web.browser(@meta)
240
-
241
- if @meta["HTTP_X_FORWARDED_FOR"]
242
- @ip = @meta["HTTP_X_FORWARDED_FOR"].split(",")[0].strip
243
- elsif @meta["REMOTE_ADDR"]
244
- @ip = @meta["REMOTE_ADDR"]
245
- else
246
- raise "Could not figure out the IP of the session."
247
- end
240
+ @ip = @hb.ip(:meta => @meta)
248
241
 
249
242
  @hb.log_puts "Figuring out session-ID, session-object and more." if @debug
250
243
  if @cookie["HayabusaSession"].to_s.length > 0
@@ -99,7 +99,7 @@ class Hayabusa::Models::Log < Knj::Datarow
99
99
  def ip
100
100
  meta_d = self.meta
101
101
 
102
- return meta_d[:HTTP_X_FORWARDED_FOR] if meta_d.has_key?(:HTTP_X_FORWARDED_FOR)
102
+ return meta_d[:HTTP_X_FORWARDED_FOR].split(/\s*,\s*/).first if meta_d.has_key?(:HTTP_X_FORWARDED_FOR)
103
103
  return meta_d[:REMOTE_ADDR] if meta_d.has_key?(:REMOTE_ADDR)
104
104
  return "[no ip logged]"
105
105
  end
@@ -8,6 +8,7 @@ describe "Hayabusa" do
8
8
 
9
9
  Http2.new(:host => "localhost") do |http|
10
10
  res = http.post(:url => "hayabusa_cgi_test/vars_post_test.rhtml", :post => {
11
+ "test_special_chars" => "1%23+-456",
11
12
  "var" => {
12
13
  0 => 1,
13
14
  1 => 2,
@@ -30,6 +31,7 @@ describe "Hayabusa" do
30
31
  raise "Error when parsing result: '#{data}'."
31
32
  end
32
33
 
34
+ raise "Expected 'test_special_chars' to be '1%23+-456' but it wasnt: '#{data["test_special_chars"]}'." if data["test_special_chars"] != "1%23+-456"
33
35
 
34
36
  res = http.get("hayabusa_cgi_test/threadded_content_test.rhtml")
35
37
  raise "Expected body to be '123456' but it was: '#{res.body}'." if res.body != "123456"
@@ -15,6 +15,7 @@ describe "Hayabusa" do
15
15
  begin
16
16
  Http2.new(:host => "localhost") do |http|
17
17
  res = http.post(:url => "hayabusa_fcgi_test/vars_post_test.rhtml", :post => {
18
+ "test_special_chars" => "1%23+-456",
18
19
  "var" => {
19
20
  0 => 1,
20
21
  1 => 2,
@@ -37,6 +38,7 @@ describe "Hayabusa" do
37
38
  raise "Error when parsing result: '#{data}'."
38
39
  end
39
40
 
41
+ raise "Expected 'test_special_chars' to be '1%23+-456' but it wasnt: '#{data["test_special_chars"]}'." if data["test_special_chars"] != "1%23+-456"
40
42
 
41
43
  res = http.get("hayabusa_fcgi_test/threadded_content_test.rhtml")
42
44
  raise "Expected body to be '123456' but it was: '#{res.body}'." if res.body != "123456"
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: hayabusa
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.9
5
+ version: 0.0.10
6
6
  platform: ruby
7
7
  authors:
8
8
  - Kasper Johansen
@@ -10,8 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-08-29 00:00:00 +02:00
14
- default_executable:
13
+ date: 2012-09-11 00:00:00 Z
15
14
  dependencies:
16
15
  - !ruby/object:Gem::Dependency
17
16
  name: knjrbfw
@@ -236,7 +235,6 @@ files:
236
235
  - tests/fcgi_test/vars_get_test.rhtml
237
236
  - tests/fcgi_test/vars_header_test.rhtml
238
237
  - tests/fcgi_test/vars_post_test.rhtml
239
- has_rdoc: true
240
238
  homepage: http://github.com/kaspernj/hayabusa
241
239
  licenses:
242
240
  - MIT
@@ -250,7 +248,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
250
248
  requirements:
251
249
  - - ">="
252
250
  - !ruby/object:Gem::Version
253
- hash: -4101097160978567586
251
+ hash: 3667106797343681147
254
252
  segments:
255
253
  - 0
256
254
  version: "0"
@@ -263,7 +261,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
263
261
  requirements: []
264
262
 
265
263
  rubyforge_project:
266
- rubygems_version: 1.6.2
264
+ rubygems_version: 1.8.24
267
265
  signing_key:
268
266
  specification_version: 3
269
267
  summary: A threadded web/app-server that supports stand-alone, CGI and FCGI-modes.