Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: MsgID without downloading the mail ?



Permlink Replies: 3 - Last Post: Jun 5, 2017 11:17 AM Last Post By: Remy Lebeau (Te... Threads: [ Previous | Next ]
Asger Joergensen

Posts: 370
Registered: 11/18/08
MsgID without downloading the mail ?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 2, 2017 8:50 AM
Hi

Is it possible to get the TIdMessage::MsgId without downloading the
whole message ?

I'm thinking something like what I can do to get internal date:
FIdIMAP4->UIDRetrieveValue( sUID, L"MESSAGE-ID", sMessageID )

Thanks in advance
Bet regards
Asger
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: MsgID without downloading the mail ?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 2, 2017 9:46 AM   in response to: Asger Joergensen in response to: Asger Joergensen
Asger Joergensen wrote:

Is it possible to get the TIdMessage::MsgId without downloading the
whole message ?

You could use the TIdIMAP4.(UID)RetrieveEnvelope() method, which
populates the following TIdMessage property values:

Date
Subject
FromList
Sender
ReplyTo
Recipients
CCList
BccList
InReplyTo
MsgId ***

I'm thinking something like what I can do to get internal date:

FIdIMAP4->UIDRetrieveValue( sUID, L"MESSAGE-ID", sMessageID )

The (UID)RetrieveValue() methods are a simplied wrapper for a FETCH
command (https://tools.ietf.org/html/rfc3501#section-6.4.5). You can
retreive the entire email header by fetching "RFC822.HEADER" or
"BODY.PEEK[HEADER]", or you can retreive just the "Message-ID" by
itself (or any other specific headers) by fetching "BODY[HEADER.FIELDS
(MESSAGE-ID)])". Either way, you will have to parse the resulting
string manually to extract the "Message-ID" header value.

--
Remy Lebeau (TeamB)
Asger Joergensen

Posts: 370
Registered: 11/18/08
Re: MsgID without downloading the mail ?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 2, 2017 10:51 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Hi Remy

I will try UIDRetrieveEnvelope() if I can't make it work just getting
the Message-ID

Remy Lebeau (TeamB) wrote:

The (UID)RetrieveValue() methods are a simplied wrapper for a FETCH
command (https://tools.ietf.org/html/rfc3501#section-6.4.5). You can
retreive the entire email header by fetching "RFC822.HEADER" or
"BODY.PEEK[HEADER]", or you can retreive just the "Message-ID" by
itself (or any other specific headers) by fetching "BODY[HEADER.FIELDS
(MESSAGE-ID)])". Either way, you will have to parse the resulting
string manually to extract the "Message-ID" header value.

trying this code:

   String sMessageID;
   if( FIdIMAP4->UIDRetrieveValue( sUID, L"BODY[HEADER.FIELDS(MESSAGE-ID)]", sMessageID ) )
   {
      DebugStr( sMessageID );
   } 


Gives me an EIdReplyIMAP4Error exception saying this:

Unexpected: Non-last response line (i.e. a data line) only contained one word,
instead of a * followed by one or more words, offending line:
DI0MjQzNDM0MzQ0NDQ0NDQ1NDU0NTQ2NDY0NjQ3NDc0NzQ4NDg0ODQ5NDk0OTRB

trying this code:
   String sMessageID;
   if( FIdIMAP4->UIDRetrieveValue( sUID, L"BODY[HEADER.FIELDS (TO)]", sMessageID ) )
   {
      DebugStr( sMessageID );
   } 


Just makes the function fail.:(
So I guess MESSAGE-ID is not the right command word.
Further testing shows that if I put in a space between FIELDS and ( they both just fail so
MESSAGE-ID might be right after all, but then some other thing is wrong.

Thanks for helping
Best regards
Asger

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: MsgID without downloading the mail ?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 5, 2017 11:17 AM   in response to: Asger Joergensen in response to: Asger Joergensen
Asger Joergensen wrote:

trying this code:

   String sMessageID;
   if( FIdIMAP4->UIDRetrieveValue( sUID,
L"BODY[HEADER.FIELDS(MESSAGE-ID)]", sMessageID ) )    {
      DebugStr( sMessageID );
   } 

You are missing a required space after 'HEADER.FIELDS' and before '('.
See my earlier example again, or the examples in the RFC. The formal
definition of "section-msgtext" is in RFC 3501 Section 9:

section-msgtext = "HEADER" / "HEADER.FIELDS" [".NOT"] SP header-list /
"TEXT"
; top-level or MESSAGE/RFC822 part

Note the "SP" in front of "header-list".

Gives me an EIdReplyIMAP4Error exception saying this:

Unexpected: Non-last response line (i.e. a data line) only contained
one word, instead of a * followed by one or more words, offending
line: DI0MjQzNDM0MzQ0NDQ0NDQ1NDU0NTQ2NDY0NjQ3NDc0NzQ4NDg0ODQ5NDk0OTRB

That does not appear to be a valid IMAP response. Maybe a server bug?
What does the COMPLETE response look like?

When I send that same command to one of my IMAP servers (Yahoo), I do
not get an exception raised. UIDRetrieveValue() just returns false
instead. This is the actual server response:

C6 UID FETCH 10990 (BODY[HEADER.FIELDS(MESSAGE-ID)])
C6 BAD [CLIENTBUG] UID FETCH Command arguments invalid


When I put the space in, this is the response I get instead:

C6 UID FETCH 10990 (BODY[HEADER.FIELDS (MESSAGE-ID)])
* 1 FETCH (FLAGS (\Answered \Seen) UID 10990 BODY[HEADER.FIELDS
(MESSAGE-ID)] {84}
Message-ID: <...>
 
)
C6 OK UID FETCH completed


However, UIDRetrieveValue() still returns false, even though the
response was successful. That means TIdIMAP4 is having trouble parsing
the response.

Turns out that inside of TIdIMAP4.ParseLastCmdResult(), the call to
ParseIntoBrackettedQuotedAndUnquotedParts() is not splitting the
response correctly, the space characters in 'BODY[HEADER.FIELDS
(MESSAGE-ID)]' and 'Message-ID: <...>' are confusing it.

trying this code:

   String sMessageID;
   if( FIdIMAP4->UIDRetrieveValue( sUID, L"BODY[HEADER.FIELDS (TO)]",
sMessageID ) )    {
      DebugStr( sMessageID );
   } 


Just makes the function fail.:(

Same as above. It is actually succeeding, TIdIMAP4 is just not parsing
the response correctly.

I have opened a bug report:

#175 Parsing error in
TIdIMAP4.ParseIntoBrackettedQuotedAndUnquotedParts()
https://github.com/IndySockets/Indy/issues/175

So I guess MESSAGE-ID is not the right command word.

It is correct, per the IMAP spec, section 6.4.5:

BODY[<section>]<<partial>>
The text of a particular body section. The section
specification is a set of zero or more part specifiers
delimited by periods. A part specifier is either a part number
or one of the following: HEADER, HEADER.FIELDS,
HEADER.FIELDS.NOT, MIME, and TEXT. An empty section
specification refers to the entire message, including the
header.

...

The HEADER, HEADER.FIELDS, and HEADER.FIELDS.NOT part
specifiers refer to the [RFC-2822] header of the message or of
an encapsulated [MIME-IMT] MESSAGE/RFC822 message.
HEADER.FIELDS and HEADER.FIELDS.NOT are followed by a list of
field-name (as defined in [RFC-2822]) names, and return a
subset of the header. The subset returned by HEADER.FIELDS
contains only those header fields with a field-name that
matches one of the names in the list; similarly, the subset
returned by HEADER.FIELDS.NOT contains only the header fields
with a non-matching field-name. The field-matching is
case-insensitive but otherwise exact. Subsetting does not
exclude the [RFC-2822] delimiting blank line between the header
and the body; the blank line is included in all header fetches,
except in the case of a message which has no body and no blank
line.

That says that any RFC-2822 compliant header name can be requested.
"Message-ID" is a valid header name, and it is defined in RFC-2822.

Further testing shows that if I put in a space between FIELDS and (
they both just fail so MESSAGE-ID might be right after all, but then
some other thing is wrong.

Yes, something else is going wrong. UIDRetrieveValue() is not parsing
the valid response correctly.

--
Remy Lebeau (TeamB)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02