sinatraをcgiで動かした

軽量フレームワークsinatraが熱い。

確かに、個人で作ってるサイトではRailsは設定が大変だし、動いてももっさりだし。ということで、さくらのレンタルサーバsinatraを動作させてみました。
オフィシャルページ(Sinatra)にはcgiで動作させるためのドキュメントが一切ないのには参りましたね。

インストール

gem install で一発インストールできますが、デフォルトだとsinatra-0.9.2, Rack-1.0.0 がインストールされました。
ですが、Rack-1.0.0だと不具合があるので、別途Rack-0.9.1をインストールしておきます。

gem install sinatra
gem install rack --version='0.9.1'
Rackの設定

Rackはwebサーバの違いを吸収してくれるライブラリで、こいつのおかげでSinatraはいろんなサーバ上で動作できるのですが、cgiで動作させるには設定が必要です。
ここではアプリの本体とはファイルを分けておきます。

File Edit Options Buffers Tools Help
#!/usr/local/bin/ruby

load 'start.rb'

set :run, false
Rack::Handler::CGI.run Sinatra::Application
sinatraアプリ本体

アプリ本体は以下のような感じ。gemを使うためのPATHの設定は環境に合わせて。

  • start.rb
#!/usr/local/bin/ruby

$LOAD_PATH.push("/home/user/lib")
$LOAD_PATH.push("/home/user/lib/ruby")
ENV['GEM_HOME'] ||= '/home/user/lib/ruby/gem'

require 'rubygems'
require 'sinatra'

get '/?' do
  'Hello Sinatra World!'
end

get '/test/?' do
  'test'
end
エラーの回避

さて、これでウェブブラウザからアクセスすると、 Internal Server Error になります。

$GEM_HOME/gems/rack-0.9.1/lib/rackのrequest.rbを修正します。

  • request.rb
           #@env["rack.input"].rewind 
           # ↑を↓に変更
           begin
             @env["rack.input"].rewind if @env["rack.input"].respond_to?(:rewind)
           rescue Errno::ESPIPE
           end

これでブラウザからアクセスすると Hello Sinatra World! が表示されます。

URLのリダイレクト

さて、'/?'にアクセスすることはできたのですが、'/test/?'にアクセスしてみると、エラーになります。'/test/?'にアクセスするためには 'index.cgi/test'とurlを指定しないといけません。
.htaccessを作成し、'/test/?'を'index/test'にリダイレクトしましょう。

RewriteEngine On
RewriteBase /lab/sinatra
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) index.cgi/$1 [L]

再度ブラウザからアクセスすると、無事'hello'が表示されました!

これでsinatraの設置は完了です。軽量フレームワークといっても、それなりにはまりどころがありました。

訂正

当初はRack-1.0.0のまま動作させてましたが、multipart/form-data のpostでエラーになり、Rack-0.9.1にしたところ動作しましたので記述を変更しました。