]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
http: limit the initial send amount to used upload buffer size
authorDaniel Stenberg <daniel@haxx.se>
Thu, 6 May 2021 08:25:56 +0000 (10:25 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 7 May 2021 06:51:39 +0000 (08:51 +0200)
Previously this logic would cap the send to CURL_MAX_WRITE_SIZE bytes,
but for the situations where a larger upload buffer has been set, this
function can benefit from sending more bytes. With default size used,
this does the same as before.

Also changed the storage of the size to an 'unsigned int' as it is not
allowed to be set larger than 2M.

Also added cautions to the man pages about changing buffer sizes in
run-time.

Closes #7022

docs/libcurl/opts/CURLOPT_BUFFERSIZE.3
docs/libcurl/opts/CURLOPT_UPLOAD_BUFFERSIZE.3
lib/http.c
lib/setopt.c
lib/smb.c
lib/smtp.c
lib/urldata.h

index 06f082cea2af834bf6cdb190526d480be47bfd8c..c76d23269f5940284322bc4eed395238f3b504d3 100644 (file)
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2017, 2021, 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
@@ -39,6 +39,9 @@ actually get the given size.
 This buffer size is by default \fICURL_MAX_WRITE_SIZE\fP (16kB). The maximum
 buffer size allowed to be set is \fICURL_MAX_READ_SIZE\fP (512kB). The minimum
 buffer size allowed to be set is 1024.
+
+DO NOT set this option on a handle that is currently used for an active
+transfer as that may lead to unintended consequences.
 .SH DEFAULT
 CURL_MAX_WRITE_SIZE (16kB)
 .SH PROTOCOLS
index 896417a105afb2f791b0249c3bb6de87c17c5631..ffa5a629129176a662b7d53d6b25c86458cb3830 100644 (file)
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2018, 2021, 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
@@ -43,6 +43,9 @@ allowed to be set is 2 megabytes. The minimum buffer size allowed to be set is
 
 Since curl 7.61.1 the upload buffer is allocated on-demand - so if the handle
 isn't used for upload, this buffer will not be allocated at all.
+
+DO NOT set this option on a handle that is currently used for an active
+transfer as that may lead to unintended consequences.
 .SH DEFAULT
 64 kB
 .SH PROTOCOLS
index eece05513e2e829b0d014251146bddbb70b71f13..4d8d945964c54bb0b1f2855076c5363a20002b5c 100644 (file)
@@ -1273,14 +1273,6 @@ CURLcode Curl_buffer_send(struct dynbuf *in,
     else
       sendsize = size;
 
-    /* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk
-       when we speak HTTPS, as if only a fraction of it is sent now, this data
-       needs to fit into the normal read-callback buffer later on and that
-       buffer is using this size.
-    */
-    if(sendsize > CURL_MAX_WRITE_SIZE)
-      sendsize = CURL_MAX_WRITE_SIZE;
-
     /* OpenSSL is very picky and we must send the SAME buffer pointer to the
        library when we attempt to re-send this buffer. Sending the same data
        is not enough, we must use the exact same address. For this reason, we
@@ -1293,6 +1285,14 @@ CURLcode Curl_buffer_send(struct dynbuf *in,
       Curl_dyn_free(in);
       return result;
     }
+    /* We never send more than upload_buffer_size bytes in one single chunk
+       when we speak HTTPS, as if only a fraction of it is sent now, this data
+       needs to fit into the normal read-callback buffer later on and that
+       buffer is using this size.
+    */
+    if(sendsize > (size_t)data->set.upload_buffer_size)
+      sendsize = (size_t)data->set.upload_buffer_size;
+
     memcpy(data->state.ulbuf, ptr, sendsize);
     ptr = data->state.ulbuf;
   }
index 9ad984e7990382598ed037a88517c22ee220c279..1ded7ad3e03f2584d4d73a90d16ec5c79110de9e 100644 (file)
@@ -2198,7 +2198,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
     else if(arg < UPLOADBUFFER_MIN)
       arg = UPLOADBUFFER_MIN;
 
-    data->set.upload_buffer_size = arg;
+    data->set.upload_buffer_size = (unsigned int)arg;
     Curl_safefree(data->state.ulbuf); /* force a realloc next opportunity */
     break;
 
index 183bc12a517c031edc34b6825791f70e054c62ed..0bf595ca06e014e875d015ca24ff87f7dbc58115 100644 (file)
--- a/lib/smb.c
+++ b/lib/smb.c
@@ -627,9 +627,8 @@ static CURLcode smb_send_and_recv(struct Curl_easy *data, void **msg)
 
   /* Check if there is data in the transfer buffer */
   if(!smbc->send_size && smbc->upload_size) {
-    size_t nread = smbc->upload_size > data->set.upload_buffer_size ?
-      data->set.upload_buffer_size :
-      smbc->upload_size;
+    size_t nread = smbc->upload_size > (size_t)data->set.upload_buffer_size ?
+      (size_t)data->set.upload_buffer_size : smbc->upload_size;
     data->req.upload_fromhere = data->state.ulbuf;
     result = Curl_fillreadbuffer(data, nread, &nread);
     if(result && result != CURLE_AGAIN)
index be4cd675cafa49052be79a8cbe3680d445409eb8..e1560f583d22cb73c5f0b6cef1b4f86051ab1b70 100644 (file)
@@ -1821,7 +1821,7 @@ CURLcode Curl_smtp_escape_eob(struct Curl_easy *data, const ssize_t nread)
       return CURLE_OUT_OF_MEMORY;
     }
   }
-  DEBUGASSERT(data->set.upload_buffer_size >= (size_t)nread);
+  DEBUGASSERT((size_t)data->set.upload_buffer_size >= (size_t)nread);
 
   /* Have we already sent part of the EOB? */
   eob_sent = smtp->eob;
index 04daf778a3d258331f3cc62da5b0973e7a38a45f..421a86b62a6d70072cde663b2f59fe4b056256f1 100644 (file)
@@ -1722,8 +1722,8 @@ struct UserDefined {
   struct ssl_general_config general_ssl; /* general user defined SSL stuff */
   long dns_cache_timeout; /* DNS cache timeout */
   long buffer_size;      /* size of receive buffer to use */
-  size_t upload_buffer_size; /* size of upload buffer to use,
-                                keep it >= CURL_MAX_WRITE_SIZE */
+  unsigned int upload_buffer_size; /* size of upload buffer to use,
+                                      keep it >= CURL_MAX_WRITE_SIZE */
   void *private_data; /* application-private data */
   struct curl_slist *http200aliases; /* linked list of aliases for http200 */
   unsigned char ipver; /* the CURL_IPRESOLVE_* defines in the public header