David Houlder added --form-string

This commit is contained in:
Daniel Stenberg 2005-03-12 19:39:27 +00:00
parent 88a4dc2795
commit 2f8085af15
4 changed files with 38 additions and 8 deletions

View File

@ -299,6 +299,13 @@ POST (HTTP)
curl -F "docpicture=@dog.gif" -F "catpicture=@cat.gif" curl -F "docpicture=@dog.gif" -F "catpicture=@cat.gif"
To send a field value literally without interpreting a leading '@'
or '<', or an embedded ';type=', use --form-string instead of
-F. This is recommended when the value is obtained from a user or
some other unpredictable source. Under these circumstances, using
-F instead of --form-string would allow a user to trick curl into
uploading a file.
REFERRER REFERRER
A HTTP request has the option to include information about which address A HTTP request has the option to include information about which address

View File

@ -388,6 +388,12 @@ setting filename=, like this:
See further examples and details in the MANUAL. See further examples and details in the MANUAL.
This option can be used multiple times. This option can be used multiple times.
.IP "--form-string <name=string>"
(HTTP) Similar to \fI--form\fP except that the value string for the named
parameter is used literally. Leading \&'@' and \&'<' characters, and the
\&';type=' string in the value have no special meaning. Use this in
preference to \fI--form\fP if there's any possibility that the string value
may accidentally trigger the \&'@' or \&'<' features of \fI--form\f{.
.IP "-g/--globoff" .IP "-g/--globoff"
This option switches off the "URL globbing parser". When you set this option, This option switches off the "URL globbing parser". When you set this option,
you can specify URLs that contain the letters {}[] without having them being you can specify URLs that contain the letters {}[] without having them being

View File

@ -355,6 +355,7 @@ static void help(void)
" --ftp-pasv Use PASV instead of PORT (F)", " --ftp-pasv Use PASV instead of PORT (F)",
" --ftp-ssl Enable SSL/TLS for the ftp transfer (F)", " --ftp-ssl Enable SSL/TLS for the ftp transfer (F)",
" -F/--form <name=content> Specify HTTP multipart POST data (H)", " -F/--form <name=content> Specify HTTP multipart POST data (H)",
" --form-string <name=string> Specify HTTP multipart POST data (H)",
" -g/--globoff Disable URL sequences and ranges using {} and []", " -g/--globoff Disable URL sequences and ranges using {} and []",
" -G/--get Send the -d data with a HTTP GET (H)", " -G/--get Send the -d data with a HTTP GET (H)",
" -h/--help This help text", " -h/--help This help text",
@ -774,6 +775,9 @@ static void list_engines (const struct curl_slist *engines)
* Specify files to upload with 'name=@filename'. Supports specified * Specify files to upload with 'name=@filename'. Supports specified
* given Content-Type of the files. Such as ';type=<content-type>'. * given Content-Type of the files. Such as ';type=<content-type>'.
* *
* If literal_value is set, any initial '@' or '<' in the value string
* loses its special meaning, as does any embedded ';type='.
*
* You may specify more than one file for a single name (field). Specify * You may specify more than one file for a single name (field). Specify
* multiple files by writing it like: * multiple files by writing it like:
* *
@ -804,7 +808,8 @@ static void list_engines (const struct curl_slist *engines)
static int formparse(char *input, static int formparse(char *input,
struct curl_httppost **httppost, struct curl_httppost **httppost,
struct curl_httppost **last_post) struct curl_httppost **last_post,
bool literal_value)
{ {
/* nextarg MUST be a string in the format 'name=contents' and we'll /* nextarg MUST be a string in the format 'name=contents' and we'll
build a linked list with the info */ build a linked list with the info */
@ -829,7 +834,7 @@ static int formparse(char *input,
} }
contp = contents; contp = contents;
if('@' == contp[0]) { if('@' == contp[0] && !literal_value) {
struct multi_files *multi_start = NULL, *multi_current = NULL; struct multi_files *multi_start = NULL, *multi_current = NULL;
/* we use the @-letter to indicate file name(s) */ /* we use the @-letter to indicate file name(s) */
contp++; contp++;
@ -974,7 +979,7 @@ static int formparse(char *input,
else { else {
struct curl_forms info[4]; struct curl_forms info[4];
int i = 0; int i = 0;
char *ct = strstr(contp, ";type="); char *ct = literal_value? NULL: strstr(contp, ";type=");
info[i].option = CURLFORM_COPYNAME; info[i].option = CURLFORM_COPYNAME;
info[i].value = name; info[i].value = name;
@ -987,7 +992,7 @@ static int formparse(char *input,
ct[0]=0; /* zero terminate here */ ct[0]=0; /* zero terminate here */
} }
if( contp[0]=='<' ) { if( contp[0]=='<' && !literal_value) {
info[i].option = CURLFORM_FILECONTENT; info[i].option = CURLFORM_FILECONTENT;
info[i].value = contp+1; info[i].value = contp+1;
i++; i++;
@ -1280,6 +1285,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
{"Eg","capath ", TRUE}, {"Eg","capath ", TRUE},
{"f", "fail", FALSE}, {"f", "fail", FALSE},
{"F", "form", TRUE}, {"F", "form", TRUE},
{"Fs","form-string", TRUE},
{"g", "globoff", FALSE}, {"g", "globoff", FALSE},
{"G", "get", FALSE}, {"G", "get", FALSE},
{"h", "help", FALSE}, {"h", "help", FALSE},
@ -1361,8 +1367,10 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
do { do {
/* we can loop here if we have multiple single-letters */ /* we can loop here if we have multiple single-letters */
if(!longopt) if(!longopt) {
letter = parse?(char)*parse:'\0'; letter = parse?(char)*parse:'\0';
subletter='\0';
}
else { else {
letter = parse[0]; letter = parse[0];
subletter = parse[1]; subletter = parse[1];
@ -1833,7 +1841,8 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
to sort this out slowly and carefully */ to sort this out slowly and carefully */
if(formparse(nextarg, if(formparse(nextarg,
&config->httppost, &config->httppost,
&config->last_post)) &config->last_post,
subletter=='s')) /* 's' means literal string */
return PARAM_BAD_USE; return PARAM_BAD_USE;
if(SetHTTPrequest(HTTPREQ_POST, &config->httpreq)) if(SetHTTPrequest(HTTPREQ_POST, &config->httpreq))
return PARAM_BAD_USE; return PARAM_BAD_USE;

View File

@ -19,7 +19,7 @@ http
HTTP RFC1867-type formposting with filename= and type= HTTP RFC1867-type formposting with filename= and type=
</name> </name>
<command> <command>
http://%HOSTIP:%HTTPPORT/we/want/39 -F name=daniel -F tool=curl -F "file=@log/test39.txt;filename=fakerfile;type=moo/foobar" -F file2=@log/test39.txt http://%HOSTIP:%HTTPPORT/we/want/39 -F name=daniel -F tool=curl --form-string "str1=@literal" --form-string "str2=<verbatim;type=xxx/yyy" -F "file=@log/test39.txt;filename=fakerfile;type=moo/foobar" -F file2=@log/test39.txt
</command> </command>
# We create this file before the command is invoked! # We create this file before the command is invoked!
<file name="log/test39.txt"> <file name="log/test39.txt">
@ -41,7 +41,7 @@ User-Agent: curl/7.10.4 (i686-pc-linux-gnu) libcurl/7.10.4 OpenSSL/0.9.7a ipv6 z
Host: 127.0.0.1:%HTTPPORT Host: 127.0.0.1:%HTTPPORT
Pragma: no-cache Pragma: no-cache
Accept: */* Accept: */*
Content-Length: 594 Content-Length: 810
Expect: 100-continue Expect: 100-continue
Content-Type: multipart/form-data; boundary=----------------------------24e78000bd32 Content-Type: multipart/form-data; boundary=----------------------------24e78000bd32
@ -54,6 +54,14 @@ Content-Disposition: form-data; name="tool"
curl curl
------------------------------24e78000bd32 ------------------------------24e78000bd32
Content-Disposition: form-data; name="str1"
@literal
------------------------------24e78000bd32
Content-Disposition: form-data; name="str2"
<verbatim;type=xxx/yyy
------------------------------24e78000bd32
Content-Disposition: form-data; name="file"; filename="fakerfile" Content-Disposition: form-data; name="file"; filename="fakerfile"
Content-Type: moo/foobar Content-Type: moo/foobar