8

(これは私の最初の SO の質問なので、Zend 固有のものではないことを願っています。私が知る限り、これは問題ではないと言えます。Zend 固有のフォーラムに投稿することもできましたが、特にZend Frameworkを超えるMIME関連の問題が回答に含まれる可能性があるため、ここで少なくとも良い回答が得られる可能性が高いと感じています.私は基本的に、私が直面している問題がZFと見なされるべきかどうかを理解しようとしています.バグ、または私が何かを誤解している、または誤用している場合。)

Zend_Mail を使用して、メール配信サービスである SendGrid を介して送信される MIME メッセージを作成しています。彼らのプラットフォームでは、SMTP サーバーを介して電子メールを送信できますが、値が非常に長くなる独自のパラメーターの JSON エンコード文字列である特別なヘッダー (X-SMTPAPI) を使用すると、追加機能が提供されます。

最終的に、渡していたヘッダーが長すぎて (1000 文字を超えると思います)、エラーが発生しました。Zend_Mail::addHeader() に値を渡す前に、PHP のネイティブの wordwrap() 関数を介して値が渡されることを知っていたので、混乱しました。したがって、行の長さは問題にならないと考えました。

addHeader() は非常に意図的に改行を削除し、コメントによる特別な説明はありません。

// In Zend_Mail::addHeader()
$value = $this->_filterOther($value);


// In Zend_Mail::_filterOther()
$rule = array("\r" => '',
              "\n" => '',
              "\t" => '',
);
return strtr($data, $rule);

わかりました、これは最初は理にかなっているように思えました。おそらく、ZF は書式設定と行の折り返しを完全に制御したいと考えています。Zend_Mail::addHeader() で呼び出される次のメソッドは、

$value = $this->_encodeHeader($value);

このメソッドは、値を (必要に応じて quoted-printable または base64 のいずれかで) エンコードし、適切な長さの行にチャンクします

その方法を調べると、改行 (\n) は確かに印刷できない文字と見なされます! したがって、前のメソッド呼び出しで文字列からそれらが取り除かれていなければ、長いヘッダーは QP としてエンコードされ、72 文字の行にチャンクされ、すべてが正常に機能します。実際、_filterOther() の呼び出しをコメントアウトしたテストを行ったところ、長いヘッダーがエンコードされ、問題なく処理されました。しかし今、削除した行の背後にある目的を本当に理解せずに ZF に不注意なハックを行ったので、これは長期的な解決策にはなりません。

私の中期的な解決策は、Zend_Mail を拡張し、新しいメソッド addHeaderForceEncode() を作成することでした。このメソッドは、常にヘッダーの値をエンコードし、常に短い行にチャンクします。しかし、そもそも _filterOther() 呼び出しが必要な理由が理解できないため、まだ満足していません。おそらく、それを回避する必要はまったくありません。

改行を削除するというこの動作が存在する理由を誰かに説明できますか? ヘッダーに改行以外の「印刷できない文字」が含まれていないと、ヘッダーが長くなりすぎる状況が必然的に発生するようです。

私はこの件に関してさまざまな検索を行い、いくつかの ZF バグ レポートに目を通しましたが、これについて話している人は見たことがありません。驚くべきことに、それは本当にあいまいな問題のようです。参考までに、私は ZF 1.11.11 で作業しています。


更新:誰かが私がこれについてオープンした ZF の問題を追跡したい場合は、次のとおりです: Zend_Mail::addHeader() は長いヘッダーを展開し、例外をスローします

4

1 に答える 1

6

あなたはおそらくいくつかのことに遭遇しています。RFC 2821 に従って、SMTP のテキスト行は 1000 文字を超えることはできません。

テキスト行

を含むテキスト行の最大合計長は 1000 文字です (透明性のために複製された先頭のドットはカウントされません)。この数は、SMTP サービス拡張機能を使用することで増加する可能性があります。

ヘッダーに改行を含めることはできないため、Zend が改行を削除しているのはおそらくそのためです。長いヘッダーの場合、改行 (SMTP の CRLF) とタブを挿入して "ラップ" するのが一般的です。

RFC 822からの抜粋:

各ヘッダー フィールドは、フィールド名とフィールド本体で構成される ASCII 文字の単一の論理行として表示できます。便宜上、この概念エンティティのフィールド本体部分は、複数行の表現に分割できます。これは「折り畳み」と呼ばれます。一般的なルールは、線形空白 (単純な LWSP 文字ではない) が存在する可能性がある場合は常に、代わりに少なくとも 1 つの LWSP 文字が続く CRLF を挿入することができるということです。

関数は_encodeHeader()おそらく行の長さを確認する必要があり、ヘッダーが魔法の値よりも長い場合は、「折り返しとタブ」を実行して複数の行にまたがるようにします。

于 2012-01-03T22:53:53.407 に答える