Froze rails gems
[depot.git] / vendor / rails / railties / lib / commands / ncgi / listener
1 #!/usr/bin/env ruby
2
3 require 'stringio'
4 require 'fileutils'
5 require 'fcgi_handler'
6
7 def message(s)
8 $stderr.puts "listener: #{s}" if ENV && ENV["DEBUG_GATEWAY"]
9 end
10
11 class RemoteCGI < CGI
12 attr_accessor :stdinput, :stdoutput, :env_table
13 def initialize(env_table, input = nil, output = nil)
14 self.env_table = env_table
15 self.stdinput = input || StringIO.new
16 self.stdoutput = output || StringIO.new
17 super()
18 end
19
20 def out(stream) # Ignore the requested output stream
21 super(stdoutput)
22 end
23 end
24
25 class Listener
26 include DRbUndumped
27
28 def initialize(timeout, socket_path)
29 @socket = File.expand_path(socket_path)
30 @mutex = Mutex.new
31 @active = false
32 @timeout = timeout
33
34 @handler = RailsFCGIHandler.new
35 @handler.extend DRbUndumped
36
37 message 'opening socket'
38 DRb.start_service("drbunix:#{@socket}", self)
39
40 message 'entering process loop'
41 @handler.process! self
42 end
43
44 def each_cgi(&cgi_block)
45 @cgi_block = cgi_block
46 message 'entering idle loop'
47 loop do
48 sleep @timeout rescue nil
49 die! unless @active
50 @active = false
51 end
52 end
53
54 def process(env, input)
55 message 'received request'
56 @mutex.synchronize do
57 @active = true
58
59 message 'creating input stream'
60 input_stream = StringIO.new(input)
61 message 'building CGI instance'
62 cgi = RemoteCGI.new(eval(env), input_stream)
63
64 message 'yielding to fcgi handler'
65 @cgi_block.call cgi
66 message 'yield finished -- sending output'
67
68 cgi.stdoutput.seek(0)
69 output = cgi.stdoutput.read
70
71 return output
72 end
73 end
74
75 def die!
76 message 'shutting down'
77 DRb.stop_service
78 FileUtils.rm_f @socket
79 Kernel.exit 0
80 end
81 end
82
83 socket_path = ARGV.shift
84 timeout = (ARGV.shift || 90).to_i
85
86 Listener.new(timeout, socket_path)