86 lines
1.8 KiB
Plaintext
86 lines
1.8 KiB
Plaintext
|
#!/usr/local/bin/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)
|