2012-03-06 20 views
7

Estoy accediendo a la interfaz IMAP de GMail a través de python. Tengo un comando como este:El comando IMAP "encabezado de búsqueda" falla cuando el texto de búsqueda contiene un signo de exclamación (!), Ampersand (&), etc.

UID SEARCH HEADER Message-ID "[email protected]" 

que tiene éxito (1 devuelve el UID del mensaje coincidente, o 0 si no existe). Sin embargo, si el texto de búsqueda contiene ciertos caracteres (como & o!), El texto de búsqueda se trunca en ese punto. Esto significa:

UID SEARCH HEADER Message-ID "[email protected]" 

el tratamiento es el mismo que

UID SEARCH HEADER Message-ID "" 

también:

UID SEARCH HEADER Message-ID "[email protected]" 

se trata como:

UID SEARCH HEADER Message-ID "abc" 

He pasado por el lenguaje IMAP especificaciones, y de la especificación de lenguaje ABNF s eems como esos caracteres deben ser válidos. ¿Por qué gmail trunca estas frases de búsqueda en el "!" y "&" caracteres? ¿Hay alguna forma de escapar de ellos? (¡He intentado!, Falla como una cadena mal codificada). ¿Hay un RFC o un documento que muestre lo que realmente debería ser aceptado? ¿Es esto un error en la implementación imap de gmail?

También he intentado formato literal, los mismos resultados:

UID SEARCH HEADER Message-ID {15} 
[email protected] 

Aún así tratadas como:

UID SEARCH HEADER Message-ID {3} 
abc 

Gracias!

IMAP RFC3501 comando Buscar: http://tools.ietf.org/html/rfc3501#section-6.4.4 sintaxis formal: http://tools.ietf.org/html/rfc3501#section-9

+0

puedo confirmar que no hay nada especial sobre el uso de un signo de exclamación en la consulta de búsqueda. Lo más probable es que hayas encontrado un error en Gmail.Sugiero usar varios servidores IMAP diferentes durante el desarrollo, en particular debido a que la implementación IMAP de Gmail no es muy conocida por su conformidad con la especificación IMAP. – nosid

+0

Gracias, nosid. Desafortunadamente, el servidor IMAP que necesito usar con este código es gmail, por lo que las pruebas en otros no ayudarán con este error. Pero es bueno saber que no estoy leyendo las especificaciones incorrectamente. Trataré de encontrar la manera de reportar este error a google. – rocketmonkeys

+0

Sí, actualmente tengo este problema al hacer una búsqueda IMAP en Gmail a través del cliente de correo * alpine * que intenta seleccionar todos los mensajes con temas que contengan '!'. –

Respuesta

1

he estado golpeando este problema a mí mismo desde hace meses.

ENCABEZADO DE BÚSQUEDA Message-ID < -! &! ...>

Terminó salteando algunas búsquedas de MsgId que comienzan con '< -'. También vea los problemas con &! 'S ... No estoy seguro de cómo solucionar esto bien.

¿Alguna vez recibió una palabra de Google sobre este error?

Gracias mucho

2

Estoy en gran medida basando mi respuesta en el descubrimiento (por Max) en los comentarios a la pregunta original que la aplicación de búsqueda de Gmail utiliza una base de datos de respaldo que tiene el contenido textual ya se dividió en palabra fichas en lugar de almacenar el texto completo y hacer una búsqueda de subcadena.

Así que aquí es una posible solución que se puede utilizar con Gmail en C# usando mi MailKit biblioteca (que es una biblioteca IMAP de bajo nivel bastante así que esto debería traducirse fácilmente en pseudocódigo básico):

// given: text = "[email protected]" 

// split the search text on '!' 
var words = text.Split (new char[] { '!' }, StringSplitOptions.RemoveEmptyEntries); 

// build a search query... 
var query = SearchQuery.HeaderContains ("Message-ID", words[0]); 
for (int i = 1; i < words.Count; i++) 
    query = query.And (SearchQuery.HeaderContains ("Message-ID", words[i])); 

// this will result in a query like this: 
// HEADER "Message-ID" "abc" HEADER "Message-ID" "[email protected]" 

// Do the UID SEARCH with the constructed query: 
// A001 UID SEARCH HEADER "Message-Id" "abc" HEADER "Message-Id" "[email protected]" 
var uids = mailbox.Search (query); 

// Now UID FETCH the ENVELOPE (and UID) for each of the potential matches: 
// A002 UID FETCH <uids> (UID ENVELOPE) 
var messages = mailbox.Fetch (uids, MessageSummaryItems.UniqueId | 
    MessageSummaryItems.Envelope); 

// Now perform a manual comparison of the Message-IDs to get only exact matches... 
var matches = new UniqueIdSet (SortOrder.Ascending); 
foreach (var message in messages) { 
    if (message.Envelope.MessageId.Contains (text)) 
     matches.Add (message.UniqueId); 
} 

// 'matches' now contains only the set of UIDs that exactly match your search query 
Cuestiones relacionadas