1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at http://curl.haxx.se/docs/copyright.html.
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ***************************************************************************/
23 #include "curl_setup.h"
25 #include <curl/curl.h>
27 /* Length of the random boundary string. */
28 #define BOUNDARY_LENGTH 40
30 #if !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY)
32 #if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
36 #include "curl_urldata.h" /* for struct SessionHandle */
37 #include "curl_formdata.h"
38 #include "curl_rand.h"
39 #include "curl_strequal.h"
40 #include "curl_memory.h"
41 #include "curl_sendf.h"
43 #define _MPRINTF_REPLACE /* use our functions only */
44 #include <curl/mprintf.h>
46 /* The last #include file should be: */
47 #include "curl_memdebug.h"
49 #endif /* !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY) */
51 #ifndef CURL_DISABLE_HTTP
54 static char *Curl_basename(char *path);
55 #define basename(x) Curl_basename((x))
58 static size_t readfromfile(struct Form *form, char *buffer, size_t size);
60 /* What kind of Content-Type to use on un-specified files with unrecognized
62 #define HTTPPOST_CONTENTTYPE_DEFAULT "application/octet-stream"
64 #define FORM_FILE_SEPARATOR ','
65 #define FORM_TYPE_SEPARATOR ';'
67 /***************************************************************************
71 * Adds a HttpPost structure to the list, if parent_post is given becomes
72 * a subpost of parent_post instead of a direct list element.
74 * Returns newly allocated HttpPost on success and NULL if malloc failed.
76 ***************************************************************************/
77 static struct curl_httppost *
78 AddHttpPost(char *name, size_t namelength,
79 char *value, size_t contentslength,
80 char *buffer, size_t bufferlength,
83 struct curl_slist* contentHeader,
84 char *showfilename, char *userp,
85 struct curl_httppost *parent_post,
86 struct curl_httppost **httppost,
87 struct curl_httppost **last_post)
89 struct curl_httppost *post;
90 post = calloc(1, sizeof(struct curl_httppost));
93 post->namelength = (long)(name?(namelength?namelength:strlen(name)):0);
94 post->contents = value;
95 post->contentslength = (long)contentslength;
96 post->buffer = buffer;
97 post->bufferlength = (long)bufferlength;
98 post->contenttype = contenttype;
99 post->contentheader = contentHeader;
100 post->showfilename = showfilename;
108 /* now, point our 'more' to the original 'more' */
109 post->more = parent_post->more;
111 /* then move the original 'more' to point to ourselves */
112 parent_post->more = post;
115 /* make the previous point to this */
117 (*last_post)->next = post;
126 /***************************************************************************
130 * Adds a FormInfo structure to the list presented by parent_form_info.
132 * Returns newly allocated FormInfo on success and NULL if malloc failed/
133 * parent_form_info is NULL.
135 ***************************************************************************/
136 static FormInfo * AddFormInfo(char *value,
138 FormInfo *parent_form_info)
141 form_info = calloc(1, sizeof(struct FormInfo));
144 form_info->value = value;
146 form_info->contenttype = contenttype;
147 form_info->flags = HTTPPOST_FILENAME;
152 if(parent_form_info) {
153 /* now, point our 'more' to the original 'more' */
154 form_info->more = parent_form_info->more;
156 /* then move the original 'more' to point to ourselves */
157 parent_form_info->more = form_info;
163 /***************************************************************************
165 * ContentTypeForFilename()
167 * Provides content type for filename if one of the known types (else
168 * (either the prevtype or the default is returned).
170 * Returns some valid contenttype for filename.
172 ***************************************************************************/
173 static const char * ContentTypeForFilename (const char *filename,
174 const char *prevtype)
176 const char *contenttype = NULL;
179 * No type was specified, we scan through a few well-known
180 * extensions and pick the first we match!
186 static const struct ContentType ctts[]={
187 {".gif", "image/gif"},
188 {".jpg", "image/jpeg"},
189 {".jpeg", "image/jpeg"},
190 {".txt", "text/plain"},
191 {".html", "text/html"},
192 {".xml", "application/xml"}
196 /* default to the previously set/used! */
197 contenttype = prevtype;
199 contenttype = HTTPPOST_CONTENTTYPE_DEFAULT;
201 if(filename) { /* in case a NULL was passed in */
202 for(i=0; i<sizeof(ctts)/sizeof(ctts[0]); i++) {
203 if(strlen(filename) >= strlen(ctts[i].extension)) {
204 if(strequal(filename +
205 strlen(filename) - strlen(ctts[i].extension),
206 ctts[i].extension)) {
207 contenttype = ctts[i].type;
213 /* we have a contenttype by now */
217 /***************************************************************************
221 * Copies the 'source' data to a newly allocated buffer buffer (that is
222 * returned). Uses buffer_length if not null, else uses strlen to determine
223 * the length of the buffer to be copied
225 * Returns the new pointer or NULL on failure.
227 ***************************************************************************/
228 static char *memdup(const char *src, size_t buffer_length)
235 length = buffer_length;
237 length = strlen(src);
241 /* no length and a NULL src pointer! */
244 buffer = malloc(length+add);
246 return NULL; /* fail */
248 memcpy(buffer, src, length);
250 /* if length unknown do null termination */
252 buffer[length] = '\0';
257 /***************************************************************************
261 * Stores a formpost parameter and builds the appropriate linked list.
263 * Has two principal functionalities: using files and byte arrays as
264 * post parts. Byte arrays are either copied or just the pointer is stored
265 * (as the user requests) while for files only the filename and not the
268 * While you may have only one byte array for each name, multiple filenames
269 * are allowed (and because of this feature CURLFORM_END is needed after
270 * using CURLFORM_FILE).
274 * Simple name/value pair with copied contents:
275 * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
276 * CURLFORM_COPYCONTENTS, "value", CURLFORM_END);
278 * name/value pair where only the content pointer is remembered:
279 * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
280 * CURLFORM_PTRCONTENTS, ptr, CURLFORM_CONTENTSLENGTH, 10, CURLFORM_END);
281 * (if CURLFORM_CONTENTSLENGTH is missing strlen () is used)
283 * storing a filename (CONTENTTYPE is optional!):
284 * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
285 * CURLFORM_FILE, "filename1", CURLFORM_CONTENTTYPE, "plain/text",
288 * storing multiple filenames:
289 * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
290 * CURLFORM_FILE, "filename1", CURLFORM_FILE, "filename2", CURLFORM_END);
293 * CURL_FORMADD_OK on success
294 * CURL_FORMADD_MEMORY if the FormInfo allocation fails
295 * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form
296 * CURL_FORMADD_NULL if a null pointer was given for a char
297 * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed
298 * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used
299 * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error)
300 * CURL_FORMADD_MEMORY if a HttpPost struct cannot be allocated
301 * CURL_FORMADD_MEMORY if some allocation for string copying failed.
302 * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array
304 ***************************************************************************/
307 CURLFORMcode FormAdd(struct curl_httppost **httppost,
308 struct curl_httppost **last_post,
311 FormInfo *first_form, *current_form, *form = NULL;
312 CURLFORMcode return_value = CURL_FORMADD_OK;
313 const char *prevtype = NULL;
314 struct curl_httppost *post = NULL;
315 CURLformoption option;
316 struct curl_forms *forms = NULL;
317 char *array_value=NULL; /* value read from an array */
319 /* This is a state variable, that if TRUE means that we're parsing an
320 array that we got passed to us. If FALSE we're parsing the input
321 va_list arguments. */
322 bool array_state = FALSE;
325 * We need to allocate the first struct to fill in.
327 first_form = calloc(1, sizeof(struct FormInfo));
329 return CURL_FORMADD_MEMORY;
331 current_form = first_form;
334 * Loop through all the options set. Break if we have an error to report.
336 while(return_value == CURL_FORMADD_OK) {
338 /* first see if we have more parts of the array param */
339 if(array_state && forms) {
340 /* get the upcoming option from the given array */
341 option = forms->option;
342 array_value = (char *)forms->value;
344 forms++; /* advance this to next entry */
345 if(CURLFORM_END == option) {
346 /* end of array state */
352 /* This is not array-state, get next option */
353 option = va_arg(params, CURLformoption);
354 if(CURLFORM_END == option)
361 /* we don't support an array from within an array */
362 return_value = CURL_FORMADD_ILLEGAL_ARRAY;
364 forms = va_arg(params, struct curl_forms *);
368 return_value = CURL_FORMADD_NULL;
373 * Set the Name property.
375 case CURLFORM_PTRNAME:
376 #ifdef CURL_DOES_CONVERSIONS
377 /* Treat CURLFORM_PTR like CURLFORM_COPYNAME so that libcurl will copy
378 * the data in all cases so that we'll have safe memory for the eventual
382 current_form->flags |= HTTPPOST_PTRNAME; /* fall through */
384 case CURLFORM_COPYNAME:
385 if(current_form->name)
386 return_value = CURL_FORMADD_OPTION_TWICE;
388 char *name = array_state?
389 array_value:va_arg(params, char *);
391 current_form->name = name; /* store for the moment */
393 return_value = CURL_FORMADD_NULL;
396 case CURLFORM_NAMELENGTH:
397 if(current_form->namelength)
398 return_value = CURL_FORMADD_OPTION_TWICE;
400 current_form->namelength =
401 array_state?(size_t)array_value:(size_t)va_arg(params, long);
405 * Set the contents property.
407 case CURLFORM_PTRCONTENTS:
408 current_form->flags |= HTTPPOST_PTRCONTENTS; /* fall through */
409 case CURLFORM_COPYCONTENTS:
410 if(current_form->value)
411 return_value = CURL_FORMADD_OPTION_TWICE;
414 array_state?array_value:va_arg(params, char *);
416 current_form->value = value; /* store for the moment */
418 return_value = CURL_FORMADD_NULL;
421 case CURLFORM_CONTENTSLENGTH:
422 if(current_form->contentslength)
423 return_value = CURL_FORMADD_OPTION_TWICE;
425 current_form->contentslength =
426 array_state?(size_t)array_value:(size_t)va_arg(params, long);
429 /* Get contents from a given file name */
430 case CURLFORM_FILECONTENT:
431 if(current_form->flags != 0)
432 return_value = CURL_FORMADD_OPTION_TWICE;
434 const char *filename = array_state?
435 array_value:va_arg(params, char *);
437 current_form->value = strdup(filename);
438 if(!current_form->value)
439 return_value = CURL_FORMADD_MEMORY;
441 current_form->flags |= HTTPPOST_READFILE;
442 current_form->value_alloc = TRUE;
446 return_value = CURL_FORMADD_NULL;
450 /* We upload a file */
453 const char *filename = array_state?array_value:
454 va_arg(params, char *);
456 if(current_form->value) {
457 if(current_form->flags & HTTPPOST_FILENAME) {
459 char *fname = strdup(filename);
461 return_value = CURL_FORMADD_MEMORY;
463 form = AddFormInfo(fname, NULL, current_form);
465 Curl_safefree(fname);
466 return_value = CURL_FORMADD_MEMORY;
469 form->value_alloc = TRUE;
476 return_value = CURL_FORMADD_NULL;
479 return_value = CURL_FORMADD_OPTION_TWICE;
483 current_form->value = strdup(filename);
484 if(!current_form->value)
485 return_value = CURL_FORMADD_MEMORY;
487 current_form->flags |= HTTPPOST_FILENAME;
488 current_form->value_alloc = TRUE;
492 return_value = CURL_FORMADD_NULL;
497 case CURLFORM_BUFFERPTR:
498 current_form->flags |= HTTPPOST_PTRBUFFER|HTTPPOST_BUFFER;
499 if(current_form->buffer)
500 return_value = CURL_FORMADD_OPTION_TWICE;
503 array_state?array_value:va_arg(params, char *);
505 current_form->buffer = buffer; /* store for the moment */
506 current_form->value = buffer; /* make it non-NULL to be accepted
510 return_value = CURL_FORMADD_NULL;
514 case CURLFORM_BUFFERLENGTH:
515 if(current_form->bufferlength)
516 return_value = CURL_FORMADD_OPTION_TWICE;
518 current_form->bufferlength =
519 array_state?(size_t)array_value:(size_t)va_arg(params, long);
522 case CURLFORM_STREAM:
523 current_form->flags |= HTTPPOST_CALLBACK;
524 if(current_form->userp)
525 return_value = CURL_FORMADD_OPTION_TWICE;
528 array_state?array_value:va_arg(params, char *);
530 current_form->userp = userp;
531 current_form->value = userp; /* this isn't strictly true but we
532 derive a value from this later on
533 and we need this non-NULL to be
534 accepted as a fine form part */
537 return_value = CURL_FORMADD_NULL;
541 case CURLFORM_CONTENTTYPE:
543 const char *contenttype =
544 array_state?array_value:va_arg(params, char *);
545 if(current_form->contenttype) {
546 if(current_form->flags & HTTPPOST_FILENAME) {
548 char *type = strdup(contenttype);
550 return_value = CURL_FORMADD_MEMORY;
552 form = AddFormInfo(NULL, type, current_form);
555 return_value = CURL_FORMADD_MEMORY;
558 form->contenttype_alloc = TRUE;
565 return_value = CURL_FORMADD_NULL;
568 return_value = CURL_FORMADD_OPTION_TWICE;
572 current_form->contenttype = strdup(contenttype);
573 if(!current_form->contenttype)
574 return_value = CURL_FORMADD_MEMORY;
576 current_form->contenttype_alloc = TRUE;
579 return_value = CURL_FORMADD_NULL;
583 case CURLFORM_CONTENTHEADER:
585 /* this "cast increases required alignment of target type" but
586 we consider it OK anyway */
587 struct curl_slist* list = array_state?
588 (struct curl_slist*)array_value:
589 va_arg(params, struct curl_slist*);
591 if(current_form->contentheader)
592 return_value = CURL_FORMADD_OPTION_TWICE;
594 current_form->contentheader = list;
598 case CURLFORM_FILENAME:
599 case CURLFORM_BUFFER:
601 const char *filename = array_state?array_value:
602 va_arg(params, char *);
603 if(current_form->showfilename)
604 return_value = CURL_FORMADD_OPTION_TWICE;
606 current_form->showfilename = strdup(filename);
607 if(!current_form->showfilename)
608 return_value = CURL_FORMADD_MEMORY;
610 current_form->showfilename_alloc = TRUE;
615 return_value = CURL_FORMADD_UNKNOWN_OPTION;
620 if(CURL_FORMADD_OK != return_value) {
621 /* On error, free allocated fields for all nodes of the FormInfo linked
622 list without deallocating nodes. List nodes are deallocated later on */
624 for(ptr = first_form; ptr != NULL; ptr = ptr->more) {
625 if(ptr->name_alloc) {
626 Curl_safefree(ptr->name);
627 ptr->name_alloc = FALSE;
629 if(ptr->value_alloc) {
630 Curl_safefree(ptr->value);
631 ptr->value_alloc = FALSE;
633 if(ptr->contenttype_alloc) {
634 Curl_safefree(ptr->contenttype);
635 ptr->contenttype_alloc = FALSE;
637 if(ptr->showfilename_alloc) {
638 Curl_safefree(ptr->showfilename);
639 ptr->showfilename_alloc = FALSE;
644 if(CURL_FORMADD_OK == return_value) {
645 /* go through the list, check for completeness and if everything is
646 * alright add the HttpPost item otherwise set return_value accordingly */
649 for(form = first_form;
652 if(((!form->name || !form->value) && !post) ||
653 ( (form->contentslength) &&
654 (form->flags & HTTPPOST_FILENAME) ) ||
655 ( (form->flags & HTTPPOST_FILENAME) &&
656 (form->flags & HTTPPOST_PTRCONTENTS) ) ||
659 (form->flags & HTTPPOST_BUFFER) &&
660 (form->flags & HTTPPOST_PTRBUFFER) ) ||
662 ( (form->flags & HTTPPOST_READFILE) &&
663 (form->flags & HTTPPOST_PTRCONTENTS) )
665 return_value = CURL_FORMADD_INCOMPLETE;
669 if(((form->flags & HTTPPOST_FILENAME) ||
670 (form->flags & HTTPPOST_BUFFER)) &&
671 !form->contenttype ) {
672 /* our contenttype is missing */
674 = strdup(ContentTypeForFilename(form->value, prevtype));
675 if(!form->contenttype) {
676 return_value = CURL_FORMADD_MEMORY;
679 form->contenttype_alloc = TRUE;
681 if(!(form->flags & HTTPPOST_PTRNAME) &&
682 (form == first_form) ) {
683 /* Note that there's small risk that form->name is NULL here if the
684 app passed in a bad combo, so we better check for that first. */
686 /* copy name (without strdup; possibly contains null characters) */
687 form->name = memdup(form->name, form->namelength);
689 return_value = CURL_FORMADD_MEMORY;
692 form->name_alloc = TRUE;
694 if(!(form->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE |
695 HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER |
696 HTTPPOST_CALLBACK)) ) {
697 /* copy value (without strdup; possibly contains null characters) */
698 form->value = memdup(form->value, form->contentslength);
700 return_value = CURL_FORMADD_MEMORY;
703 form->value_alloc = TRUE;
705 post = AddHttpPost(form->name, form->namelength,
706 form->value, form->contentslength,
707 form->buffer, form->bufferlength,
708 form->contenttype, form->flags,
709 form->contentheader, form->showfilename,
715 return_value = CURL_FORMADD_MEMORY;
719 if(form->contenttype)
720 prevtype = form->contenttype;
723 if(CURL_FORMADD_OK != return_value) {
724 /* On error, free allocated fields for nodes of the FormInfo linked
725 list which are not already owned by the httppost linked list
726 without deallocating nodes. List nodes are deallocated later on */
728 for(ptr = form; ptr != NULL; ptr = ptr->more) {
729 if(ptr->name_alloc) {
730 Curl_safefree(ptr->name);
731 ptr->name_alloc = FALSE;
733 if(ptr->value_alloc) {
734 Curl_safefree(ptr->value);
735 ptr->value_alloc = FALSE;
737 if(ptr->contenttype_alloc) {
738 Curl_safefree(ptr->contenttype);
739 ptr->contenttype_alloc = FALSE;
741 if(ptr->showfilename_alloc) {
742 Curl_safefree(ptr->showfilename);
743 ptr->showfilename_alloc = FALSE;
749 /* Always deallocate FormInfo linked list nodes without touching node
750 fields given that these have either been deallocated or are owned
751 now by the httppost linked list */
753 FormInfo *ptr = first_form->more;
754 Curl_safefree(first_form);
762 * curl_formadd() is a public API to add a section to the multipart formpost.
767 CURLFORMcode curl_formadd(struct curl_httppost **httppost,
768 struct curl_httppost **last_post,
773 va_start(arg, last_post);
774 result = FormAdd(httppost, last_post, arg);
780 * AddFormData() adds a chunk of data to the FormData linked list.
782 * size is incremented by the chunk length, unless it is NULL
784 static CURLcode AddFormData(struct FormData **formp,
790 struct FormData *newform = malloc(sizeof(struct FormData));
792 return CURLE_OUT_OF_MEMORY;
793 newform->next = NULL;
795 if(type <= FORM_CONTENT) {
796 /* we make it easier for plain strings: */
798 length = strlen((char *)line);
800 newform->line = malloc(length+1);
803 return CURLE_OUT_OF_MEMORY;
805 memcpy(newform->line, line, length);
806 newform->length = length;
807 newform->line[length]=0; /* zero terminate for easier debugging */
810 /* For callbacks and files we don't have any actual data so we just keep a
811 pointer to whatever this points to */
812 newform->line = (char *)line;
814 newform->type = type;
817 (*formp)->next = newform;
824 if(type != FORM_FILE)
825 /* for static content as well as callback data we add the size given
829 /* Since this is a file to be uploaded here, add the size of the actual
831 if(!strequal("-", newform->line)) {
833 if(!stat(newform->line, &file)) {
834 *size += file.st_size;
843 * AddFormDataf() adds printf()-style formatted data to the formdata chain.
846 static CURLcode AddFormDataf(struct FormData **formp,
848 const char *fmt, ...)
853 vsnprintf(s, sizeof(s), fmt, ap);
856 return AddFormData(formp, FORM_DATA, s, 0, size);
860 * Curl_formclean() is used from curl_http.c, this cleans a built FormData
863 void Curl_formclean(struct FormData **form_ptr)
865 struct FormData *next, *form;
872 next=form->next; /* the following form line */
873 if(form->type <= FORM_CONTENT)
874 free(form->line); /* free the line */
875 free(form); /* free the struct */
877 } while((form = next) != NULL); /* continue */
884 * Serialize a curl_httppost struct.
885 * Returns 0 on success.
889 int curl_formget(struct curl_httppost *form, void *arg,
890 curl_formget_callback append)
894 struct FormData *data, *ptr;
896 rc = Curl_getformdata(NULL, &data, form, NULL, &size);
900 for(ptr = data; ptr; ptr = ptr->next) {
901 if((ptr->type == FORM_FILE) || (ptr->type == FORM_CALLBACK)) {
906 Curl_FormInit(&temp, ptr);
909 nread = readfromfile(&temp, buffer, sizeof(buffer));
910 if((nread == (size_t) -1) ||
911 (nread > sizeof(buffer)) ||
912 (nread != append(arg, buffer, nread))) {
915 Curl_formclean(&data);
921 if(ptr->length != append(arg, ptr->line, ptr->length)) {
922 Curl_formclean(&data);
927 Curl_formclean(&data);
932 * curl_formfree() is an external function to free up a whole form post
935 void curl_formfree(struct curl_httppost *form)
937 struct curl_httppost *next;
940 /* no form to free, just get out of this */
944 next=form->next; /* the following form line */
946 /* recurse to sub-contents */
948 curl_formfree(form->more);
950 if(!(form->flags & HTTPPOST_PTRNAME) && form->name)
951 free(form->name); /* free the name */
953 (HTTPPOST_PTRCONTENTS|HTTPPOST_BUFFER|HTTPPOST_CALLBACK)) &&
955 free(form->contents); /* free the contents */
956 if(form->contenttype)
957 free(form->contenttype); /* free the content type */
958 if(form->showfilename)
959 free(form->showfilename); /* free the faked file name */
960 free(form); /* free the struct */
962 } while((form = next) != NULL); /* continue */
965 #ifndef HAVE_BASENAME
967 (Quote from The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004
970 The basename() function shall take the pathname pointed to by path and
971 return a pointer to the final component of the pathname, deleting any
972 trailing '/' characters.
974 If the string pointed to by path consists entirely of the '/' character,
975 basename() shall return a pointer to the string "/". If the string pointed
976 to by path is exactly "//", it is implementation-defined whether '/' or "//"
979 If path is a null pointer or points to an empty string, basename() shall
980 return a pointer to the string ".".
982 The basename() function may modify the string pointed to by path, and may
983 return a pointer to static storage that may then be overwritten by a
984 subsequent call to basename().
986 The basename() function need not be reentrant. A function that is not
987 required to be reentrant is not required to be thread-safe.
990 static char *Curl_basename(char *path)
992 /* Ignore all the details above for now and make a quick and simple
993 implementaion here */
997 s1=strrchr(path, '/');
998 s2=strrchr(path, '\\');
1001 path = (s1 > s2? s1 : s2)+1;
1012 static char *strippath(const char *fullfile)
1016 filename = strdup(fullfile); /* duplicate since basename() may ruin the
1017 buffer it works on */
1020 base = strdup(basename(filename));
1022 free(filename); /* free temporary buffer */
1024 return base; /* returns an allocated string or NULL ! */
1028 * Curl_getformdata() converts a linked list of "meta data" into a complete
1029 * (possibly huge) multipart formdata. The input list is in 'post', while the
1030 * output resulting linked lists gets stored in '*finalform'. *sizep will get
1031 * the total size of the whole POST.
1032 * A multipart/form_data content-type is built, unless a custom content-type
1033 * is passed in 'custom_content_type'.
1035 * This function will not do a failf() for the potential memory failures but
1036 * should for all other errors it spots. Just note that this function MAY get
1037 * a NULL pointer in the 'data' argument.
1040 CURLcode Curl_getformdata(struct SessionHandle *data,
1041 struct FormData **finalform,
1042 struct curl_httppost *post,
1043 const char *custom_content_type,
1046 struct FormData *form = NULL;
1047 struct FormData *firstform;
1048 struct curl_httppost *file;
1049 CURLcode result = CURLE_OK;
1051 curl_off_t size = 0; /* support potentially ENORMOUS formposts */
1053 char *fileboundary = NULL;
1054 struct curl_slist* curList;
1056 *finalform = NULL; /* default form is empty */
1059 return result; /* no input => no output! */
1061 boundary = Curl_FormBoundary();
1063 return CURLE_OUT_OF_MEMORY;
1065 /* Make the first line of the output */
1066 result = AddFormDataf(&form, NULL,
1067 "%s; boundary=%s\r\n",
1068 custom_content_type?custom_content_type:
1069 "Content-Type: multipart/form-data",
1073 Curl_safefree(boundary);
1076 /* we DO NOT include that line in the total size of the POST, since it'll be
1077 part of the header! */
1084 result = AddFormDataf(&form, &size, "\r\n");
1090 result = AddFormDataf(&form, &size, "--%s\r\n", boundary);
1094 /* Maybe later this should be disabled when a custom_content_type is
1095 passed, since Content-Disposition is not meaningful for all multipart
1098 result = AddFormDataf(&form, &size,
1099 "Content-Disposition: form-data; name=\"");
1103 result = AddFormData(&form, FORM_DATA, post->name, post->namelength,
1108 result = AddFormDataf(&form, &size, "\"");
1113 /* If used, this is a link to more file names, we must then do
1114 the magic to include several files with the same field name */
1116 Curl_safefree(fileboundary);
1117 fileboundary = Curl_FormBoundary();
1119 result = CURLE_OUT_OF_MEMORY;
1123 result = AddFormDataf(&form, &size,
1124 "\r\nContent-Type: multipart/mixed,"
1135 /* If 'showfilename' is set, that is a faked name passed on to us
1136 to use to in the formpost. If that is not set, the actually used
1137 local file name should be added. */
1140 /* if multiple-file */
1141 char *filebasename = NULL;
1142 if(!file->showfilename) {
1143 filebasename = strippath(file->contents);
1145 result = CURLE_OUT_OF_MEMORY;
1150 result = AddFormDataf(&form, &size,
1151 "\r\n--%s\r\nContent-Disposition: "
1152 "attachment; filename=\"%s\"",
1154 (file->showfilename?file->showfilename:
1156 Curl_safefree(filebasename);
1160 else if(post->flags & (HTTPPOST_FILENAME|HTTPPOST_BUFFER|
1161 HTTPPOST_CALLBACK)) {
1162 /* it should be noted that for the HTTPPOST_FILENAME and
1163 HTTPPOST_CALLBACK cases the ->showfilename struct member is always
1164 assigned at this point */
1165 if(post->showfilename || (post->flags & HTTPPOST_FILENAME)) {
1167 (!post->showfilename)?strippath(post->contents):NULL;
1169 result = AddFormDataf(&form, &size,
1170 "; filename=\"%s\"",
1171 (post->showfilename?post->showfilename:
1173 Curl_safefree(filebasename);
1180 if(file->contenttype) {
1181 /* we have a specified type */
1182 result = AddFormDataf(&form, &size,
1183 "\r\nContent-Type: %s",
1189 curList = file->contentheader;
1191 /* Process the additional headers specified for this form */
1192 result = AddFormDataf( &form, &size, "\r\n%s", curList->data );
1195 curList = curList->next;
1200 result = AddFormDataf(&form, &size, "\r\n\r\n");
1204 if((post->flags & HTTPPOST_FILENAME) ||
1205 (post->flags & HTTPPOST_READFILE)) {
1206 /* we should include the contents from the specified file */
1209 fileread = strequal("-", file->contents)?
1210 stdin:fopen(file->contents, "rb"); /* binary read for win32 */
1213 * VMS: This only allows for stream files on VMS. Stream files are
1214 * OK, as are FIXED & VAR files WITHOUT implied CC For implied CC,
1215 * every record needs to have a \n appended & 1 added to SIZE
1219 if(fileread != stdin) {
1220 /* close the file */
1222 /* add the file name only - for later reading from this */
1223 result = AddFormData(&form, FORM_FILE, file->contents, 0, &size);
1226 /* When uploading from stdin, we can't know the size of the file,
1227 * thus must read the full file as before. We *could* use chunked
1228 * transfer-encoding, but that only works for HTTP 1.1 and we
1229 * can't be sure we work with such a server.
1233 while((nread = fread(buffer, 1, sizeof(buffer), fileread)) != 0) {
1234 result = AddFormData(&form, FORM_CONTENT, buffer, nread, &size);
1242 failf(data, "couldn't open file \"%s\"", file->contents);
1244 result = CURLE_READ_ERROR;
1247 else if(post->flags & HTTPPOST_BUFFER)
1248 /* include contents of buffer */
1249 result = AddFormData(&form, FORM_CONTENT, post->buffer,
1250 post->bufferlength, &size);
1251 else if(post->flags & HTTPPOST_CALLBACK)
1252 /* the contents should be read with the callback and the size
1253 is set with the contentslength */
1254 result = AddFormData(&form, FORM_CALLBACK, post->userp,
1255 post->contentslength, &size);
1257 /* include the contents we got */
1258 result = AddFormData(&form, FORM_CONTENT, post->contents,
1259 post->contentslength, &size);
1262 } while(file && !result); /* for each specified file for this field */
1268 /* this was a multiple-file inclusion, make a termination file
1270 result = AddFormDataf(&form, &size,
1277 } while((post = post->next) != NULL); /* for each field */
1279 /* end-boundary for everything */
1280 if(CURLE_OK == result)
1281 result = AddFormDataf(&form, &size,
1286 Curl_formclean(&firstform);
1287 Curl_safefree(fileboundary);
1288 Curl_safefree(boundary);
1294 Curl_safefree(fileboundary);
1295 Curl_safefree(boundary);
1297 *finalform = firstform;
1303 * Curl_FormInit() inits the struct 'form' points to with the 'formdata'
1304 * and resets the 'sent' counter.
1306 int Curl_FormInit(struct Form *form, struct FormData *formdata )
1309 return 1; /* error */
1311 form->data = formdata;
1314 form->fread_func = ZERO_NULL;
1322 * The read callback that this function may use can return a value larger than
1323 * 'size' (which then this function returns) that indicates a problem and it
1324 * must be properly dealt with
1326 static size_t readfromfile(struct Form *form, char *buffer,
1330 bool callback = (form->data->type == FORM_CALLBACK)?TRUE:FALSE;
1333 if(form->fread_func == ZERO_NULL)
1336 nread = form->fread_func(buffer, 1, size, form->data->line);
1340 /* this file hasn't yet been opened */
1341 form->fp = fopen(form->data->line, "rb"); /* b is for binary */
1343 return (size_t)-1; /* failure */
1345 nread = fread(buffer, 1, size, form->fp);
1348 /* this is the last chunk from the file, move on */
1353 form->data = form->data->next;
1360 * Curl_FormReader() is the fread() emulation function that will be used to
1361 * deliver the formdata to the transfer loop and then sent away to the peer.
1363 size_t Curl_FormReader(char *buffer,
1372 form=(struct Form *)mydata;
1374 wantedsize = size * nitems;
1377 return 0; /* nothing, error, empty */
1379 if((form->data->type == FORM_FILE) ||
1380 (form->data->type == FORM_CALLBACK)) {
1381 gotsize = readfromfile(form, buffer, wantedsize);
1384 /* If positive or -1, return. If zero, continue! */
1389 if((form->data->length - form->sent ) > wantedsize - gotsize) {
1391 memcpy(buffer + gotsize , form->data->line + form->sent,
1392 wantedsize - gotsize);
1394 form->sent += wantedsize-gotsize;
1399 memcpy(buffer+gotsize,
1400 form->data->line + form->sent,
1401 (form->data->length - form->sent) );
1402 gotsize += form->data->length - form->sent;
1406 form->data = form->data->next; /* advance */
1408 } while(form->data && (form->data->type < FORM_CALLBACK));
1409 /* If we got an empty line and we have more data, we proceed to the next
1410 line immediately to avoid returning zero before we've reached the end. */
1416 * Curl_formpostheader() returns the first line of the formpost, the
1417 * request-header part (which is not part of the request-body like the rest of
1420 char *Curl_formpostheader(void *formp, size_t *len)
1423 struct Form *form=(struct Form *)formp;
1426 return 0; /* nothing, ERROR! */
1428 header = form->data->line;
1429 *len = form->data->length;
1431 form->data = form->data->next; /* advance */
1436 #else /* CURL_DISABLE_HTTP */
1437 CURLFORMcode curl_formadd(struct curl_httppost **httppost,
1438 struct curl_httppost **last_post,
1443 return CURL_FORMADD_DISABLED;
1446 int curl_formget(struct curl_httppost *form, void *arg,
1447 curl_formget_callback append)
1452 return CURL_FORMADD_DISABLED;
1455 void curl_formfree(struct curl_httppost *form)
1458 /* does nothing HTTP is disabled */
1461 #endif /* CURL_DISABLE_HTTP */
1463 #if !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY)
1466 * Curl_FormBoundary() creates a suitable boundary string and returns an
1467 * allocated one. This is also used by SSL-code so it must be present even
1468 * if HTTP is disabled!
1470 char *Curl_FormBoundary(void)
1475 static const char table16[]="0123456789abcdef";
1477 retstring = malloc(BOUNDARY_LENGTH+1);
1480 return NULL; /* failed */
1482 strcpy(retstring, "----------------------------");
1484 for(i=strlen(retstring); i<BOUNDARY_LENGTH; i++)
1485 retstring[i] = table16[Curl_rand()%16];
1487 /* 28 dashes and 12 hexadecimal digits makes 12^16 (184884258895036416)
1489 retstring[BOUNDARY_LENGTH]=0; /* zero terminate */
1494 #endif /* !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY) */