ヘッダーを表示させよう
ヘッダーの表示(最新の1メールのみ)
前回までで、ソケットを使用したPOPサーバへの接続まで完成しました。
次にヘッダーの取得ですが、ヘッダーの表示コマンドは「TOP」を使用します。
[TOP 1 0]とする事で、先頭のメールのヘッダー部分のみを表示することができます。
試しに、1件目のメールのヘッダーを全て表示する処理をしてみます。
→
表示画面
1: #!/usr/bin/perl
2: print "Content-type:text/html\n\n";
3: use Socket;
4:
5: #---接続情報の設定-----
6: $pop_server="pop.grot3.com"; #POPサーバー名の指定(サーバ名は仮定です)
7: $account="grot3"; #POPサーバー用アカウント(仮定です)
8: $password="1234567"; #POPサーバー用パスワード(仮定です)
9:
10: &ConnectPop; #サブプロシージャ(ConnectPop)の呼び出し
11:
12: print SOCKET "TOP $mcount 0\n"; #最新メールのヘッダー表示のコマンド
13:
14: while (<SOCKET>){
15: $resp=$_;
16: if($resp eq "\.\r\n"){last;} #メール表示の最終行は必ず[.(ドット)]のみの行のため
17: print "$resp\n<BR>";
18: }
19:
20: close (SOCKET); #ソケット接続の終了
21:
22: #----------------------------------------------
23: #接続
24: #----------------------------------------------
25: sub ConnectPop{
〜省略〜
26:}
メモ:
一件のメールのヘッダー表示例です。
※前回作成したConnectPop関数については、表示を省略しています。
ヘッダーの表示(最新の1メールのみ)
ヘッダーの処理について、説明します。
ヘッダーの形式は、[ヘッダー名:値]のように、コロンを挟んで左がヘッダー名、右が値です。
したがって、基本的にはsplit関数を使用して、ヘッダー名と値を取得すればOKです。
例:
($name,$value)=split(/:/,$_);
ただし、ここで注意が必要なのが2点。
- 2つのヘッダー情報が一行になっている場合がある
- 1つのヘッダーが複数行にまたがっている場合がある
1: #!/usr/bin/perl
2: print "Content-type:text/html\n\n";
3: use Socket;
4:
5: #---接続情報の設定-----
6: $pop_server="pop.grot3.com"; #POPサーバー名の指定(サーバ名は仮定です)
7: $account="grot3"; #POPサーバー用アカウント(仮定です)
8: $password="1234567"; #POPサーバー用パスワード(仮定です)
9:
10: &ConnectPop; #サブプロシージャ(ConnectPop)の呼び出し
11:
12: print SOCKET "TOP $mcount 0\n"; #最新メールのヘッダー表示のコマンド
13:
14: while (<SOCKET>){
15: $resp=$_;
16: if($resp eq "\.\r\n"){last;} #メール表示の最終行は必ず[.(ドット)]のみの行のため
17: &MailHeader($resp); #サブプロシージャ(MailHeader)の呼び出し
18: }
19:
20: close (SOCKET); #ソケット接続の終了
21:
22: #----------------------------------------------
23: #接続
24: #----------------------------------------------
25: sub ConnectPop{
〜省略〜
26: }
27:
28: #----------------------------------------------
29: #ヘッダー処理(ヘッダー名を変数名とし、値を代入)
30: #----------------------------------------------
31: sub MailHeader{
32: if($resp =~ m/\;/){@_=split(/\;/,$resp);} #2つのヘッダー情報が一行になっている場合の対応「;(セミコロン)」で区切る
33: foreach (@_){
34: $resp=$_;
35: if($resp =~ m/^\S/){$name="";} #先頭がホワイトスペースでない場合のみ、ヘッダー名をクリアして処理を次のヘッダーへ移行する
36: if($name eq ""){
37: @array=split(/:/,$resp);
38: if($array[0]=~m/Content-Transfer-Encoding/i){$array[0]=Encoding;} #変数名に-(ハイフン)は使用できないための対策
39: $name=$array[0];shift(@array); #コロンで区切り、一番左側を変数名として使用。次行で残りを値として代入
40: $$name=join(':',@array); #時刻など、データに「:(コロン)」が使用されていても回避できる
41: } else {
42: $$name .= $_; #ヘッダー行が 移行していない場合、追加する
43: }
44:
45: if($$name=~m/boundary=/i){@_=split(/boundary=/,$$name);$Boundary=$_[1];$Boundary=~s/\"//g;$Boundary=~s/\r\n//g;}
46: if($$name=~m/charset=/i){@_=split(/charset=/,$$name);$charset=$_[1];$charset=~s/\r\n//g;$charset=~s/\"//g;}
47:
48: $$name=~s/^ //g; #変数の先頭スペースを削除
49: $$name=~s/\r\n//g;$$name=~s/\t//g; #変数内の改行・タブの消去(何か嫌なので)
50: $$name=~s/</</g; #特殊文字のエスケープ
51: $$name=~s/>/>/g; #特殊文字のエスケープ
52: }
53: }
メモ:
ヘッダー名にを変数名とし、値を代入しています。
先ほどの問題に対し、以下の対応を行っています。
- [パターン1]2つのヘッダー情報が一行になっている場合がある
[対策]→32行目で「;(セミコロン)」で区切る
- [パターン2]1つのヘッダーの値の文字数が多く、複数行にまたがっている場合がある
[対策]→35行目で ホワイトスペースから行が始まる場合、続きとする。37行目で変数に値を追加する
※45〜46行目について。
boundary・charsetは区切りがコロン(
:)ではなくイコール(
=)のため、別処理しています。
ヘッダーの表示(最新〜30件分)
→
表示画面
1: #!/usr/bin/perl
2: print "Content-type:text/html\n\n";
3: use Socket;
4:
5: #---接続情報の設定-----
6: $pop_server="pop.grot3.com"; #POPサーバー名の指定(サーバ名は仮定です)
7: $account="grot3"; #POPサーバー用アカウント(仮定です)
8: $password="1234567"; #POPサーバー用パスワード(仮定です)
9:
10: &ConnectPop; #サブプロシージャ(ConnectPop)の呼び出し
11:
12: #--最新メール〜30件分の表示-----
13: for ($i = $mcount; $i > $mcount -30; $i--) {
14: print SOCKET "TOP $i 0\n"; #ヘッダー表示のコマンド
15: while (<SOCKET>){
16: $resp=$_;
17: if($resp eq "\.\r\n"){last;} #メール表示の最終行は必ず[.(ドット)]のみの行のため
18: &MailHeader($resp); #サブプロシージャ(MailHeader)の呼び出し
19: }
20:
21: print $mcount - $i + 1 . "<BR>"; #最新を[1]として、番号付け
22: print "To=$To<BR>"; #To(宛先)
23: print "From=$From<BR>"; #From(送信元)
24: print "Subject=$Subject<BR>"; #Subject(件名)
25: print "Date=$Date<BR>"; #Date(送信日時)
26: print "<HR>";
27: }
28:
29: close (SOCKET); #ソケット接続の終了
30:
31: #----------------------------------------------
32: #接続
33: #----------------------------------------------
34: sub ConnectPop{
〜省略〜
35: }
36:
37: #----------------------------------------------
38: #ヘッダー処理(ヘッダー名を変数名とし、値を代入)
39: #----------------------------------------------
40: sub MailHeader{
〜省略〜
41: }
メモ:
ヘッダーの表示で必要なのが、送信元・宛先・件名・受信日時 etc…とりあえず今はこんなもの
このままだと日本語はエンコードされた状態で表示され、いわゆる文字化け状態となります。
デコード処理は次回…
ヘッダーの表示(最新〜30件分)
→
表示画面
1: #!/usr/bin/perl
2: print "Content-type:text/html\n\n";
3: use Socket;
4:
5: #---接続情報の設定-----
6: $pop_server="pop.grot3.com"; #POPサーバー名の指定(サーバ名は仮定です)
7: $account="grot3"; #POPサーバー用アカウント(仮定です)
8: $password="1234567"; #POPサーバー用パスワード(仮定です)
9:
10: &ConnectPop; #サブプロシージャ(ConnectPop)の呼び出し
11:
12: #--最新メール〜任意件数分の表示-----
13: $Dispnum=50; #一ページでの表示件数
14:
15: print "<TABLE border=1><TR bgcolor=#98FB98><TH>番号</TH><TH>差出</TH><TH>件名</TH><TH>日時</TH></TR>\n";
16:
17: for ($i = $mcount; $i > $mcount - $Dispnum; $i--) {
18: print SOCKET "TOP $i 0\n"; #ヘッダー表示のコマンド
19: while (<SOCKET>){
20: $resp=$_;
21: if($resp eq "\.\r\n"){last;} #メール表示の最終行は必ず[.(ドット)]のみの行のため
22: &MailHeader($resp); #サブプロシージャ(MailHeader)の呼び出し
23: }
24: print "<TR><TD>$i</TD><TD>$From</TD><TD>$Subject</TD><TD>$Date</TD>\n";
25: }
26: print "</TABLE>\n";
27:
28: close (SOCKET); #ソケット接続の終了
29:
30: #----------------------------------------------
31: #接続
32: #----------------------------------------------
33: sub ConnectPop{
〜省略〜
34: }
35:
36: #----------------------------------------------
37: #ヘッダー処理(ヘッダー名を変数名とし、値を代入)
38: #----------------------------------------------
39: sub MailHeader{
〜省略〜
40: }
メモ:
13〜27行をそっくり入れ替えました。
ループ処理毎にテーブルで体裁を整えて、それらしくしています。