CGIプログラムを作ってみよう

CGIとは

Webページは通常固定的な内容のファイルを外部に対して配付するものである が、プログラムを起動した結果をWebコンテンツとして相手に送ることもできる。 CGIはその一つで Common Gateway Interface の略である。→ より詳しく

CGIの仕組み

基本は単純で、「Webサーバ(Apache等)が送るのと同じように データを出力」すれば良い。Webサーバがどういうデータを送っているか 実際に確認しよう。

  1. Webブラウザで simple.txtを見る。

  2. Webブラウザで「View → Page Source」してHTMLソースを確認する。

  3. ktermでWebサーバと直接お話しして実際にどんなやりとりがあるか 確認する。

    % telnet roy 80
    GET /simple.txt HTTP/1.0
    (Returnを2回)
    

    (こんな出力になる)

このうち、Content-type: .... の行と次の空行(ヘッダ) を含めて出力するようにするとCGIプログラムとなる。

簡単なCGIプログラム

現在の日付け・時刻を表示するだけのRubyプログラムは 以下のようになる。

date.rb

#!/usr/bin/env ruby
print Time.now, "\n"

1行目の #!/usr/bin/env ruby は、 マジックコードといい、Rubyインタプリタの起動方法をあらかじめシステムに 教え込ませるためのものであり、CGIとして利用する場合に必要となる。

これを、CGIプログラムとして動かすためには、ヘッダも出力するように 変更する。また、ファイル名の拡張子を .cgi とし、 そのファイルを~/public_htmlディレクトリに置く。

C-x C-f で、~/public_html/date.cgi を 開いて以下の通りに作成・保存する。

date.cgi

#!/usr/bin/env ruby
print "Content-type: text/plain\n\n"
print Time.now, "\n"

また、システムが直接Rubyプログラムを実行できるよう、ファイルに 実行属性をつける必要がある。実行属性は kterm で chmod コマンドを 利用して付与する。

% chmod +x ~/public_html/date.cgi

これで準備完了。date.cgi のURLをWebブラウザで 開いてみよう。101教室では

http://roy/~i2005xyz/date.cgi
(xyzは自分の番号)

となる。

入力を伴うCGIプログラム

CGIプログラムに何かの入力値を与えるためには、それを読み込んで プログラムを呼び出すHTMLファイルが必要となる。HTMLファイルで 値を読み込むためにはformタグを利用する。

先に体験

entry.html

<html>
<head>
<title>
URANAI?
</title>
</head>

<body>
<h1>いい加減な血液型占い!</h1>

<form method=POST action="./blood.cgi">
<p>あなたの血液型は?: 
<input name="btype" size="4">
</p>
<p><input type="submit" value="それ行け!">
<input type="reset" value="消去">
</p>
</form>

</body>
</html>

つぎに、blood.rbを元にCGIとして機能するように変更した blood.cgiを示す。

#!/usr/bin/env ruby
print "Content-type: text/plain; charset=EUC-JP\n\n"

require 'kconv'			# 漢字コード変換時に必要
x = Hash.new
method = ENV["REQUEST_METHOD"]
if /POST/i =~ method then
  length = ENV["CONTENT_LENGTH"].to_i
  query = STDIN.read(length)
elsif /GET/i =~ method then
  query = ENV["QUERY_STRING"]
else
  query = ARGV.join('&')
end
for unit in query.split(/\&/)
  if /^([a-z]+)=(.*)/ =~ unit
    key, value = $1, $2
    x[key] = value
    value.gsub!(/%(..)/){[$1.hex].pack("c")} # これでURLデコードが一発
    value = Kconv::toeuc(value)		     # EUCに変換
  end
end

# ここまではどんなCGIでもほぼ同じ
# 上記の処理により、HTMLで input name="hoge" の欄で
# 入力した値がRubyプログラムの変数 x['hoge'] に代入
# される。入力蘭が何個あっても全て入る。
# 以下 blood.cgi 特有の処理。

btype = x['btype']
if /ab/i =~ btype
  print "器用ですか?\n"
elsif /a/i =~ btype
  print "まめですか?\n"
elsif /b/i =~ btype
  print "熱血ですか?\n"
elsif /o/i =~ btype
  print "大きいですか?\n"
else
  print "まじめにやってね\n"
end

Rubyの学習について

Rubyのインストール

Rubyホームページの Ruby本体ダウンロードに進むと必要なファイルへのリンクがある。

質問の場

今回の講座に関する質問を出し、参加者同士で教えあって 理解を進めて行くためのメイリングリスト Unix2005-ML の入り方。

To: unix2005@e.koeki-u.ac.jp
Subject: subscribe

(自己紹介を本文に書く)

(送信形式は必ず「プレインテキスト」で)

Unix2005-ML参加者同士でやりたいこと。


(C)2005 OKOMA Lab. koeki-u.ac.jp