このページでは、インターネットでホームページなどをブラウジングするときに利用する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で再度アクセスする必要があります。