このページでは、インターネットでホームページなどをブラウジングするときに利用するHTTPプロトコルについて、Perlスクリプトを使って説明しています。
HTTPプロトコルとは、Hypertext Transfer Protocolの略で、インターネットでホームページなどをブラウジングするときに利用しているプロトコルです。
HTTPプロトコルは、TCP/IP上のプロトコルで、通常80番ポートを使ってアクセスします。
詳細な定義は、以下のRFCで定義されています。
RFC-2068は、古くなっている(obsolated)ため、RFC-2616を参照しましょう。
基本的にHTTPプロトコルは、メッセージを要求(リクエスト)し、その応答結果(レスポンス)を表示するだけです。
Perlでホームページを表示するためのソースを作成してみます。
Webサーバに直接接続する場合は、ホスト名、ポート番号、URLディレクトリが必要です。
プロキシサーバに接続する場合は、プロキシサーバのホスト名とポート番号、URLが必要です。
Perlプログラムで、通信処理には、Socketモジュールを使っています。
socket関数でソケットを生成し、connect関数で接続した後、ソケットハンドルを経由して、入出力を行います。
基本的な流れは、ネットワークプログラミングと同じです。
注意する点としては、ソケットをautoreflushモードにする必要がある点です。
autoreflushモードにしないとデータがバッファリングされてしまい、応答が返って来なくなります。
autoreflushモードにするためには、FileHandleモジュールを使っています。
| http.pl |
|---|
#!/usr/local/bin/perl
# @(#)http.pl Copyright (C)2001 ASH. http://ash.jp/
#
# 簡易ブラウジングスクリプト(HTTP)
# Usage: http.pl URL(http://host:port/dir/file)
#
use strict;
use Socket;
use FileHandle;
my ($proxy_host, $proxy_port, $http);
my ($con_host, $con_port);
my ($host, $port, $url, $path, $ip, $sockaddr);
my ($arg, $buf);
($arg) = @ARGV;
# HTTPプロトコルのバージョン
#$http = '1.1';
# プロキシサーバの設定
#$proxy_host = 'XXX.XXX.XXX.XXX';
#$proxy_port = 8080;
# デフォルトホストの設定
$host = 'localhost';
$port = getservbyname('http', 'tcp');
$path = '/';
# URL解析処理
$arg =~ m!(http:)?(//)?([^:/]*)?(:([0-9]+)?)?(/.*)?!;
if ($3) {$host = $3;}
if ($5) {$port = $5;}
if ($6) {$path = $6;}
#print "host=$host, port=$port, url=$url\n";
if ($proxy_host) {
# プロキシサーバ経由
$con_host = $proxy_host;
$con_port = $proxy_port;
$url = $arg;
} else {
$con_host = $host;
$con_port = $port;
$url = $path;
}
# ソケットの生成
$ip = inet_aton($con_host) || die "host($con_host) not found.\n";
$sockaddr = pack_sockaddr_in($con_port, $ip);
socket(SOCKET, PF_INET, SOCK_STREAM, 0) || die "socket error.\n";
# ソケットの接続
connect(SOCKET, $sockaddr) || die "connect $con_host $con_port error.\n";
autoflush SOCKET (1);
# HTTP要求を送信
if ($http eq '1.1') {
print SOCKET "GET $url HTTP/1.1\n";
print SOCKET "Host: $host\n";
print SOCKET "Connection: close\n\n";
} else {
print SOCKET "GET $url HTTP/1.0\n\n";
}
# HTTP応答を受信
while (chomp($buf=<SOCKET>)) {
print "$buf\n";
}
# 終了処理
close(SOCKET);
|
HTTP 1.1でアクセスする場合は、$httpにHTTPバージョン(1.1)を設定します。
HTTP 1.1では、Host指定が必須となっています。
また、HTTP 1.1では、Keep-Alive機能が有効となっていますので、最後のリクエストには、Connection: closeを追加する必要があります。
Connection: closeがWebサーバに届かない場合は、WebサーバのKeep-Aliveのタイムアウト時間(15秒程度)により、セッションは閉じられます。
# HTTPプロトコルのバージョン $http = '1.1'; |
ファイアウォールなどがある場合は、$proxy_hostと、$proxy_portにプロキシサーバの情報を指定してください。 プロキシサーバを利用する場合は、URLの解析は、プロキシサーバがやってくれますので、GETメソッドにはディレクトリではなく、URLをそのまま指定するようになっています。
# プロキシサーバの設定 $proxy_host = 'プロキシサーバ名'; $proxy_port = プロキシサーバのポート番号; 例: $proxy_host = 'px01.ash.jp'; $proxy_port = 8080; |
実際に、PerlでホームページのトップページをGETしてみます。
URLの指定方法は、Lynxなどのブラウザと同じです。
HTTPヘッダの内容と、HTMLソースが表示されます。
Unix# http.pl http://localhost:80/ HTTP/1.1 200 OK Date: Fri, 17 Nov 2000 06:38:43 GMT Server: Apache/1.3.0 (Unix) Connection: close Content-Type: text/html <html><body> ・・・ 中略 ・・・ </body></html> |
URLとしてディレクトリを指定する場合、最後の'/'を省略すると、301 Moved エラーが返却されます。 このような場合は、指定されたURLで再度アクセスする必要があります。