Ruby で CGI > 送受信_フォームデータの扱い> 問題
<input type="text" name="messe" value=""> で入力された文章を表示する簡単な掲示板を作ってみてください
♪
♪
たぶん、一番シンプルな答え:html ファイル自体を書き換えてしまいます
#!/usr/local/bin/ruby -Ks
if /messe=([^&]+)(&|\z)/ =~ ENV['QUERY_STRING'].to_s then
messe = $1
messe.gsub!(/\+/," ") # URI デコード
messe.gsub!(/%[a-fA-F\d]{2}/){ $&[1,2].hex.chr } # URI デコード
messe.gsub!(/&/,"&") # XSS 対策
messe.gsub!(/&#(\d{2,4});/){ "&#" + $1 + ";" } # XSS 対策(一部解除)
messe.gsub!(/</,"<") # XSS 対策
messe.gsub!(/>/,">") # XSS 対策
messe.gsub!(/"/,""") # XSS 対策
messe.gsub!(/'/,"'") # XSS 対策
messe = "\n<p>" + messe + "</p><hr>" # htmlとして整える
html = open("index.html"){|f| f.read } rescue "<html><body><h1>Error!</h1></body></html>"
html.sub!(/<\/form>/){ $& + messe } # メッセージを挟み込む
open("index.html","w"){|f| f.print html } rescue 0 # html ファイルを書き換える
end
puts "Location: ./index.html" # html ファイルへジャンプ
puts
index.html
としました。本CGIと同じディレクトリ内に置きます。index.html
のモードを0666に書き換えてください
chmod 666 index.htmlこのモードは、「同じサーバーにログイン出来れば誰でも読み書きできる」という事を了解した上で使ってください。
rescue 0
としてありますLocation:
でジャンプしますページの雛形と、メッセージファイルを分離してみます。例えばこんなのでどうでしょうか
#!/usr/local/bin/ruby -Ks
LogFile = "messages.txt" # メッセージ保存ファイル
if /messe=([^&]+)(&|\z)/ =~ ENV['QUERY_STRING'].to_s then
messe = $1
messe.gsub!(/\+/," ") # URI デコード
messe.gsub!(/%[a-fA-F\d]{2}/){ $&[1,2].hex.chr } # URI デコード
messe.gsub!(/[\r\n\f\t\v\0]/,"") # 改行,改ページ,水平垂直タブ,隠し文字の削除
open(LogFile,"a"){|f| f.puts messe } rescue 0 # メッセージの追記保存
end
html = open("temp.html"){|f| f.read } rescue "<html><body><h1>Error!</h1></body></html>"
mes = open( LogFile ){|f| f.read } rescue "Error!" # メッセージファイルを開く
mes.gsub!(/&/,"&") # XSS 対策
mes.gsub!(/&#(\d{2,4});/){ "&#" + $1 + ";" } # XSS 対策(一部解除)
mes.gsub!(/</,"<") # XSS 対策
mes.gsub!(/>/,">") # XSS 対策
mes.gsub!(/"/,""") # XSS 対策
mes.gsub!(/'/,"'") # XSS 対策
mes.each do |line|
html.sub!(/<\/form>/){ $& + "\n<p>" + line.chomp + "</p><hr>" } # メッセージ付加
end
print <<HOGEHOGE
Content-Disposition: filename="bbs1.html"
Content-Length: #{ html.length }
Content-type: text/html;charset=Shift_JIS
HOGEHOGE
print html
touch messages.txt chmod 666 messages.txtなお、このモード0666のファイルは、同じサーバーにログイン出来る人なら誰でも読み書きできるので注意してください。
最新の20件だけを表示させたい場合は、例えば、ファイルを後ろから読み込むUNIXコマンドtailを使って、
#!/usr/local/bin/ruby -Ks
LogFile = "messages.txt" # メッセージ保存ファイル
if /messe=([^&]+)(&|\z)/ =~ ENV['QUERY_STRING'].to_s then
messe = $1
messe.gsub!(/\+/," ") # URI デコード
messe.gsub!(/%[a-fA-F\d]{2}/){ $&[1,2].hex.chr } # URI デコード
messe.gsub!(/[\r\n\f\t\v\0]/,"") # 改行,改ページ,水平垂直タブ,隠し文字の削除
open(LogFile,"a"){|f| f.puts messe } rescue 0 # メッセージの追記保存
end
html = open("temp.html"){|f| f.read } rescue "<html><body><h1>Error!</h1></body></html>"
mes = `tail -20 #{ LogFile }` rescue "Error!" # メッセージファイルを開く
mes.gsub!(/&/,"&") # XSS 対策
mes.gsub!(/&#(\d{2,4});/){ "&#" + $1 + ";" } # XSS 対策(一部解除)
mes.gsub!(/</,"<") # XSS 対策
mes.gsub!(/>/,">") # XSS 対策
mes.gsub!(/"/,""") # XSS 対策
mes.gsub!(/'/,"'") # XSS 対策
mes.each do |line|
html.sub!(/<\/form>/){ $& + "\n<p>" + line.chomp + "</p><hr>" } # メッセージ付加
end
print <<HOGEHOGE
Content-Disposition: filename="bbs1.html"
Content-Length: #{ html.length }
Content-type: text/html;charset=Shift_JIS
HOGEHOGE
print html
a = Array.new
n = 1
f = File.open((LogFile)
while line = f.gets do
a += [ sprintf("%02d. ",n) + line ]
n += 1
a.shift if a.size > 20
end
f.close
mes = a.join
以上です。