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
A HTTP request has the option to include information about which address
See further examples and details in the MANUAL.
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"
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
" --ftp-pasv Use PASV instead of PORT (F)",
" --ftp-ssl Enable SSL/TLS for the ftp transfer (F)",
" -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/--get Send the -d data with a HTTP GET (H)",
" -h/--help This help text",
* Specify files to upload with 'name=@filename'. Supports specified
* 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
* multiple files by writing it like:
*
static int formparse(char *input,
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
build a linked list with the info */
}
contp = contents;
- if('@' == contp[0]) {
+ if('@' == contp[0] && !literal_value) {
struct multi_files *multi_start = NULL, *multi_current = NULL;
/* we use the @-letter to indicate file name(s) */
contp++;
else {
struct curl_forms info[4];
int i = 0;
- char *ct = strstr(contp, ";type=");
+ char *ct = literal_value? NULL: strstr(contp, ";type=");
info[i].option = CURLFORM_COPYNAME;
info[i].value = name;
ct[0]=0; /* zero terminate here */
}
- if( contp[0]=='<' ) {
+ if( contp[0]=='<' && !literal_value) {
info[i].option = CURLFORM_FILECONTENT;
info[i].value = contp+1;
i++;
{"Eg","capath ", TRUE},
{"f", "fail", FALSE},
{"F", "form", TRUE},
+ {"Fs","form-string", TRUE},
{"g", "globoff", FALSE},
{"G", "get", FALSE},
{"h", "help", FALSE},
do {
/* we can loop here if we have multiple single-letters */
- if(!longopt)
+ if(!longopt) {
letter = parse?(char)*parse:'\0';
+ subletter='\0';
+ }
else {
letter = parse[0];
subletter = parse[1];
to sort this out slowly and carefully */
if(formparse(nextarg,
&config->httppost,
- &config->last_post))
+ &config->last_post,
+ subletter=='s')) /* 's' means literal string */
return PARAM_BAD_USE;
if(SetHTTPrequest(HTTPREQ_POST, &config->httpreq))
return PARAM_BAD_USE;
HTTP RFC1867-type formposting with filename= and type=
</name>
<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>
# We create this file before the command is invoked!
<file name="log/test39.txt">
Host: 127.0.0.1:%HTTPPORT\r
Pragma: no-cache\r
Accept: */*\r
-Content-Length: 594\r
+Content-Length: 810\r
Expect: 100-continue\r
Content-Type: multipart/form-data; boundary=----------------------------24e78000bd32\r
\r
\r
curl\r
------------------------------24e78000bd32\r
+Content-Disposition: form-data; name="str1"\r
+\r
+@literal\r
+------------------------------24e78000bd32\r
+Content-Disposition: form-data; name="str2"\r
+\r
+<verbatim;type=xxx/yyy\r
+------------------------------24e78000bd32\r
Content-Disposition: form-data; name="file"; filename="fakerfile"\r
Content-Type: moo/foobar\r
\r