I can’t understand why Zend_Mail :: addHeader () wraps newline

(Since this is my first SO question, let me just say that I hope this is not too specific for Zend. As far as I can tell, this should not be a problem. Although I could post it in the Zend-specific forum, I feel that I, at least, get a good answer here as soon as possible, especially since the answer may include MIME-related issues that go beyond the scope of the Zend Framework. I am basically trying to figure out if there should be a problem that I encounter, it is considered a ZF error, or if I misunderstand something or use it incorrectly zuyu.)

I used Zend_Mail to create a MIME message that is sent via SendGrid, an email distribution service. Their platform allows you to send e-mail through their SMTP server, but gives additional functions when you use a special header (X-SMTPAPI), the value of which is a JSON encoded string of patented parameters, which can take quite a lot of time.

In the end, the header that I skipped went too long (I think> 1000 characters) and I got errors. I was confused because I knew that it goes through the PHP function native wordwrap () before passing the value to Zend_Mail :: addHeader (), so I thought that the length of the string would never be a problem.

It turns out that addHeader () translates newline strings very intensively and without any special explanation in the comments.

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

Well, at first it seemed reasonable - perhaps ZF wants to have full control over the formatting and wrapping of lines. The following method called in Zend_Mail :: addHeader (),

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

This method encodes a value (as indicated by quotation marks or base64) and splits it into strings of appropriate length, but only if it contains "non-printable characters", as defined by Zend_Mime :: isPrintable ($ value).

In this method, newlines (\ n) are indeed considered non-printable characters! Therefore, if they had not been removed from the line in the previous method call, the long header would have been encoded as QP and marked in 72-char lines, and everything would work fine. In fact, I did a test where I commented on the call to _filterOther (), and the long header gets the encoding and passes without problems. But now I just did the reckless hack of ZF, not understanding the goals behind the line I deleted, so this cannot be a long-term solution.

My medium-term solution was to extend Zend_Mail and create a new addHeaderForceEncode () method that will always encode the value of the header and thus always put it in short lines. But I'm still not satisfied because I don’t understand why this call to _filterOther () was necessary in the first place - maybe I didn’t have to go around it at all.

Can someone explain to me why this behavior exists to remove newlines? This seems to inevitably lead to situations where the title may take up too much if it does not contain any “non-printable characters” other than newlines.

I did several different searches on this subject and looked at some ZF error reports, but did not see anyone talking about it. Surprisingly, this is apparently a very obscure issue. FYI I work with ZF 11.11.11.


Update: In case someone wants to follow the ZF problem, I opened it, here it is: Zend_Mail :: addHeader () Expands long headers, then throws an exception

+8
php mime smtp zend-framework zend-mail
source share
1 answer

You probably come across a few things. Per RFC 2821 , text strings in SMTP cannot exceed 1000 characters:

text string

The maximum total length of a text string, including 1000 characters (not counting the leading point, duplicated for transparency). This number can be increased through the use of SMTP Service Extensions.

The header cannot contain newlines, so perhaps Zend robs them. For long headers, it is usually necessary to insert a line break (CRLF in SMTP) and a tab to “wrap” them.

Excerpt from RFC 822 :

Each header field can be considered as a single logical line ASCII characters containing the field name and body field. For convenience, the field portion of this conceptual object can be divided into a multi-line representation; this is called folding. A general rule is that there can be linear white space everywhere (not just LWSP characters), CRLF immediately after which it follows that one LWSP char can be inserted.

I would say that the _encodeHeader() function should probably look at the length of the string, and if the title is longer than some magic value, make "wrap and tab" so that it spans several lines.

+6
source share

All Articles