Froze rails gems
[depot.git] / vendor / rails / railties / lib / commands / ncgi / listener
diff --git a/vendor/rails/railties/lib/commands/ncgi/listener b/vendor/rails/railties/lib/commands/ncgi/listener
new file mode 100755 (executable)
index 0000000..7079ef7
--- /dev/null
@@ -0,0 +1,86 @@
+#!/usr/bin/env ruby
+
+require 'stringio'
+require 'fileutils'
+require 'fcgi_handler'
+
+def message(s)
+  $stderr.puts "listener: #{s}" if ENV && ENV["DEBUG_GATEWAY"]
+end
+
+class RemoteCGI < CGI
+  attr_accessor :stdinput, :stdoutput, :env_table
+  def initialize(env_table, input = nil, output = nil)
+    self.env_table = env_table
+    self.stdinput = input || StringIO.new
+    self.stdoutput = output || StringIO.new
+    super()
+  end
+
+  def out(stream) # Ignore the requested output stream
+    super(stdoutput)
+  end
+end
+
+class Listener
+  include DRbUndumped
+
+  def initialize(timeout, socket_path)
+    @socket = File.expand_path(socket_path)
+    @mutex = Mutex.new
+    @active = false
+    @timeout = timeout
+
+    @handler = RailsFCGIHandler.new
+    @handler.extend DRbUndumped
+
+    message 'opening socket'
+    DRb.start_service("drbunix:#{@socket}", self)
+
+    message 'entering process loop'
+    @handler.process! self
+  end
+
+  def each_cgi(&cgi_block)
+    @cgi_block = cgi_block
+    message 'entering idle loop'
+    loop do
+      sleep @timeout rescue nil
+      die! unless @active
+      @active = false
+    end
+  end
+
+  def process(env, input)
+    message 'received request'
+    @mutex.synchronize do
+      @active = true
+
+      message 'creating input stream'
+      input_stream = StringIO.new(input)
+      message 'building CGI instance'
+      cgi = RemoteCGI.new(eval(env), input_stream)
+
+      message 'yielding to fcgi handler'
+      @cgi_block.call cgi
+      message 'yield finished -- sending output'
+
+      cgi.stdoutput.seek(0)
+      output = cgi.stdoutput.read
+
+      return output
+    end
+  end
+
+  def die!
+    message 'shutting down'
+    DRb.stop_service
+    FileUtils.rm_f @socket
+    Kernel.exit 0
+  end
+end
+
+socket_path = ARGV.shift
+timeout = (ARGV.shift || 90).to_i
+
+Listener.new(timeout, socket_path)