monoの開発ブログ

Rack 1.1.0をCGIで動作させる場合にPOSTが使えない問題への対処

RackをCGIとして使うときにPOSTで生じる問題は以前から存在していましたが、1.1.0では以前と同じ対処法が使えなかったのでメモしておきます。SinatraやRamazeもRackベースなのでこの対処法で動作するようになると思います。

この内容をrack_fix.rbなどとして保存しておいて、rack本体より後でrequireすればエラーを抑止することができます。

module Rack  class Request    def POST      if @env["rack.input"].nil?        raise "Missing rack.input"      elsif @env["rack.request.form_input"].eql? @env["rack.input"]        @env["rack.request.form_hash"]      elsif form_data? || parseable_data?        @env["rack.request.form_input"] = @env["rack.input"]        unless @env["rack.request.form_hash"] = parse_multipart(env)          form_vars = @env["rack.input"].read          # Fix for Safari Ajax postings that always append \0          form_vars.sub!(/\0\z/, '')          @env["rack.request.form_vars"] = form_vars          @env["rack.request.form_hash"] = parse_query(form_vars)          begin            @env["rack.input"].rewind          rescue Lint::LintError          end        end        @env["rack.request.form_hash"]      else        {}      end    end  endend

rewind時に飛ぶ例外を握りつぶしているのは以前と同じですが、1.1.0では例外の種類がこれまでのErrno::ESPIPEからRack::Lint::LintErrorに変更されたようなので対応しています。Rack::Lint::LintErrorは広く利用されているので握りつぶしていいのか微妙なところですが、今のところ問題は起きていません。