2012-01-03 11 views
8

(Dado que esta es mi primera pregunta SO, permítanme decir que espero que no sea tan específica de Zend. Por lo que puedo decir, esto no debería ser un problema. Aunque podría haberlo publicado en un foro específico de Zend, siento que al menos es probable que obtenga una buena respuesta aquí, especialmente dado que la respuesta podría incluir problemas relacionados con MIME que trascienden Zend Framework. m, básicamente, tratando de entender si el problema que estoy enfrentando debe considerarse un error ZF, o si estoy malentendido algo o mal uso de ella.)No entiendo por qué Zend_Mail :: addHeader() elimina las nuevas líneas

he estado usando Zend_Mail para construir un mensaje MIME que se enviado a través de SendGrid, un servicio de distribución de correo electrónico. Su plataforma le permite enviar correos electrónicos a través de su servidor SMTP, pero brinda funciones adicionales cuando usa un encabezado especial (X-SMTPAPI) cuyo valor es una cadena codificada JSON de parámetros de propiedad, que puede ser bastante larga.

Finalmente, el encabezado que estaba pasando se hizo demasiado largo (creo que> 1000 caracteres) y obtuve errores. Estaba confundido porque sabía que se estaba pasando a través de la función wordwrap() nativa de PHP antes de pasar el valor a Zend_Mail :: addHeader(), así que pensé que la longitud de la línea nunca debería ser un problema.

Resulta que addHeader() elimina nuevas líneas muy deliberadamente, y sin ninguna explicación particular a modo de comentarios.

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


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

Ok, esto parecía razonable al principio - tal vez ZF quiere un control total del formateo y del ajuste de línea. El siguiente método llamado en Zend_Mail :: addHeader() es

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

Este método codifica el valor (ya sea citado imprimible o base64 según corresponda) y trozos en líneas de longitud apropiada, pero solamente si contiene "caracteres no imprimibles", según lo determinado por Zend_Mime :: isPrintable ($ value).

Al examinar ese método, las líneas nuevas (\ n) se consideran, de hecho, caracteres no imprimibles. Así que si no hubieran sido eliminados de la cadena en la llamada al método anterior, el encabezado largo se codificaría como QP y se fragmentaría en líneas de 72 caracteres, y todo funcionaría bien. De hecho, hice una prueba donde comenté la llamada a _filterOther(), y el encabezado largo se codifica y se procesa sin problemas. Pero ahora acabo de hacer un truco descuidado de ZF sin entender realmente el propósito detrás de la línea que eliminé, por lo que esta no puede ser una solución a largo plazo.

Mi solución a medio plazo ha sido extender Zend_Mail y crear un nuevo método, addHeaderForceEncode(), que siempre codificará el valor del encabezado y, por lo tanto, siempre lo dividirá en líneas cortas. Pero todavía no estoy satisfecho porque no entiendo por qué esa llamada de _filterOther() fue necesaria en primer lugar, tal vez no debería estar trabajando en absoluto.

¿Alguien me puede explicar por qué existe este comportamiento de eliminar las nuevas líneas? Parece conducir inevitablemente a situaciones en las que un encabezado puede ser demasiado largo si no contiene ningún "carácter no imprimible" que no sean líneas nuevas.

He realizado varias búsquedas diferentes sobre este tema y he examinado algunos informes de fallas ZF, pero no he visto a nadie hablar de esto. Sorprendentemente, parece ser un problema realmente oscuro. FYI Estoy trabajando con ZF 1.11.11.


Actualización: En caso de que alguien quiere seguir el tema ZF abrí sobre esto, aquí está: Zend_Mail::addHeader() UNfolds long headers, then throws exception

+1

StackOverflow puede responder todo;) +1 Para su primera pregunta aquí. – Flavius

+0

Gracias por hacerme sentir bienvenido. – LinusR

Respuesta

6

Probablemente se esté corriendo en algunas cosas. Per RFC 2821, líneas de texto en SMTP no pueden exceder de 1000 caracteres:

línea de texto

La longitud total máxima de una línea de texto que incluye el IS 1000 caracteres (sin contar el punto inicial duplicado para transparencia) Este número puede aumentarse mediante el uso de las extensiones de servicio SMTP .

Un encabezado no puede contener líneas nuevas, por lo que es probable que Zend las elimine. Para los encabezados largos, es común insertar un salto de línea (CRLF en SMTP) y una pestaña para "envolverlos".

Extracto de RFC 822:

Cada campo de encabezado puede ser vista como una sola línea, lógica de caracteres ASCII, que comprende un nombre de campo y un campo-cuerpo. Para mayor comodidad, la parte del cuerpo del campo de esta entidad conceptual se puede dividir en una representación de múltiples líneas; este se llama "plegado". La regla general es que dondequiera que haya puede ser lineal-espacio-blanco (NO simplemente LWSP-chars), un CRLF seguido inmediatamente de POR LO MENOS un LWSP-char puede estar en su lugar insertado.

yo diría que la función _encodeHeader() debe posiblemente mirar longitud de la línea, y si la cabecera es más largo que un cierto valor magia, hacer el "envolver y ficha" tenerlo abarcar varias líneas.

+2

Lo revisé también y no aparece Zend_Mail admite el plegado del encabezado, ni tampoco le da una forma de agregar un "encabezado sin procesar" que no procesa. Parece que esta modificación se haría mejor en el método '_prepareHeaders' de' Zend_Mail_Transport_Abstract'. Si pasa el tercer parámetro '$ append' a' addHeader', doblará los datos adjuntos, pero también agregará una coma al final de la línea que creo que rompería su JSON. Esto podría ser digno de crear un [problema] (http://framework.zend.com/issues/secure/Dashboard.jspa). – drew010

+0

@tomlogic No entiendo por qué dijiste "Un encabezado no puede contener líneas nuevas, por eso es por lo que Zend las está eliminando", ya que las líneas nuevas como parte de CRLF son necesarias para doblar (como también lo indicaste a través del RFC 822) . Pero, en general, supongo que está de acuerdo en que falta algo de reconocimiento en addHeader() o _encodeHeader()? – LinusR

+0

@LinusR: Creo que Zend no espera un encabezado doblado, y es por eso que está eliminando las nuevas líneas. En mi opinión, Zend debería aceptar un encabezado doblado (donde cada CRLF va seguido de espacios en blanco, sin CR o LF desnudos) o intentar doblar encabezados largos. – tomlogic

Cuestiones relacionadas