- PR -

Perl の CGI から sendmail でメール送信

投稿者投稿内容
asp
会議室デビュー日: 2003/05/29
投稿数: 8
投稿日時: 2003-09-04 11:36
perl 5.8.0

Perl の CGI から sendmail を使用してメールを自動送信しています。

送信自体は出来るのですが、本文の途中でメールヘッダ (↓参照) のようなものが現れ、
それ以後の文字は quoted-printable にエンコードされて、文字化けしてしまいます。

他のサーバに同じ CGI を設置した場合、
文字化けせず問題なくメールが読めます。
wakwak.com というサーバに設置した場合のみ、上記現象が発生してしまいます。

CGI では、送られてきた文字列を jcode.pl で JIS に変換して、
時々 \n で改行し、sendmail で送信しています。

---------------

(ここまでの本文は正常)

Mime-Version: 1.0
Content-Type: text/plain; charset="iso-8859-1"
X-wakwak: 10383
To: メールアドレス
Content-Transfer-Encoding: quoted-printable
Date: Wed, 3 Sep 2003 08:09:07 +0900
From: メールアドレス

(ここから本文が文字化け)

足りない情報などありましたら、ご指摘下さい。


[ メッセージ編集済み 編集者: asp 編集日時 2003-09-04 14:37 ]
Marionette
ベテラン
会議室デビュー日: 2003/08/08
投稿数: 70
投稿日時: 2003-09-04 15:20
> Content-Type: text/plain; charset="iso-8859-1"
> X-wakwak: 10383
> To: メールアドレス
> Content-Transfer-Encoding: quoted-printable
> Date: Wed, 3 Sep 2003 08:09:07 +0900
> From: メールアドレス

現時点では、文字化けせずに読めるのは『たまたま』くらいのつもりでいた方がよろしいのではと思います。
メールなんてどこを経由して届くかわかりませんしね。

charsetが違うのと Subject:に日本語が含まれているせいではないでしょうか。
規格に則るなら

Content-Type: text/plain; charset="iso-2022-jp"
Content-Transfer-Encoding: 7bit
From: =?ISO-2022-JP?B?<encoded addresss>?= <hogehoge@hoge.com>
Subject: =?ISO-2022-JP?B?<encoded subject>?=

のようにするのが正しい方法だと思います(To: も同様です)。
<encoded addresss>、<encoded subject>の部分は、元々は
From: ほげほげ <hogehoge@hoge.com>
Subject: フォームメール送信テスト
のようになっていたものを、それぞれ JISに変換後、Base64でエンコードしたものです。
試してみてください。
perl用の Base64モジュールもあります。インストールされているかどうか分かりませんので確認してください。

nkfが使えるなら パラメータを与えることでエンコードすることも出来ます(OSと nkfのバージョンによりますが)。
ヘッダ部とボディーを別々に変換して連結すれば一番簡単です。

改行コードは規格では CRLFです。
SMTP接続する場合は、必ず CRLFに変換する必要があります。
(一部のサーバで受信できなくて、原因が分かるまでずいぶん時間がかかりました。)
コマンドパラメータとして sendmailに渡す場合は、気にしなくていいかも分かりません。

[ メッセージ編集済み 編集者: Marionette 編集日時 2003-09-04 15:34 ]
asp
会議室デビュー日: 2003/05/29
投稿数: 8
投稿日時: 2003-09-04 15:34
ありがとうございます。

Subject が日本語ですので、
半角英数字に変更して試してみたいと思います。

補足ですが、

> Content-Type: text/plain; charset="iso-8859-1"
> X-wakwak: 10383
> To: メールアドレス
> Content-Transfer-Encoding: quoted-printable
> Date: Wed, 3 Sep 2003 08:09:07 +0900
> From: メールアドレス

は、メールヘッダでなく本文中に現れてしまいます。
asp
会議室デビュー日: 2003/05/29
投稿数: 8
投稿日時: 2003-09-05 09:45
Subject を日本語から半角英数に変更しましたが、
現象は変わりませんでした。

ソースは以下の通りです。

#!/usr/bin/perl

require './jcode.pl';
$query_file = 'http://www.xxx.xx/xxx.html';
$smail = 'xxxx@xxx.xx';
$sname = 'xxxxx';
$sendmail = '/usr/sbin/sendmail';
$trans = 'xxxx@xxx.xx';
$ftitle = 'title';
$clength = $ENV{'CONTENT_LENGTH'};
if($clength ne '')
{
  read(STDIN, $query_string, $clength);
  @elements = split(/&/,$query_string);
  $i = 0;
  foreach $element (@elements)
  {
    (@name[$i], $buf) = split(/=/, $element);
    $buf =~ tr/+/ /;
      $buf =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
    &jcode'convert(*buf, 'jis');
    @value[$i] = $buf;
    $i++;
  }
  &jcode'convert(*ftitle, 'jis');
  open (MAIL, "|$sendmail $trans");
  print MAIL "From: $smail ($sname)\n";
  print MAIL "Subject: $ftitle\n";
  for($j = 0; $j < $i; $j++)
  {
    print MAIL "*@name[$j]\n";
    print MAIL "@value[$j]\n";
  }
  close(MAIL);
  print "Location: $query_file\n\n";
}


[ メッセージ編集済み 編集者: asp 編集日時 2003-09-05 09:48 ]
未記入
大ベテラン
会議室デビュー日: 2003/06/28
投稿数: 219
投稿日時: 2003-09-05 10:21
Ken-Labと申します。

私が記憶違いをしているか見落としていたら申し訳ないのですが、ヘッダ部分と本文の
間の改行は \n\n になっている必要があったような気がします。
それと、Base64エンコーディングですが、自分はmimew.plを使っています。
あくまでご参考ということで。

それから、wakwakさんにアップロードしたときのみ本件が発生するということになりますと
wakwakさんの環境が特別なのかな〜、と考えます。wakwakさんの環境を確認する必要がある
ように思われますが、いかがでしょう?
ヒデ
ベテラン
会議室デビュー日: 2002/12/12
投稿数: 76
お住まい・勤務地: 横浜
投稿日時: 2003-09-05 10:33
以前、私が勉強を兼ねて作ったのは、下記の通りで問題なく動きました。
とりあえず、メールの送信部分だけですが、参考にしみてください。
本文は、"message\n" 以下です。
Ken-Labさんが、仰るように改行が足りないみたいですね。

open(OUT,"|$mailer $send_ad") || die "送信できませんでした...\n";
print OUT "Date: $wday, $day $mont $year $hour:$min:$sec +0900\n";
print OUT "From: \"$user_id\"<$from_ad>\n"; # User mail address #
print OUT "To: $send_ad\n";
print OUT "Subject: $subj\n";
print OUT "Mime-Version: 1.0\n";
print OUT "Content-Type: text/plain; charset=ISO-2022-JP\n";
print OUT "Content-Transfer-Encoding: 7bit\n";
print OUT "\n";

print OUT "message\n";
ててて
会議室デビュー日: 2003/09/01
投稿数: 11
投稿日時: 2003-09-05 10:36
  print MAIL "From: $smail ($sname)\n";

って

  print MAIL "From: $smail ($sname)\r\n\r\n";

しなくてもいくもんなんですかね?
もし的外れな質問だったらごめんなさい。
ほむら
ぬし
会議室デビュー日: 2003/02/28
投稿数: 583
お住まい・勤務地: 東京都
投稿日時: 2003-09-05 11:18
ども。ほむらです。
Perlという単語に反応してしまいました。(笑
--------------
改行については"\n"でよいと思います。

逆に皆さんが言われているとおり
ヘッダの間に一行以上の空行が必要です。
また、ヘッダの内容も短すぎるのでできれば
自分で必要事項を付け加えてみてはどうでしようか。。

インターネットメッセージに関するRFCが役に立つと思います。

それと、今回sendmailを使用しているということですので
open(MAIL,〜)の直後に
local($_); select((select(MAIL), $| = 1)[0]);
はあったほうがいいと思います。

それと本文の最後に "\n.\n"も必要ですね。。。
僕の使用していた環境だと.を入れた瞬間sendmailは終わってしまう感じでしたので
close(MAIL);はなくてもいいかもしれません。

# ところで本文が文字化けってJISの文字がうまく表示できていないということですか?


[ メッセージ編集済み 編集者: ほむら 編集日時 2003-09-05 11:20 ]

スキルアップ/キャリアアップ(JOB@IT)