Here is a patch against Moonwolf’s excellent ruby-fcgi-0.8.2, inspired by
ahoward’s mod_fcgi.
The principle changes are:
(1) Added an FCGI::each_cgi method
#!/usr/bin/ruby
require “fcgi”
FCGI.each_cgi {|cgi|
name = cgi[‘name’][0]
puts cgi.header
puts "You are #{name} " if name
puts “Connecting from #{cgi.remote_addr}”
}
The above code runs without modification under FastCGI, as a standalone CGI,
and from the keyboard. (I’d be interested to know if it runs under mod_ruby
too). It also handles SIGPIPE and SIGUSR1, see below.
(2) In the C version, added a dummy FCGI::Stream#binmode (this is needed
because the standard CGI library calls stdinput.binmode when processing POST
data)
(3) Fixed mod_fcgi’s flushing of the previous request when using POST. It
turns out that constants CGI_PARAMS/CGI_COOKIES are created under the ::CGI
module, not under ::FCGI::CGI
(4) Sorted out signal handling in the C library, and as a side effect made
it not block threads. It now calls rb_thread_select before FCGX_Accept_r.
There is a fairly detailled description of how signal handling works in the
attached patch as ext/fcgi/README.signals. But now, a SIGUSR1 during
FCGI::each_cgi will either process a request in its entirety, or not at all.
If you want protection from SIGTERM or other signals then you should install
your own handler for the duration of the request, e.g.
FCGI.each_cgi {|cgi|
trap(‘SIGTERM’) { exit_please = true }
… do stuff
trap(‘SIGTERM’,‘DEFAULT’)
break if exit_please
end
In principle, it may now be possible to run multiple FastCGI threads in a
single process, by starting a new thread after each FCGI::accept call. I
have not tried this.
Talking of testing, plenty is needed. I have run this under FreeBSD-4.7 and
Solaris-2.8 using the C library (fcgi-2.4.0). But I have not used the
pure-Ruby version at all, as I don’t have stringIO, and I have not tried any
other OS including Windows. Neither have I tested under any version of Ruby
other than 1.6.8, and it’s possible there have been changes to the cgi.rb
library.
Enjoy…
Brian.
ruby-fcgi-0.8.2.patch.gz (3.4 KB)