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 +