hayabusa 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +20 -0
  4. data/Gemfile.lock +59 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.rdoc +19 -0
  7. data/Rakefile +49 -0
  8. data/VERSION +1 -0
  9. data/bin/check_running.rb +69 -0
  10. data/bin/hayabusa_benchmark.rb +82 -0
  11. data/bin/hayabusa_cgi.rb +84 -0
  12. data/bin/hayabusa_fcgi.fcgi +159 -0
  13. data/bin/hayabusa_fcgi.rb +159 -0
  14. data/bin/knjappserver_start.rb +42 -0
  15. data/conf/apache2_cgi_rhtml_conf.conf +10 -0
  16. data/conf/apache2_fcgi_rhtml_conf.conf +22 -0
  17. data/hayabusa.gemspec +151 -0
  18. data/lib/hayabusa.rb +518 -0
  19. data/lib/hayabusa_cgi_session.rb +128 -0
  20. data/lib/hayabusa_cgi_tools.rb +102 -0
  21. data/lib/hayabusa_custom_io.rb +22 -0
  22. data/lib/hayabusa_database.rb +125 -0
  23. data/lib/hayabusa_erb_handler.rb +27 -0
  24. data/lib/hayabusa_ext/cleaner.rb +140 -0
  25. data/lib/hayabusa_ext/cmdline.rb +52 -0
  26. data/lib/hayabusa_ext/errors.rb +135 -0
  27. data/lib/hayabusa_ext/logging.rb +404 -0
  28. data/lib/hayabusa_ext/mailing.rb +158 -0
  29. data/lib/hayabusa_ext/sessions.rb +71 -0
  30. data/lib/hayabusa_ext/threadding.rb +96 -0
  31. data/lib/hayabusa_ext/threadding_timeout.rb +101 -0
  32. data/lib/hayabusa_ext/translations.rb +43 -0
  33. data/lib/hayabusa_ext/web.rb +190 -0
  34. data/lib/hayabusa_http_server.rb +102 -0
  35. data/lib/hayabusa_http_session.rb +361 -0
  36. data/lib/hayabusa_http_session_contentgroup.rb +176 -0
  37. data/lib/hayabusa_http_session_page_environment.rb +66 -0
  38. data/lib/hayabusa_http_session_post_multipart.rb +135 -0
  39. data/lib/hayabusa_http_session_request.rb +219 -0
  40. data/lib/hayabusa_http_session_response.rb +144 -0
  41. data/lib/hayabusa_models.rb +8 -0
  42. data/lib/kernel_ext/gettext_methods.rb +22 -0
  43. data/lib/kernel_ext/magic_methods.rb +61 -0
  44. data/lib/models/log.rb +130 -0
  45. data/lib/models/log_access.rb +88 -0
  46. data/lib/models/log_data.rb +27 -0
  47. data/lib/models/log_data_link.rb +3 -0
  48. data/lib/models/log_data_value.rb +21 -0
  49. data/lib/models/log_link.rb +65 -0
  50. data/lib/models/session.rb +35 -0
  51. data/pages/benchmark.rhtml +0 -0
  52. data/pages/benchmark_print.rhtml +14 -0
  53. data/pages/benchmark_simple.rhtml +3 -0
  54. data/pages/benchmark_threadded_content.rhtml +21 -0
  55. data/pages/debug_database_connections.rhtml +46 -0
  56. data/pages/debug_http_sessions.rhtml +40 -0
  57. data/pages/debug_memory_usage.rhtml +16 -0
  58. data/pages/error_notfound.rhtml +12 -0
  59. data/pages/logs_latest.rhtml +57 -0
  60. data/pages/logs_show.rhtml +32 -0
  61. data/pages/spec.rhtml +41 -0
  62. data/pages/spec_post.rhtml +3 -0
  63. data/pages/spec_test_multiple_clients.rhtml +3 -0
  64. data/pages/spec_thread_joins.rhtml +21 -0
  65. data/pages/spec_threadded_content.rhtml +40 -0
  66. data/pages/tests.rhtml +14 -0
  67. data/spec/cgi_spec.rb +47 -0
  68. data/spec/custom_urls_spec.rb +35 -0
  69. data/spec/fcgi_multiple_processes_spec.rb +32 -0
  70. data/spec/fcgi_spec.rb +69 -0
  71. data/spec/hayabusa_spec.rb +194 -0
  72. data/spec/spec_helper.rb +12 -0
  73. data/tests/cgi_test/config_cgi.rb +6 -0
  74. data/tests/cgi_test/threadded_content_test.rhtml +23 -0
  75. data/tests/cgi_test/vars_get_test.rhtml +4 -0
  76. data/tests/cgi_test/vars_header_test.rhtml +3 -0
  77. data/tests/cgi_test/vars_post_test.rhtml +4 -0
  78. data/tests/fcgi_test/config_fcgi.rb +6 -0
  79. data/tests/fcgi_test/index.rhtml +3 -0
  80. data/tests/fcgi_test/sleeper.rhtml +4 -0
  81. data/tests/fcgi_test/threadded_content_test.rhtml +23 -0
  82. data/tests/fcgi_test/vars_get_test.rhtml +4 -0
  83. data/tests/fcgi_test/vars_header_test.rhtml +3 -0
  84. data/tests/fcgi_test/vars_post_test.rhtml +4 -0
  85. metadata +257 -0
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,20 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ gem "knjrbfw"
7
+ gem "erubis"
8
+ gem "mail"
9
+ gem "datet"
10
+ gem "http2"
11
+
12
+ # Add dependencies to develop your gem here.
13
+ # Include everything needed to run rake, tests, features, etc.
14
+ group :development do
15
+ gem "json"
16
+ gem "rspec", "~> 2.3.0"
17
+ gem "bundler", ">= 1.0.0"
18
+ gem "jeweler", "~> 1.6.3"
19
+ gem "sqlite3" if RUBY_ENGINE != "jruby"
20
+ end
@@ -0,0 +1,59 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ datet (0.0.15)
5
+ diff-lcs (1.1.3)
6
+ erubis (2.7.0)
7
+ git (1.2.5)
8
+ http2 (0.0.10)
9
+ i18n (0.6.0)
10
+ jeweler (1.6.4)
11
+ bundler (~> 1.0)
12
+ git (>= 1.2.5)
13
+ rake
14
+ json (1.7.4)
15
+ knjrbfw (0.0.85)
16
+ datet
17
+ http2
18
+ php4r
19
+ tsafe
20
+ wref
21
+ mail (2.4.4)
22
+ i18n (>= 0.4.0)
23
+ mime-types (~> 1.16)
24
+ treetop (~> 1.4.8)
25
+ mime-types (1.19)
26
+ php4r (0.0.2)
27
+ datet
28
+ http2
29
+ polyglot (0.3.3)
30
+ rake (0.9.2.2)
31
+ rspec (2.3.0)
32
+ rspec-core (~> 2.3.0)
33
+ rspec-expectations (~> 2.3.0)
34
+ rspec-mocks (~> 2.3.0)
35
+ rspec-core (2.3.1)
36
+ rspec-expectations (2.3.0)
37
+ diff-lcs (~> 1.1.2)
38
+ rspec-mocks (2.3.0)
39
+ sqlite3 (1.3.6)
40
+ treetop (1.4.10)
41
+ polyglot
42
+ polyglot (>= 0.3.1)
43
+ tsafe (0.0.11)
44
+ wref (0.0.5)
45
+
46
+ PLATFORMS
47
+ ruby
48
+
49
+ DEPENDENCIES
50
+ bundler (>= 1.0.0)
51
+ datet
52
+ erubis
53
+ http2
54
+ jeweler (~> 1.6.3)
55
+ json
56
+ knjrbfw
57
+ mail
58
+ rspec (~> 2.3.0)
59
+ sqlite3
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Kasper Johansen
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,19 @@
1
+ = hayabusa
2
+
3
+ Description goes here.
4
+
5
+ == Contributing to hayabusa
6
+
7
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
8
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
9
+ * Fork the project.
10
+ * Start a feature/bugfix branch.
11
+ * Commit and push until you are happy with your contribution.
12
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
13
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2012 Kasper Johansen. See LICENSE.txt for
18
+ further details.
19
+
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "hayabusa"
18
+ gem.homepage = "http://github.com/kaspernj/hayabusa"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{A threadded web/app-server that supports stand-alone, CGI and FCGI-modes.}
21
+ gem.description = %Q{A threadded web/app-server that focuses on threadding, shared ressources, speed and more.}
22
+ gem.email = "k@spernj.org"
23
+ gem.authors = ["Kasper Johansen"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rspec/core'
29
+ require 'rspec/core/rake_task'
30
+ RSpec::Core::RakeTask.new(:spec) do |spec|
31
+ spec.pattern = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
35
+ spec.pattern = 'spec/**/*_spec.rb'
36
+ spec.rcov = true
37
+ end
38
+
39
+ task :default => :spec
40
+
41
+ require 'rdoc/task'
42
+ Rake::RDocTask.new do |rdoc|
43
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
44
+
45
+ rdoc.rdoc_dir = 'rdoc'
46
+ rdoc.title = "hayabusa #{version}"
47
+ rdoc.rdoc_files.include('README*')
48
+ rdoc.rdoc_files.include('lib/**/*.rb')
49
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # This script checks if the hayabusa is running - if not it forks and start it.
4
+ require "rubygems"
5
+ require "optparse"
6
+ Dir.chdir("#{File.dirname(__FILE__)}/../")
7
+
8
+ begin
9
+ options = {
10
+ :command => "ruby hayabusa_start.rb",
11
+ :title => "hayabusa",
12
+ :forking => true
13
+ }
14
+ OptionParser.new do |opts|
15
+ opts.banner = "Usage: hayabusa.rb [options]"
16
+
17
+ opts.on("--command=[cmd]", "Run verbosely.") do |cmd|
18
+ options[:command] = cmd
19
+ end
20
+
21
+ opts.on("--title=[title]", "The title of the appserver that should be checked for.") do |title|
22
+ options[:title] = title
23
+ end
24
+
25
+ opts.on("--forking=[forkval]", "If you want the script to fork or not.") do |forking|
26
+ if forking.to_i >= 1
27
+ options[:forking] = true
28
+ else
29
+ options[:forking] = false
30
+ end
31
+ end
32
+
33
+ opts.on("--knjrbfw_path=[path]") do |path|
34
+ options[:knjrbfw_path] = path
35
+ end
36
+ end.parse!
37
+ rescue OptionParser::InvalidOption => e
38
+ print "#{e.message}\n"
39
+ exit
40
+ end
41
+
42
+ if !options[:title]
43
+ print "No title was given.\n"
44
+ exit
45
+ end
46
+
47
+ if !options[:command]
48
+ print "No command to execute was given.\n"
49
+ exit
50
+ end
51
+
52
+ require "#{options[:knjrbfw_path]}knjrbfw"
53
+
54
+ tmpdir = "#{Knj::Os.tmpdir}/hayabusa"
55
+ tmppath = "#{tmpdir}/run_#{options[:title]}"
56
+ count = 0
57
+
58
+ if File.exists?(tmppath)
59
+ pid = File.read(tmppath).to_s.strip
60
+ count = Knj::Unix_proc.list("pids" => [pid]).length if pid.to_s.length > 0
61
+ end
62
+
63
+ exit if count > 0
64
+
65
+ if options[:forking]
66
+ exec(options[:command]) if fork.nil?
67
+ else
68
+ exec(options[:command])
69
+ end
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ Dir.chdir(File.dirname(__FILE__))
4
+
5
+ require "optparse"
6
+ require "sqlite3" if RUBY_ENGINE != "jruby"
7
+
8
+ begin
9
+ args = {
10
+ :filename => "benchmark.rhtml"
11
+ }
12
+
13
+ OptionParser.new do |opts|
14
+ opts.banner = "Usage: benchmark.rb [options]"
15
+
16
+ opts.on("-f FILENAME", "--file FILENAME", "The filename that should be requested from the server.") do |t|
17
+ args[:filename] = t
18
+ end
19
+
20
+ opts.on("-k PATH", "--knjrbfw PATH", "The path of knjrbfw if it should not be loaded from gems.") do |path|
21
+ args[:knjrbfw_path] = path
22
+ end
23
+ end.parse!
24
+ end
25
+
26
+ db_path = "#{File.dirname(__FILE__)}/benchmark_db.sqlite3"
27
+
28
+ appserver_args = {
29
+ :debug => false,
30
+ :port => 15081,
31
+ :doc_root => "#{File.dirname(__FILE__)}/../pages",
32
+ :db_args => {
33
+ :type => "sqlite3",
34
+ :path => db_path,
35
+ :return_keys => "symbols"
36
+ }
37
+ }
38
+
39
+ require "rubygems"
40
+ require "erubis"
41
+ require "#{args[:knjrbfw_path]}/knjrbfw.rb"
42
+ require "../hayabusa.rb"
43
+
44
+ if args[:knjrbfw_path]
45
+ appserver_args[:knjrbfw_path] = args[:knjrbfw_path]
46
+ else
47
+ require "knjrbfw"
48
+ end
49
+
50
+ require "knj/autoload"
51
+
52
+ appsrv = Hayabusa.new(appserver_args)
53
+ appsrv.start
54
+
55
+ count_requests = 0
56
+ 1.upto(50) do |count_thread|
57
+ Knj::Thread.new(count_thread) do |count_thread|
58
+ print "Thread #{count_thread} started.\n"
59
+
60
+ http = Http2.new(
61
+ :host => "localhost",
62
+ :port => 15081,
63
+ :user_agent => "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.1; debugid:#{count_thread}) Gecko/20060111 Firefox/3.6.0.1",
64
+ :debug => false
65
+ )
66
+
67
+ loop do
68
+ resp = http.get(:url => args[:filename])
69
+ count_requests += 1
70
+ raise "Invalid code: #{resp.code}\n" if resp.code.to_i != 200
71
+ end
72
+ end
73
+ end
74
+
75
+ loop do
76
+ last_count = count_requests
77
+ sleep 1
78
+ counts_betw = count_requests - last_count
79
+ print "#{counts_betw} /sec\n"
80
+ end
81
+
82
+ appsrv.join
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/ruby
2
+
3
+ #This scripts start an appserver, executes a HTTP-request and terminates.
4
+ #Good for programming appserver-supported projects without running an appserver all the time,
5
+ #but really slow because of startup for every request.
6
+
7
+ begin
8
+ #Read real path.
9
+ file = __FILE__
10
+ file = File.readlink(file) if File.symlink?(file)
11
+ file = File.realpath(file)
12
+
13
+ require "#{File.dirname(file)}/../lib/hayabusa.rb"
14
+ require "knjrbfw"
15
+
16
+ #Spawn CGI-variable to emulate FCGI part.
17
+ cgi_tools = Hayabusa::Cgi_tools.new
18
+
19
+ require "cgi"
20
+ cgi = CGI.new
21
+ cgi_tools.cgi = cgi
22
+
23
+ #print "Content-Type: text/html\r\n"
24
+ #print "\r\n"
25
+
26
+ raise "No HTTP_HAYABUSA_CGI_CONFIG-header was given." if !ENV["HTTP_HAYABUSA_CGI_CONFIG"]
27
+ require ENV["HTTP_HAYABUSA_CGI_CONFIG"]
28
+
29
+ begin
30
+ conf = Hayabusa::CGI_CONF
31
+ rescue NameError
32
+ raise "No 'Hayabusa::CGI_CONF'-constant was spawned by '#{ENV["HTTP_HAYABUSA_CGI_CONFIG"]}'."
33
+ end
34
+
35
+ #The rest is copied from the FCGI-part.
36
+ headers = {}
37
+ cgi_tools.env_table.each do |key, val|
38
+ if key[0, 5] == "HTTP_" and key != "HTTP_HAYABUSA_CGI_CONFIG"
39
+ key = key[5, key.length].gsub("_", " ").gsub(" ", "-")
40
+ headers[key] = val
41
+ end
42
+ end
43
+
44
+ cgi_data = {
45
+ :headers => headers,
46
+ :get => Knj::Web.parse_urlquery(cgi_tools.env_table["QUERY_STRING"], :urldecode => true, :force_utf8 => true),
47
+ :meta => cgi_tools.env_table.to_hash
48
+ }
49
+ if cgi_tools.request_method == "POST"
50
+ cgi_data[:post] = cgi_tools.convert_fcgi_post(cgi_tools.params)
51
+ else
52
+ cgi_data[:post] = {}
53
+ end
54
+
55
+ #Spawn appserver.
56
+ hayabusa_conf = {
57
+ :cmdline => false,
58
+ :events => false,
59
+ :cleaner => false,
60
+ :dbrev => false,
61
+ :mail_require => false,
62
+ :debug => false,
63
+ :cgi => cgi_data,
64
+ :webserver => false
65
+ }
66
+ hayabusa_conf.merge!(Hayabusa::CGI_CONF[:hayabusa]) if Hayabusa::CGI_CONF[:hayabusa]
67
+ hayabusa = Hayabusa.new(hayabusa_conf).start_cgi_request
68
+ rescue Exception => e
69
+ print "Content-Type: text/html\r\n"
70
+ print "\n\n"
71
+
72
+ if Kernel.const_defined?(:Knj)
73
+ print Knj::Errors.error_str(e, {:html => true})
74
+ else
75
+ puts e.inspect
76
+ puts e.backtrace
77
+ end
78
+
79
+ begin
80
+ hayabusa.stop if hayabusa
81
+ rescue => e
82
+ print "<br />\n<br />\n#{Knj::Errors.error_str(e, {:html => true})}"
83
+ end
84
+ end
@@ -0,0 +1,159 @@
1
+ #!/usr/bin/ruby
2
+
3
+ #This scripts start an appserver, executes a HTTP-request for every FCGI-request and terminates when FCGI terminates.
4
+ #Good for programming appserver-supported projects that doesnt need threadding without running an appserver all the time.
5
+
6
+ #It doesnt support shared threadding or objects because multiple instances in form of processes will be executed.
7
+
8
+ #Its a bit slower because it needs to flush writes to the database at end of every request and re-read them on spawn, because multiple instances might be present.
9
+
10
+ error_log_file = "/tmp/hayabusa_fcgi.log"
11
+
12
+ begin
13
+ File.unlink(error_log_file) if File.exists?(error_log_file)
14
+ rescue Errno::ENOENT
15
+ #ignore.
16
+ end
17
+
18
+ begin
19
+ require "rubygems"
20
+ require "knjrbfw"
21
+ require "fcgi"
22
+ require "fileutils"
23
+ require "#{File.dirname(Knj::Os.realpath(__FILE__))}/../lib/hayabusa.rb"
24
+
25
+ #Spawn CGI-variable to emulate FCGI part.
26
+ cgi_tools = Hayabusa::Cgi_tools.new
27
+
28
+ #We cant define the Hayabusa-server untuil we receive the first headers, so wait for the first request.
29
+ hayabusa = nil
30
+ fcgi_proxy = nil
31
+
32
+ FCGI.each_cgi do |cgi|
33
+ begin
34
+ #cgi.print "Content-Type: text/html\r\n"
35
+ #cgi.print "\r\n"
36
+
37
+ cgi_tools.cgi = cgi
38
+
39
+ if !hayabusa
40
+ raise "No HTTP_HAYABUSA_FCGI_CONFIG-header was given." if !cgi.env_table["HTTP_HAYABUSA_FCGI_CONFIG"]
41
+ require cgi.env_table["HTTP_HAYABUSA_FCGI_CONFIG"]
42
+
43
+ begin
44
+ conf = Hayabusa::FCGI_CONF
45
+ rescue NameError
46
+ raise "No 'Hayabusa::FCGI_CONF'-constant was spawned by '#{cgi.env_table["HTTP_HAYABUSA_FCGI_CONFIG"]}'."
47
+ end
48
+
49
+ hayabusa_conf = Hayabusa::FCGI_CONF[:hayabusa]
50
+ hayabusa_conf.merge!(
51
+ :cmdline => false,
52
+ :port => 0 #Ruby picks random port and we get the actual port after starting the appserver.
53
+ )
54
+
55
+ #Figure out if this should be a host-FCGI-process or a proxy-FCGI-process.
56
+ fcgi_config_fp = "#{Knj::Os.tmpdir}/hayabusa_fcgi_#{hayabusa_conf[:title]}_fcgi.conf"
57
+ FileUtils.touch(fcgi_config_fp) if !File.exists?(fcgi_config_fp)
58
+
59
+ begin
60
+ File.open(fcgi_config_fp) do |fp|
61
+ fp.flock(File::LOCK_EX)
62
+
63
+ fcgi_config_cont = File.read(fcgi_config_fp)
64
+
65
+ if !fcgi_config_cont.empty?
66
+ fcgi_config = Marshal.load(File.read(fcgi_config_fp))
67
+ pid = fcgi_config[:pid]
68
+
69
+ if Knj::Unix_proc.pid_running?(pid)
70
+ fcgi_proxy = fcgi_config
71
+
72
+ require "http2"
73
+ http = Http2.new(:host => "localhost", :port => fcgi_proxy[:port].to_i)
74
+ fcgi_proxy[:http] = http
75
+ end
76
+ else
77
+ fcgi_config = nil
78
+ end
79
+
80
+ if !fcgi_proxy
81
+ File.open(fcgi_config_fp, "w") do |fp|
82
+ hayabusa = Hayabusa.new(hayabusa_conf)
83
+
84
+ #Start web-server for proxy-requests.
85
+ hayabusa.start
86
+
87
+ fp.write(Marshal.dump(
88
+ :pid => Process.pid,
89
+ :port => hayabusa.port
90
+ ))
91
+ end
92
+ end
93
+ end
94
+ ensure
95
+ File.open(fcgi_config_fp).flock(File::LOCK_UN)
96
+ end
97
+ end
98
+
99
+
100
+
101
+ if fcgi_proxy
102
+ #Proxy request to the host-FCGI-process.
103
+ cgi_tools.proxy_request_to(:cgi => cgi, :http => fcgi_proxy[:http])
104
+ else
105
+ #Host the FCGI-process.
106
+
107
+ #Enforce $stdout variable.
108
+ $stdout = hayabusa.cio
109
+
110
+ #The rest is copied from the FCGI-part.
111
+ headers = {}
112
+ cgi.env_table.each do |key, val|
113
+ if key[0, 5] == "HTTP_" and key != "HTTP_HAYABUSA_FCGI_CONFIG"
114
+ key = key[5, key.length].gsub("_", " ").gsub(" ", "-")
115
+ headers[key] = val
116
+ end
117
+ end
118
+
119
+ meta = cgi.env_table.to_hash
120
+
121
+ uri = Knj::Web.parse_uri(meta["REQUEST_URI"])
122
+ meta["PATH_TRANSLATED"] = File.basename(uri[:path])
123
+
124
+ cgi_data = {
125
+ :cgi => cgi,
126
+ :headers => headers,
127
+ :get => Knj::Web.parse_urlquery(cgi.env_table["QUERY_STRING"], :urldecode => true, :force_utf8 => true),
128
+ :meta => meta
129
+ }
130
+ if cgi.request_method == "POST"
131
+ cgi_data[:post] = cgi_tools.convert_fcgi_post(cgi.params)
132
+ else
133
+ cgi_data[:post] = {}
134
+ end
135
+
136
+ hayabusa.config[:cgi] = cgi_data
137
+
138
+
139
+ #Handle request.
140
+ hayabusa.start_cgi_request
141
+ end
142
+ rescue Exception => e
143
+ cgi.print "Content-Type: text/html\r\n"
144
+ cgi.print "\r\n"
145
+ cgi.print Knj::Errors.error_str(e, :html => true)
146
+ cgi.print Knj.p(cgi_data, true) if cgi_data
147
+ end
148
+ end
149
+ rescue Exception => e
150
+ if !e.is_a?(Interrupt)
151
+ File.open(error_log_file, "w") do |fp|
152
+ fp.puts e.inspect
153
+ fp.puts e.backtrace
154
+ fp.puts ""
155
+ end
156
+ end
157
+
158
+ raise e
159
+ end