tool_getparam: build post data using dynbuf (more)

This commit is contained in:
Daniel Stenberg 2024-01-08 17:00:05 +01:00
parent 1dba44b2f1
commit 1f4433dad4
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
5 changed files with 26 additions and 55 deletions

View File

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

View File

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

View File

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

View File

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

View File

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