Chris Combes added CURLFORM_BUFFER, CURLFORM_BUFFERPTR, CURLFORM_BUFFERLENGTH
This commit is contained in:
@@ -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),
|
||||||
|
172
lib/formdata.c
172
lib/formdata.c
@@ -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;
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
Reference in New Issue
Block a user