Chris Combes added CURLFORM_BUFFER, CURLFORM_BUFFERPTR, CURLFORM_BUFFERLENGTH

This commit is contained in:
Daniel Stenberg
2002-06-12 21:40:59 +00:00
parent dafd644fe7
commit 131645dc31
3 changed files with 149 additions and 42 deletions

View File

@@ -65,6 +65,11 @@ struct curl_httppost {
long namelength; /* length of name length */ long namelength; /* length of name length */
char *contents; /* pointer to allocated data contents */ char *contents; /* pointer to allocated data contents */
long contentslength; /* length of contents field */ 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 */ char *contenttype; /* Content-Type */
struct curl_slist* contentheader; /* list of extra headers for this form */ 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 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 */ do not free in formfree */
#define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer #define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer
do not free in formfree */ 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 char *showfilename; /* The file name to show. If not set, the actual
file name will be used (if this is a file part) */ file name will be used (if this is a file part) */
}; };
@@ -658,6 +668,11 @@ typedef enum {
CFINIT(ARRAY), CFINIT(ARRAY),
CFINIT(OBSOLETE), CFINIT(OBSOLETE),
CFINIT(FILE), CFINIT(FILE),
CFINIT(BUFFER),
CFINIT(BUFFERPTR),
CFINIT(BUFFERLENGTH),
CFINIT(CONTENTTYPE), CFINIT(CONTENTTYPE),
CFINIT(CONTENTHEADER), CFINIT(CONTENTHEADER),
CFINIT(FILENAME), CFINIT(FILENAME),

View File

@@ -400,6 +400,10 @@ int curl_formparse(char *input,
static struct curl_httppost * static struct curl_httppost *
AddHttpPost(char * name, long namelength, AddHttpPost(char * name, long namelength,
char * value, long contentslength, char * value, long contentslength,
/* CMC: Added support for buffer uploads */
char * buffer, long bufferlength,
char *contenttype, char *contenttype,
long flags, long flags,
struct curl_slist* contentHeader, struct curl_slist* contentHeader,
@@ -416,6 +420,11 @@ AddHttpPost(char * name, long namelength,
post->namelength = name?(namelength?namelength:(long)strlen(name)):0; post->namelength = name?(namelength?namelength:(long)strlen(name)):0;
post->contents = value; post->contents = value;
post->contentslength = contentslength; post->contentslength = contentslength;
/* CMC: Added support for buffer uploads */
post->buffer = buffer;
post->bufferlength = bufferlength;
post->contenttype = contenttype; post->contenttype = contenttype;
post->contentheader = contentHeader; post->contentheader = contentHeader;
post->showfilename = showfilename; post->showfilename = showfilename;
@@ -783,9 +792,63 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
} }
break; 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: case CURLFORM_CONTENTTYPE:
{ {
char *contenttype = char *contenttype =
array_state?array_value:va_arg(params, char *); array_state?array_value:va_arg(params, char *);
if (current_form->contenttype) { if (current_form->contenttype) {
if (current_form->flags & HTTPPOST_FILENAME) { 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_FILENAME) && ( (form->flags & HTTPPOST_FILENAME) &&
(form->flags & HTTPPOST_PTRCONTENTS) ) || (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_READFILE) &&
(form->flags & HTTPPOST_PTRCONTENTS) ) (form->flags & HTTPPOST_PTRCONTENTS) )
) { ) {
@@ -859,7 +928,8 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
break; break;
} }
else { else {
if ( (form->flags & HTTPPOST_FILENAME) && if ( ((form->flags & HTTPPOST_FILENAME) ||
(form->flags & HTTPPOST_BUFFER)) &&
!form->contenttype ) { !form->contenttype ) {
/* our contenttype is missing */ /* our contenttype is missing */
form->contenttype form->contenttype
@@ -875,7 +945,11 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
} }
if ( !(form->flags & HTTPPOST_FILENAME) && if ( !(form->flags & HTTPPOST_FILENAME) &&
!(form->flags & HTTPPOST_READFILE) && !(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) */ /* copy value (without strdup; possibly contains null characters) */
if (AllocAndCopy(&form->value, form->contentslength)) { if (AllocAndCopy(&form->value, form->contentslength)) {
return_value = CURL_FORMADD_MEMORY; return_value = CURL_FORMADD_MEMORY;
@@ -884,6 +958,10 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
} }
post = AddHttpPost(form->name, form->namelength, post = AddHttpPost(form->name, form->namelength,
form->value, form->contentslength, form->value, form->contentslength,
/* CMC: Added support for buffer uploads */
form->buffer, form->bufferlength,
form->contenttype, form->flags, form->contenttype, form->flags,
form->contentheader, form->showfilename, form->contentheader, form->showfilename,
post, httppost, post, httppost,
@@ -1085,9 +1163,9 @@ CURLcode Curl_getFormData(struct FormData **finalform,
fileboundary = Curl_FormBoundary(); fileboundary = Curl_FormBoundary();
size += AddFormDataf(&form, size += AddFormDataf(&form,
"\r\nContent-Type: multipart/mixed," "\r\nContent-Type: multipart/mixed,"
" boundary=%s\r\n", " boundary=%s\r\n",
fileboundary); fileboundary);
} }
file = post; file = post;
@@ -1099,26 +1177,30 @@ CURLcode Curl_getFormData(struct FormData **finalform,
local file name should be added. */ local file name should be added. */
if(post->more) { if(post->more) {
/* if multiple-file */ /* if multiple-file */
size += AddFormDataf(&form, size += AddFormDataf(&form,
"\r\n--%s\r\nContent-Disposition: " "\r\n--%s\r\nContent-Disposition: "
"attachment; filename=\"%s\"", "attachment; filename=\"%s\"",
fileboundary, fileboundary,
(file->showfilename?file->showfilename: (file->showfilename?file->showfilename:
file->contents)); file->contents));
} }
else if(post->flags & HTTPPOST_FILENAME) { else if((post->flags & HTTPPOST_FILENAME) ||
size += AddFormDataf(&form,
"; filename=\"%s\"", /* CMC: Added support for buffer uploads */
(post->showfilename?post->showfilename: (post->flags & HTTPPOST_BUFFER)) {
size += AddFormDataf(&form,
"; filename=\"%s\"",
(post->showfilename?post->showfilename:
post->contents)); post->contents));
} }
if(file->contenttype) { if(file->contenttype) {
/* we have a specified type */ /* we have a specified type */
size += AddFormDataf(&form, size += AddFormDataf(&form,
"\r\nContent-Type: %s", "\r\nContent-Type: %s",
file->contenttype); file->contenttype);
} }
curList = file->contentheader; curList = file->contentheader;
@@ -1136,47 +1218,53 @@ CURLcode Curl_getFormData(struct FormData **finalform,
*/ */
if(file->contenttype && if(file->contenttype &&
!strnequal("text/", file->contenttype, 5)) { !strnequal("text/", file->contenttype, 5)) {
/* this is not a text content, mention our binary encoding */ /* this is not a text content, mention our binary encoding */
size += AddFormData(&form, "\r\nContent-Transfer-Encoding: binary", 0); size += AddFormData(&form, "\r\nContent-Transfer-Encoding: binary", 0);
} }
#endif #endif
size += AddFormData(&form, "\r\n\r\n", 0); size += AddFormData(&form, "\r\n\r\n", 0);
if((post->flags & HTTPPOST_FILENAME) || if((post->flags & HTTPPOST_FILENAME) ||
(post->flags & HTTPPOST_READFILE)) { (post->flags & HTTPPOST_READFILE)) {
/* we should include the contents from the specified file */ /* we should include the contents from the specified file */
FILE *fileread; FILE *fileread;
char buffer[1024]; char buffer[1024];
int nread; int nread;
fileread = strequal("-", file->contents)?stdin: fileread = strequal("-", file->contents)?stdin:
/* binary read for win32 crap */ /* binary read for win32 crap */
/*VMS??*/ fopen(file->contents, "rb"); /* ONLY ALLOWS FOR STREAM FILES ON VMS */ /*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?? 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 */ /*VMS?? For implied CC, every record needs to have a \n appended & 1 added to SIZE */
if(fileread) { if(fileread) {
while((nread = fread(buffer, 1, 1024, fileread))) while((nread = fread(buffer, 1, 1024, fileread)))
size += AddFormData(&form, buffer, nread); size += AddFormData(&form, buffer, nread);
if(fileread != stdin) if(fileread != stdin)
fclose(fileread); fclose(fileread);
} }
else { else {
#if 0 #if 0
/* File wasn't found, add a nothing field! */ /* File wasn't found, add a nothing field! */
size += AddFormData(&form, "", 0); size += AddFormData(&form, "", 0);
#endif #endif
Curl_formclean(firstform); Curl_formclean(firstform);
free(boundary); free(boundary);
*finalform = NULL; *finalform = NULL;
return CURLE_READ_ERROR; 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 { else {
/* include the contents we got */ /* include the contents we got */
size += AddFormData(&form, post->contents, post->contentslength); size += AddFormData(&form, post->contents, post->contentslength);
} }
} while((file = file->more)); /* for each specified file for this field */ } 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 /* this was a multiple-file inclusion, make a termination file
boundary: */ boundary: */
size += AddFormDataf(&form, size += AddFormDataf(&form,
"\r\n--%s--", "\r\n--%s--",
fileboundary); fileboundary);
free(fileboundary); free(fileboundary);
} }
@@ -1193,8 +1281,8 @@ CURLcode Curl_getFormData(struct FormData **finalform,
/* end-boundary for everything */ /* end-boundary for everything */
size += AddFormDataf(&form, size += AddFormDataf(&form,
"\r\n--%s--\r\n", "\r\n--%s--\r\n",
boundary); boundary);
*sizep = size; *sizep = size;

View File

@@ -45,6 +45,10 @@ typedef struct FormInfo {
char *contenttype; char *contenttype;
long flags; 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 char *showfilename; /* The file name to show. If not set, the actual
file name will be used */ file name will be used */
struct curl_slist* contentheader; struct curl_slist* contentheader;