Apache等を使わずにPythonがインストールされていれば、一行のコマンドでローカル環境でWebサーバを作成できます。このPythonのWebサーバはCGIも動作させることもできるので、簡単なCGIプログラムを動かす方法として、ApacheのWebサーバを設定するのが面倒という方にもおすすめです。
CGIとは
CGI(Common Gateway Interface)とは、プラットフォームに依存しない方法で、Webサーバ(HTTPサーバ)の下で、外部プログラムを実行させるための仕組みになります。
サーバがアプリケーションのゲートウェイとして振る舞います。サーバはブラウザ(クライアント)からの要求(リクエスト)を、CGIプログラムが受け取る情報(CGI要求)に変換します。その後、CGIプログラムはその情報を受け取った後に実行されます。そして、CGIプログラムからの出力(CGI応答)をサーバがクライアントのための応答(レスポンス)に変換します。
CGIの動作の流れ
実行環境
OS:Ubuntu 16.04
pythonバージョン:python 2.7.12
PythonでワンライナーWebサーバ
Pythonで簡易的なWebサーバを構築するのはとても簡単です。Python2ならば標準にあるCGIHTTPServerというモジュールを利用することで、CGIが動くWebサーバを起動できます。
起動するコマンドはたった一行です。
1 |
python -m CGIHTTPServer 3000 |
-mオプションでモジュールを指定して、コマンドライン引数ではポート番号を指定します。
ポート番号を省略するとデフォルトとして8000番ポートで起動します。
Python3の場合は、SimpleHTTPServerやCGIHTTPServerは、http.serverモジュールに統合されました。そのため、http.serverを用いて、実行します。cgiを使用する場合は--cgiオプションを使用します。
1 |
python3 -m http.server --cgi 3000 |
このワンライナーのコマンドだけでローカル環境で動くWebサーバを起動できます。このWebサーバはCtrl+cで終了することができます。
このローカル環境のWebサーバはコマンドを起動したカレントディレクトリをドキュメントルートとして、ページにアクセスすることができます。例えば、ページにアクセスするために以下のhtmlファイルを作成します。
test.html
1 2 3 4 5 6 7 8 9 10 |
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Web Server Test</title> </head> <body> <h1>Hello World</h1> </body> </html> |
カレントディレクトリからディレクトリ構造が以下の状態にして、コマンドを実行します。
1 2 3 4 5 6 7 8 |
$tree . └── test.html 0 directories, 1 file $ $python -m CGIHTTPServer 3000 Serving HTTP on 0.0.0.0 port 3000 ... |
Webサーバを起動させている状態でブラウザにアクセスします。アドレスは'localhost:3000/test.html'になります。すると'Hello World'と書かれたページにアクセスできます。
アクセス結果
CGIプログラムを動かしてみる
上のワンライナーのコマンドで起動したWebサーバでCGIプログラムを動かすには、決められたディレクトリの中にCGIプログラムを入れる必要があります。CGIHTTPServerでCGIプログラムを実行できるディレクトリは'cgi-bin'と'htbin'のディレクトリになります。
それでは、起動したWebサーバでCGIプログラムを実行します。ここで、起動するプログラムはBashで書かれたプログラムを使用します。
test.cgi
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#!/bin/bash echo "Content-Type:text/html" echo echo "<!DOCTYPE html>" echo "<html>" echo "<head>" echo "<meta charset="utf-8" />" echo "<title>CGI Program Test</title>" echo "</head>" echo "<body>" echo "<h1>CGI Program Output!!</h1>" echo "</body>" echo "</html>" |
このtest.shのパーミッションを755に設定します。
1 2 |
$chmod -v 755 cgi-bin/test.cgi 'cgi-bin/test.cgi' のモードを 0664 (rw-rw-r--) から 0755 (rwxr-xr-x) へ変更しました |
カレントディレクトリからのディレクトリ構造を以下のようにして、Webサーバを起動します。
1 2 3 4 5 6 7 8 9 10 |
$tree . ├── cgi-bin │ └── test.cgi └── test.html 1 directory, 2 files $ $python -m CGIHTTPServer 3000 Serving HTTP on 0.0.0.0 port 3000 ... |
アドレス'localhost:3000/cgi-bin/test.cgi'にブラウザでアクセスしてみると以下のように表示されます。
アクセス結果
CGIの環境変数を確認してみる
クライアント要求をCGI要求に変換したとき渡される情報として、RFC3875に規定されているいくつかの環境変数があります。この環境変数を確認してみたいと思います。
表示する環境変数を絞るために、Webサーバを起動させるときにenvコマンドの-iオプションを通して、実行します。そうすると、現在の環境変数を一度すべて削除した状態でプログラムを実行することができます。
1 |
env -i python -m CGIHTTPServer 3000 |
この環境変数を削除した状態で、どのような環境変数があるかを確認するCGIプログラムを作成します。htmlではなく、単純なテキストとして出力するため、Content-Typeをtext/plainにします。
cgi-env.cgi
1 2 3 4 5 6 |
#!/bin/bash echo "Content-Type:text/plain" echo printenv |
このCGIプログラムのパーミッションを変更します。
1 2 |
$chmod -v 755 cgi-bin/cgi-env.cgi 'cgi-bin/cgi-env.cgi' のモードを 0664 (rw-rw-r--) から 0755 (rwxr-xr-x) へ変更しました |
カレントディレクトリからのディレクトリ構造を以下のようにして、コマンドを実行します。
1 2 3 4 5 6 7 8 9 10 11 |
$tree . ├── cgi-bin │ ├── cgi-env.cgi │ └── test.cgi └── test.html 1 directory, 3 files $ $env -i python -m CGIHTTPServer 3000 Serving HTTP on 0.0.0.0 port 3000 ... |
'localhost:3000/cgi-bin/cgi-env.cgi'にアクセスすると以下のようなページが表示されます。
アクセス結果
私の環境での、cgi-env.cgiにアクセスした内容は以下のようになりました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
HTTP_USER_AGENT=Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:58.0) Gecko/20100101 Firefox/58.0 SERVER_PORT=3000 SCRIPT_NAME=/cgi-bin/cgi-env.cgi REMOTE_HOST=localhost PATH_INFO= PWD=/home/ubuntu/python-cgi-webserver PATH_TRANSLATED=/home/ubuntu/python-cgi-webserver HTTP_REFERER= HTTP_ACCEPT= text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 REMOTE_ADDR=127.0.0.1 SHLVL=1 SERVER_NAME=ubuntu-VirtualBox CONTENT_LENGTH= SERVER_SOFTWARE=SimpleHTTP/0.6 Python/2.7.12 QUERY_STRING= GATEWAY_INTERFACE=CGI/1.1 SERVER_PROTOCOL=HTTP/1.0 CONTENT_TYPE=text/plain HTTP_COOKIE= REQUEST_METHOD=GET _=/usr/local/bin/printenv |
CGIの環境変数について、少し見てみたいと思います。
REQUEST_METHODの情報はクライアントからの要求がGETメソッドで送られたかPOSTメソッドで送られたか等の情報を見ることができます。この環境変数を元にGETかPOSTか等の条件分岐でCGIプログラムの動作を変更することができます。
QUERY_STRINGの情報は'http://localhost:3000/cgi-bin/cgi-env.cgi?var1=aaa&var2=bbb'のようにアクセスしたときに、'?'以降の文字列がQUERY_STRINGに以下のように情報が入ります。
1 |
QUERY_STRING=var1=aaa&var2=bbb |
このQUERY_STRINGの情報はGETメソッドで情報の渡すときに利用できます。
他の環境変数についてはRFC3875の4.1.節を確認してみるとよいでしょう。
まとめ
pythonの短いコマンドでWebサーバを簡単に起動できます。簡単なCGIプログラムを動かしてみたいなら、十分利用できます。例えば、CGIプログラムの簡単な学習などに利用できると思います。
Apacheがなくても、Pythonがインストールされているならば、CGIが動かせるWebサーバを起動でき、CGIプログラムも簡単に実行できるので、興味があれば試してみてください。
参考
python2のWebサーバで使用するモジュールについては、SimpleHTTPServerとCGIHTTPServerのドキュメントが参考になります。
Python3のWebサーバで使用するモジュールについてはhttp.serverのドキュメントが参考になります。
CGIの仕様のRFCはRFC3875になります。