views:

856

answers:

4

(Bear with me, I promise this gets to shebang and windows.)

I have about the simplest of WEBRick servers put together:

require 'webrick'
include WEBrick

s = HTTPServer.new(:Port=>2000, :DocumentRoot=>Dir::pwd)
s.start

Couldn't be simpler. This basic server does accept http connections (firefox, internet exploder, wget, TELENT) and deals with them appropriately, as long as I'm just fetching static documents. If, however, I set one of the files in the directory to have a .cgi extension, I get a 500 back and the following on the server's terminal:

ERROR CGIHandler: c:/rubyCGI/test.cgi: 
C:/...[snip]...webrick/httpservlet/cgi_runner.rb:45: in 'exec': Exec format error - ...[snip]...

I've done a few things on the command line to mimic what is going on in line 45 of cgi_runner.rb

c:\>ruby
exec "c:/rubyCGI/test.cgi"
^Z
(same error erupts)

c:\>ruby
exec "ruby c:/rubyCGI/test.cgi"
^Z
Content-type: text/html

Mares eat oats and does eat oats and I'll be home for Christmas.

Clearly, WEBrick hasn't been cleared for landing on windows. Your usual headaches of corporate paranoia prevent me from modifying webrick, so can I get the shebang notation in c:/rubyCGI/test.cgi recognized by the OS (windows) so I don't have to explicitly tell it each time which interpreter to use? I could assign all .cgi files to be associated with ruby, but that would be limiting in the long run.

UPDATE: Since posting this, it has occurred to me that it may not be possible at all to run a cgi web server from ruby; ruby has no forking support. With no ability to fork a process, a cgi server would have to execute each cgi script one-at-a-time, neglecting all concurrent requests while the first one completed. While this may be acceptable for some, it would not work for my application. Nevertheless, I would still be very interested in an answer to my original question—that of getting shebang working under windows.

+2  A: 

I think what you want is to associate the file extension with Ruby. I don't think it's possible to get the !# notation to work on Windows but it is possible to get Windows to automatically launch a script with a particular interpreter (as in your second example). A good step by step discussion of what you'd want to do is here. You specifically want the section headed: "To create file associations for unassociated file types". I think that will accomplish what you're trying to do.

Onorio Catenacci
A: 

Not really to argue... but why bother webrick when mongrel is much faster and with native compiled with windows? And of coz, that means no shebang is needed.

goodwill
A: 

A generic solution that works for both Ruby 1.8.6.pxxx and 1.9.1.p0 on Windows is the following:

Edit the file: c:\ruby\lib\ruby\1.9.1\webrick\httpservlet\cgi_runner.rb

Add the following lines at the top of the file:

if "1.9.1" == RUBY_VERSION
  require 'rbconfig'  #constants telling where Ruby runs from
end

Now, locate the last line where is says: exec ENV["SCRIPT_FILENAME"] Comment that line out and add the following code:

# --- from here ---
if "1.9.1" == RUBY_VERSION  #use RbConfig
  Ruby = File::join(RbConfig::CONFIG['bindir'],
                        RbConfig::CONFIG['ruby_install_name'])
  Ruby << RbConfig::CONFIG['EXEEXT']
else                        # use ::Config
  Ruby = File::join(::Config::CONFIG['bindir'],
                        ::Config::CONFIG['ruby_install_name'])
  Ruby << ::Config::CONFIG['EXEEXT']
end

if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
  exec "#{Ruby}", ENV["SCRIPT_FILENAME"]
else
  exec ENV["SCRIPT_FILENAME"]
end
# --- to here ---

Save the file and restart the webrick server.

Explanation: This code just builds a variable 'Ruby' with the full path to "ruby.exe", and (if you're running on Windows) it passes the additional parameter "c:\ruby\bin\ruby.exe" , to the Kernel.exec() method, so that your script can be executed.

A: 

Actually, it is possible to get Windows to recognize shebang notation in script files. It can be done in a relatively short script in say, Ruby or AutoIt. Only a rather simple parser for the first line of a script file is required, along with some file manipulation. I have done this a couple times when either cross-compatibilty of script files was required or when Windows file extensions did not suffice.

totochto