Revising dispatch.cgi to run Rails applications?

Hi,

I am trying to set up Ruby on Rails with FastCGI for Apache 2 on
Linux. I am followoing instructions here –
http://it.kndb.net/entry/show/id/79.
But step 4 is confusing me. It reads:

  1. Revise various setting file
    Basically, confirm that mod_fcgi module of Apache is available and
    change dispatch.cgi into dispatch.cgi at the .htaccess of Rails
    application to run Ruby on Rails.

It does not elaborate further. What does the above mean? How do I
modify the .htaccess/dispatch.cgi file?

Thanks, - Dave

[email protected] wrote:

  1. Revise various setting file
    Basically, confirm that mod_fcgi module of Apache is available and
    change dispatch.cgi into dispatch.cgi at the .htaccess of Rails
    application to run Ruby on Rails.

It does not elaborate further. What does the above mean? How do I
modify the .htaccess/dispatch.cgi file?

Thanks, - Dave

Does this help? I use mod_fcgid instead of mod_fcgi but I believe this
will be somewhat similar to what you need.

$ cat .htaccess

General Apache options

#AddHandler fastcgi-script .fcgi
Options +FollowSymLinks +ExecCGI +Includes
AddHandler fcgid-script .fcgi
#AddHandler cgi-script .cgi

If you don’t want Rails to look in certain directories,

use the following rewrite rules so that Apache won’t rewrite certain

requests

Example:

RewriteCond %{REQUEST_URI} ^/notrails.*

RewriteRule .* - [L]

Redirect all requests not available on the filesystem to Rails

By default the cgi dispatcher is used which is very slow

For better performance replace the dispatcher with the fastcgi one

Example:

RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]

RewriteEngine On

If your Rails application is accessed via an Alias directive,

then you MUST also set the RewriteBase in this htaccess file.

Example:

Alias /myrailsapp /path/to/myrailsapp/public

RewriteBase /myrailsapp

RewriteRule ^$ index.html [QSA]
RewriteRule ^([^.]+)$ $1.html [QSA]
RewriteCond %{REQUEST_FILENAME} !-f
#RewriteRule ^(.)$ dispatch.cgi [QSA,L]
RewriteRule ^(.
)$ dispatch.fcgi [QSA,L]

In case Rails experiences terminal errors

Instead of displaying this message you can supply a file here which

will be rendered instead

Example:

ErrorDocument 500 /500.html

ErrorDocument 500 “

Application error

Rails application failed to
start properly”

$ cat dispatch.fcgi
#!/usr/bin/ruby

You may specify the path to the FastCGI crash log (a log of unhandled

exceptions which forced the FastCGI instance to exit, great for

debugging)

and the number of requests to process before running garbage

collection.

By default, the FastCGI crash log is RAILS_ROOT/log/fastcgi.crash.log

and the GC period is nil (turned off). A reasonable number of

requests

could range from 10-100 depending on the memory footprint of your app.

Example:

# Default log path, normal GC behavior.

RailsFCGIHandler.process!

# Default log path, 50 requests between GC.

RailsFCGIHandler.process! nil, 50

# Custom log path, normal GC behavior.

RailsFCGIHandler.process! ‘/var/log/myapp_fcgi_crash.log’

require File.dirname(FILE) + “/…/config/environment”
require ‘fcgi_handler’

RailsFCGIHandler.process!

Thanks for this. I’m still having some issues. Would you mind
posting your httpd.conf file, or at least the parts that pertain to
RoR?

Again, I appreciate your help, - Dave

On Jan 15, 9:03 pm, James B. [email protected]

[email protected] wrote:

Thanks for this. I’m still having some issues. Would you mind
posting your httpd.conf file, or at least the parts that pertain to
RoR?

The setup given below is tested and works. However, it is for Apache
2.0.x and not for Apache 2.2.x and is for fcgid and not fcgi. Also, I
use ssl even in development so that this configuration is for https.
You can remove all the ssl stuff and the rewrties used to force ssl but
I am providing you with a working configuration so I am not going to
guess at what parts I can remove safely. If I have missed something
significant then please forgive me, I set all this up more than a year
ago.

Generally, I do not modify conf/httpd.conf, I split things out into
functionally distinct configuration files that I then place in conf.d or
virtual.d as appropriate and which are loaded by these conf/httpd.conf
directives:

Load config files from the config directory “/etc/httpd/conf.d”.

Include conf.d/*.conf

2007 March 07 - Load virtual server config files from

/etc/httpd/virtual.d
Include virtual.d/*.conf

However, setup for mod_fcgid is an exception to this, probably because I
did it a very long time ago and have changed styles since. The entry I
presently have in httpd.conf for this is:

2005 Mar 04 JBB8 - added mod_fcgid

LoadModule fcgid_module modules/mod_fcgid.so

AddHandler fcgid-script .fcgi
SocketPath /tmp/fcgid_sock
IdleTimeout 3600
ProcessLifeTime 7200
MaxProcessCount 8
DefaultMaxClassProcessCount 2
IPCConnectTimeout 8
IPCCommTimeout 60

Pay attention to directives that may be wrapped across lines by the
message editor. In conf.d I have this:

$ cat conf.d/ruby_rails.conf

BOF

2006 Mar 04 JBB8 - added mod_ruby

LoadModule ruby_module modules/mod_ruby.so

ClearModuleList

RubyRequire apache/ruby-run RubySafeLevel 0

For rails

<Files *.rb>
SetHandler ruby-object
RubyHandler Apache::RubyRun.instance

Execute files under /ruby as Ruby scripts

<Location /ruby>
SetHandler ruby-object
RubyHandler Apache::RubyRun.instance

Execute *.rbx files as Ruby scripts

<Files *.rbx>
SetHandler ruby-object
RubyHandler Apache::RubyRun.instance

for eruby

RubyRequire apache/eruby-run

Handle files under /eruby as eRuby files

<Location /eruby>
SetHandler ruby-object
RubyHandler Apache::ERubyRun.instance

Handle *.rhtml files as eRuby files

<Files *.rhtml>
SetHandler ruby-object
RubyHandler Apache::ERubyRun.instance

<Directory /var/www/eruby>
Options ExecCGI

EOF

In virtual.d I have:

$ cat virtual.d/ca.harte-lyne.testheart.conf

BOF

ca.harte-lyne.testheart.conf 2007 Mar 21 James B. Byrne JBB8

This configuration file forces users to connect via SSL

If the incoming request is already https:// then the

directives contained below in the section

will apply. Note that ssl requires IP addressed virtual hosts

to work and that the necessary Listen directives must be placed

in the appropriate configuration files as well.

These modules are required for Rails applications

<IfModule !mod_rewrite.c>
LoadModule rewrite_module modules/mod_rewrite.so

<IfModule !mod_env.c>
LoadModule env_module modules/mod_env.so

This is the http site configuration

<VirtualHost 216.185.71.101:80>
SetEnv RAILS_ENV development
ServerName testheart.harte-lyne.ca
DocumentRoot
/home/byrnejb/Software/Development/Projects/theheart/public
ErrorLog
/home/byrnejb/Software/Development/Projects/theheart/log/testheart_error.log
LogLevel warn
TransferLog
/home/byrnejb/Software/Development/Projects/theheart/log/testheart_access.log

RewriteEngine on
RewriteLog
home/byrnejb/Software/Development/Projects/theheart/log/theheart_rewrite.log

RewriteLogLevel 0=off 1=basic 2=verbose 3+=module developer debuging

RewriteLogLevel 0

Force SSL

RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^(..)?(…+.)(…+)$ [NC]
RewriteRule (^.
$) https://%1%2%3/ [L,R]

SSL virtual host configuration

<VirtualHost 216.185.71.101:443>
SetEnv RAILS_ENV development
ServerName testheart.harte-lyne.ca
DocumentRoot
/home/byrnejb/Software/Development/Projects/theheart/public
ErrorLog
/home/byrnejb/Software/Development/Projects/theheart/log/testheart_ssl_error.log
LogLevel warn
TransferLog
/home/byrnejb/Software/Development/Projects/theheart/log/testheart_ssl_access.log

RewriteEngine on
RewriteLog
home/byrnejb/Software/Development/Projects/theheart/log/theheart_ssl_rewrite.log

RewriteLogLevel 0=off 1=basic 2=verbose 3+=module developer debuging

RewriteLogLevel 0

SSL Engine Switch:

Enable/Disable SSL for this virtual host.

SSLEngine on
SSLOptions +StrictRequire

SSL Cipher Suite:

List the ciphers that the client is permitted to negotiate.

See the mod_ssl documentation for a complete list.

SSLCipherSuite
ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP

Server Certificate:

Point SSLCertificateFile at a PEM encoded certificate. If

the certificate is encrypted, then you will be prompted for a

pass phrase. Note that a kill -HUP will prompt again. A test

certificate can be generated with `make certificate’ under

built time. Keep in mind that if you’ve both a RSA and a DSA

certificate you can configure both in parallel (to also allow

the use of DSA ciphers, etc.)

SSLCertificateFile /usr/share/ssl/certs/theheart-cert.pem

Server Private Key:

If the key is not combined with the certificate, use this

directive to point at the key file. Keep in mind that if

you’ve both a RSA and a DSA private key you can configure

both in parallel (to also allow the use of DSA ciphers, etc.)

SSLCertificateKeyFile /usr/share/ssl/private/theheart-key.pem

Server Certificate Chain:

or wiki.anything.tld and www.wiki.anything.tld

Point SSLCertificateChainFile at a file containing the

concatenation of PEM encoded CA certificates which form the

certificate chain for the server certificate. Alternatively

the referenced file can be the same as SSLCertificateFile

when the CA certificates are directly appended to the server

certificate for convinience.

#SSLCertificateChainFile /etc/httpd/conf/ssl.crt/ca.crt

Certificate Authority (CA):

Set the CA certificate verification path where to find CA

certificates for client authentication or alternatively one

huge file containing all of them (file must be PEM encoded)

Note: Inside SSLCACertificatePath you need hash symlinks

to point to the certificate files. Use the provided

Makefile to update the hash symlinks after changes.

SSLCACertificateFile /usr/share/ssl/certs/ca-bundle.crt

Certificate Revocation Lists (CRL):

Set the CA revocation path where to find CA CRLs for client

authentication or alternatively one huge file containing all

of them (file must be PEM encoded)

Note: Inside SSLCARevocationPath you need hash symlinks

to point to the certificate files. Use the provided

Makefile to update the hash symlinks after changes.

#SSLCARevocationPath /etc/httpd/conf/ssl.crl
#SSLCARevocationFile /etc/httpd/conf/ssl.crl/ca-bundle.crl

Client Authentication (Type):

Client certificate verification type and depth. Types are

none, optional, require and optional_no_ca. Depth is a

number which specifies how deeply to verify the certificate

issuer chain before deciding the certificate is not valid.

#SSLVerifyClient require
#SSLVerifyDepth 10

Access Control:

With SSLRequire you can do per-directory access control based

on arbitrary complex boolean expressions containing server

variable checks and other lookup directives. The syntax is a

mixture between C and Perl. See the mod_ssl documentation

for more details.

#
#SSLRequire ( %{SSL_CIPHER} !~ m/^(EXP|NULL)/ \

and %{SSL_CLIENT_S_DN_O} eq “Snake Oil, Ltd.” \

and %{SSL_CLIENT_S_DN_OU} in {“Staff”, “CA”, “Dev”} \

and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5 \

and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20 ) \

or %{REMOTE_ADDR} =~ m/^192.76.162.[0-9]+$/

#

SSL Engine Options:

Set various options for the SSL engine.

o FakeBasicAuth:

Translate the client X.509 into a Basic Authorisation. This means

that

the standard Auth/DBMAuth methods can be used for access control.

The

user name is the `one line’ version of the client’s X.509

certificate.

Note that no password is obtained from the user. Every entry in

the user

file needs this password: `xxj31ZMTZzkVA’.

o ExportCertData:

This exports two additional environment variables: SSL_CLIENT_CERT

and

SSL_SERVER_CERT. These contain the PEM-encoded certificates of the

server (always existing) and the client (only existing when client

authentication is used). This can be used to import the

certificates

into CGI scripts.

o StdEnvVars:

This exports the standard SSL/TLS related `SSL_*’ environment

variables.

Per default this exportation is switched off for performance

reasons,

because the extesthearttion step is an expensive operation and is

usually

useless for serving static content. So one usually enables the

exportation for CGI and SSI requests only.

o StrictRequire:

This denies access when “SSLRequireSSL” or “SSLRequire” applied

even

under a “Satisfy any” situation, i.e. when it applies access is

denied

and no other module can change it.

o OptRenegotiate:

This enables optimized SSL connection renegotiation handling when

SSL

directives are used in per-directory context.

#SSLOptions +FakeBasicAuth +ExportCertData +CompatEnvVars +StrictRequire

<Files ~ “.(cgi|shtml|phtml|php[d]?|rb)$”>
SSLOptions +StdEnvVars

<Directory
“/home/byrnejb/Software/Development/Projects/theheart/public/”>
SSLOptions +StdEnvVars
Options ExecCGI FollowSymLinks
AddHandler cgi-script .cgi
AllowOverride All
Order allow,deny
Allow from All

Digest authentication for this site will be removed when application

authentication is integrated with the network ldap system. Use the

htdigest utility to maintain users in /etc/httpd/access.d/.htdigest

# AuthType Digest = userid + realm + md5 password hash AuthType Digest # The AuthName is the realm AuthName ca.harte-lyne.theheart AuthDigestDomain / AuthDigestFile /etc/httpd/access.d/.htdigest Require valid-user

SSL Protocol Adjustments:

The safe and default but still SSL/TLS standard compliant shutdown

approach is that mod_ssl sends the close notify alert but doesn’t

wait for

the close notify alert from client. When you need a different

shutdown

approach you can use one of the following variables:

o ssl-unclean-shutdown:

This forces an unclean shutdown when the connection is closed,

i.e. no

SSL close notify alert is send or allowed to received. This

violates

the SSL/TLS standard but is needed for some brain-dead browsers.

Use

this when you receive I/O errors because of the standard approach

where

mod_ssl sends the close notify alert.

o ssl-accurate-shutdown:

This forces an accurate shutdown when the connection is closed,

i.e. a

SSL close notify alert is send and mod_ssl waits for the close

notify

alert of the client. This is 100% SSL/TLS standard compliant, but

in

practice often causes hanging connections with brain-dead

browsers. Use

this only for browsers where you know that their SSL

implementation

works correctly.

Notice: Most problems of broken clients are also related to the HTTP

keep-alive facility, so you usually additionally want to disable

keep-alive for those clients, too. Use variable “nokeepalive” for

this.

Similarly, one has to force some clients to use HTTP/1.0 to

workaround

their broken HTTP/1.1 implementation. Use variables “downgrade-1.0”

and

“force-response-1.0” for this.

SetEnvIf User-Agent “.MSIE.
nokeepalive ssl-unclean-shutdown
downgrade-1.0 force-response-1.0

Per-Server Logging:

The home of a custom SSL log file. Use this when you want a

compact non-error SSL logfile on a virtual host basis.

CustomLog logs/ssl_request_log
“%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x “%r” %b”

EOF

Again, I appreciate your help, - Dave

You are most welcome. I am so often on the requesting side that it
gives me great pleasure to be able to assist someone else.

Regards,