summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/examples/smtp-mime.c3
-rw-r--r--docs/libcurl/curl_mime_filedata.31
-rw-r--r--lib/formdata.c5
-rw-r--r--lib/mime.c15
-rw-r--r--src/tool_formparse.c23
-rw-r--r--src/tool_setopt.c8
-rw-r--r--tests/data/test1737
7 files changed, 48 insertions, 14 deletions
diff --git a/docs/examples/smtp-mime.c b/docs/examples/smtp-mime.c
index a467535a9..2895dbc31 100644
--- a/docs/examples/smtp-mime.c
+++ b/docs/examples/smtp-mime.c
@@ -153,6 +153,9 @@ int main(void)
* clean up in the end.
*/
curl_easy_cleanup(curl);
+
+ /* Free multipart message. */
+ curl_mime_free(mime);
}
return (int)res;
diff --git a/docs/libcurl/curl_mime_filedata.3 b/docs/libcurl/curl_mime_filedata.3
index fcd86cc18..71562edd0 100644
--- a/docs/libcurl/curl_mime_filedata.3
+++ b/docs/libcurl/curl_mime_filedata.3
@@ -35,7 +35,6 @@ contents.
\fIpart\fP is the part's to assign contents to.
\fIfilename\fP points to the nul-terminated file's path name. The pointer can
be NULL to detach previous part contents settings.
-If \fIfilename\fP is "-", part contents data will be read from stdin.
Filename storage can be safely be reused after this call.
As a side effect, the part's remote file name is set to the base name of the
diff --git a/lib/formdata.c b/lib/formdata.c
index 129086dee..b7ea21c8c 100644
--- a/lib/formdata.c
+++ b/lib/formdata.c
@@ -897,7 +897,10 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
clen = -1;
if(post->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE)) {
- result = curl_mime_filedata(part, file->contents);
+ if(!strcmp(file->contents, "-"))
+ result = Curl_mime_file(part, stdin, 0);
+ else
+ result = curl_mime_filedata(part, file->contents);
if(!result && (post->flags & HTTPPOST_READFILE))
result = curl_mime_filename(part, NULL);
}
diff --git a/lib/mime.c b/lib/mime.c
index 11d387d62..9e1336475 100644
--- a/lib/mime.c
+++ b/lib/mime.c
@@ -634,8 +634,18 @@ static int mime_part_rewind(struct Curl_mimepart *part)
targetstate = MIMESTATE_BODY;
if(part->state.state > targetstate) {
res = CURL_SEEKFUNC_CANTSEEK;
- if(part->seekfunc)
+ if(part->seekfunc) {
res = part->seekfunc(part->arg, part->origin, SEEK_SET);
+ switch(res) {
+ case CURL_SEEKFUNC_OK:
+ case CURL_SEEKFUNC_FAIL:
+ case CURL_SEEKFUNC_CANTSEEK:
+ break;
+ default:
+ res = CURL_SEEKFUNC_FAIL;
+ break;
+ }
+ }
}
if(res == CURL_SEEKFUNC_OK)
@@ -907,9 +917,6 @@ CURLcode curl_mime_filedata(struct Curl_mimepart *part, const char *filename)
if(!part || !filename)
return CURLE_BAD_FUNCTION_ARGUMENT;
- if(!strcmp(filename, "-"))
- return Curl_mime_file(part, stdin, 0);
-
if(stat(filename, &sbuf) || access(filename, R_OK))
result = CURLE_READ_ERROR;
diff --git a/src/tool_formparse.c b/src/tool_formparse.c
index cf19c0508..fc5162eed 100644
--- a/src/tool_formparse.c
+++ b/src/tool_formparse.c
@@ -347,6 +347,21 @@ static int get_param_part(struct OperationConfig *config, char **str,
return sep & 0xFF;
}
+/* Check if file is "-". If so, use a callback to read OUR stdin (to
+ * workaround Windows DLL file handle caveat).
+ * Else use curl_mime_filedata(). */
+static CURLcode file_or_stdin(curl_mimepart *part, const char *file)
+{
+ CURLcode ret = CURLE_OK;
+
+ if(strcmp(file, "-"))
+ return curl_mime_filedata(part, file);
+
+ return curl_mime_data_cb(part, -1, (curl_read_callback) fread,
+ (curl_seek_callback) fseek, NULL, stdin);
+}
+
+
/***************************************************************************
*
* formparse()
@@ -547,9 +562,9 @@ int formparse(struct OperationConfig *config,
}
/* Setup file in part. */
- res = curl_mime_filedata(part, data);
+ res = file_or_stdin(part, data);
if(res) {
- warnf(config->global, "curl_mime_filedata failed!\n");
+ warnf(config->global, "setting file %s failed!\n", data);
if(res != CURLE_READ_ERROR) {
if(subparts != *mimecurrent)
curl_mime_free(subparts);
@@ -619,9 +634,9 @@ int formparse(struct OperationConfig *config,
}
/* Setup file in part. */
- res = curl_mime_filedata(part, data);
+ res = file_or_stdin(part, data);
if(res) {
- warnf(config->global, "curl_mime_filedata failed!\n");
+ warnf(config->global, "setting file %s failed!\n", data);
if(res != CURLE_READ_ERROR) {
Curl_safefree(contents);
return 22;
diff --git a/src/tool_setopt.c b/src/tool_setopt.c
index 4e25e9e12..19646ea69 100644
--- a/src/tool_setopt.c
+++ b/src/tool_setopt.c
@@ -450,9 +450,11 @@ static CURLcode libcurl_generate_mime(curl_mime *mime, int *mimeno)
filename = part->filename;
}
break;
- case MIMEKIND_FILE:
- /* Can only be stdin in the current context. */
- CODE1("curl_mime_file(part%d, \"-\");", *mimeno);
+ case MIMEKIND_CALLBACK:
+ /* Can only be reading stdin in the current context. */
+ CODE1("curl_mime_data_cb(part%d, -1, (curl_read_callback) fread, \\",
+ *mimeno);
+ CODE0(" (curl_seek_callback) fseek, NULL, stdin);");
break;
case MIMEKIND_DATA:
#ifdef CURL_DOES_CONVERSIONS
diff --git a/tests/data/test173 b/tests/data/test173
index 865ef7ba2..754950105 100644
--- a/tests/data/test173
+++ b/tests/data/test173
@@ -53,9 +53,11 @@ POST /we/want/173 HTTP/1.1
User-Agent: curl/7.12.1-CVS (i686-pc-linux-gnu) libcurl/7.12.1-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.6
Host: %HOSTIP:%HTTPPORT
Accept: */*
-Content-Length: 360
+Transfer-Encoding: chunked
+Expect: 100-continue
Content-Type: multipart/form-data; boundary=----------------------------5dbea401cd8c
+168
------------------------------5dbea401cd8c
Content-Disposition: form-data; name="field1"
@@ -74,6 +76,9 @@ line7
line8
------------------------------5dbea401cd8c--
+
+0
+
</protocol>
</verify>
</testcase>