hayabusa 0.0.9 → 0.0.10

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