以前、SSIを使ってみました。
Docker + Alpine3.5 + Apache2.4 + Python3.6で、SSIを使ってみた - メモ的な思考的な
今回はCGIのリダイレクトを使ってみます。
目次
- 環境
- Locationヘッダを使ったリダイレクト
- NPHスクリプトによる、Locationヘッダを使ったリダイレクト
- NPHスクリプト + 環境変数による、Locationヘッダを使ったリダイレクト
- その他
- ソースコード
環境
なお、Dockerfileは以前のものを流用し、Dockerは以下のコマンドで利用しています。
## DockerfileからDockerイメージをビルド $ docker image build -t alpine:python3_httpd24_redirect . ## Dockerコンテナを起動し、CGIのディレクトリをホストと共有 $ docker container run -p 8081:80 --name redirect -v `pwd`/cgi/:/usr/local/apache2/cgi-bin/ alpine:python3_httpd24_redirect
また、動作確認にはcurl
を使います。
インターネットにアクセスしよう 番外編 : curlの使い方 - Cocoaはやっぱり!
Locationヘッダを使ったリダイレクト
今回はLocationヘッダを使ったリダイレクトを試します。
LocationヘッダのURLの仕様は、RFC7231にあり、
Location = URI-reference
7.1.2. Location | RFC 7231 — HTTP/1.1: Semantics and Content (日本語訳)
とのことです。
URI-reference
の定義は、RFC3986にあり、
URI-reference は、URI か相対的参照のどちらかである。 URI-reference の先頭がコロン分離記号を従えるスキームの構文に合致しなければ、URI-reference は相対的参照である。
4.1. URI 参照 | Uniform Resource Identifier (URI): 一般的構文 - RFC3986 日本語訳の複製
とのことです。
そのため、今回は相対的参照として、ホスト以下を記載します。
以上をもとに、
- リダイレクト前:redirect.py
- リダイレクト後:done_redirect.py
の2ファイルを用意します。
redirect.py
#!/usr/bin/python3 # HTTPレスポンスヘッダ print('Location: /cgi-bin/done_redirect.py') print('')
done_redirect.py
#!/usr/bin/python3 # HTTPレスポンスヘッダ print('Content-Type: text/plain;charset=utf-8') print('') print('Hello')
curlのL
オプションでリダイレクトに対応し、v
オプションで実際の往復を見てみます。
$ curl -L -v http://localhost:8081/cgi-bin/redirect.py * Trying ::1... * Connected to localhost (::1) port 8081 (#0) > GET /cgi-bin/redirect.py HTTP/1.1 > Host: localhost:8081 > User-Agent: curl/7.43.0 > Accept: */* > < HTTP/1.1 200 OK < Date: Sat, 20 May 2017 21:22:27 GMT < Server: Apache/2.4.25 (Unix) < Transfer-Encoding: chunked < Content-Type: text/plain;charset=utf-8 < Hello * Connection #0 to host localhost left intact
リダイレクトが行われているようですが、ステータスコードが200になっていました。
NPHスクリプトによる、Locationヘッダを使ったリダイレクト
ステータスコードも自由に変更できる方法を探したところ、書籍「CGIプログラミング 第2版」の3章にApacheのNPH (Non Parsed Headers)スクリプトを使う方法が紹介されていました*1。
- 作者: スコットグーリッジ,ガンザーバージニックス,シシャガンダヴァラム,Scott Guelich,Gunther Birznieks,Shishir Gundavaram,田辺茂也,大川佳織
- 出版社/メーカー: オライリー・ジャパン
- 発売日: 2001/06
- メディア: 単行本
- 購入: 2人 クリック: 69回
- この商品を含むブログ (42件) を見る
また、RFC3875などにも記載があります。
書籍ではPerlを使っていましたが、今回はPythonで書いてみます。
- ファイル名の接頭辞に
nph-
を付ける - 少なくとも、ステータス行、Conent-Typeヘッダ、Serverヘッダを出力する
とのことですので、以下のPythonスクリプトを書きました。
nph-redirect_hardcord.py
#!/usr/bin/python3 # HTTPレスポンスヘッダ # NPHなので、ステータスラインも記述する print('HTTP/1.1 302 Found') print('Location: /cgi-bin/done_redirect.py') print('Server: hoge') print('')
curlにて確認します。
$ curl -L -v http://localhost:8081/cgi-bin/nph-redirect_hardcord.py * Trying ::1... * Connected to localhost (::1) port 8081 (#0) > GET /cgi-bin/nph-redirect_hardcord.py HTTP/1.1 > Host: localhost:8081 > User-Agent: curl/7.43.0 > Accept: */* > < HTTP/1.1 302 Found < Location: /cgi-bin/done_redirect.py < Server: hoge * no chunk, no close, no size. Assume close to signal end < * Closing connection 0 * Issue another request to this URL: 'http://localhost:8081/cgi-bin/done_redirect.py' * Hostname localhost was found in DNS cache * Trying ::1... * Connected to localhost (::1) port 8081 (#1) > GET /cgi-bin/done_redirect.py HTTP/1.1 > Host: localhost:8081 > User-Agent: curl/7.43.0 > Accept: */* > < HTTP/1.1 200 OK < Date: Sat, 20 May 2017 22:14:46 GMT < Server: Apache/2.4.25 (Unix) < Transfer-Encoding: chunked < Content-Type: text/plain;charset=utf-8 < Hello * Connection #1 to host localhost left intact
302リダイレクトになりました。
NPHスクリプト + 環境変数による、Locationヘッダを使ったリダイレクト
上記のNPHスクリプトでは色々とハードコーディングしていたため、
を使うように変更します。
nph-redirect_environ.py
#!/usr/bin/python3 import os # ステータスコードとメッセージはPythonの定数を使う # https://docs.python.jp/3/library/http.html from http import HTTPStatus # CGIの環境変数からプロトコルとバージョン・ホストを取得する protocol = os.environ.get('SERVER_PROTOCOL') server = os.environ.get('SERVER_SOFTWARE') # HTTPレスポンスヘッダ print(f'{protocol} {HTTPStatus.FOUND.value} {HTTPStatus.FOUND.phrase}') print('Location: /cgi-bin/done_redirect.py') print(f'Server: {server}') print('')
curlで確認します。
$ curl -L -v http://localhost:8081/cgi-bin/nph-redirect_environ.py > GET /cgi-bin/nph-redirect_environ.py HTTP/1.1 > Host: localhost:8081 > User-Agent: curl/7.43.0 > Accept: */* > < HTTP/1.1 302 Found < Location: /cgi-bin/done_redirect.py < Server: Apache/2.4.25 (Unix) < > GET /cgi-bin/done_redirect.py HTTP/1.1 > Host: localhost:8081 > User-Agent: curl/7.43.0 > Accept: */* > < HTTP/1.1 200 OK < Date: Sat, 20 May 2017 22:23:31 GMT < Server: Apache/2.4.25 (Unix) < Transfer-Encoding: chunked < Content-Type: text/plain;charset=utf-8 < Hello
同じく、302リダイレクトになりました。
その他
NPHスクリプトを使う際、環境によっては以下のエラーが出るようです。
apache - Apache2 sends two HTTP headers with a mapped “nph-” CGI - Stack Overflow
ソースコード
GitHubに上げました。alpine_apache_python36_redirect
ディレクトリの中が今回のものです。
thinkAmi-sandbox/Docker_Apache-sample
*1:旧版の英語版であれば、オライリーの「O'Reilly Open Books Project」により公開されています:http://www.oreilly.com/openbook/cgi/ch03_08.html