MIME 编码的折叠主题标头在调用 mail() 时导致警告
Posted
技术标签:
【中文标题】MIME 编码的折叠主题标头在调用 mail() 时导致警告【英文标题】:MIME encoded folded Subject header results in warning when calling mail() 【发布时间】:2013-04-20 17:05:14 【问题描述】:当主题标头被 MIME 编码并折叠 mail()
时,会导致 php 警告:
<?php
$mime_subject = "=?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?=\r\n =?ISO-8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?=";
mail( "name@domain.com", $mime_subject , "Hallo");
=> mail(): Bad parameters to mail() function, mail not sent.
主题行是 RFC2047(第 8 节)中的示例之一。它被折叠成两行,mail()
不喜欢它。由于它在其他主机上运行良好,我怀疑配置错误。但那会是哪一个呢?
PHP 是 5.4.0 版
有什么想法吗?
编辑:
关于 php 配置的更多信息:
'./configure' '--prefix=/home/www/PHP/php-5.4.0' '--with-openssl'
'--with-zlib-dir=/usr/lib/' '--with-jpeg-dir=/usr/lib/' '--with-mysql'
'--enable-fastcgi' '--with-informix=/opt/informix'
'--with-oci8=shared,instantclient,/opt/oracleclient/instantclient,10.2'
'--enable-pcntl' '--with-gettext' '--with-ldap' '--with-curl'
'--with-gd' '--with-freetype-dir=/usr/include/freetype2/' '--with-dom'
'--enable-bcmath' '--enable-soap' '--enable-mbstring'
'--with-mcrypt=shared,/usr/local/libmcrypt' '--enable-pdo'
'--with-pdo-mysql' '--enable-zip' '--with-imap' '--with-kerberos'
'--with-imap-ssl' '--with-ldap-sasl' '--with-icu-dir=/usr' '--enable-intl'
mail.add_x_header Off Off
mail.force_extra_parameters no value no value
mail.log no value no value
sendmail_from no value no value
sendmail_path /usr/sbin/sendmail -t -i /usr/sbin/sendmail -t -i
SMTP localhost localhost
smtp_port 25 25
mailparse version 2.1.6
【问题讨论】:
换行的目的是什么?无论如何,您并没有传递任何人类可读的内容,我推测删除它会解决问题。 因为 RFC2047 第 2 节。编码字的语法:“编码字”的长度不得超过 75 个字符,包括“字符集”、“编码”、“编码文本”、和分隔符。如果希望编码的文本多于 75 个字符的“编码字”,则可以使用多个“编码字”(由 CRLF SPACE 分隔)。 (ietf.org/rfc/rfc2047.txt) 是的,但如果这不是 PHP 界面向您公开的内容,则不一定相关。 我不确定我理解你的意思。根据php.net/manual/en/function.mail.php,主题需要遵守2047。我在它工作的其他机器上进行了测试。我只是想知道,为什么它不能在一台机器上工作。 【参考方案1】:您是正确的,该示例应该只是“我可以阅读”。但是 PHP 文档中的另一个注释提到,一些邮件传输代理会自动将 \n
更改为 \r\n
,因此如果您已经提供了 \r\n
(变为 \r\r\n
),则会导致问题。
因此您可以尝试使用下面的代码(虽然它不符合标准,但您的邮件代理可能会使其符合标准)
<?php
$mime_subject = "=?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?=\n=?ISO-8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?=";
mail( "name@domain.com", $mime_subject , "Hallo");
?>
PHP 在自己的代码中几乎不会检查有效主题,因此它全部由您的邮件代理处理。
PHP 源代码(只是主题检查,看它没有什么特别的):
if (subject_len > 0)
subject_r = estrndup(subject, subject_len);
for (; subject_len; subject_len--)
if (!isspace((unsigned char) subject_r[subject_len - 1]))
break;
subject_r[subject_len - 1] = '\0';
for (i = 0; subject_r[i]; i++)
if (iscntrl((unsigned char) subject_r[i]))
/* According to RFC 822, section 3.1.1 long headers may be separated into
* parts using CRLF followed at least one linear-white-space character ('\t' or ' ').
* To prevent these separators from being replaced with a space, we use the
* SKIP_LONG_HEADER_SEP to skip over them. */
SKIP_LONG_HEADER_SEP(subject_r, i);
subject_r[i] = ' ';
else
subject_r = subject;
【讨论】:
问题出现在 \n 和 \r\n 上。标准中需要额外的空间。我想这是为了检测多行标题。它甚至在您发布的来源中也是如此。 我们正在使用 sendmail。您是否碰巧哪种配置可能导致此错误? 笨蛋,先打空格部分再加代码。删除它。额外的\r
有几个,但根据 qmail 的说法,它最为人所知。您的文件/编码可能是什么?如果使用utf8_encode($subject)
发送呢?检查 ***.com/questions/8171856/… 以获取在 sendmail 上存在编码问题的 python 脚本
没有 UTF-8,只有 ISO-8859-1。仅使用属于 8859-1 一部分的非英语字符(德语变音符号和法语重音字符)。
这是一种猜谜游戏 :) 但是我的服务器有一些与你的不同的设置,如果你可以改变它来测试,可能会让它工作。对我来说,mail.add_x_header
都打开了,sendmail_from
有一个本地值(电子邮件地址),sendmail_path
没有任何值。还设置了mail.log
,但我认为这并不重要。但是当然设置日志可以帮助您确定哪里出错了。没有任何设置与您正在做的事情直接相关,但是由于它应该可以正常工作,因此您有时会在最奇怪的地方找到解决方案以上是关于MIME 编码的折叠主题标头在调用 mail() 时导致警告的主要内容,如果未能解决你的问题,请参考以下文章