aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/curl/curl.h15
-rw-r--r--lib/formdata.c172
-rw-r--r--lib/formdata.h4
3 files changed, 149 insertions, 42 deletions
diff --git a/include/curl/curl.h b/include/curl/curl.h
index 7dc7b70b4..686204210 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -65,6 +65,11 @@ struct curl_httppost {
long namelength; /* length of name length */
char *contents; /* pointer to allocated data contents */
long contentslength; /* length of contents field */
+
+ /* CMC: Added support for buffer uploads */
+ char *buffer; /* pointer to allocated buffer contents */
+ long bufferlength; /* length of buffer field */
+
char *contenttype; /* Content-Type */
struct curl_slist* contentheader; /* list of extra headers for this form */
struct curl_httppost *more; /* if one field name has more than one file, this
@@ -76,6 +81,11 @@ struct curl_httppost {
do not free in formfree */
#define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer
do not free in formfree */
+
+/* CMC: Added support for buffer uploads */
+#define HTTPPOST_BUFFER (1<<4) /* upload file from buffer */
+#define HTTPPOST_PTRBUFFER (1<<5) /* upload file from pointer contents */
+
char *showfilename; /* The file name to show. If not set, the actual
file name will be used (if this is a file part) */
};
@@ -658,6 +668,11 @@ typedef enum {
CFINIT(ARRAY),
CFINIT(OBSOLETE),
CFINIT(FILE),
+
+ CFINIT(BUFFER),
+ CFINIT(BUFFERPTR),
+ CFINIT(BUFFERLENGTH),
+
CFINIT(CONTENTTYPE),
CFINIT(CONTENTHEADER),
CFINIT(FILENAME),
diff --git a/lib/formdata.c b/lib/formdata.c
index 5c1575e57..b4623ec70 100644
--- a/lib/formdata.c
+++ b/lib/formdata.c
@@ -400,6 +400,10 @@ int curl_formparse(char *input,
static struct curl_httppost *
AddHttpPost(char * name, long namelength,
char * value, long contentslength,
+
+ /* CMC: Added support for buffer uploads */
+ char * buffer, long bufferlength,
+
char *contenttype,
long flags,
struct curl_slist* contentHeader,
@@ -416,6 +420,11 @@ AddHttpPost(char * name, long namelength,
post->namelength = name?(namelength?namelength:(long)strlen(name)):0;
post->contents = value;
post->contentslength = contentslength;
+
+ /* CMC: Added support for buffer uploads */
+ post->buffer = buffer;
+ post->bufferlength = bufferlength;
+
post->contenttype = contenttype;
post->contentheader = contentHeader;
post->showfilename = showfilename;
@@ -783,9 +792,63 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
}
break;
}
+
+ /* CMC: Added support for buffer uploads */
+ case CURLFORM_BUFFER:
+ {
+ char *filename = array_state?array_value:
+ va_arg(params, char *);
+
+ if (current_form->value) {
+ if (current_form->flags & HTTPPOST_BUFFER) {
+ if (filename) {
+ if (!(current_form = AddFormInfo(strdup(filename),
+ NULL, current_form)))
+ return_value = CURL_FORMADD_MEMORY;
+ }
+ else
+ return_value = CURL_FORMADD_NULL;
+ }
+ else
+ return_value = CURL_FORMADD_OPTION_TWICE;
+ }
+ else {
+ if (filename)
+ current_form->value = strdup(filename);
+ else
+ return_value = CURL_FORMADD_NULL;
+ current_form->flags |= HTTPPOST_BUFFER;
+ }
+ break;
+ }
+
+ /* CMC: Added support for buffer uploads */
+ case CURLFORM_BUFFERPTR:
+ current_form->flags |= HTTPPOST_PTRBUFFER;
+ if (current_form->buffer)
+ return_value = CURL_FORMADD_OPTION_TWICE;
+ else {
+ char *buffer =
+ array_state?array_value:va_arg(params, char *);
+ if (buffer)
+ current_form->buffer = buffer; /* store for the moment */
+ else
+ return_value = CURL_FORMADD_NULL;
+ }
+ break;
+
+ /* CMC: Added support for buffer uploads */
+ case CURLFORM_BUFFERLENGTH:
+ if (current_form->bufferlength)
+ return_value = CURL_FORMADD_OPTION_TWICE;
+ else
+ current_form->bufferlength =
+ array_state?(long)array_value:va_arg(params, long);
+ break;
+
case CURLFORM_CONTENTTYPE:
{
- char *contenttype =
+ char *contenttype =
array_state?array_value:va_arg(params, char *);
if (current_form->contenttype) {
if (current_form->flags & HTTPPOST_FILENAME) {
@@ -852,6 +915,12 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
(form->flags & HTTPPOST_FILENAME) ) ||
( (form->flags & HTTPPOST_FILENAME) &&
(form->flags & HTTPPOST_PTRCONTENTS) ) ||
+
+ /* CMC: Added support for buffer uploads */
+ ( (!form->buffer) &&
+ (form->flags & HTTPPOST_BUFFER) &&
+ (form->flags & HTTPPOST_PTRBUFFER) ) ||
+
( (form->flags & HTTPPOST_READFILE) &&
(form->flags & HTTPPOST_PTRCONTENTS) )
) {
@@ -859,7 +928,8 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
break;
}
else {
- if ( (form->flags & HTTPPOST_FILENAME) &&
+ if ( ((form->flags & HTTPPOST_FILENAME) ||
+ (form->flags & HTTPPOST_BUFFER)) &&
!form->contenttype ) {
/* our contenttype is missing */
form->contenttype
@@ -875,7 +945,11 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
}
if ( !(form->flags & HTTPPOST_FILENAME) &&
!(form->flags & HTTPPOST_READFILE) &&
- !(form->flags & HTTPPOST_PTRCONTENTS) ) {
+ !(form->flags & HTTPPOST_PTRCONTENTS) &&
+
+ /* CMC: Added support for buffer uploads */
+ !(form->flags & HTTPPOST_PTRBUFFER) ) {
+
/* copy value (without strdup; possibly contains null characters) */
if (AllocAndCopy(&form->value, form->contentslength)) {
return_value = CURL_FORMADD_MEMORY;
@@ -884,6 +958,10 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
}
post = AddHttpPost(form->name, form->namelength,
form->value, form->contentslength,
+
+ /* CMC: Added support for buffer uploads */
+ form->buffer, form->bufferlength,
+
form->contenttype, form->flags,
form->contentheader, form->showfilename,
post, httppost,
@@ -1085,9 +1163,9 @@ CURLcode Curl_getFormData(struct FormData **finalform,
fileboundary = Curl_FormBoundary();
size += AddFormDataf(&form,
- "\r\nContent-Type: multipart/mixed,"
- " boundary=%s\r\n",
- fileboundary);
+ "\r\nContent-Type: multipart/mixed,"
+ " boundary=%s\r\n",
+ fileboundary);
}
file = post;
@@ -1099,26 +1177,30 @@ CURLcode Curl_getFormData(struct FormData **finalform,
local file name should be added. */
if(post->more) {
- /* if multiple-file */
- size += AddFormDataf(&form,
- "\r\n--%s\r\nContent-Disposition: "
+ /* if multiple-file */
+ size += AddFormDataf(&form,
+ "\r\n--%s\r\nContent-Disposition: "
"attachment; filename=\"%s\"",
- fileboundary,
+ fileboundary,
(file->showfilename?file->showfilename:
file->contents));
}
- else if(post->flags & HTTPPOST_FILENAME) {
- size += AddFormDataf(&form,
- "; filename=\"%s\"",
- (post->showfilename?post->showfilename:
+ else if((post->flags & HTTPPOST_FILENAME) ||
+
+ /* CMC: Added support for buffer uploads */
+ (post->flags & HTTPPOST_BUFFER)) {
+
+ size += AddFormDataf(&form,
+ "; filename=\"%s\"",
+ (post->showfilename?post->showfilename:
post->contents));
}
if(file->contenttype) {
- /* we have a specified type */
- size += AddFormDataf(&form,
- "\r\nContent-Type: %s",
- file->contenttype);
+ /* we have a specified type */
+ size += AddFormDataf(&form,
+ "\r\nContent-Type: %s",
+ file->contenttype);
}
curList = file->contentheader;
@@ -1136,47 +1218,53 @@ CURLcode Curl_getFormData(struct FormData **finalform,
*/
if(file->contenttype &&
- !strnequal("text/", file->contenttype, 5)) {
- /* this is not a text content, mention our binary encoding */
- size += AddFormData(&form, "\r\nContent-Transfer-Encoding: binary", 0);
+ !strnequal("text/", file->contenttype, 5)) {
+ /* this is not a text content, mention our binary encoding */
+ size += AddFormData(&form, "\r\nContent-Transfer-Encoding: binary", 0);
}
#endif
size += AddFormData(&form, "\r\n\r\n", 0);
if((post->flags & HTTPPOST_FILENAME) ||
- (post->flags & HTTPPOST_READFILE)) {
- /* we should include the contents from the specified file */
- FILE *fileread;
- char buffer[1024];
- int nread;
+ (post->flags & HTTPPOST_READFILE)) {
+ /* we should include the contents from the specified file */
+ FILE *fileread;
+ char buffer[1024];
+ int nread;
- fileread = strequal("-", file->contents)?stdin:
+ fileread = strequal("-", file->contents)?stdin:
/* binary read for win32 crap */
-/*VMS??*/ fopen(file->contents, "rb"); /* ONLY ALLOWS FOR STREAM FILES ON VMS */
-/*VMS?? Stream files are OK, as are FIXED & VAR files WITHOUT implied CC */
-/*VMS?? For implied CC, every record needs to have a \n appended & 1 added to SIZE */
- if(fileread) {
- while((nread = fread(buffer, 1, 1024, fileread)))
- size += AddFormData(&form, buffer, nread);
+ /*VMS??*/ fopen(file->contents, "rb"); /* ONLY ALLOWS FOR STREAM FILES ON VMS */
+ /*VMS?? Stream files are OK, as are FIXED & VAR files WITHOUT implied CC */
+ /*VMS?? For implied CC, every record needs to have a \n appended & 1 added to SIZE */
+ if(fileread) {
+ while((nread = fread(buffer, 1, 1024, fileread)))
+ size += AddFormData(&form, buffer, nread);
if(fileread != stdin)
fclose(fileread);
- }
+ }
else {
#if 0
/* File wasn't found, add a nothing field! */
- size += AddFormData(&form, "", 0);
+ size += AddFormData(&form, "", 0);
#endif
Curl_formclean(firstform);
free(boundary);
*finalform = NULL;
return CURLE_READ_ERROR;
- }
+ }
+
+ /* CMC: Added support for buffer uploads */
+ } else if (post->flags & HTTPPOST_BUFFER) {
+ /* include contents of buffer */
+ size += AddFormData(&form, post->buffer, post->bufferlength);
}
+
else {
- /* include the contents we got */
- size += AddFormData(&form, post->contents, post->contentslength);
+ /* include the contents we got */
+ size += AddFormData(&form, post->contents, post->contentslength);
}
} while((file = file->more)); /* for each specified file for this field */
@@ -1184,8 +1272,8 @@ CURLcode Curl_getFormData(struct FormData **finalform,
/* this was a multiple-file inclusion, make a termination file
boundary: */
size += AddFormDataf(&form,
- "\r\n--%s--",
- fileboundary);
+ "\r\n--%s--",
+ fileboundary);
free(fileboundary);
}
@@ -1193,8 +1281,8 @@ CURLcode Curl_getFormData(struct FormData **finalform,
/* end-boundary for everything */
size += AddFormDataf(&form,
- "\r\n--%s--\r\n",
- boundary);
+ "\r\n--%s--\r\n",
+ boundary);
*sizep = size;
diff --git a/lib/formdata.h b/lib/formdata.h
index 1657f4122..e56f85822 100644
--- a/lib/formdata.h
+++ b/lib/formdata.h
@@ -45,6 +45,10 @@ typedef struct FormInfo {
char *contenttype;
long flags;
+ /* CMC: Added support for buffer uploads */
+ char *buffer; /* pointer to existing buffer used for file upload */
+ long bufferlength;
+
char *showfilename; /* The file name to show. If not set, the actual
file name will be used */
struct curl_slist* contentheader;