Introuced --data-urlencode to the curl tool for easier url encoding of the

data sent in a post.
This commit is contained in:
Daniel Stenberg 2007-11-20 10:08:42 +00:00
parent 2f928797cf
commit 600d0b1303
4 changed files with 119 additions and 18 deletions

View File

@ -7,6 +7,14 @@
Changelog Changelog
Daniel S (20 Nov 2007)
- Fixed a very long-lasting mprintf() bug that occured when we did "%.*s%s",
since the second %s would then wrongly used the numerical precision argument
instead and crash.
- Introuced --data-urlencode to the curl tool for easier url encoding of the
data sent in a post.
Daniel S (18 Nov 2007) Daniel S (18 Nov 2007)
- Rob Crittenden fixed SSL connections with NSS done with the multi-interface - Rob Crittenden fixed SSL connections with NSS done with the multi-interface

View File

@ -1,7 +1,7 @@
Curl and libcurl 7.17.2 Curl and libcurl 7.17.2
Public curl releases: 103 Public curl releases: 103
Command line options: 121 Command line options: 122
curl_easy_setopt() options: 147 curl_easy_setopt() options: 147
Public functions in libcurl: 55 Public functions in libcurl: 55
Public web site mirrors: 42 Public web site mirrors: 42
@ -10,7 +10,7 @@ Curl and libcurl 7.17.2
This release includes the following changes: This release includes the following changes:
o o --data-urlencode was added
This release includes the following bugfixes: This release includes the following bugfixes:

View File

@ -261,6 +261,20 @@ the \fI--data-ascii\fP option, this is for you.
If this option is used several times, the ones following the first will If this option is used several times, the ones following the first will
append data. append data.
.IP "--data-urlencode <data>"
(HTTP) This posts data, similar to the other --data options with the exception
that this will do partial URL encoding. (Added in 7.17.2)
The <data> part should be using one of the two following syntaxes:
.RS
.IP "name=content"
This will make curl URL encode the content part and pass that on. Note that
the name part is not encoded.
.IP "name@filename"
This will make curl load data from the given file, URL encode that data and
pass it on in the POST like \fIname=urlencoded-data\fP. Note that the name
part is not encoded.
.RE
.IP "--digest" .IP "--digest"
(HTTP) Enables HTTP Digest authentication. This is a authentication that (HTTP) Enables HTTP Digest authentication. This is a authentication that
prevents the password from being sent over the wire in clear text. Use this in prevents the password from being sent over the wire in clear text. Use this in

View File

@ -357,6 +357,7 @@ struct OutStruct {
}; };
struct Configurable { struct Configurable {
CURL *easy; /* once we have one, we keep it here */
bool remote_time; bool remote_time;
char *random_file; char *random_file;
char *egd_file; char *egd_file;
@ -619,6 +620,7 @@ static void help(void)
" -d/--data <data> HTTP POST data (H)", " -d/--data <data> HTTP POST data (H)",
" --data-ascii <data> HTTP POST ASCII data (H)", " --data-ascii <data> HTTP POST ASCII data (H)",
" --data-binary <data> HTTP POST binary data (H)", " --data-binary <data> HTTP POST binary data (H)",
" --data-urlencode <name=data/name@filename> HTTP POST data url encoded (H)",
" --negotiate Use HTTP Negotiate Authentication (H)", " --negotiate Use HTTP Negotiate Authentication (H)",
" --digest Use HTTP Digest Authentication (H)", " --digest Use HTTP Digest Authentication (H)",
" --disable-eprt Inhibit using EPRT or LPRT (F)", " --disable-eprt Inhibit using EPRT or LPRT (F)",
@ -1532,6 +1534,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
{"d", "data", TRUE}, {"d", "data", TRUE},
{"da", "data-ascii", TRUE}, {"da", "data-ascii", TRUE},
{"db", "data-binary", TRUE}, {"db", "data-binary", TRUE},
{"de", "data-urlencode", TRUE},
{"D", "dump-header", TRUE}, {"D", "dump-header", TRUE},
{"e", "referer", TRUE}, {"e", "referer", TRUE},
{"E", "cert", TRUE}, {"E", "cert", TRUE},
@ -2045,12 +2048,83 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
/* postfield data */ /* postfield data */
{ {
char *postdata=NULL; char *postdata=NULL;
FILE *file;
if('@' == *nextarg) { if(subletter == 'e') { /* --data-urlencode*/
/* [name]=[content], we encode the content part only
* [name]@[file name]
*
* Case 2: we first load the file using that name and then encode
* the content.
*/
char *p = strchr(nextarg, '=');
long size = 0;
size_t nlen;
if(!p)
p = strchr(nextarg, '@');
if(!p) {
warnf(config, "bad use of --data-urlencode\n");
return PARAM_BAD_USE;
}
nlen = p - nextarg; /* length of the name part */
if('@' == *p) {
/* a '@' letter, it means that a file name or - (stdin) follows */
p++; /* pass the separator */
if(curlx_strequal("-", p)) {
file = stdin;
SET_BINMODE(stdin);
}
else {
file = fopen(p, "rb");
if(!file)
warnf(config,
"Couldn't read data from file \"%s\", this makes "
"an empty POST.\n", nextarg);
}
postdata = file2memory(file, &size);
if(file && (file != stdin))
fclose(file);
}
else {
GetStr(&postdata, ++p);
size = strlen(postdata);
}
if(!postdata) {
/* no data from the file, point to a zero byte string to make this
get sent as a POST anyway */
postdata=strdup("");
}
else {
char *enc = curl_easy_escape(config->easy, postdata, size);
if(enc) {
/* now make a string with the name from above and append the
encoded string */
size_t outlen = nlen + strlen(enc) + 2;
char *n = malloc(outlen);
if(!n)
return PARAM_NO_MEM;
snprintf(n, outlen, "%.*s=%s", nlen, nextarg, enc);
curl_free(enc);
free(postdata);
if(n) {
postdata = n;
}
else
return PARAM_NO_MEM;
}
else
return PARAM_NO_MEM;
}
}
else if('@' == *nextarg) {
/* the data begins with a '@' letter, it means that a file name /* the data begins with a '@' letter, it means that a file name
or - (stdin) follows */ or - (stdin) follows */
FILE *file;
nextarg++; /* pass the @ */ nextarg++; /* pass the @ */
if(curlx_strequal("-", nextarg)) { if(curlx_strequal("-", nextarg)) {
@ -3334,6 +3408,9 @@ static void free_config_fields(struct Configurable *config)
curl_slist_free_all(config->postquote); curl_slist_free_all(config->postquote);
curl_slist_free_all(config->headers); curl_slist_free_all(config->headers);
curl_slist_free_all(config->telnet_options); curl_slist_free_all(config->telnet_options);
if(config->easy)
curl_easy_cleanup(config->easy);
} }
#ifdef WIN32 #ifdef WIN32
@ -3443,9 +3520,9 @@ CURLcode _my_setopt(CURL *curl, struct Configurable *config, const char *name,
if(config->libcurl) { if(config->libcurl) {
/* we only use this for real if --libcurl was used */ /* we only use this for real if --libcurl was used */
bufp = curl_maprintf("%scurl_easy_setopt(hnd, %s, %s);%s", bufp = curlx_maprintf("%scurl_easy_setopt(hnd, %s, %s);%s",
remark?"/* ":"", name, value, remark?"/* ":"", name, value,
remark?" [REMARK] */":""); remark?" [REMARK] */":"");
if (!bufp || !curl_slist_append(easycode, bufp)) if (!bufp || !curl_slist_append(easycode, bufp))
ret = CURLE_OUT_OF_MEMORY; ret = CURLE_OUT_OF_MEMORY;
@ -3577,6 +3654,17 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
} }
#endif #endif
/*
* Get a curl handle to use for all forthcoming curl transfers. Cleanup
* when all transfers are done.
*/
curl = curl_easy_init();
if(!curl) {
clean_getout(config);
return CURLE_FAILED_INIT;
}
config->easy = curl;
memset(&outs,0,sizeof(outs)); memset(&outs,0,sizeof(outs));
config->outs = &outs; config->outs = &outs;
@ -3733,16 +3821,6 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
} }
} }
/*
* Get a curl handle to use for all forthcoming curl transfers. Cleanup
* when all transfers are done.
*/
curl = curl_easy_init();
if(!curl) {
clean_getout(config);
return CURLE_FAILED_INIT;
}
/* This is the first entry added to easycode and it initializes the slist */ /* This is the first entry added to easycode and it initializes the slist */
easycode = curl_slist_append(easycode, "CURL *hnd = curl_easy_init();"); easycode = curl_slist_append(easycode, "CURL *hnd = curl_easy_init();");
if(!easycode) { if(!easycode) {
@ -4663,6 +4741,7 @@ quit_curl:
/* cleanup the curl handle! */ /* cleanup the curl handle! */
curl_easy_cleanup(curl); curl_easy_cleanup(curl);
config->easy = NULL; /* cleanup now */
if (easycode) if (easycode)
curl_slist_append(easycode, "curl_easy_cleanup(hnd);"); curl_slist_append(easycode, "curl_easy_cleanup(hnd);");