MBOX-Line: From tss at iki.fi  Sat May 12 01:42:41 2012
To: imap-protocol@u.washington.edu
From: Timo Sirainen <tss@iki.fi>
Date: Fri Jun  8 12:34:48 2018
Subject: [Imap-protocol] partial fetch of BODY data
In-Reply-To: <4FAE0F7F.9000709@ymail.com>
References: <4FAE0F7F.9000709@ymail.com>
Message-ID: <2A0907F0-BF62-4E83-B3BE-0957A736A820@iki.fi>

On 12.5.2012, at 10.21, Bill Shannon wrote:

> The spec says of a FETCH BODY request:
> 
>         Any partial fetch that attempts to read beyond the end of the
>         text is truncated as appropriate.  A partial fetch that starts
>         at octet 0 is returned as a partial fetch, even if this
>         truncation happened.

This is mainly about how the server is supposed to reply to it, i.e. it should still give BODY[]<0> reply instead of BODY[]. All partial replies may be truncated, this just tries to clarify that offset=0 shouldn't be treated as a special case.

> The spec says of a FETCH BODY response:
> 
>         If the origin octet is specified, this string is a substring of
>         the entire body contents, starting at that origin octet.  This
>         means that BODY[]<0> MAY be truncated, but BODY[] is NEVER
>         truncated.

This is an instruction for client implementors about what they may assume about the replies.

> It's not clear whether the truncation being talked about is the same in
> both cases.  If it were only allowed to truncate the response at the end
> of the data, "BODY[]" would be allowed to be truncated as well, so it
> seems that it must be talking about truncation for some other reason.

Truncation means that a partial fetch ended before the requested number of bytes. BODY[] always requests all bytes.

> If I do "FETCH 2 (BODY[]<0.16384>)" and the server responds
> "2 FETCH (BODY[]<0> {2817}", can I assume that that's the end
> of the data or not?

If the client remembers that it fetched 16384 bytes (or anything more than 2817 bytes) it can assume it's at end of data.

> What if I request "FETCH 2 (BODY[]<16384.16384>)" and the response is
> "2 FETCH (BODY[]<16384> {2817}"?  Is that a different case than above,
> since the request doesn't start at octet 0?

If this was the same mail as above then the server's reply would be an empty string. But assuming a different mail then the message's size can be assumed to be 19201 bytes.

> If I do "FETCH 2 (BODY[]<2817.16384>)" and the server responds
> "2 FETCH (BODY[]<2817> {0}" I know I'm at the end of the data.  

Yes. The reply may also be "" instead of {0}.

> Is
> "2 FETCH (BODY[]<2817> NIL)" semantically equivalent?  The spec says:
> 
>         ...  If the starting octet is beyond
>         the end of the text, an empty string is returned.
> 
> Is "NIL" equivalent to an empty string in this case?  

No.

> It would appear not,
> according to this part of the spec:
> 
>   The special form "NIL" represents the non-existence of a particular
>   data item that is represented as a string or parenthesized list, as
>   distinct from the empty string "" or the empty parenthesized list ().
> 
> Even though the syntax specifies "nstring", is "NIL" a valid response
> in this case?

A well behaving server should never return NIL to any replies. But many servers do if the fetched message has already been expunged by another session.
