]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
imap: make imap_send use dynbuf for the send buffer management
authorDaniel Stenberg <daniel@haxx.se>
Thu, 24 Sep 2020 21:04:15 +0000 (23:04 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 25 Sep 2020 06:35:01 +0000 (08:35 +0200)
Reuses the buffer and thereby reduces number of mallocs over a transfer.

Closes #6010

lib/dynbuf.h
lib/imap.c
lib/imap.h
tests/runtests.pl

index 90a4f6622992bc57c8b950808330617006103ec6..39b859570638f4ed6501ffc33eabdbbfeb3b456a 100644 (file)
@@ -84,4 +84,5 @@ int Curl_dyn_vprintf(struct dynbuf *dyn, const char *format, va_list ap_save);
 #define DYN_QLOG_NAME       1024
 #define DYN_H1_TRAILER      4096
 #define DYN_PINGPPONG_CMD   (64*1024)
+#define DYN_IMAP_CMD        (64*1024)
 #endif
index 02fc796e474367c0f0a7cee706b991157fea7503..46367be10339d014b68d156a013ce504d67eea83 100644 (file)
@@ -1429,6 +1429,7 @@ static CURLcode imap_connect(struct connectdata *conn, bool *done)
   imapc->preftype = IMAP_TYPE_ANY;
   Curl_sasl_init(&imapc->sasl, &saslimap);
 
+  Curl_dyn_init(&imapc->dyn, DYN_IMAP_CMD);
   /* Initialise the pingpong layer */
   Curl_pp_setup(pp);
   Curl_pp_init(pp);
@@ -1632,6 +1633,7 @@ static CURLcode imap_disconnect(struct connectdata *conn, bool dead_connection)
 
   /* Disconnect from the server */
   Curl_pp_disconnect(&imapc->pp);
+  Curl_dyn_free(&imapc->dyn);
 
   /* Cleanup the SASL module */
   Curl_sasl_cleanup(conn, imapc->sasl.authused);
@@ -1733,30 +1735,25 @@ static CURLcode imap_sendf(struct connectdata *conn, const char *fmt, ...)
 {
   CURLcode result = CURLE_OK;
   struct imap_conn *imapc = &conn->proto.imapc;
-  char *taggedfmt;
-  va_list ap;
 
   DEBUGASSERT(fmt);
 
-  /* Calculate the next command ID wrapping at 3 digits */
-  imapc->cmdid = (imapc->cmdid + 1) % 1000;
-
   /* Calculate the tag based on the connection ID and command ID */
   msnprintf(imapc->resptag, sizeof(imapc->resptag), "%c%03d",
-            'A' + curlx_sltosi(conn->connection_id % 26), imapc->cmdid);
-
-  /* Prefix the format with the tag */
-  taggedfmt = aprintf("%s %s", imapc->resptag, fmt);
-  if(!taggedfmt)
-    return CURLE_OUT_OF_MEMORY;
+            'A' + curlx_sltosi(conn->connection_id % 26),
+            (++imapc->cmdid)%1000);
 
-  /* Send the data with the tag */
-  va_start(ap, fmt);
-  result = Curl_pp_vsendf(&imapc->pp, taggedfmt, ap);
-  va_end(ap);
-
-  free(taggedfmt);
+  /* start with a blank buffer */
+  Curl_dyn_reset(&imapc->dyn);
 
+  /* append tag + space + fmt */
+  result = Curl_dyn_addf(&imapc->dyn, "%s %s", imapc->resptag, fmt);
+  if(!result) {
+    va_list ap;
+    va_start(ap, fmt);
+    result = Curl_pp_vsendf(&imapc->pp, Curl_dyn_ptr(&imapc->dyn), ap);
+    va_end(ap);
+  }
   return result;
 }
 
index 4786f56241855d4697097aa25d46c36d36001c75..8f373d28435b296bab4914c497a80b2b80242e4e 100644 (file)
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2009 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2009 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -75,13 +75,14 @@ struct imap_conn {
   bool preauth;               /* Is this connection PREAUTH? */
   struct SASL sasl;           /* SASL-related parameters */
   unsigned int preftype;      /* Preferred authentication type */
-  int cmdid;                  /* Last used command ID */
+  unsigned int cmdid;         /* Last used command ID */
   char resptag[5];            /* Response tag to wait for */
   bool tls_supported;         /* StartTLS capability supported by server */
   bool login_disabled;        /* LOGIN command disabled by server */
   bool ir_supported;          /* Initial response supported by server */
   char *mailbox;              /* The last selected mailbox */
   char *mailbox_uidvalidity;  /* UIDVALIDITY parsed from select response */
+  struct dynbuf dyn;          /* for the IMAP commands */
 };
 
 extern const struct Curl_handler Curl_handler_imap;
index 7bfaab57a9ae3dc5e1f959b310ad8389d5489ad4..49b318dc7e131a2d6a45983292739bc3c80fac9c 100755 (executable)
@@ -166,7 +166,7 @@ my $SSHSRVMD5 = "[uninitialized]"; # MD5 of ssh server public key
 
 my $srcdir = $ENV{'srcdir'} || '.';
 my $CURL="../src/curl".exe_ext('TOOL'); # what curl executable to run on the tests
-my $VCURL=$CURL;   # what curl binary to use to verify the servers with
+my $VCURL="curl";   # what curl binary to use to verify the servers with
                    # VCURL is handy to set to the system one when the one you
                    # just built hangs or crashes and thus prevent verification
 my $DBGCURL=$CURL; #"../src/.libs/curl";  # alternative for debugging