about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2010-10-28 09:43:15 +0000
committerEric Wong <normalperson@yhbt.net>2010-10-28 09:43:15 +0000
commit7a01cae820a175c2f7fd85e43f2e06ec8174340d (patch)
tree3dc01fb2d282ddd7b69e29a0913e720193dbeab7
parentc37172c8febcec7f8a491b6e229260ca607e14b0 (diff)
downloadzbatery-7a01cae820a175c2f7fd85e43f2e06ec8174340d.tar.gz
updates for Rainbows! 1.0.0
There are some internal API changes here.
-rwxr-xr-xbin/zbatery55
-rw-r--r--lib/zbatery.rb81
-rw-r--r--t/test_isolate.rb7
-rw-r--r--zbatery.gemspec8
4 files changed, 47 insertions, 104 deletions
diff --git a/bin/zbatery b/bin/zbatery
index fe7b011..6d781b9 100755
--- a/bin/zbatery
+++ b/bin/zbatery
@@ -1,20 +1,17 @@
-#!/usr/bin/ruby
+#!/this/will/be/overwritten/or/wrapped/anyways/do/not/worry/ruby
 # -*- encoding: binary -*-
 require 'unicorn/launcher'
 require 'zbatery'
 require 'optparse'
 
 ENV["RACK_ENV"] ||= "development"
-daemonize = false
-listeners = []
-options = { :listeners => listeners }
-host, port = Unicorn::Const::DEFAULT_HOST, Unicorn::Const::DEFAULT_PORT
-set_listener = false
+rackup_opts = Unicorn::Configurator::RACKUP
+options = rackup_opts[:options]
 
 opts = OptionParser.new("", 24, '  ') do |opts|
-  opts.banner = "Usage: #{File.basename($0)} " \
-                "[ruby options] [zbatery options] [rackup config file]"
-
+  cmd = File.basename($0)
+  opts.banner = "Usage: #{cmd} " \
+                "[ruby options] [#{cmd} options] [rackup config file]"
   opts.separator "Ruby options:"
 
   lineno = 1
@@ -41,34 +38,34 @@ opts = OptionParser.new("", 24, '  ') do |opts|
     require library
   end
 
-  opts.separator "Zbatery options:"
+  opts.separator "#{cmd} options:"
 
   # some of these switches exist for rackup command-line compatibility,
 
   opts.on("-o", "--host HOST",
           "listen on HOST (default: #{Unicorn::Const::DEFAULT_HOST})") do |h|
-    host = h
-    set_listener = true
+    rackup_opts[:host] = h
+    rackup_opts[:set_listener] = true
   end
 
   opts.on("-p", "--port PORT",
           "use PORT (default: #{Unicorn::Const::DEFAULT_PORT})") do |p|
-    port = p.to_i
-    set_listener = true
+    rackup_opts[:port] = p.to_i
+    rackup_opts[:set_listener] = true
   end
 
-  opts.on("-E", "--env ENVIRONMENT",
-          "use ENVIRONMENT for defaults (default: development)") do |e|
+  opts.on("-E", "--env RACK_ENV",
+          "use RACK_ENV for defaults (default: development)") do |e|
     ENV["RACK_ENV"] = e
   end
 
   opts.on("-D", "--daemonize", "run daemonized in the background") do |d|
-    daemonize = d ? true : false
+    rackup_opts[:daemonize] = !!d
   end
 
   opts.on("-P", "--pid FILE", "DEPRECATED") do |f|
-    warn %q{Use of --pid/-P is strongly discouraged}
-    warn %q{Use the 'pid' directive in the Zbatery config file instead}
+    warn "Use of --pid/-P is strongly discouraged"
+    warn "Use the 'pid' directive in the Zbatery config file instead"
     options[:pid] = f
   end
 
@@ -77,15 +74,15 @@ opts = OptionParser.new("", 24, '  ') do |opts|
     warn "-s/--server only exists for compatibility with rackup"
   end
 
-  # Zbatery/Unicorn-specific stuff
+  # Rainbows!/Unicorn-specific stuff
   opts.on("-l", "--listen {HOST:PORT|PATH}",
           "listen on HOST:PORT or PATH",
           "this may be specified multiple times",
           "(default: #{Unicorn::Const::DEFAULT_LISTEN})") do |address|
-    listeners << address
+    options[:listeners] << address
   end
 
-  opts.on("-c", "--config-file FILE", "Unicorn-specific config file") do |f|
+  opts.on("-c", "--config-file FILE", "Zbatery-specific config file") do |f|
     options[:config_file] = f
   end
 
@@ -102,27 +99,23 @@ opts = OptionParser.new("", 24, '  ') do |opts|
   end
 
   opts.on_tail("-v", "--version", "Show version") do
-    puts "zbatery v#{Zbatery::VERSION}"
+    puts "Zbatery v#{Zbatery::VERSION}"
     exit
   end
 
   opts.parse! ARGV
 end
 
-config = ARGV[0] || "config.ru"
-abort "configuration file #{config} not found" unless File.exist?(config)
-
-app = Unicorn.builder(config, opts)
-listeners << "#{host}:#{port}" if set_listener
+app = Unicorn.builder(ARGV[0] || 'config.ru', opts)
 
 if $DEBUG
   require 'pp'
   pp({
-    :zbatery_options => options,
+    :unicorn_options => options,
     :app => app,
-    :daemonize => daemonize,
+    :daemonize => rackup_opts[:daemonize],
   })
 end
 
-Unicorn::Launcher.daemonize!(options) if daemonize
+Unicorn::Launcher.daemonize!(options) if rackup_opts[:daemonize]
 Zbatery.run(app, options)
diff --git a/lib/zbatery.rb b/lib/zbatery.rb
index dc36544..8d5a582 100644
--- a/lib/zbatery.rb
+++ b/lib/zbatery.rb
@@ -18,21 +18,10 @@ module Zbatery
 
   Rainbows::Const::RACK_DEFAULTS["SERVER_SOFTWARE"] = "Zbatery #{VERSION}"
 
-  # true if our Ruby implementation supports unlinked files
-  UnlinkedIO = begin
-    tmp = Unicorn::Util.tmpio
-    tmp.chmod(0)
-    tmp.close
-    true
-  rescue
-    false
-  end
-
   # we don't actually fork workers, but allow using the
   # {before,after}_fork hooks found in Unicorn/Rainbows!
   # config files...
   FORK_HOOK = lambda { |_,_| }
-
 end
 
 # :stopdoc:
@@ -47,12 +36,7 @@ module Rainbows
       build_app! unless preload_app
       Rainbows::Response.setup(self.class)
       Rainbows::MaxBody.setup
-
-      # avoid spurious wakeups and blocking-accept() with 1.8 green threads
-      if RUBY_VERSION.to_f < 1.9
-        require "io/nonblock"
-        HttpServer::LISTENERS.each { |l| l.nonblock = true }
-      end
+      Rainbows::ProcessClient.const_set(:APP, @app)
 
       logger.info "Zbatery #@use worker_connections=#@worker_connections"
     end
@@ -68,6 +52,7 @@ module Rainbows
     # this class is only used to avoid breaking Unicorn user switching
     class DeadIO
       def chown(*args); end
+      alias fcntl chown
     end
 
     # only used if no concurrency model is specified
@@ -75,11 +60,8 @@ module Rainbows
       init_worker_process(worker)
       begin
         ret = IO.select(LISTENERS, nil, nil, nil) and
-        ret.first.each do |sock|
-          begin
-            process_client(sock.accept_nonblock)
-          rescue Errno::EAGAIN, Errno::ECONNABORTED
-          end
+        ret[0].each do |sock|
+          io = sock.kgio_tryaccept and process_client(io)
         end
       rescue Errno::EINTR
       rescue Errno::EBADF, TypeError
@@ -108,32 +90,24 @@ module Rainbows
     end
 
     def join
-      begin
-        trap(:INT) { stop(false) } # Mongrel trapped INT for Win32...
-
-        # try these anyways regardless of platform...
-        trap(:TERM) { stop(false) }
-        trap(:QUIT) { stop }
-        trap(:USR1) { reopen_logs }
-        trap(:USR2) { reexec }
-
-        # no other way to reliably switch concurrency models...
-        trap(:HUP) { reexec; stop }
-
-        # technically feasible in some cases, just not sanely supportable:
-        %w(TTIN TTOU WINCH).each do |sig|
-          trap(sig) { logger.info "SIG#{sig} is not handled by Zbatery" }
-        end
-      rescue => e # hopefully ignores errors on Win32...
-        logger.error "failed to setup signal handler: #{e.message}"
+      trap(:INT) { stop(false) }
+      trap(:TERM) { stop(false) }
+      trap(:QUIT) { stop }
+      trap(:USR1) { reopen_logs }
+      trap(:USR2) { reexec }
+      trap(:HUP) { reexec; stop }
+
+      # technically feasible in some cases, just not sanely supportable:
+      %w(TTIN TTOU WINCH).each do |sig|
+        trap(sig) { logger.info "SIG#{sig} is not handled by Zbatery" }
       end
 
       if ready_pipe
         ready_pipe.syswrite($$.to_s)
-        ready_pipe.close rescue nil
+        ready_pipe.close
         self.ready_pipe = nil
       end
-
+      extend(Rainbows.const_get(@use))
       worker = Worker.new(0, DeadIO.new)
       before_fork.call(self, worker)
       worker_loop(worker) # runs forever
@@ -160,24 +134,5 @@ module Rainbows
   end
 end
 
-module Unicorn
-
-  class Configurator
-    DEFAULTS[:before_fork] = DEFAULTS[:after_fork] = Zbatery::FORK_HOOK
-  end
-
-  unless Zbatery::UnlinkedIO
-    require 'tempfile'
-    class Util
-
-      # Tempfiles should get automatically unlinked by GC
-      def self.tmpio
-        fp = Tempfile.new("zbatery")
-        fp.binmode
-        fp.sync = true
-        fp
-      end
-    end
-  end
-
-end
+Unicorn::Configurator::DEFAULTS[:before_fork] =
+  Unicorn::Configurator::DEFAULTS[:after_fork] = Zbatery::FORK_HOOK
diff --git a/t/test_isolate.rb b/t/test_isolate.rb
index 9ce3ff5..11ef662 100644
--- a/t/test_isolate.rb
+++ b/t/test_isolate.rb
@@ -14,9 +14,9 @@ old_out = $stdout.dup
 $stdout.reopen($stderr)
 
 Isolate.now!(opts) do
-  gem 'rack', '1.1.0'
-  gem 'unicorn', '1.1.3'
-  gem 'rainbows', '0.97.0'
+  gem 'rack', '1.2.1'
+  gem 'unicorn', '2.0.0'
+  gem 'rainbows', '1.0.0'
 
   if engine == "ruby"
     gem 'sendfile', '1.0.0' # next Rubinius should support this
@@ -29,7 +29,6 @@ Isolate.now!(opts) do
     gem 'async_sinatra', '0.2.1'
 
     gem 'neverblock', '0.1.6.2'
-    gem 'cramp', '0.11'
   end
 
   if defined?(::Fiber) && engine == "ruby"
diff --git a/zbatery.gemspec b/zbatery.gemspec
index 3b1bdde..def7d73 100644
--- a/zbatery.gemspec
+++ b/zbatery.gemspec
@@ -50,12 +50,8 @@ Gem::Specification.new do |s|
   #   espace-neverblock + eventmachine
   #   async_sinatra + sinatra + eventmachine
   #
-  # rainbows 0.91.1 depends on unicorn ~> 0.97.1, previous versions of
-  # Unicorn were vulnerable to a remote DoS when exposed directly to
-  # untrusted clients (a configuration only supported by Zbatery and Rainbows!,
-  # Unicorn has never and will never be supported without trusted LAN clients.
-  s.add_dependency(%q<rainbows>, [">= 0.97.0", "<= 1.0.0"])
-  s.add_development_dependency(%q<isolate>, "~> 2.1.0")
+  s.add_dependency(%q<rainbows>, ["~> 1.0.0"])
+  s.add_development_dependency(%q<isolate>, "~> 3.0.0")
 
   # s.licenses = %w(GPLv2 Ruby) # accessor not compatible with older RubyGems
 end