Added support for CURLFORM_FILENAME to set the filename field of a file

part.
This commit is contained in:
Daniel Stenberg 2002-03-11 15:18:59 +00:00
parent 5799852424
commit 9f374c2050
2 changed files with 76 additions and 50 deletions

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 2002, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* In order to be useful for every potential user, curl and libcurl are * In order to be useful for every potential user, curl and libcurl are
* dual-licensed under the MPL and the MIT/X-derivate licenses. * dual-licensed under the MPL and the MIT/X-derivate licenses.
@ -171,8 +171,8 @@ static void GetStr(char **string,
static static
int FormParse(char *input, int FormParse(char *input,
struct HttpPost **httppost, struct curl_httppost **httppost,
struct HttpPost **last_post) struct curl_httppost **last_post)
{ {
/* nextarg MUST be a string in the format 'name=contents' and we'll /* nextarg MUST be a string in the format 'name=contents' and we'll
build a linked list with the info */ build a linked list with the info */
@ -186,8 +186,8 @@ int FormParse(char *input,
char *prevtype = NULL; char *prevtype = NULL;
char *sep; char *sep;
char *sep2; char *sep2;
struct HttpPost *post; struct curl_httppost *post;
struct HttpPost *subpost; /* a sub-node */ struct curl_httppost *subpost; /* a sub-node */
unsigned int i; unsigned int i;
/* Preallocate contents to the length of input to make sure we don't /* Preallocate contents to the length of input to make sure we don't
@ -296,9 +296,9 @@ int FormParse(char *input,
/* For the first file name, we allocate and initiate the main list /* For the first file name, we allocate and initiate the main list
node */ node */
post = (struct HttpPost *)malloc(sizeof(struct HttpPost)); post = (struct curl_httppost *)malloc(sizeof(struct curl_httppost));
if(post) { if(post) {
memset(post, 0, sizeof(struct HttpPost)); memset(post, 0, sizeof(struct curl_httppost));
GetStr(&post->name, name); /* get the name */ GetStr(&post->name, name); /* get the name */
GetStr(&post->contents, contp); /* get the contents */ GetStr(&post->contents, contp); /* get the contents */
post->contentslength = 0; post->contentslength = 0;
@ -320,9 +320,10 @@ int FormParse(char *input,
else { else {
/* we add a file name to the previously allocated node, known as /* we add a file name to the previously allocated node, known as
'post' now */ 'post' now */
subpost =(struct HttpPost *)malloc(sizeof(struct HttpPost)); subpost =(struct curl_httppost *)
malloc(sizeof(struct curl_httppost));
if(subpost) { if(subpost) {
memset(subpost, 0, sizeof(struct HttpPost)); memset(subpost, 0, sizeof(struct curl_httppost));
GetStr(&subpost->name, name); /* get the name */ GetStr(&subpost->name, name); /* get the name */
GetStr(&subpost->contents, contp); /* get the contents */ GetStr(&subpost->contents, contp); /* get the contents */
subpost->contentslength = 0; subpost->contentslength = 0;
@ -342,9 +343,9 @@ int FormParse(char *input,
} while(sep && *sep); /* loop if there's another file name */ } while(sep && *sep); /* loop if there's another file name */
} }
else { else {
post = (struct HttpPost *)malloc(sizeof(struct HttpPost)); post = (struct curl_httppost *)malloc(sizeof(struct curl_httppost));
if(post) { if(post) {
memset(post, 0, sizeof(struct HttpPost)); memset(post, 0, sizeof(struct curl_httppost));
GetStr(&post->name, name); /* get the name */ GetStr(&post->name, name); /* get the name */
if( contp[0]=='<' ) { if( contp[0]=='<' ) {
GetStr(&post->contents, contp+1); /* get the contents */ GetStr(&post->contents, contp+1); /* get the contents */
@ -378,8 +379,8 @@ int FormParse(char *input,
} }
int curl_formparse(char *input, int curl_formparse(char *input,
struct HttpPost **httppost, struct curl_httppost **httppost,
struct HttpPost **last_post) struct curl_httppost **last_post)
{ {
return FormParse(input, httppost, last_post); return FormParse(input, httppost, last_post);
} }
@ -394,27 +395,28 @@ int curl_formparse(char *input,
* Returns newly allocated HttpPost on success and NULL if malloc failed. * Returns newly allocated HttpPost on success and NULL if malloc failed.
* *
***************************************************************************/ ***************************************************************************/
static struct HttpPost * AddHttpPost(char * name, static struct curl_httppost *
long namelength, AddHttpPost(char * name, long namelength,
char * value, char * value, long contentslength,
long contentslength, char *contenttype,
char *contenttype, long flags,
long flags, struct curl_slist* contentHeader,
struct curl_slist* contentHeader, char *showfilename,
struct HttpPost *parent_post, struct curl_httppost *parent_post,
struct HttpPost **httppost, struct curl_httppost **httppost,
struct HttpPost **last_post) struct curl_httppost **last_post)
{ {
struct HttpPost *post; struct curl_httppost *post;
post = (struct HttpPost *)malloc(sizeof(struct HttpPost)); post = (struct curl_httppost *)malloc(sizeof(struct curl_httppost));
if(post) { if(post) {
memset(post, 0, sizeof(struct HttpPost)); memset(post, 0, sizeof(struct curl_httppost));
post->name = name; post->name = name;
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;
post->contenttype = contenttype; post->contenttype = contenttype;
post->contentheader = contentHeader; post->contentheader = contentHeader;
post->showfilename = showfilename;
post->flags = flags; post->flags = flags;
} }
else else
@ -627,14 +629,14 @@ typedef enum {
} FORMcode; } FORMcode;
static static
FORMcode FormAdd(struct HttpPost **httppost, FORMcode FormAdd(struct curl_httppost **httppost,
struct HttpPost **last_post, struct curl_httppost **last_post,
va_list params) va_list params)
{ {
FormInfo *first_form, *current_form, *form; FormInfo *first_form, *current_form, *form;
FORMcode return_value = FORMADD_OK; FORMcode return_value = FORMADD_OK;
const char *prevtype = NULL; const char *prevtype = NULL;
struct HttpPost *post = NULL; struct curl_httppost *post = NULL;
CURLformoption option; CURLformoption option;
struct curl_forms *forms = NULL; struct curl_forms *forms = NULL;
const char *array_value; /* value read from an array */ const char *array_value; /* value read from an array */
@ -677,9 +679,9 @@ FORMcode FormAdd(struct HttpPost **httppost,
continue; continue;
} }
else { else {
/* check that the option is OK in an array */ /* Check that the option is OK in an array.
TODO: make ALL options work in arrays */
/* Daniel's note: do we really need to do this? */
if ( (option <= CURLFORM_ARRAY_START) || if ( (option <= CURLFORM_ARRAY_START) ||
(option >= CURLFORM_ARRAY_END) ) { (option >= CURLFORM_ARRAY_END) ) {
return_value = FORMADD_ILLEGAL_ARRAY; return_value = FORMADD_ILLEGAL_ARRAY;
@ -829,7 +831,7 @@ FORMcode FormAdd(struct HttpPost **httppost,
if( array_state ) if( array_state )
list = (struct curl_slist*)array_value; list = (struct curl_slist*)array_value;
else else
list = va_arg(params,struct curl_slist*); list = va_arg(params, struct curl_slist*);
if( current_form->contentheader ) if( current_form->contentheader )
return_value = FORMADD_OPTION_TWICE; return_value = FORMADD_OPTION_TWICE;
@ -838,6 +840,16 @@ FORMcode FormAdd(struct HttpPost **httppost,
break; break;
} }
case CURLFORM_FILENAME:
{
char *filename = array_state?(char *)array_value:
va_arg(params, char *);
if( current_form->showfilename )
return_value = FORMADD_OPTION_TWICE;
else
current_form->showfilename = strdup(filename);
break;
}
default: default:
return_value = FORMADD_UNKNOWN_OPTION; return_value = FORMADD_UNKNOWN_OPTION;
} }
@ -889,7 +901,7 @@ FORMcode FormAdd(struct HttpPost **httppost,
post = AddHttpPost(form->name, form->namelength, post = AddHttpPost(form->name, form->namelength,
form->value, form->contentslength, form->value, form->contentslength,
form->contenttype, form->flags, form->contenttype, form->flags,
form->contentheader, form->contentheader, form->showfilename,
post, httppost, post, httppost,
last_post); last_post);
@ -915,8 +927,8 @@ FORMcode FormAdd(struct HttpPost **httppost,
return return_value; return return_value;
} }
int curl_formadd(struct HttpPost **httppost, int curl_formadd(struct curl_httppost **httppost,
struct HttpPost **last_post, struct curl_httppost **last_post,
...) ...)
{ {
va_list arg; va_list arg;
@ -1009,9 +1021,9 @@ void Curl_formclean(struct FormData *form)
} }
/* external function to free up a whole form post chain */ /* external function to free up a whole form post chain */
void curl_formfree(struct HttpPost *form) void curl_formfree(struct curl_httppost *form)
{ {
struct HttpPost *next; struct curl_httppost *next;
if(!form) if(!form)
/* no form to free, just get out of this */ /* no form to free, just get out of this */
@ -1030,18 +1042,20 @@ void curl_formfree(struct HttpPost *form)
free(form->contents); /* free the contents */ free(form->contents); /* free the contents */
if(form->contenttype) if(form->contenttype)
free(form->contenttype); /* free the content type */ free(form->contenttype); /* free the content type */
if(form->showfilename)
free(form->showfilename); /* free the faked file name */
free(form); /* free the struct */ free(form); /* free the struct */
} while((form=next)); /* continue */ } while((form=next)); /* continue */
} }
struct FormData *Curl_getFormData(struct HttpPost *post, struct FormData *Curl_getFormData(struct curl_httppost *post,
int *sizep) int *sizep)
{ {
struct FormData *form = NULL; struct FormData *form = NULL;
struct FormData *firstform; struct FormData *firstform;
struct HttpPost *file; struct curl_httppost *file;
int size =0; int size =0;
char *boundary; char *boundary;
@ -1093,16 +1107,25 @@ struct FormData *Curl_getFormData(struct HttpPost *post,
file = post; file = post;
do { do {
/* If 'showfilename' is set, that is a faked name passed on to us
to use to in the formpost. If that is not set, the actually used
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: attachment; filename=\"%s\"", "\r\n--%s\r\nContent-Disposition: "
fileboundary, file->contents); "attachment; filename=\"%s\"",
fileboundary,
(file->showfilename?file->showfilename:
file->contents));
} }
else if(post->flags & HTTPPOST_FILENAME) { else if(post->flags & HTTPPOST_FILENAME) {
size += AddFormDataf(&form, size += AddFormDataf(&form,
"; filename=\"%s\"", "; filename=\"%s\"",
post->contents); (post->showfilename?post->showfilename:
post->contents));
} }
if(file->contenttype) { if(file->contenttype) {
@ -1294,8 +1317,8 @@ int Curl_FormReadOneLine(char *buffer,
#ifdef _FORM_DEBUG #ifdef _FORM_DEBUG
int FormAddTest(const char * errormsg, int FormAddTest(const char * errormsg,
struct HttpPost **httppost, struct curl_httppost **httppost,
struct HttpPost **last_post, struct curl_httppost **last_post,
...) ...)
{ {
int result; int result;
@ -1341,8 +1364,8 @@ int main()
int size; int size;
int nread; int nread;
char buffer[4096]; char buffer[4096];
struct HttpPost *httppost=NULL; struct curl_httppost *httppost=NULL;
struct HttpPost *last_post=NULL; struct curl_httppost *last_post=NULL;
struct curl_forms forms[4]; struct curl_forms forms[4];
struct FormData *form; struct FormData *form;
@ -1451,9 +1474,9 @@ int main(int argc, char **argv)
#endif #endif
int i; int i;
char *nextarg; char *nextarg;
struct HttpPost *httppost=NULL; struct curl_httppost *httppost=NULL;
struct HttpPost *last_post=NULL; struct curl_httppost *last_post=NULL;
struct HttpPost *post; struct curl_httppost *post;
int size; int size;
int nread; int nread;
char buffer[4096]; char buffer[4096];

View File

@ -8,7 +8,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 2002, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* In order to be useful for every potential user, curl and libcurl are * In order to be useful for every potential user, curl and libcurl are
* dual-licensed under the MPL and the MIT/X-derivate licenses. * dual-licensed under the MPL and the MIT/X-derivate licenses.
@ -44,6 +44,9 @@ typedef struct FormInfo {
long contentslength; long contentslength;
char *contenttype; char *contenttype;
long flags; long flags;
char *showfilename; /* The file name to show. If not set, the actual
file name will be used */
struct curl_slist* contentheader; struct curl_slist* contentheader;
struct FormInfo *more; struct FormInfo *more;
} FormInfo; } FormInfo;