Unverified Commit 6987fcef authored by Nicklas Avén's avatar Nicklas Avén Committed by Daniel Stenberg
Browse files

imap: change from "FETCH" to "UID FETCH"

... and add "MAILINDEX".

As described in #2789, this is a suggested solution.  Changing UID=xx to
actually get mail with UID xx and add "MAILINDEX" to get a mail with a
special index in the mail box (old behavior).  So MAILINDEX=1 gives the
first non deleted mail in the mail box.

Fixes #2789
Closes #2815
parent 2825f46d
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -187,7 +187,10 @@ imap://user:password@mail.example.com/INBOX - Performs a folder list on the
user's inbox

imap://user:password@mail.example.com/INBOX/;UID=1 - Selects the user's inbox
and fetches message 1
and fetches message with uid = 1

imap://user:password@mail.example.com/INBOX/;MAILINDEX=1 - Selects the user's inbox
and fetches the first message in the mail box

imap://user:password@mail.example.com/INBOX;UIDVALIDITY=50/;UID=2 - Selects
the user's inbox, checks the UIDVALIDITY of the mailbox is 50 and fetches
+42 −21
Original line number Diff line number Diff line
@@ -421,7 +421,6 @@ static CURLcode imap_perform_capability(struct connectdata *conn)
{
  CURLcode result = CURLE_OK;
  struct imap_conn *imapc = &conn->proto.imapc;

  imapc->sasl.authmechs = SASL_AUTH_NONE; /* No known auth. mechanisms yet */
  imapc->sasl.authused = SASL_AUTH_NONE;  /* Clear the auth. mechanism used */
  imapc->tls_supported = FALSE;           /* Clear the TLS capability */
@@ -683,24 +682,37 @@ static CURLcode imap_perform_fetch(struct connectdata *conn)
{
  CURLcode result = CURLE_OK;
  struct IMAP *imap = conn->data->req.protop;

  /* Check we have a UID */
  if(!imap->uid) {
    failf(conn->data, "Cannot FETCH without a UID.");
    return CURLE_URL_MALFORMAT;
  }
  if(imap->uid) {

    /* Send the FETCH command */
    if(imap->partial)
    result = imap_sendf(conn, "FETCH %s BODY[%s]<%s>",
      result = imap_sendf(conn, "UID FETCH %s BODY[%s]<%s>",
                            imap->uid,
                            imap->section ? imap->section : "",
                            imap->partial);
    else
    result = imap_sendf(conn, "FETCH %s BODY[%s]",
      result = imap_sendf(conn, "UID FETCH %s BODY[%s]",
                            imap->uid,
                            imap->section ? imap->section : "");
  }
  else if(imap->mindex) {

    /* Send the FETCH command */
    if(imap->partial)
      result = imap_sendf(conn, "FETCH %s BODY[%s]<%s>",
                            imap->mindex,
                            imap->section ? imap->section : "",
                            imap->partial);
    else
      result = imap_sendf(conn, "FETCH %s BODY[%s]",
                            imap->mindex,
                            imap->section ? imap->section : "");
  }
  else {
        failf(conn->data, "Cannot FETCH without a UID.");
        return CURLE_URL_MALFORMAT;
  }
  if(!result)
    state(conn, IMAP_FETCH);

@@ -1464,9 +1476,10 @@ static CURLcode imap_done(struct connectdata *conn, CURLcode status,
    result = status;         /* use the already set error code */
  }
  else if(!data->set.connect_only && !imap->custom &&
          (imap->uid || data->set.upload ||
          (imap->uid || imap->mindex || data->set.upload ||
          data->set.mimepost.kind != MIMEKIND_NONE)) {
    /* Handle responses after FETCH or APPEND transfer has finished */

    if(!data->set.upload && data->set.mimepost.kind == MIMEKIND_NONE)
      state(conn, IMAP_FETCH_FINAL);
    else {
@@ -1490,6 +1503,7 @@ static CURLcode imap_done(struct connectdata *conn, CURLcode status,
  Curl_safefree(imap->mailbox);
  Curl_safefree(imap->uidvalidity);
  Curl_safefree(imap->uid);
  Curl_safefree(imap->mindex);
  Curl_safefree(imap->section);
  Curl_safefree(imap->partial);
  Curl_safefree(imap->query);
@@ -1543,14 +1557,14 @@ static CURLcode imap_perform(struct connectdata *conn, bool *connected,
  else if(imap->custom && (selected || !imap->mailbox))
    /* Custom command using the same mailbox or no mailbox */
    result = imap_perform_list(conn);
  else if(!imap->custom && selected && imap->uid)
  else if(!imap->custom && selected && (imap->uid || imap->mindex))
    /* FETCH from the same mailbox */
    result = imap_perform_fetch(conn);
  else if(!imap->custom && selected && imap->query)
    /* SEARCH the current mailbox */
    result = imap_perform_search(conn);
  else if(imap->mailbox && !selected &&
         (imap->custom || imap->uid || imap->query))
         (imap->custom || imap->uid || imap->mindex || imap->query))
    /* SELECT the mailbox */
    result = imap_perform_select(conn);
  else
@@ -2016,6 +2030,13 @@ static CURLcode imap_parse_url_path(struct connectdata *conn)
      imap->uid = value;
      value = NULL;
    }
    else if(strcasecompare(name, "MAILINDEX") && !imap->mindex) {
      if(valuelen > 0 && value[valuelen - 1] == '/')
        value[valuelen - 1] = '\0';

      imap->mindex = value;
      value = NULL;
    }
    else if(strcasecompare(name, "SECTION") && !imap->section) {
      if(valuelen > 0 && value[valuelen - 1] == '/')
        value[valuelen - 1] = '\0';
@@ -2043,7 +2064,7 @@ static CURLcode imap_parse_url_path(struct connectdata *conn)

  /* Does the URL contain a query parameter? Only valid when we have a mailbox
     and no UID as per RFC-5092 */
  if(imap->mailbox && !imap->uid && *ptr == '?') {
  if(imap->mailbox && !imap->uid && !imap->mindex && *ptr == '?') {
    /* Find the length of the query parameter */
    begin = ++ptr;
    while(imap_is_bchar(*ptr))
+1 −0
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ struct IMAP {
  char *mailbox;          /* Mailbox to select */
  char *uidvalidity;      /* UIDVALIDITY to check in select */
  char *uid;              /* Message UID to fetch */
  char *mindex;           /* Index in mail box of mail to fetch */
  char *section;          /* Message SECTION to fetch */
  char *partial;          /* Message PARTIAL to fetch */
  char *query;            /* Query to search for */
+1 −1
Original line number Diff line number Diff line
@@ -93,7 +93,7 @@ test809 test810 test811 test812 test813 test814 test815 test816 test817 \
test818 test819 test820 test821 test822 test823 test824 test825 test826 \
test827 test828 test829 test830 test831 test832 test833 test834 test835 \
test836 test837 test838 test839 test840 test841 test842 test843 test844 \
test845 test846 \
test845 test846 test847 \
\
test850 test851 test852 test853 test854 test855 test856 test857 test858 \
test859 test860 test861 test862 test863 test864 test865 test866 test867 \
+1 −1
Original line number Diff line number Diff line
@@ -51,7 +51,7 @@ http
IMAP FETCH tunneled through HTTP proxy
 </name>
 <command>
'imap://imap.1321:%IMAPPORT/1321/;UID=1' -u user:secret -p -x %HOSTIP:%PROXYPORT
'imap://imap.1321:%IMAPPORT/1321/;MAILINDEX=1' -u user:secret -p -x %HOSTIP:%PROXYPORT
</command>
</client>

Loading