Ramaze を CGI として動かす

プロジェクト(scratch)作成

ramaze --create scratch --adapter cgi

--adapter cgiとしても、生成されるのはWebrick用のソースである。

public/dispatch.cgi を作成

#!/usr/bin/env ruby

require 'rubygems'
require 'ramaze'

Ramaze::Log.loggers = [ Ramaze::Logger::Informer.new( __DIR__("../ramaze.log") ) ]
Ramaze::Global.adapter = :cgi

$ramaze_0 = __DIR__("../start.rb")
alias $0 $ramaze_0

Dir.chdir File.dirname($0)
load File.basename($0)

なんで、 $0 = __DIR__("../start.rb") ではないのかというと、ディレクトリのフルパスが長すぎる(例えば /path/to/very/long/path )と $0 に格納したら、途中で切れて( /path/to/ve )しまうからだ。

[ruby-dev:29124] Re: [ BUG ] $0 cannot keep the given string - no...@ruby-lang.org - org.ruby-lang.ruby-dev - MarkMail

なお、start.rb と同じフォルダに chdir してから start.rb に制御を移さないと、なぜか "no such action: /page" というエラーになってしまう。

(追記)今はもっとシンプルに書いて、こうしている。

#!/usr/bin/env ruby

# Go to application directory.
Dir.chdir(File.dirname($0))
Dir.chdir("..")

require 'rubygems'
require 'ramaze'

Ramaze::Log.loggers = [ Ramaze::Logger::Informer.new("ramaze.log") ]
Ramaze::Global.adapter = :cgi

$0 = "start.rb"
load $0

start.rb を編集

Ramaze.start :adapter => :webrick, :port => 7000
となっているのを単に、
Ramaze.start
としてやる。

public/.htaccess作成

RewriteEngine on
RewriteRule ^(.*)$ dispatch.cgi [QSA,L]

Illegal seek エラー?

なんかエラーになった!

Errno::ESPIPE - Illegal seek

原因箇所は:

/opt/local/lib/ruby/gems/1.8/gems/rack-0.9.1/lib/rack/request.rb:
  in rewind @env["rack.input"].rewind if @env["rack.input"].respond_to?(:rewind)

これは、

$ ruby -e "IO.pipe[0].rewind"   
-e:1:in `rewind': Illegal seek (Errno::ESPIPE)
        from -e:1

としたのと同じこと。 CGI Adapter はあんまりテストされていないのかな…。とりあえず、

Index: request.rb
===================================================================
--- request.rb	(revision 6)
+++ request.rb	(working copy)
@@ -113,7 +113,9 @@
             Utils::Multipart.parse_multipart(env)
           @env["rack.request.form_vars"] = @env["rack.input"].read
           @env["rack.request.form_hash"] = Utils.parse_query(@env["rack.request.form_vars"])
-          @env["rack.input"].rewind if @env["rack.input"].respond_to?(:rewind)
+          begin
+            @env["rack.input"].rewind if @env["rack.input"].respond_to?(:rewind)
+          rescue Errno::ESPIPE; end
         end
         @env["rack.request.form_hash"]
       else

という風に直して、

再度アクセスする

http://localhost/path/to/scratch/public/

めでたく成功〜。

Welcome to Ramaze!

Ramaze is working correctly with this application, now you can start working.

Intel Core2Duo 2.1GHz のマイマシンで、実行時間は約 0.3 秒だった。実際アプリを組めばさらに時間がかかるだろうが、これなら十分CGIとして動かせそうである。

$ command time ./scratch/public/dispatch.cgi < /dev/null > /dev/null
        0.29 real         0.23 user         0.05 sys