From 0ec4c66fbaea2d024e4efa16a608e9099ef49de3 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 10 Sep 2004 21:47:52 +0000 Subject: [PATCH] fixed -F to support setting type= even on parts that aren't file-uploads --- CHANGES | 4 ++++ RELEASE-NOTES | 1 + docs/curl.1 | 10 +++++++--- src/main.c | 33 +++++++++++++++++++++++++----- tests/data/Makefile.am | 2 +- tests/data/test186 | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 95 insertions(+), 9 deletions(-) create mode 100644 tests/data/test186 diff --git a/CHANGES b/CHANGES index 6e805fb..4f945ad 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,10 @@ Changelog Daniel (10 September 2004) +- As found out by Jonas Forsman, curl didn't allow -F to set Content-Type on + text-parts. Starting now, we can do -F "name=daniel;type=text/extra". Added + test case 186 to verify. + - Bug report #1025986. When following a Location: with a custom Host: header replacement, curl only replaced the Host: header on the initial request and didn't replace it on the following ones. This resulted in requests with diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 6976282..aceb5d4 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -14,6 +14,7 @@ This release includes the following changes: This release includes the following bugfixes: + o -F can now add Content-Type on non-file sections o double Host: header when following Location: with replaced Host: fixed o curl_multi_add_handle() return code fix o "Proxy-Connection: close" is now understood and properly dealt with diff --git a/docs/curl.1 b/docs/curl.1 index 5553bcd..a804010 100644 --- a/docs/curl.1 +++ b/docs/curl.1 @@ -338,7 +338,7 @@ If this option is used twice, the second will again disable silent failure. If this option is used twice, the second will again disable silent failure. .IP "-F/--form " (HTTP) This lets curl emulate a filled in form in which a user has pressed the -submit button. This causes curl to POST data using the content-type +submit button. This causes curl to POST data using the Content-Type multipart/form-data according to RFC1867. This enables uploading of binary files etc. To force the 'content' part to be be a file, prefix the file name with an @ sign. To just get the content part from a file, prefix the file name @@ -355,11 +355,15 @@ input: To read the file's content from stdin insted of a file, use - where the file name should've been. This goes for both @ and < constructs. -You can also tell curl what Content-Type to use for the file upload part, by -using 'type=', in a manner similar to: +You can also tell curl what Content-Type to use by using 'type=', in a manner +similar to: \fBcurl\fP -F "web=@index.html;type=text/html" url.com +or + +\fBcurl\fP -F "name=daniel;type=text/foo" url.com + See further examples and details in the MANUAL. This option can be used multiple times. diff --git a/src/main.c b/src/main.c index 03c854d..87886ad 100644 --- a/src/main.c +++ b/src/main.c @@ -920,19 +920,42 @@ static int formparse(char *input, } } else { + struct curl_forms info[4]; + int i = 0; + char *ct = strstr(contp, ";type="); + + info[i].option = CURLFORM_COPYNAME; + info[i].value = name; + i++; + + if(ct) { + info[i].option = CURLFORM_CONTENTTYPE; + info[i].value = &ct[6]; + i++; + ct[0]=0; /* zero terminate here */ + } + if( contp[0]=='<' ) { + info[i].option = CURLFORM_FILECONTENT; + info[i].value = contp+1; + i++; + info[i].option = CURLFORM_END; + if (curl_formadd(httppost, last_post, - CURLFORM_COPYNAME, name, - CURLFORM_FILECONTENT, contp+1, CURLFORM_END) != 0) { - fprintf(stderr, "curl_formadd failed!\n"); + CURLFORM_ARRAY, info, CURLFORM_END ) != 0) { + fprintf(stderr, "curl_formadd failed, possibly the file %s is bad!\n", + contp+1); free(contents); return 6; } } else { + info[i].option = CURLFORM_COPYCONTENTS; + info[i].value = contp; + i++; + info[i].option = CURLFORM_END; if (curl_formadd(httppost, last_post, - CURLFORM_COPYNAME, name, - CURLFORM_COPYCONTENTS, contp, CURLFORM_END) != 0) { + CURLFORM_ARRAY, info, CURLFORM_END) != 0) { fprintf(stderr, "curl_formadd failed!\n"); free(contents); return 7; diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index 3135a41..8d296c2 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -26,7 +26,7 @@ EXTRA_DIST = test1 test108 test117 test127 test20 test27 test34 test46 \ test512 test165 test166 test167 test168 test169 test170 test171 \ test172 test204 test205 test173 test174 test175 test176 test177 \ test513 test514 test178 test179 test180 test181 test182 test183 \ - test184 test185 + test184 test185 test186 # The following tests have been removed from the dist since they no longer # work. We need to fix the test suite's FTPS server first, then bring them diff --git a/tests/data/test186 b/tests/data/test186 new file mode 100644 index 0000000..1450d4e --- /dev/null +++ b/tests/data/test186 @@ -0,0 +1,54 @@ +# Server-side + + +HTTP/1.1 200 OK swsclose +Date: Thu, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake + +blablabla + + + + +# Client-side + + +http + + +HTTP RFC1867-type formposting with types on text fields + + +http://%HOSTIP:%HTTPPORT/we/want/186 -F "name=daniel;type=moo/foo" -F "html= hello;type=text/html" + +# We create this file before the command is invoked! + + +# Verify data after the test has been "shot" + + +^(User-Agent:|Content-Type: multipart/form-data;|------------).* + + +POST /we/want/186 HTTP/1.1 +User-Agent: curl/7.12.2-CVS (i686-pc-linux-gnu) libcurl/7.12.2-CVS OpenSSL/0.9.7d zlib/1.2.1.1 c-ares/1.2.0 libidn/0.5.2 +Host: 127.0.0.1:%HTTPPORT +Pragma: no-cache +Accept: */* +Content-Length: 305 +Expect: 100-continue +Content-Type: multipart/form-data; boundary=----------------------------212d9006ceb5 + +------------------------------212d9006ceb5 +Content-Disposition: form-data; name="name" +Content-Type: moo/foo + +daniel +------------------------------212d9006ceb5 +Content-Disposition: form-data; name="html" +Content-Type: text/html + + hello +------------------------------212d9006ceb5-- + + -- 2.7.4