HTTP レスポンスを解析する |
←[www.kasai.fm]
1. 概要
このページでは、perl を使って HTTP レスポンスを解析する方法を説明します。2. HTTP レスポンスの構造
perl プログラムの文法や、書き方、実行の方法は、既に知っている事を前提にしています。
ここで説明するのは、HTTP レスポンスを解釈するプログラムだけです。HTTP レスポンスをサーバから取り寄せる方法は、perl から他の Web ページを読み込むを参考にして下さい。
HTTP レスポンスとは、Web サーバから送られてくるデータの事です。
ちょっと考えると、これはただの HTML や画像データのような気がしますが、実際はもう少し複雑で、色々な付加情報が含まれています。
ブラウザ(HTTP クライアント)は、この付加情報を見ることによって、転送をスムーズに行ったり、情報の種類を判別したりしています。
よって、例えば自分で telnet を使ってサーバにアクセスした場合などは、目的のデータ(HTML や画像)を得る為に、もうちょっと努力して、この付加情報を解釈せねばならないのです。
ブラウザも、Web サーバから送られてくる HTTP レスポンスを解析し、ホームページとして表示しています。
HTTP レスポンスは、ある文法に従って構成されるテキストメッセージです。
文法は、IETF の RFC2616(別ウィンドウ)で規定されています。
3. レスポンスからデータ部を取り出す手順
下記のプログラムを使用すると簡単です。4. プログラムソース
(1) analysisHTTP
- 2003年 1月18日
- 改行を分割する正規表現を、
\r\n
から\r?\n
に変更。(UNIXサーバ上では\r
が必要ないため)
横浜のH.N.様よりご指摘頂きました。ありがとうございます。- 2002年 1月16日未明
- ヘッダ部とデータ部を分割する正規表現を変更。(環境により正しく動かなかったのが修正されました)
- 2002年 1月12日未明
- 初稿。transfer-extension および chunk 以外の transfer-coding は理解せず、それらは素通りする。
####### HTTP レスポンスを解析する
# 動作に必要な環境:
# ・perl 5 以降
# 使用方法:
# require('analysisHTTP');
# require('decodeChunk');
# %data = &analysisHTTP($http_response);
# # $data{BODY} に、データ部(HTML や JPEG 画像)が入る。
# # $data{STATUS} に、ステータスコード行が入る。
# # $data{ヘッダ名} に、ヘッダに書かれていた値が入る。
sub analysisHTTP{
my $data = $_[0];
my %head;
my ( $head, $body ) = split(/\r?\n\r?\n/, $data, 2);
my ( $status, @headline ) = split(/\r?\n/, $head);
foreach $line(@headline){
my ($item, $val) = split(/:\s*/, $line, 2);
$head{$item} = $val;
}
if ($head{'Transfer-Encoding'}){
foreach $te( split(/\s*:\s*/, $head{'Transfer-Encoding'}) ){
my ( $coding, @parameter ) = split(/\s*;\s/, $te);
my %parameter;
foreach $parameter(@parameter){
my ( $item, $val ) = split(/\s*=\s/, $parameter, 2);
$parameter{$item} = $val;
}
$body = &decodeChunk($body) if ($coding eq 'chunked');
}
}
return (%head, 'STATUS', $status, 'BODY', $body);
}
1;
(2) decodeChunk
- 2002年 1月12日未明
- 初稿。chunk-extension、空でない trailer は理解しない(ただしエラーにはならない)。
####### chunk transfer-coding をデコードする
# HTTP レスポンスの chunked transfer coding されたデータを
# 解釈(平文に戻す)します。
# 動作に必要な環境:
# ・perl 5 以降
# 使用方法:
# require('decodeChunk');
# $flat_data = &decodeChunk($chunked_data);
sub decodeChunk{
my ($chunk_body, $data) = ($_[0]);
do {
my %chunk_ext;
my ($topchunk_sizeline, $chunk_body) = split(/\r?\n/, $chunk_body, 2);
my ($topchunk_size, @topchunk_ext) = split(/\s*;\s*/, $topchunk_sizeline);
$topchunk_size = hex($topchunk_size);
foreach $ext(@topchunk_ext){
my ( $item, $val ) = split(/=/, $ext, 2);
$chunk_ext{$item} = $val;
}
my $chunk_part;
($chunk_part, $chunk_body)
= ( substr($chunk_body, 0, $topchunk_size), substr($chunk_body, $topchunk_size + 1) );
$data .= $chunk_part;
} while ($topchunk_size);
$chunk_body =~ s/\r?\n\r?\n$//;
return $data;
}
1;
5. 使用方法
使用する手順は次の通りです。
- 上記 (1)(2) のソースコードをコピー&ペーストし、(1) を analysisHTTP、(2) を decodeChunkというファイル名でそれぞれ保存します。
- この機能を使いたいプログラムを analysisHTTP, decodeChunk と同じフォルダに置き、
require('analysisHTTP');と、プログラムの中に書きます。プログラムのどこに書いても OK です。
require('decodeChunk');- HTTP レスポンスを解析する時は、
%http = &analysisHTTP($http_response);のようにします。($http_response) の部分に、解析したい HTTP レスポンスの入った変数名(スカラー値)を書く訳です。- %http には、次のように結果が格納されます。
$http{STATUS} ステータスコード行 $http{BODY} 実データ $http{ヘッダ名} ヘッダ値
6. 免責
本プログラムは、自由に配布、使用、改変して頂いて結構です。転載の許可も必要ありません。
但し本プログラムを使用した結果、何らかの損害を被ったとしても、当方では責任を負いかねます。ご了承ください。
と言いつつ虫の好い話ですが、バグや無駄な部分等を発見されましたら、下記アドレスまでご一報頂ければ幸いです。
←[www.kasai.fm]