<?xml version="1.0" encoding="US-ASCII"?>

<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
<!ENTITY RFC2045 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2045.xml">
<!ENTITY RFC2119 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml">
<!ENTITY RFC2854 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2854.xml">
<!ENTITY RFC3501 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.3501.xml">
<!ENTITY RFC3629 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.3629.xml">
<!ENTITY RFC5182 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5182.xml">
<!ENTITY RFC5234 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5234.xml">
<!ENTITY RFC5255 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5255.xml">
]>

<?xml-stylesheet type='text/xsl' href='rfc2629.xslt' ?>

<?rfc strict="yes" ?>
<?rfc toc="yes"?>
<?rfc symrefs="yes"?>
<?rfc sortrefs="yes" ?>
<?rfc compact="yes" ?>
<?rfc subcompact="no" ?>

<rfc category="std" docName="draft-slusarz-imap-fetch-snippet-00" ipr="trust200902">
  <front>
    <title abbrev="IMAP: SNIPPET Extension">IMAP4 Extension: Message Snippet Generation</title>
    <author fullname="Michael Slusarz" initials="M." surname="Slusarz">
      <organization>Open-Xchange Inc.</organization>

      <address>
        <postal>
          <street></street>
          <city>Denver</city>
          <region>Colorado</region>
          <code></code>
          <country>US</country>
        </postal>
        <phone></phone>
        <email>michael.slusarz@open-xchange.com</email>
      </address>
    </author>

    <date year="2018" />

    <area>ART</area>
    <!-- <workgroup>EXTRA</workgroup> -->

    <keyword>IMAP4</keyword>
    <keyword>FETCH</keyword>
    <keyword>SNIPPET</keyword>

    <abstract>
        <t>This document specifies an IMAP protocol extension which allows
        a client to request that a server provide an abbreviated representation
        of a message (a snippet of text) that can be used by a client to provide
        a useful contextual preview of the message contents.</t>
    </abstract>
  </front>

  <middle>
    <section anchor="Introduction" title="Introduction">
        <t>Many modern mail clients display small extracts of the body text as
        an aid to allow a user to quickly decide whether they are interested in
        viewing the full message contents. Mail clients implementing the
        Internet Message Access Protocol (IMAP; <xref target="RFC3501">RFC
        3501</xref>) would benefit from a standardized, consistent way to
        generate these brief previews of messages (a "snippet").</t>

        <t>Generation of snippets on the server has several benefits. First,
        it allows consistent representation of snippets across all clients.
        This standardized display can reduce user confusion when using
        multiple clients, as abbreviated message representations in clients
        will show identical message details.</t>

        <t>Second, server-side snippet generation is more efficient. A
        client-based algorithm needs to issue, at a minimum, a FETCH
        BODYSTRUCTURE command in order to determine which <xref
        target="RFC2045">MIME</xref> body part(s) should be represented in
        the snippet. Subsequently, at least one FETCH BODY command may be
        needed to retrieve body data used in snippet generation. These FETCH
        commands cannot be pipelined since the BODYSTRUCTURE query must be
        parsed on the client before the list of parts to be retrieved via the
        BODY command(s) can be determined.</t>

        <t>Additionally, it may be difficult to predict the amount of body
        data that must be retrieved to adequately represent the part via a
        snippet, therefore requiring inefficient fetching of excessive data
        in order to account for this uncertainty. For example, a snippet
        algorithm to display data contained in a <xref
        target="RFC2854">text/html</xref> part will likely
        strip the markup tags to obtain textual content. However, without
        fetching the entire content of the part, there is no way to guarantee
        that sufficient non-tag content will exist unless either 1) the entire
        part is retrieved or 2) an additional partial FETCH is executed when
        the client determines that it does not possess sufficient data from a
        previous partial FETCH to display an adequate representation of the
        snippet.</t>

        <t>Finally, server generation allows caching in a centralized
        location. Using server generated snippets allows snippets
        to be generated globally once per message, and then cached
        indefinitely. Retrieval of message data may be expensive within a
        server, for example, so a server can be configured to reduce its
        storage retrieval load by pre-generating snippet data.</t>

        <t>A server that supports the SNIPPET extension indicates this with one
        or more capability names consisting of "SNIPPET=" followed by a
        supported snippet algorithm name. This format provides for future
        upwards-compatible extensions and/or the ability to use locally-defined
        snippet algorithms.</t>
    </section>

    <section anchor="Conventions" title="Conventions Used In This Document">
        <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
        "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
        document are to be interpreted as described in <xref
        target="RFC2119">RFC 2119</xref>.</t>

        <t>"User" is used to refer to a human user, whereas "client" refers to
        the software being run by the user.</t>

        <t>In examples, "C:" and "S:" indicate lines sent by the client and
        server respectively. If a single "C:" or "S:" label applies to
        multiple lines, then the line breaks between those lines are for
        editorial clarity only and are not part of the actual protocol
        exchange.</t>
    </section>

    <section anchor="Fetch" title="FETCH Data Item">
      <section title="Command">
        <t>To retrieve a snippet for a message, the "SNIPPET" FETCH attribute
        is used when issuing a FETCH command.</t>

        <t>If no algorithm identifier is provided, the server decides which
        of its built-in algorithms to use to generate the snippet text.</t>

        <t>Alternately, the client may explicitly indicate which algorithm(s)
        should be used in a parenthesized list after the SNIPPET attribute
        containing the name of the algorithm. These algorithms MUST be one of
        the algorithms identified as supported in the SNIPPET capability
        responses. If a client requests an algorithm that is unsupported, the
        server MUST return a tagged BAD response.</t>

        <t>The order of the algorithms in the parenthesized list (from left
        to right) defines the client's priority decision. Duplicate algorithms
        in the list SHOULD be ignored. For purposes of duplicate detection,
        <xref target="Modifiers">priority modifiers</xref> should be ignored.
        A server MUST honor a client's algorithm priority decision.</t>
      </section>

      <section title="Response">
        <t>The algorithm used by the server to generate the snippet is
        returned preceding the snippet string.</t>

        <t>The server returns a variable-length string that is the generated
        snippet for that message.</t>

        <t>A server SHOULD strive to generate the same string for a given
        message for each request. However, since snippets are understood to be
        a representation of the message data and not a canonical view of its
        contents, a client MUST NOT assume that a message snippet is
        immutable for a given message. This relaxed requirement permits a
        server to offer snippets as an option without requiring potentially
        burdensome storage and/or processing requirements to guarantee
        immutability for a use case that does not require this strictness.</t>

        <t>If the snippet is not available, the server MUST return NIL as the
        SNIPPET response. A NIL response indicates to the client that
        snippet information MAY become available in a future SNIPPET FETCH
        request.</t>
      </section>
    </section>

    <section anchor="Algorithms" title="SNIPPET Algorithms">
      <section anchor="FUZZY" title="FUZZY">
        <t>The FUZZY algorithm directs the server to use any internal
        algorithm it desires, subject to the below limitations, to generate
        a textual snippet for a message.</t>

        <t>The FUZZY algorithm MUST be implemented by any server that supports
        the SNIPPET extension.</t>

        <t>The generated string MUST NOT be content transfer encoded and MUST
        be encoded in <xref target="RFC3629">UTF-8</xref>.</t>

        <t>The snippet text MUST be treated as text/plain MIME data by the
        client.</t>

        <t>The server SHOULD limit the length of the snippet text to 100
        characters. The server MUST NOT output snippet text longer than 200
        characters.</t>

        <t>The server SHOULD remove any formatting markup that exists in the
        original text.</t>

        <t>If the FUZZY algorithm generates a snippet that is not based on
        the body content of the message and the <xref
        target="RFC5255">LANGUAGE</xref> extension is supported by the server,
        the snippet text SHOULD be generated according to the the language
        rules that apply to human-readable text.</t>
      </section>
    </section>

    <section anchor="Modifiers" title="SNIPPET Priority Modifiers">
      <section anchor="LAZY" title="LAZY">
        <t>The LAZY modifier directs the server to return the snippet
        representation only if that data can be returned without undue
        delay to the client.</t>

        <t>This modifier allows a client to inform the server that snippet
        data is nice-to-have, but the server SHOULD NOT block the return of
        other FETCH information at the expense of generating the snippet
        data.</t>

        <t>For example, a client displaying the initial mailbox listing to a
        user may want to display snippet information associated with
        messages in that listing. However, this information is secondary to
        providing the mailbox listing, with message details, and the client
        is willing to load any unavailable snippets in the background and
        display them as they are provided by the server. In this case, the
        client would use the LAZY modifier to the desired algorithm(s) to
        direct the server to only return pre-generated snippet data so that
        retrieval of the other FETCH information is not blocked by possibly
        expensive snippet generation.</t>

        <t>The LAZY modifier MUST be implemented by any server that supports
        the SNIPPET extension.</t>
      </section>
    </section>

    <section anchor="Examples" title="Examples">
      <figure>
        <preamble>Example 1: Requesting FETCH without explicit algorithm
        selection</preamble>

        <artwork><![CDATA[
  C: A1 CAPABILITY
  S: * CAPABILITY IMAP4rev1 SNIPPET=FUZZY
  S: A1 OK Capability command completed.
  [...a mailbox is SELECTed...]
  C: A2 FETCH 1 (RFC822.SIZE SNIPPET)
  S: * 1 FETCH (RFC822.SIZE 20000 SNIPPET (FUZZY {61}
  S: This is the first line of text from the first text part.
  S: ))
  S: A2 OK FETCH complete.
]]></artwork>
      </figure>

      <figure>
        <preamble>Example 2: Requesting FETCH with explicit algorithm
        selection</preamble>

        <artwork><![CDATA[
  C: B1 CAPABILITY
  S: * CAPABILITY IMAP4rev1 SNIPPET=FUZZY
  S: B1 OK Capability command completed.
  [...a mailbox is SELECTed...]
  C: B2 FETCH 1 (RFC822.SIZE SNIPPET (FUZZY))
  S: * 1 FETCH (RFC822.SIZE 20000 SNIPPET (FUZZY {61}
  S: This is the first line of text from the first text part.
  S: ))
  S: B2 OK FETCH complete.
]]></artwork>
      </figure>

      <figure>
        <preamble>Example 3: Requesting FETCH with invalid explicit algorithm
        selection</preamble>

        <artwork><![CDATA[
  C: C1 CAPABILITY
  S: * CAPABILITY IMAP4rev1 SNIPPET=FUZZY
  S: C1 OK Capability command completed.
  [...a mailbox is SELECTed...]
  C: C2 FETCH 1 (RFC822.SIZE SNIPPET (X-SNIPPET-ALGO))
  S: C2 BAD FETCH contains invalid snippet algorithm name.
]]></artwork>
      </figure>

      <figure>
        <preamble>Example 4: Use explicit algorithm priority selection, with
        LAZY modifier, to obtain snippets during initial mailbox listing if
        readily available; otherwise, load snippets in background</preamble>

        <artwork><![CDATA[
  C: D1 CAPABILITY
  S: * CAPABILITY IMAP4rev1 SNIPPET=FUZZY
  S: D1 OK Capability command completed.
  [...a mailbox is SELECTed...]
  C: D2 FETCH 1:3 (ENVELOPE SNIPPET (LAZY=FUZZY))
  S: * 1 FETCH (ENVELOPE ("Wed, 25 Oct 2017 15:03:11 +0000" [...])
     SNIPPET (FUZZY {61}
  S: This is the first line of text from the first text part.
  S: ))
  S: * 2 FETCH (SNIPPET (FUZZY "") ENVELOPE
     ("Thu, 26 Oct 2017 12:17:23 +0000" [...]))
  S: * 3 FETCH (ENVELOPE ("Fri, 27 Oct 2017 22:19:21 +0000" [...])
     SNIPPET (FUZZY NIL))
  S: D2 OK FETCH completed.
  [...Client knows that message 2 has a snippet that is empty;
      therefore, client only needs to request message 3 snippet again
      (e.g. in background)...]
  C: D3 FETCH 3 (SNIPPET (FUZZY))
  S: * 3 FETCH (SNIPPET (FUZZY {25}
  S: First sentence of mail 3.
  S: ))
  S: D3 OK Fetch completed.
]]></artwork>
      </figure>

      <figure>
        <preamble>Example 5: Retrieve snippet information for search results
        within a single mailbox. Use <xref target="RFC5182">SEARCHRES</xref>
        extension to save a round-trip.</preamble>

        <artwork><![CDATA[
  C: E1 CAPABILITY
  S: * CAPABILITY IMAP4rev1 SNIPPET=FUZZY SEARCHRES
  S: E1 OK Capability command completed.
  [...a mailbox is SELECTed...]
  C: E2 SEARCH RETURN (SAVE) FROM "FOO"
  C: E3 FETCH $ (UID SNIPPET (LAZY=FUZZY))
  S: E2 OK SEARCH completed.
  S: * 5 FETCH (UID 13 SNIPPET (FUZZY {9}
  S: Snippet!
  S: ))
  S: * 9 FETCH (UID 23 SNIPPET (FUZZY NIL))
  S: E3 OK FETCH completed.
  [...Retrieve message 9 snippet in background...]
  C: E4 UID FETCH 23 (SNIPPET (FUZZY))
  S: * 9 FETCH (SNIPPET (FUZZY {17}
  S: Another snippet!
  S: ))
  S: E4 OK FETCH completed.
]]></artwork>
      </figure>
    </section>

    <section anchor="Syntax" title="Formal Syntax">
      <t>The following syntax specification uses the augmented Backus-Naur
      Form (BNF) as described in <xref target="RFC5234">ABNF</xref>. It
      includes definitions from <xref target="RFC3501">IMAP</xref>.</t>

      <figure>
        <artwork type="abnf"><![CDATA[
  capability        =/ "SNIPPET=FUZZY"

  fetch-att         =/ "SNIPPET" [SP "(" snippet-alg-fetch *(SP
                       snippet-alg-fetch) ")"]

  msg-att-dynamic   =/ "SNIPPET" SP "(" snippet-alg SP nstring ")"

  snippet-alg       =  "FUZZY" / snippet-alg-ext

  snippet-alg-ext   =  atom  ; New algorithms MUST be registered with
                             ; IANA

  snippet-alg-fetch =  snippet-alg / snippet-mod "=" snippet-alg

  snippet-mod       =  "LAZY" / snippet-mod-ext

  snippet-mod-ext   =  atom  ; New priority modifiers MUST be
                             ; registered with IANA
]]></artwork>
      </figure>
    </section>

    <section anchor="Acknowledgements" title="Acknowledgements">
      <t>The author would like to thank the following people for their
      comments and contributions to this document: Stephan Bosch, Teemu
      Huovila, Jeff Sipek, Timo Sirainen, Steffen Templin, and Aki Tuomi.</t>
    </section>

    <!-- Possibly a 'Contributors' section ... -->

    <section anchor="IANA" title="IANA Considerations">
      <t><xref target="RFC3501">IMAP4</xref> capabilities are registered by
      publishing a standards track or IESG-approved experimental RFC.
      The registry is currently located at:
        <list hangIndent="8" style="empty">
          <t>http://www.iana.org/assignments/imap-capabilities</t>
        </list>
      </t>

      <t>This document requests that IANA adds the "SNIPPET=FUZZY" capability
      to the <xref target="RFC3501">IMAP4</xref> capabilities registry.</t>
    </section>

    <section anchor="Security" title="Security Considerations">
      <t>There are no known additional security issues with this extension
      beyond those described in the base protocol described in
      <xref target="RFC3501">IMAP4</xref>.</t>
    </section>
  </middle>

  <back>
    <references title="Normative References">
      &RFC2119;
      &RFC3501;
      &RFC5234;
      &RFC5255;
    </references>

    <references title="Informative References">
      &RFC2045;
      &RFC2854;
      &RFC3629;
      &RFC5182;
    </references>

    <section title="Change History (To be removed by RFC Editor before
    publication)">
      <t>Changes from draft-slusarz-imap-fetch-snippet-00:
        <list style='symbols'>
          <t>TODO</t>
        </list>
      </t>
    </section>
  </back>
</rfc>
