[#46033] cgi をするときのデバック方法について — Nobuyuki Inaba <nobuyuki.inaba@...>

稲葉と申します。

15 messages 2009/05/22
[#46034] Re: cgi をするときのデバック方法について — rubikitch@... 2009/05/23

From: Nobuyuki Inaba <nobuyuki.inaba@gmail.com>

[ruby-list:46045] Re: cgi をするときのデバック方法について

From: Shigeru SUZUKA <shige.pc@...>
Date: 2009-05-31 13:24:43 UTC
List: ruby-list #46045
初めまして。 鈴鹿と申します。


CGI のソースを読んでみました。
# ruby -v => ruby 1.8.7 (2008-08-11 patchlevel 72) [i386-mswin32]


irbで CGI.new したときに起動するモードですが、
read_from_cmdline メソッドで実装されていました。
irb から起動した場合、HTTPヘッダの読み取りなどを飛ばして、フォームデータのパース処理が
実行されるようです。


また、ファイルアップロードですが、フォームのデータが、マルチパートでなければなりません。
マルチパートにするには、HTTPヘッダに 「Content-Type: multipart/form-data; ・・・」 が
必要なのですが、irb で CGI.new した後には、これを指定することができません。

CGI.new する前に、
 ENV['REQUEST_METHOD'] = "POST"
 ENV['CONTENT_TYPE'] = "multipart/form-data; boundary=・・・"
とすれば、マルチパートの処理になりますが、
このモードではread_from_cmdline メソッドが使用されず、通常のCGIの動作になります。


ですので、自前でCGIの動作を模倣する必要があると思います。
模倣するソースコードを書いてみましたので、参考にしていただけたらと思います。
# irb でテストするのにはあまり向いていなさそうですけど。

申し訳ないですが長くなりますので、マルチパートの仕組みついては割愛させていただきます。
とりあえず、boundary に設定されている文字列が、アップロードするファイルに含まれないように
することだけ気をつけてください。


以下、ソースコードです。

require 'cgi'
require 'stringio'


boundary="boundary"


# フォームデータ
formdata = ""
formdata << <<EOS.gsub("\n", CGI::EOL)
--#{boundary}
Content-Disposition: form-data; name="test"

test
EOS

formdata << <<EOS.gsub("\n", CGI::EOL)
--#{boundary}
Content-Disposition: form-data; name="file"; filename="testfile.txt"
Content-Type: text/plain

EOS

formdata << <<EOS
test file
test data
test text
EOS

formdata << <<EOS
--#{boundary}--"
EOS


# HTTPのヘッダを環境変数に設定
ENV['REQUEST_METHOD'] = "POST"
ENV['CONTENT_TYPE'] = "multipart/form-data; boundary=#{boundary}"
ENV['CONTENT_LENGTH'] = formdata.size.to_s


# 標準入力がフォームのデータを返すようにする
$stdin = StringIO.new(formdata)


# CGIを動かす
# ここでCGIのプログラムを require すればいいとおもいます
cgi = CGI.new

p cgi.params

puts "[test]"
puts "filename: " + cgi.params["test"][0].original_filename
puts "content type: " + cgi.params["test"][0].content_type
puts cgi.params["test"][0].read

puts
puts "[file]"
puts "filename: " + cgi.params["file"][0].original_filename
puts "content type: " + cgi.params["file"][0].content_type
puts cgi.params["file"][0].read




2009/05/23 7:42 Nobuyuki Inaba <nobuyuki.inaba@gmail.com>:
> 稲葉と申します。
>
> require 'cgi'
> form = CGI.new
> などと記述して
> ruby でcgiを組んでいます。
>
> 色々わからないなりにやっています。
>
> それで、デバッグ等で、「irb」がとても役に立って助かっています。
> <input type=hidden name=pass value=”test">
> などと言う場合
> コンソールから、
> pass=test
> ^d
> などと入れて本当に助かっていますが、
>
> <input type="FILE" name="ffile2" size="50">
> と言う場合、どうすればいいかわかりません。
>
> 何か方法はあるかと思いますが、なかなか見つけられませんでした。
> すみませんが、こう言う場合、どうしているか教えていただけないでしょうか?
>
> また、もっといいのがあれば教えて欲しいとも思います。
>
>



-- 
Shigeru SUZUKA
shige.pc@gmail.com

In This Thread