- ベストアンサー
Rubyでファイル転送
Rubyでファイル転送のcgiを作成してみましたが動作しません。 実行後は選択したファイル(aa.jpg等)が作成されますが、 容量がゼロです。(FTPで確認) Apacheエラー------ undefined local variable or method `input'for main:Object(NameError) 変数nameはファイル名であり、c:\等は含まれていません。 ruby1.8.2------ #!/usr/bin/ruby -Ku print "Content-type: text/html\n\n" require "cgi" require 'net/ftp' input = CGI.new.params; cgi = CGI.new $name = input["name"][0] if input["name"][0] open("/home/movies/#{$name}","w") do |fh| fh.binmode fh.write imput['name'][0].read end end html------ <form action="***" method="get" enctype="multipart/form-data"> <input type="file" name="name" size="30"> <input type="submit" name="regist" value="選択"></form>
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
open のブロックの中で fh.write の引数に使われてるのが 'input' じゃなくて 'imput' になってるのは 単にここに書いたときの間違いですか? Apacheのログに undefined local ... ってあるんだから これでなくても同様のtypoだったりしませんか?
その他の回答 (5)
- notnot
- ベストアンサー率47% (4900/10358)
#3です。 HTMLをちゃんと見てなかった。form を method="POST" にしてください。
補足
ご回答ありがとうございます。 下記のようなエラーが出ました。調査してみます。 /usr/lib/ruby/1.8/cgi.rb:981:in `read_multipart': no content body (EOFError) from /usr/lib/ruby/1.8/cgi.rb:1108:in `initialize_query' from /usr/lib/ruby/1.8/cgi.rb:2274:in `initialize' from /home/www/prog/test.cgi:5:in `new' from /home/www/prog/test.cgi:5 ---test.cgi #!/usr/bin/ruby -Ku print "Content-type: text/html\n\n" # require "cgi" input = CGI.new.params; cgi = CGI.new if input["regist"][0] open("/home/movies/outfile","wb") do |fh| fh.write CGI.new.params["name"].read end end puts <<-"EOB" <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title></title> </head> <body> <form action="test.cgi" method="POST" enctype="multipart/form-data"> <input type="file" name="name" size="30"> <input type="submit" name="regist" value="選択"></form> </body></html> EOB
- sakusakerZ
- ベストアンサー率25% (1/4)
あれ? ruby のバージョンは1.8.2なんですよね(これもちょっと古いですけど)。 cgi - Rubyリファレンスマニュアル http://www.ruby-lang.org/ja/man/html/cgi.html#footmark-2 にある 1.8以降の cgi.rbの動作じゃないような気がするんですが。
補足
ご回答ありがとうございます。 #ruby -v ruby 1.8.5 (2006-08-25) [i486-linux] 新規で1.8をインストールしたもので、 1.6からのアップデートはしておりません。
- sakusakerZ
- ベストアンサー率25% (1/4)
>readメソッドが定義されていませんと表示されました。 #3の回答にあるスクリプトの input = CGI.new.params["name"][0] を input = CGI.new.params["name"] と変えるとどうなりますか? if の判定も変更しないといけないような気がするけどとりあえず。
補足
undefined method `read' for ["aa.jpg"]:Array (NoMethodError) となりました。 質問文のhtmlはcgiで生成しているもので、同一ファイルでしたが、 これをcgi部とhtml部の2つのファイルに分けて試したところ、 cgiファイルが開きませんでした。 (104)Connection reset by peer: ap_content_length_filter: apr_bucket_read() failed こちらが原因かも分かりませんので、調べています。
- notnot
- ベストアンサー率47% (4900/10358)
htmlを見る限り、ファイル転送じゃなくファイルタイプのinputタグを使ったファイルのアップロードをしたいと思われます。 従って、'net/ftp' は関係ありません。 参考にしたスクリプトが悪いのかな? #!/usr/bin/ruby -Ku print "Content-type: text/html\n\n" require "cgi" input = CGI.new.params["name"][0] if input open("/home/movies/outfile","wb") do |fh| fh.write input.read end end アップロードしたクライアント側のファイル名は、 value.original_filename ですが、これをそのままサーバー側のファイル名に使ったりすると脆弱性(セキュリティーホール)になって、システムを壊される危険があります。表示する程度なら良いですが、ファイル名としては使えません。
補足
ご回答ありがとうございます。 readメソッドが定義されていませんと表示されました。 undefined method `read' for "aa.jpg":String (NoMethodError)
- sakusakerZ
- ベストアンサー率25% (1/4)
>undefined method `read' for "aa.jpg":String (NoMethodError) input['name'][0] は文字列(で、内容が'aa.jpg')なのでそれに readメソッドはありません。 ここでaa.jpg というファイルの内容を持って来たいのなら 読み込んでこないと。 Windows でなければ IO.read(input['name'][0]) でいいと思いますがこれだとバイナリモードとかの指定ができないので、 File.open(input['name'][0], 'rb'){|rh| rh.read} とかでしょうか。
補足
File.open(input['name'][0], 'rb'){|rh| rh.read } により、取得を行いましたが、 No such file or directory - aa.htmlとなります。 input['name'][0]を"D:\aa.html"へ変更しても No such file or directory - D:\aa.htmlとなります。 おそらくサーバ上(linux)のD:\aa.htmlを参照していると思いますが、 これをクライアントの参照にするにはどのようにすればよろしいでしょうか?
補足
ご回答ありがとうございます。 fh.write imput['name'][0].readを fh.write input['name'][0].readへ訂正したところ、 undefined method `read' for "aa.jpg":String (NoMethodError) となりました。 readメソッドが定義されていないエラーだと思われますが、 require "cgi"では不十分なのでしょうか?