Browse Source

tool_getparam: build post data using dynbuf (more)

Daniel Stenberg 4 months ago
parent
commit
1f4433dad4
5 changed files with 26 additions and 55 deletions
  1. 3 2
      src/tool_cfgable.c
  2. 1 1
      src/tool_cfgable.h
  3. 14 40
      src/tool_getparam.c
  4. 7 11
      src/tool_operate.c
  5. 1 1
      src/tool_setopt.c

+ 3 - 2
src/tool_cfgable.c

@@ -25,6 +25,7 @@
 
 #include "tool_cfgable.h"
 #include "tool_formparse.h"
+#include "tool_paramhlp.h"
 #include "tool_main.h"
 
 #include "memdebug.h" /* keep this as LAST include */
@@ -33,7 +34,6 @@ void config_init(struct OperationConfig *config)
 {
   memset(config, 0, sizeof(struct OperationConfig));
 
-  config->postfieldsize = -1;
   config->use_httpget = FALSE;
   config->create_dirs = FALSE;
   config->maxredirs = DEFAULT_MAXREDIRS;
@@ -45,6 +45,7 @@ void config_init(struct OperationConfig *config)
   config->http09_allowed = FALSE;
   config->ftp_skip_ip = TRUE;
   config->file_clobber_mode = CLOBBER_DEFAULT;
+  curlx_dyn_init(&config->postdata, MAX_FILE2MEMORY);
 }
 
 static void free_config_fields(struct OperationConfig *config)
@@ -59,7 +60,7 @@ static void free_config_fields(struct OperationConfig *config)
   Curl_safefree(config->cookiejar);
   curl_slist_free_all(config->cookiefiles);
 
-  Curl_safefree(config->postfields);
+  Curl_dyn_free(&config->postdata);
   Curl_safefree(config->query);
   Curl_safefree(config->referer);
 

+ 1 - 1
src/tool_cfgable.h

@@ -68,7 +68,7 @@ struct OperationConfig {
   char *proto_default;
   curl_off_t resume_from;
   char *postfields;
-  curl_off_t postfieldsize;
+  struct curlx_dynbuf postdata;
   char *referer;
   char *query;
   long timeout_ms;

+ 14 - 40
src/tool_getparam.c

@@ -803,7 +803,7 @@ static ParameterError set_data(char subletter,
   if(subletter == 'e') { /* --data-urlencode */
     err = data_urlencode(global, nextarg, &postdata, &size);
     if(err)
-      goto done;
+      return err;
   }
   else if('@' == *nextarg && (subletter != 'r')) {
     /* the data begins with a '@' letter, it means that a file name
@@ -819,8 +819,7 @@ static ParameterError set_data(char subletter,
       file = fopen(nextarg, "rb");
       if(!file) {
         errorf(global, "Failed to open %s", nextarg);
-        err = PARAM_READ_ERROR;
-        goto done;
+        return PARAM_READ_ERROR;
       }
     }
 
@@ -837,64 +836,39 @@ static ParameterError set_data(char subletter,
     if(file && (file != stdin))
       fclose(file);
     if(err)
-      goto done;
+      return err;
 
     if(!postdata) {
       /* no data from the file, point to a zero byte string to make this
          get sent as a POST anyway */
       postdata = strdup("");
-      if(!postdata) {
-        err = PARAM_NO_MEM;
-        goto done;
-      }
+      if(!postdata)
+        return PARAM_NO_MEM;
     }
   }
   else {
     err = getstr(&postdata, nextarg, ALLOW_BLANK);
     if(err)
-      goto done;
+      return err;
     if(postdata)
       size = strlen(postdata);
   }
   if(subletter == 'f')
     config->jsoned = TRUE;
 
-  if(config->postfields) {
-    /* we already have a string, append this one - perhaps with a separator */
-    struct curlx_dynbuf out;
-    curlx_dyn_init(&out, MAX_FILE2MEMORY);
-    if(curlx_dyn_addn(&out, config->postfields,
-                      (size_t)config->postfieldsize))
+  if(curlx_dyn_len(&config->postdata)) {
+    /* skip separator append for --json */
+    if(!err && (subletter != 'f')  &&
+       curlx_dyn_addn(&config->postdata, "&", 1))
       err = PARAM_NO_MEM;
-
-    /* skip the separator append for --json */
-    if(!err && (subletter != 'f')  && curlx_dyn_addn(&out, "&", 1))
-      err = PARAM_NO_MEM;
-
-    if(!err && curlx_dyn_addn(&out, postdata, size))
-      err = PARAM_NO_MEM;
-
-    config->postfieldsize = curlx_dyn_len(&out);
-    free(config->postfields);
-    Curl_safefree(postdata);
-    config->postfields = curlx_dyn_ptr(&out);
-  }
-  else {
-    config->postfields = postdata;
-    config->postfieldsize = curlx_uztoso(size);
   }
 
-  /*
-    We can't set the request type here, as this data might be used in
-    a simple GET if -G is used. Already or soon.
+  if(!err && curlx_dyn_addn(&config->postdata, postdata, size))
+    err = PARAM_NO_MEM;
 
-    if(SetHTTPrequest(HTTPREQ_SIMPLEPOST, &config->httpreq)) {
-    Curl_safefree(postdata);
-    return PARAM_BAD_USE;
-    }
-  */
+  Curl_safefree(postdata);
 
-done:
+  config->postfields = curlx_dyn_ptr(&config->postdata);
   return err;
 }
 

+ 7 - 11
src/tool_operate.c

@@ -761,15 +761,11 @@ static CURLcode single_transfer(struct GlobalConfig *global,
     if(config->use_httpget) {
       if(!httpgetfields) {
         /* Use the postfields data for an HTTP get */
-        httpgetfields = state->httpgetfields = strdup(config->postfields);
-        Curl_safefree(config->postfields);
-        if(!httpgetfields) {
-          errorf(global, "out of memory");
-          result = CURLE_OUT_OF_MEMORY;
-        }
-        else if(SetHTTPrequest(config,
-                               (config->no_body?HTTPREQ_HEAD:HTTPREQ_GET),
-                               &config->httpreq)) {
+        httpgetfields = state->httpgetfields = config->postfields;
+        config->postfields = NULL;
+        if(SetHTTPrequest(config,
+                          (config->no_body?HTTPREQ_HEAD:HTTPREQ_GET),
+                          &config->httpreq)) {
           result = CURLE_FAILED_INIT;
         }
       }
@@ -1432,9 +1428,9 @@ static CURLcode single_transfer(struct GlobalConfig *global,
           }
           else {
             my_setopt_str(curl, CURLOPT_POSTFIELDS,
-                          config->postfields);
+                          curlx_dyn_ptr(&config->postdata));
             my_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE,
-                      config->postfieldsize);
+                      (curl_off_t)curlx_dyn_len(&config->postdata));
           }
           break;
         case HTTPREQ_MIMEPOST:

+ 1 - 1
src/tool_setopt.c

@@ -660,7 +660,7 @@ CURLcode tool_setopt(CURL *curl, bool str, struct GlobalConfig *global,
       if(escape) {
         curl_off_t len = ZERO_TERMINATED;
         if(tag == CURLOPT_POSTFIELDS)
-          len = config->postfieldsize;
+          len = curlx_dyn_len(&config->postdata);
         escaped = c_escape(value, len);
         NULL_CHECK(escaped);
         CODE2("curl_easy_setopt(hnd, %s, \"%s\");", name, escaped);