ASH | サーバ | セキュリティ | Linux | FreeBSD | DB | Web | CGI | Perl | Java | XML | プログラム | ネットワーク | 標準 | Tips集

Perlでブラウズ(HTTP)

 このページでは、インターネットでホームページなどをブラウジングするときに利用するHTTPプロトコルについて、Perlスクリプトを使って説明しています。

概要

 HTTPプロトコルとは、Hypertext Transfer Protocolの略で、インターネットでホームページなどをブラウジングするときに利用しているプロトコルです。
 HTTPプロトコルは、TCP/IP上のプロトコルで、通常80番ポートを使ってアクセスします。
 詳細な定義は、以下のRFCで定義されています。 RFC-2068は、古くなっている(obsolated)ため、RFC-2616を参照しましょう。

 基本的にHTTPプロトコルは、メッセージを要求(リクエスト)し、その応答結果(レスポンス)を表示するだけです。

PerlでGETするソース

 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 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を実行

 実際に、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で再度アクセスする必要があります。



Copyright (C)1995-2002 ASH multimedia lab.
mail : info@ash.jp