【Ruby/CGI】Webサーバとのやりとりに触れてみる

2016年2月20日Ruby

こんにちは、しきゆらです

今回は、RubyでCGIを作って動作させてみたいと思います

なおVirtualboxを使い、仮想環境下にCentOS7をインストールして行っています

 


 

 

Virtualbox、CentOS、httpdのインストールに関しては詳しいサイトがたくさんあるので略

 

httpd.conf

httpdの設定ファイルですね

インストールしたままではCGIを実行できないので、設定を変更していきます

# httpd.confの編集
sudo emacs /etc/httpd/conf/httpd.conf

# 145行目あたりの記述(/var/www/htmlディレクトリブの中) ExecCGIを追加
Options Includes FollowSymLinks ExecCGI

# 248行目あたりの記述 cgi-binではCGIを実行しないのでコメントアウト
# (文頭に「#」を追記)
#ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"

# 295行目あたりの記述 ~.rbをCGIとして実行してもらう
AddHandler cgi-script .cgi .rb 

# httpd.confの設定が間違っていないかの確認
apachectl configtest

# 上記の3つを変更後、保存してemacsを終了し、httpdを再起動させる
sudo systemctl restart httpd

これで、CGIを実行できるようになったはずです

では、CGIスクリプトを書いていきます

ここでは「hello.rb」としました

#!/usr/local/bin/ruby
print "Content-type: text/html\n\n"
print "<html>\n"
print "<head>\n"
print "<title>hello</title>\n"
print "</head>\n"
print "<body>\n"
print "Hello World by Ruby!"
print '<br>'
print "This sentence is written by ruby!!"
print '<br>'
print "</body>\n"
print "</html>"

簡単な解説

1行目の部分は「シェバン行」と呼ばれるもので、このファイルを実行するインタプリタを指定しています

今回は、Rubyさんで実行してもらいたいので、Rubyの場所を指定します

なお、Rubyがどこにあるかわからない場合は

which ruby

で確認できます

 

2行目について

print "Content-type: text/html\n\n"

これは簡単に言うと、「このデータはhtmlですよー」と宣言している文です

 

Webブラウザは、Webサーバとデータのやり取りをしています

Webブラウザさんはサーバから来たデータをHTMLと認識して画面に表示したり、zipファイルと認識してダウンロードしたりしています

この時、データだけ送られてきてもそれが何のデータなのかを識別することができません

普段はファイルの拡張子がどんなデータなのかの参考になるけど、拡張子がないファイルのときはどう判断しよう・・・?

そこで、そのデータが何なのかをあらわすものが上記の2文目なんですね

 

詳しい解説はこちらのサイトにあります

ちなみに、Content-typeと出力するものの間には1行の空行を挟む必要があります

(Content-typeのところに\nを2つ入れていることに注意)

 

3行目以降は単なるHTMLですね

本来は、こんな決め打ちで書く物ではないんですが動作確認にはちょうどいいと思います

ちなみに、もっと簡単なものだと

#!/usr/local/bin/ruby
print "Content-type: text/html\n\n"
print "Hello World by Ruby!"

の3行だけあればとりあえず動作します

(これが出力するものはHTMLではないが、Webブラウザさんがいい感じに処理してくれるのでおまかせした形)

 

スクリプトを作成したら、サーバのドキュメントルートに置いてパーミッションを755あたりにすればOKです

(デフォルトのサーバのドキュメントルートは「/var/www/html」以下になっています)

Webブラウザから「サーバネーム/hello.rb」とするとこんな感じで表示されます

helloruby

 

Internal Server Errorが出たら

もしも、以下のような「Internal Server Error」が出た場合いくつか確認することがあります

Internet Server Errorの画像

  • httpdのCGI設定は間違っていないか
  • httpdの設定を変更した後、httpdを再起動させたか
  • ファイルのパーミッションは適切か
  • CGIスクリプトのシェバン行は正しいか
  • Content-typeを記述しているか
  • Content-typeの後に1行空行を入れているか

などなど、確認するべき箇所がたくさんあります

詳しいエラー内容については(デフォルトでは)「/var/log/httpd/error_log」にエラーログがあるので以下のコマンドで確認してみるといいと思います

sudo tail /var/log/httpd/error_log

もし、エラーの中で

AH01215: (13)Permission denied: exec of '/var/www/html/hello.rb' failed
End of script output before headers: hello.rb

のようになっている場合、SELinuxを停止することで改善できるかもしれません

# SELinuxが有効か確認
getenforce
#=>Enforcingならば有効、Permissiveならば無効

# 以下コマンドで無効化
sudo setenforce 0

 

 

これで、CGIを使ってWebページを表示することができました

次回は、クライアント側からサーバへの通信とか受けたデータを基に出力を変えたり、ということをやってみたいと思います

 

おわり

Posted by しきゆら