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 "urldata.h" /* for struct SessionHandle */
38 #include "curl_rand.h"
40 #include "curl_memory.h"
43 #define _MPRINTF_REPLACE /* use our functions only */
44 #include <curl/mprintf.h>
46 /* The last #include file should be: */
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);
59 static char *formboundary(void);
61 /* What kind of Content-Type to use on un-specified files with unrecognized
63 #define HTTPPOST_CONTENTTYPE_DEFAULT "application/octet-stream"
65 #define FORM_FILE_SEPARATOR ','
66 #define FORM_TYPE_SEPARATOR ';'
68 /***************************************************************************
72 * Adds a HttpPost structure to the list, if parent_post is given becomes
73 * a subpost of parent_post instead of a direct list element.
75 * Returns newly allocated HttpPost on success and NULL if malloc failed.
77 ***************************************************************************/
78 static struct curl_httppost *
79 AddHttpPost(char *name, size_t namelength,
80 char *value, size_t contentslength,
81 char *buffer, size_t bufferlength,
84 struct curl_slist* contentHeader,
85 char *showfilename, char *userp,
86 struct curl_httppost *parent_post,
87 struct curl_httppost **httppost,
88 struct curl_httppost **last_post)
90 struct curl_httppost *post;
91 post = calloc(1, sizeof(struct curl_httppost));
94 post->namelength = (long)(name?(namelength?namelength:strlen(name)):0);
95 post->contents = value;
96 post->contentslength = (long)contentslength;
97 post->buffer = buffer;
98 post->bufferlength = (long)bufferlength;
99 post->contenttype = contenttype;
100 post->contentheader = contentHeader;
101 post->showfilename = showfilename;
109 /* now, point our 'more' to the original 'more' */
110 post->more = parent_post->more;
112 /* then move the original 'more' to point to ourselves */
113 parent_post->more = post;
116 /* make the previous point to this */
118 (*last_post)->next = post;
127 /***************************************************************************
131 * Adds a FormInfo structure to the list presented by parent_form_info.
133 * Returns newly allocated FormInfo on success and NULL if malloc failed/
134 * parent_form_info is NULL.
136 ***************************************************************************/
137 static FormInfo * AddFormInfo(char *value,
139 FormInfo *parent_form_info)
142 form_info = calloc(1, sizeof(struct FormInfo));
145 form_info->value = value;
147 form_info->contenttype = contenttype;
148 form_info->flags = HTTPPOST_FILENAME;
153 if(parent_form_info) {
154 /* now, point our 'more' to the original 'more' */
155 form_info->more = parent_form_info->more;
157 /* then move the original 'more' to point to ourselves */
158 parent_form_info->more = form_info;
164 /***************************************************************************
166 * ContentTypeForFilename()
168 * Provides content type for filename if one of the known types (else
169 * (either the prevtype or the default is returned).
171 * Returns some valid contenttype for filename.
173 ***************************************************************************/
174 static const char * ContentTypeForFilename (const char *filename,
175 const char *prevtype)
177 const char *contenttype = NULL;
180 * No type was specified, we scan through a few well-known
181 * extensions and pick the first we match!
187 static const struct ContentType ctts[]={
188 {".gif", "image/gif"},
189 {".jpg", "image/jpeg"},
190 {".jpeg", "image/jpeg"},
191 {".txt", "text/plain"},
192 {".html", "text/html"},
193 {".xml", "application/xml"}
197 /* default to the previously set/used! */
198 contenttype = prevtype;
200 contenttype = HTTPPOST_CONTENTTYPE_DEFAULT;
202 if(filename) { /* in case a NULL was passed in */
203 for(i=0; i<sizeof(ctts)/sizeof(ctts[0]); i++) {
204 if(strlen(filename) >= strlen(ctts[i].extension)) {
205 if(strequal(filename +
206 strlen(filename) - strlen(ctts[i].extension),
207 ctts[i].extension)) {
208 contenttype = ctts[i].type;
214 /* we have a contenttype by now */
218 /***************************************************************************
222 * Copies the 'source' data to a newly allocated buffer buffer (that is
223 * returned). Uses buffer_length if not null, else uses strlen to determine
224 * the length of the buffer to be copied
226 * Returns the new pointer or NULL on failure.
228 ***************************************************************************/
229 static char *memdup(const char *src, size_t buffer_length)
236 length = buffer_length;
238 length = strlen(src);
242 /* no length and a NULL src pointer! */
245 buffer = malloc(length+add);
247 return NULL; /* fail */
249 memcpy(buffer, src, length);
251 /* if length unknown do null termination */
253 buffer[length] = '\0';
258 /***************************************************************************
262 * Stores a formpost parameter and builds the appropriate linked list.
264 * Has two principal functionalities: using files and byte arrays as
265 * post parts. Byte arrays are either copied or just the pointer is stored
266 * (as the user requests) while for files only the filename and not the
269 * While you may have only one byte array for each name, multiple filenames
270 * are allowed (and because of this feature CURLFORM_END is needed after
271 * using CURLFORM_FILE).
275 * Simple name/value pair with copied contents:
276 * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
277 * CURLFORM_COPYCONTENTS, "value", CURLFORM_END);
279 * name/value pair where only the content pointer is remembered:
280 * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
281 * CURLFORM_PTRCONTENTS, ptr, CURLFORM_CONTENTSLENGTH, 10, CURLFORM_END);
282 * (if CURLFORM_CONTENTSLENGTH is missing strlen () is used)
284 * storing a filename (CONTENTTYPE is optional!):
285 * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
286 * CURLFORM_FILE, "filename1", CURLFORM_CONTENTTYPE, "plain/text",
289 * storing multiple filenames:
290 * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
291 * CURLFORM_FILE, "filename1", CURLFORM_FILE, "filename2", CURLFORM_END);
294 * CURL_FORMADD_OK on success
295 * CURL_FORMADD_MEMORY if the FormInfo allocation fails
296 * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form
297 * CURL_FORMADD_NULL if a null pointer was given for a char
298 * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed
299 * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used
300 * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error)
301 * CURL_FORMADD_MEMORY if a HttpPost struct cannot be allocated
302 * CURL_FORMADD_MEMORY if some allocation for string copying failed.
303 * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array
305 ***************************************************************************/
308 CURLFORMcode FormAdd(struct curl_httppost **httppost,
309 struct curl_httppost **last_post,
312 FormInfo *first_form, *current_form, *form = NULL;
313 CURLFORMcode return_value = CURL_FORMADD_OK;
314 const char *prevtype = NULL;
315 struct curl_httppost *post = NULL;
316 CURLformoption option;
317 struct curl_forms *forms = NULL;
318 char *array_value=NULL; /* value read from an array */
320 /* This is a state variable, that if TRUE means that we're parsing an
321 array that we got passed to us. If FALSE we're parsing the input
322 va_list arguments. */
323 bool array_state = FALSE;
326 * We need to allocate the first struct to fill in.
328 first_form = calloc(1, sizeof(struct FormInfo));
330 return CURL_FORMADD_MEMORY;
332 current_form = first_form;
335 * Loop through all the options set. Break if we have an error to report.
337 while(return_value == CURL_FORMADD_OK) {
339 /* first see if we have more parts of the array param */
340 if(array_state && forms) {
341 /* get the upcoming option from the given array */
342 option = forms->option;
343 array_value = (char *)forms->value;
345 forms++; /* advance this to next entry */
346 if(CURLFORM_END == option) {
347 /* end of array state */
353 /* This is not array-state, get next option */
354 option = va_arg(params, CURLformoption);
355 if(CURLFORM_END == option)
362 /* we don't support an array from within an array */
363 return_value = CURL_FORMADD_ILLEGAL_ARRAY;
365 forms = va_arg(params, struct curl_forms *);
369 return_value = CURL_FORMADD_NULL;
374 * Set the Name property.
376 case CURLFORM_PTRNAME:
377 #ifdef CURL_DOES_CONVERSIONS
378 /* Treat CURLFORM_PTR like CURLFORM_COPYNAME so that libcurl will copy
379 * the data in all cases so that we'll have safe memory for the eventual
383 current_form->flags |= HTTPPOST_PTRNAME; /* fall through */
385 case CURLFORM_COPYNAME:
386 if(current_form->name)
387 return_value = CURL_FORMADD_OPTION_TWICE;
389 char *name = array_state?
390 array_value:va_arg(params, char *);
392 current_form->name = name; /* store for the moment */
394 return_value = CURL_FORMADD_NULL;
397 case CURLFORM_NAMELENGTH:
398 if(current_form->namelength)
399 return_value = CURL_FORMADD_OPTION_TWICE;
401 current_form->namelength =
402 array_state?(size_t)array_value:(size_t)va_arg(params, long);
406 * Set the contents property.
408 case CURLFORM_PTRCONTENTS:
409 current_form->flags |= HTTPPOST_PTRCONTENTS; /* fall through */
410 case CURLFORM_COPYCONTENTS:
411 if(current_form->value)
412 return_value = CURL_FORMADD_OPTION_TWICE;
415 array_state?array_value:va_arg(params, char *);
417 current_form->value = value; /* store for the moment */
419 return_value = CURL_FORMADD_NULL;
422 case CURLFORM_CONTENTSLENGTH:
423 if(current_form->contentslength)
424 return_value = CURL_FORMADD_OPTION_TWICE;
426 current_form->contentslength =
427 array_state?(size_t)array_value:(size_t)va_arg(params, long);
430 /* Get contents from a given file name */
431 case CURLFORM_FILECONTENT:
432 if(current_form->flags != 0)
433 return_value = CURL_FORMADD_OPTION_TWICE;
435 const char *filename = array_state?
436 array_value:va_arg(params, char *);
438 current_form->value = strdup(filename);
439 if(!current_form->value)
440 return_value = CURL_FORMADD_MEMORY;
442 current_form->flags |= HTTPPOST_READFILE;
443 current_form->value_alloc = TRUE;
447 return_value = CURL_FORMADD_NULL;
451 /* We upload a file */
454 const char *filename = array_state?array_value:
455 va_arg(params, char *);
457 if(current_form->value) {
458 if(current_form->flags & HTTPPOST_FILENAME) {
460 char *fname = strdup(filename);
462 return_value = CURL_FORMADD_MEMORY;
464 form = AddFormInfo(fname, NULL, current_form);
466 Curl_safefree(fname);
467 return_value = CURL_FORMADD_MEMORY;
470 form->value_alloc = TRUE;
477 return_value = CURL_FORMADD_NULL;
480 return_value = CURL_FORMADD_OPTION_TWICE;
484 current_form->value = strdup(filename);
485 if(!current_form->value)
486 return_value = CURL_FORMADD_MEMORY;
488 current_form->flags |= HTTPPOST_FILENAME;
489 current_form->value_alloc = TRUE;
493 return_value = CURL_FORMADD_NULL;
498 case CURLFORM_BUFFERPTR:
499 current_form->flags |= HTTPPOST_PTRBUFFER|HTTPPOST_BUFFER;
500 if(current_form->buffer)
501 return_value = CURL_FORMADD_OPTION_TWICE;
504 array_state?array_value:va_arg(params, char *);
506 current_form->buffer = buffer; /* store for the moment */
507 current_form->value = buffer; /* make it non-NULL to be accepted
511 return_value = CURL_FORMADD_NULL;
515 case CURLFORM_BUFFERLENGTH:
516 if(current_form->bufferlength)
517 return_value = CURL_FORMADD_OPTION_TWICE;
519 current_form->bufferlength =
520 array_state?(size_t)array_value:(size_t)va_arg(params, long);
523 case CURLFORM_STREAM:
524 current_form->flags |= HTTPPOST_CALLBACK;
525 if(current_form->userp)
526 return_value = CURL_FORMADD_OPTION_TWICE;
529 array_state?array_value:va_arg(params, char *);
531 current_form->userp = userp;
532 current_form->value = userp; /* this isn't strictly true but we
533 derive a value from this later on
534 and we need this non-NULL to be
535 accepted as a fine form part */
538 return_value = CURL_FORMADD_NULL;
542 case CURLFORM_CONTENTTYPE:
544 const char *contenttype =
545 array_state?array_value:va_arg(params, char *);
546 if(current_form->contenttype) {
547 if(current_form->flags & HTTPPOST_FILENAME) {
549 char *type = strdup(contenttype);
551 return_value = CURL_FORMADD_MEMORY;
553 form = AddFormInfo(NULL, type, current_form);
556 return_value = CURL_FORMADD_MEMORY;
559 form->contenttype_alloc = TRUE;
566 return_value = CURL_FORMADD_NULL;
569 return_value = CURL_FORMADD_OPTION_TWICE;
573 current_form->contenttype = strdup(contenttype);
574 if(!current_form->contenttype)
575 return_value = CURL_FORMADD_MEMORY;
577 current_form->contenttype_alloc = TRUE;
580 return_value = CURL_FORMADD_NULL;
584 case CURLFORM_CONTENTHEADER:
586 /* this "cast increases required alignment of target type" but
587 we consider it OK anyway */
588 struct curl_slist* list = array_state?
589 (struct curl_slist*)array_value:
590 va_arg(params, struct curl_slist*);
592 if(current_form->contentheader)
593 return_value = CURL_FORMADD_OPTION_TWICE;
595 current_form->contentheader = list;
599 case CURLFORM_FILENAME:
600 case CURLFORM_BUFFER:
602 const char *filename = array_state?array_value:
603 va_arg(params, char *);
604 if(current_form->showfilename)
605 return_value = CURL_FORMADD_OPTION_TWICE;
607 current_form->showfilename = strdup(filename);
608 if(!current_form->showfilename)
609 return_value = CURL_FORMADD_MEMORY;
611 current_form->showfilename_alloc = TRUE;
616 return_value = CURL_FORMADD_UNKNOWN_OPTION;
621 if(CURL_FORMADD_OK != return_value) {
622 /* On error, free allocated fields for all nodes of the FormInfo linked
623 list without deallocating nodes. List nodes are deallocated later on */
625 for(ptr = first_form; ptr != NULL; ptr = ptr->more) {
626 if(ptr->name_alloc) {
627 Curl_safefree(ptr->name);
628 ptr->name_alloc = FALSE;
630 if(ptr->value_alloc) {
631 Curl_safefree(ptr->value);
632 ptr->value_alloc = FALSE;
634 if(ptr->contenttype_alloc) {
635 Curl_safefree(ptr->contenttype);
636 ptr->contenttype_alloc = FALSE;
638 if(ptr->showfilename_alloc) {
639 Curl_safefree(ptr->showfilename);
640 ptr->showfilename_alloc = FALSE;
645 if(CURL_FORMADD_OK == return_value) {
646 /* go through the list, check for completeness and if everything is
647 * alright add the HttpPost item otherwise set return_value accordingly */
650 for(form = first_form;
653 if(((!form->name || !form->value) && !post) ||
654 ( (form->contentslength) &&
655 (form->flags & HTTPPOST_FILENAME) ) ||
656 ( (form->flags & HTTPPOST_FILENAME) &&
657 (form->flags & HTTPPOST_PTRCONTENTS) ) ||
660 (form->flags & HTTPPOST_BUFFER) &&
661 (form->flags & HTTPPOST_PTRBUFFER) ) ||
663 ( (form->flags & HTTPPOST_READFILE) &&
664 (form->flags & HTTPPOST_PTRCONTENTS) )
666 return_value = CURL_FORMADD_INCOMPLETE;
670 if(((form->flags & HTTPPOST_FILENAME) ||
671 (form->flags & HTTPPOST_BUFFER)) &&
672 !form->contenttype ) {
673 /* our contenttype is missing */
675 = strdup(ContentTypeForFilename(form->value, prevtype));
676 if(!form->contenttype) {
677 return_value = CURL_FORMADD_MEMORY;
680 form->contenttype_alloc = TRUE;
682 if(!(form->flags & HTTPPOST_PTRNAME) &&
683 (form == first_form) ) {
684 /* Note that there's small risk that form->name is NULL here if the
685 app passed in a bad combo, so we better check for that first. */
687 /* copy name (without strdup; possibly contains null characters) */
688 form->name = memdup(form->name, form->namelength);
690 return_value = CURL_FORMADD_MEMORY;
693 form->name_alloc = TRUE;
695 if(!(form->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE |
696 HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER |
697 HTTPPOST_CALLBACK)) ) {
698 /* copy value (without strdup; possibly contains null characters) */
699 form->value = memdup(form->value, form->contentslength);
701 return_value = CURL_FORMADD_MEMORY;
704 form->value_alloc = TRUE;
706 post = AddHttpPost(form->name, form->namelength,
707 form->value, form->contentslength,
708 form->buffer, form->bufferlength,
709 form->contenttype, form->flags,
710 form->contentheader, form->showfilename,
716 return_value = CURL_FORMADD_MEMORY;
720 if(form->contenttype)
721 prevtype = form->contenttype;
724 if(CURL_FORMADD_OK != return_value) {
725 /* On error, free allocated fields for nodes of the FormInfo linked
726 list which are not already owned by the httppost linked list
727 without deallocating nodes. List nodes are deallocated later on */
729 for(ptr = form; ptr != NULL; ptr = ptr->more) {
730 if(ptr->name_alloc) {
731 Curl_safefree(ptr->name);
732 ptr->name_alloc = FALSE;
734 if(ptr->value_alloc) {
735 Curl_safefree(ptr->value);
736 ptr->value_alloc = FALSE;
738 if(ptr->contenttype_alloc) {
739 Curl_safefree(ptr->contenttype);
740 ptr->contenttype_alloc = FALSE;
742 if(ptr->showfilename_alloc) {
743 Curl_safefree(ptr->showfilename);
744 ptr->showfilename_alloc = FALSE;
750 /* Always deallocate FormInfo linked list nodes without touching node
751 fields given that these have either been deallocated or are owned
752 now by the httppost linked list */
754 FormInfo *ptr = first_form->more;
755 Curl_safefree(first_form);
763 * curl_formadd() is a public API to add a section to the multipart formpost.
768 CURLFORMcode curl_formadd(struct curl_httppost **httppost,
769 struct curl_httppost **last_post,
774 va_start(arg, last_post);
775 result = FormAdd(httppost, last_post, arg);
781 * AddFormData() adds a chunk of data to the FormData linked list.
783 * size is incremented by the chunk length, unless it is NULL
785 static CURLcode AddFormData(struct FormData **formp,
791 struct FormData *newform = malloc(sizeof(struct FormData));
793 return CURLE_OUT_OF_MEMORY;
794 newform->next = NULL;
796 if(type <= FORM_CONTENT) {
797 /* we make it easier for plain strings: */
799 length = strlen((char *)line);
801 newform->line = malloc(length+1);
804 return CURLE_OUT_OF_MEMORY;
806 memcpy(newform->line, line, length);
807 newform->length = length;
808 newform->line[length]=0; /* zero terminate for easier debugging */
811 /* For callbacks and files we don't have any actual data so we just keep a
812 pointer to whatever this points to */
813 newform->line = (char *)line;
815 newform->type = type;
818 (*formp)->next = newform;
825 if(type != FORM_FILE)
826 /* for static content as well as callback data we add the size given
830 /* Since this is a file to be uploaded here, add the size of the actual
832 if(!strequal("-", newform->line)) {
834 if(!stat(newform->line, &file) && !S_ISDIR(file.st_mode))
835 *size += file.st_size;
837 return CURLE_BAD_FUNCTION_ARGUMENT;
845 * AddFormDataf() adds printf()-style formatted data to the formdata chain.
848 static CURLcode AddFormDataf(struct FormData **formp,
850 const char *fmt, ...)
855 vsnprintf(s, sizeof(s), fmt, ap);
858 return AddFormData(formp, FORM_DATA, s, 0, size);
862 * Curl_formclean() is used from http.c, this cleans a built FormData linked
865 void Curl_formclean(struct FormData **form_ptr)
867 struct FormData *next, *form;
874 next=form->next; /* the following form line */
875 if(form->type <= FORM_CONTENT)
876 free(form->line); /* free the line */
877 free(form); /* free the struct */
879 } while((form = next) != NULL); /* continue */
886 * Serialize a curl_httppost struct.
887 * Returns 0 on success.
891 int curl_formget(struct curl_httppost *form, void *arg,
892 curl_formget_callback append)
896 struct FormData *data, *ptr;
898 rc = Curl_getformdata(NULL, &data, form, NULL, &size);
902 for(ptr = data; ptr; ptr = ptr->next) {
903 if((ptr->type == FORM_FILE) || (ptr->type == FORM_CALLBACK)) {
908 Curl_FormInit(&temp, ptr);
911 nread = readfromfile(&temp, buffer, sizeof(buffer));
912 if((nread == (size_t) -1) ||
913 (nread > sizeof(buffer)) ||
914 (nread != append(arg, buffer, nread))) {
917 Curl_formclean(&data);
923 if(ptr->length != append(arg, ptr->line, ptr->length)) {
924 Curl_formclean(&data);
929 Curl_formclean(&data);
934 * curl_formfree() is an external function to free up a whole form post
937 void curl_formfree(struct curl_httppost *form)
939 struct curl_httppost *next;
942 /* no form to free, just get out of this */
946 next=form->next; /* the following form line */
948 /* recurse to sub-contents */
950 curl_formfree(form->more);
952 if(!(form->flags & HTTPPOST_PTRNAME) && form->name)
953 free(form->name); /* free the name */
955 (HTTPPOST_PTRCONTENTS|HTTPPOST_BUFFER|HTTPPOST_CALLBACK)) &&
957 free(form->contents); /* free the contents */
958 if(form->contenttype)
959 free(form->contenttype); /* free the content type */
960 if(form->showfilename)
961 free(form->showfilename); /* free the faked file name */
962 free(form); /* free the struct */
964 } while((form = next) != NULL); /* continue */
967 #ifndef HAVE_BASENAME
969 (Quote from The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004
972 The basename() function shall take the pathname pointed to by path and
973 return a pointer to the final component of the pathname, deleting any
974 trailing '/' characters.
976 If the string pointed to by path consists entirely of the '/' character,
977 basename() shall return a pointer to the string "/". If the string pointed
978 to by path is exactly "//", it is implementation-defined whether '/' or "//"
981 If path is a null pointer or points to an empty string, basename() shall
982 return a pointer to the string ".".
984 The basename() function may modify the string pointed to by path, and may
985 return a pointer to static storage that may then be overwritten by a
986 subsequent call to basename().
988 The basename() function need not be reentrant. A function that is not
989 required to be reentrant is not required to be thread-safe.
992 static char *Curl_basename(char *path)
994 /* Ignore all the details above for now and make a quick and simple
995 implementaion here */
999 s1=strrchr(path, '/');
1000 s2=strrchr(path, '\\');
1003 path = (s1 > s2? s1 : s2)+1;
1014 static char *strippath(const char *fullfile)
1018 filename = strdup(fullfile); /* duplicate since basename() may ruin the
1019 buffer it works on */
1022 base = strdup(basename(filename));
1024 free(filename); /* free temporary buffer */
1026 return base; /* returns an allocated string or NULL ! */
1029 static CURLcode formdata_add_filename(const struct curl_httppost *file,
1030 struct FormData **form,
1033 CURLcode result = CURLE_OK;
1034 char *filename = file->showfilename;
1035 char *filebasename = NULL;
1036 char *filename_escaped = NULL;
1039 filebasename = strippath(file->contents);
1041 return CURLE_OUT_OF_MEMORY;
1042 filename = filebasename;
1045 if(strchr(filename, '\\') || strchr(filename, '"')) {
1048 /* filename need be escaped */
1049 filename_escaped = malloc(strlen(filename)*2+1);
1050 if(!filename_escaped)
1051 return CURLE_OUT_OF_MEMORY;
1052 p0 = filename_escaped;
1055 if(*p1 == '\\' || *p1 == '"')
1060 filename = filename_escaped;
1062 result = AddFormDataf(form, size,
1063 "; filename=\"%s\"",
1065 Curl_safefree(filename_escaped);
1066 Curl_safefree(filebasename);
1071 * Curl_getformdata() converts a linked list of "meta data" into a complete
1072 * (possibly huge) multipart formdata. The input list is in 'post', while the
1073 * output resulting linked lists gets stored in '*finalform'. *sizep will get
1074 * the total size of the whole POST.
1075 * A multipart/form_data content-type is built, unless a custom content-type
1076 * is passed in 'custom_content_type'.
1078 * This function will not do a failf() for the potential memory failures but
1079 * should for all other errors it spots. Just note that this function MAY get
1080 * a NULL pointer in the 'data' argument.
1083 CURLcode Curl_getformdata(struct SessionHandle *data,
1084 struct FormData **finalform,
1085 struct curl_httppost *post,
1086 const char *custom_content_type,
1089 struct FormData *form = NULL;
1090 struct FormData *firstform;
1091 struct curl_httppost *file;
1092 CURLcode result = CURLE_OK;
1094 curl_off_t size = 0; /* support potentially ENORMOUS formposts */
1096 char *fileboundary = NULL;
1097 struct curl_slist* curList;
1099 *finalform = NULL; /* default form is empty */
1102 return result; /* no input => no output! */
1104 boundary = formboundary();
1106 return CURLE_OUT_OF_MEMORY;
1108 /* Make the first line of the output */
1109 result = AddFormDataf(&form, NULL,
1110 "%s; boundary=%s\r\n",
1111 custom_content_type?custom_content_type:
1112 "Content-Type: multipart/form-data",
1116 Curl_safefree(boundary);
1119 /* we DO NOT include that line in the total size of the POST, since it'll be
1120 part of the header! */
1127 result = AddFormDataf(&form, &size, "\r\n");
1133 result = AddFormDataf(&form, &size, "--%s\r\n", boundary);
1137 /* Maybe later this should be disabled when a custom_content_type is
1138 passed, since Content-Disposition is not meaningful for all multipart
1141 result = AddFormDataf(&form, &size,
1142 "Content-Disposition: form-data; name=\"");
1146 result = AddFormData(&form, FORM_DATA, post->name, post->namelength,
1151 result = AddFormDataf(&form, &size, "\"");
1156 /* If used, this is a link to more file names, we must then do
1157 the magic to include several files with the same field name */
1159 Curl_safefree(fileboundary);
1160 fileboundary = formboundary();
1162 result = CURLE_OUT_OF_MEMORY;
1166 result = AddFormDataf(&form, &size,
1167 "\r\nContent-Type: multipart/mixed,"
1178 /* If 'showfilename' is set, that is a faked name passed on to us
1179 to use to in the formpost. If that is not set, the actually used
1180 local file name should be added. */
1183 /* if multiple-file */
1184 result = AddFormDataf(&form, &size,
1185 "\r\n--%s\r\nContent-Disposition: "
1190 result = formdata_add_filename(file, &form, &size);
1194 else if(post->flags & (HTTPPOST_FILENAME|HTTPPOST_BUFFER|
1195 HTTPPOST_CALLBACK)) {
1196 /* it should be noted that for the HTTPPOST_FILENAME and
1197 HTTPPOST_CALLBACK cases the ->showfilename struct member is always
1198 assigned at this point */
1199 if(post->showfilename || (post->flags & HTTPPOST_FILENAME)) {
1200 result = formdata_add_filename(post, &form, &size);
1207 if(file->contenttype) {
1208 /* we have a specified type */
1209 result = AddFormDataf(&form, &size,
1210 "\r\nContent-Type: %s",
1216 curList = file->contentheader;
1218 /* Process the additional headers specified for this form */
1219 result = AddFormDataf( &form, &size, "\r\n%s", curList->data );
1222 curList = curList->next;
1227 result = AddFormDataf(&form, &size, "\r\n\r\n");
1231 if((post->flags & HTTPPOST_FILENAME) ||
1232 (post->flags & HTTPPOST_READFILE)) {
1233 /* we should include the contents from the specified file */
1236 fileread = strequal("-", file->contents)?
1237 stdin:fopen(file->contents, "rb"); /* binary read for win32 */
1240 * VMS: This only allows for stream files on VMS. Stream files are
1241 * OK, as are FIXED & VAR files WITHOUT implied CC For implied CC,
1242 * every record needs to have a \n appended & 1 added to SIZE
1246 if(fileread != stdin) {
1247 /* close the file */
1249 /* add the file name only - for later reading from this */
1250 result = AddFormData(&form, FORM_FILE, file->contents, 0, &size);
1253 /* When uploading from stdin, we can't know the size of the file,
1254 * thus must read the full file as before. We *could* use chunked
1255 * transfer-encoding, but that only works for HTTP 1.1 and we
1256 * can't be sure we work with such a server.
1260 while((nread = fread(buffer, 1, sizeof(buffer), fileread)) != 0) {
1261 result = AddFormData(&form, FORM_CONTENT, buffer, nread, &size);
1269 failf(data, "couldn't open file \"%s\"", file->contents);
1271 result = CURLE_READ_ERROR;
1274 else if(post->flags & HTTPPOST_BUFFER)
1275 /* include contents of buffer */
1276 result = AddFormData(&form, FORM_CONTENT, post->buffer,
1277 post->bufferlength, &size);
1278 else if(post->flags & HTTPPOST_CALLBACK)
1279 /* the contents should be read with the callback and the size
1280 is set with the contentslength */
1281 result = AddFormData(&form, FORM_CALLBACK, post->userp,
1282 post->contentslength, &size);
1284 /* include the contents we got */
1285 result = AddFormData(&form, FORM_CONTENT, post->contents,
1286 post->contentslength, &size);
1289 } while(file && !result); /* for each specified file for this field */
1295 /* this was a multiple-file inclusion, make a termination file
1297 result = AddFormDataf(&form, &size,
1304 } while((post = post->next) != NULL); /* for each field */
1306 /* end-boundary for everything */
1307 if(CURLE_OK == result)
1308 result = AddFormDataf(&form, &size,
1313 Curl_formclean(&firstform);
1314 Curl_safefree(fileboundary);
1315 Curl_safefree(boundary);
1321 Curl_safefree(fileboundary);
1322 Curl_safefree(boundary);
1324 *finalform = firstform;
1330 * Curl_FormInit() inits the struct 'form' points to with the 'formdata'
1331 * and resets the 'sent' counter.
1333 int Curl_FormInit(struct Form *form, struct FormData *formdata )
1336 return 1; /* error */
1338 form->data = formdata;
1341 form->fread_func = ZERO_NULL;
1349 * The read callback that this function may use can return a value larger than
1350 * 'size' (which then this function returns) that indicates a problem and it
1351 * must be properly dealt with
1353 static size_t readfromfile(struct Form *form, char *buffer,
1357 bool callback = (form->data->type == FORM_CALLBACK)?TRUE:FALSE;
1360 if(form->fread_func == ZERO_NULL)
1363 nread = form->fread_func(buffer, 1, size, form->data->line);
1367 /* this file hasn't yet been opened */
1368 form->fp = fopen(form->data->line, "rb"); /* b is for binary */
1370 return (size_t)-1; /* failure */
1372 nread = fread(buffer, 1, size, form->fp);
1375 /* this is the last chunk from the file, move on */
1380 form->data = form->data->next;
1387 * Curl_FormReader() is the fread() emulation function that will be used to
1388 * deliver the formdata to the transfer loop and then sent away to the peer.
1390 size_t Curl_FormReader(char *buffer,
1399 form=(struct Form *)mydata;
1401 wantedsize = size * nitems;
1404 return 0; /* nothing, error, empty */
1406 if((form->data->type == FORM_FILE) ||
1407 (form->data->type == FORM_CALLBACK)) {
1408 gotsize = readfromfile(form, buffer, wantedsize);
1411 /* If positive or -1, return. If zero, continue! */
1416 if((form->data->length - form->sent ) > wantedsize - gotsize) {
1418 memcpy(buffer + gotsize , form->data->line + form->sent,
1419 wantedsize - gotsize);
1421 form->sent += wantedsize-gotsize;
1426 memcpy(buffer+gotsize,
1427 form->data->line + form->sent,
1428 (form->data->length - form->sent) );
1429 gotsize += form->data->length - form->sent;
1433 form->data = form->data->next; /* advance */
1435 } while(form->data && (form->data->type < FORM_CALLBACK));
1436 /* If we got an empty line and we have more data, we proceed to the next
1437 line immediately to avoid returning zero before we've reached the end. */
1443 * Curl_formpostheader() returns the first line of the formpost, the
1444 * request-header part (which is not part of the request-body like the rest of
1447 char *Curl_formpostheader(void *formp, size_t *len)
1450 struct Form *form=(struct Form *)formp;
1453 return 0; /* nothing, ERROR! */
1455 header = form->data->line;
1456 *len = form->data->length;
1458 form->data = form->data->next; /* advance */
1464 * formboundary() creates a suitable boundary string and returns an allocated
1467 static char *formboundary(void)
1472 static const char table16[]="0123456789abcdef";
1474 retstring = malloc(BOUNDARY_LENGTH+1);
1477 return NULL; /* failed */
1479 strcpy(retstring, "----------------------------");
1481 for(i=strlen(retstring); i<BOUNDARY_LENGTH; i++)
1482 retstring[i] = table16[Curl_rand()%16];
1484 /* 28 dashes and 12 hexadecimal digits makes 12^16 (184884258895036416)
1486 retstring[BOUNDARY_LENGTH]=0; /* zero terminate */
1491 #else /* CURL_DISABLE_HTTP */
1492 CURLFORMcode curl_formadd(struct curl_httppost **httppost,
1493 struct curl_httppost **last_post,
1498 return CURL_FORMADD_DISABLED;
1501 int curl_formget(struct curl_httppost *form, void *arg,
1502 curl_formget_callback append)
1507 return CURL_FORMADD_DISABLED;
1510 void curl_formfree(struct curl_httppost *form)
1513 /* does nothing HTTP is disabled */
1517 #endif /* !defined(CURL_DISABLE_HTTP) */