1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2017, 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 https://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 #ifndef CURL_DISABLE_HTTP
29 #if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
33 #include "urldata.h" /* for struct Curl_easy */
35 #include "vtls/vtls.h"
40 /* The last 3 #include files should be in this order */
41 #include "curl_printf.h"
42 #include "curl_memory.h"
46 static char *Curl_basename(char *path);
47 #define basename(x) Curl_basename((x))
50 static size_t readfromfile(struct Form *form, char *buffer, size_t size);
51 static char *formboundary(struct Curl_easy *data);
53 /* What kind of Content-Type to use on un-specified files with unrecognized
55 #define HTTPPOST_CONTENTTYPE_DEFAULT "application/octet-stream"
57 #define FORM_FILE_SEPARATOR ','
58 #define FORM_TYPE_SEPARATOR ';'
60 #define HTTPPOST_PTRNAME CURL_HTTPPOST_PTRNAME
61 #define HTTPPOST_FILENAME CURL_HTTPPOST_FILENAME
62 #define HTTPPOST_PTRCONTENTS CURL_HTTPPOST_PTRCONTENTS
63 #define HTTPPOST_READFILE CURL_HTTPPOST_READFILE
64 #define HTTPPOST_PTRBUFFER CURL_HTTPPOST_PTRBUFFER
65 #define HTTPPOST_CALLBACK CURL_HTTPPOST_CALLBACK
66 #define HTTPPOST_BUFFER CURL_HTTPPOST_BUFFER
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, curl_off_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->contentlen = contentslength;
97 post->buffer = buffer;
98 post->bufferlength = (long)bufferlength;
99 post->contenttype = contenttype;
100 post->contentheader = contentHeader;
101 post->showfilename = showfilename;
103 post->flags = flags | CURL_HTTPPOST_LARGE;
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!
184 const char *extension;
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(strcasecompare(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 * Stores a formpost parameter and builds the appropriate linked list.
224 * Has two principal functionalities: using files and byte arrays as
225 * post parts. Byte arrays are either copied or just the pointer is stored
226 * (as the user requests) while for files only the filename and not the
229 * While you may have only one byte array for each name, multiple filenames
230 * are allowed (and because of this feature CURLFORM_END is needed after
231 * using CURLFORM_FILE).
235 * Simple name/value pair with copied contents:
236 * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
237 * CURLFORM_COPYCONTENTS, "value", CURLFORM_END);
239 * name/value pair where only the content pointer is remembered:
240 * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
241 * CURLFORM_PTRCONTENTS, ptr, CURLFORM_CONTENTSLENGTH, 10, CURLFORM_END);
242 * (if CURLFORM_CONTENTSLENGTH is missing strlen () is used)
244 * storing a filename (CONTENTTYPE is optional!):
245 * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
246 * CURLFORM_FILE, "filename1", CURLFORM_CONTENTTYPE, "plain/text",
249 * storing multiple filenames:
250 * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
251 * CURLFORM_FILE, "filename1", CURLFORM_FILE, "filename2", CURLFORM_END);
254 * CURL_FORMADD_OK on success
255 * CURL_FORMADD_MEMORY if the FormInfo allocation fails
256 * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form
257 * CURL_FORMADD_NULL if a null pointer was given for a char
258 * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed
259 * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used
260 * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error)
261 * CURL_FORMADD_MEMORY if a HttpPost struct cannot be allocated
262 * CURL_FORMADD_MEMORY if some allocation for string copying failed.
263 * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array
265 ***************************************************************************/
268 CURLFORMcode FormAdd(struct curl_httppost **httppost,
269 struct curl_httppost **last_post,
272 FormInfo *first_form, *current_form, *form = NULL;
273 CURLFORMcode return_value = CURL_FORMADD_OK;
274 const char *prevtype = NULL;
275 struct curl_httppost *post = NULL;
276 CURLformoption option;
277 struct curl_forms *forms = NULL;
278 char *array_value=NULL; /* value read from an array */
280 /* This is a state variable, that if TRUE means that we're parsing an
281 array that we got passed to us. If FALSE we're parsing the input
282 va_list arguments. */
283 bool array_state = FALSE;
286 * We need to allocate the first struct to fill in.
288 first_form = calloc(1, sizeof(struct FormInfo));
290 return CURL_FORMADD_MEMORY;
292 current_form = first_form;
295 * Loop through all the options set. Break if we have an error to report.
297 while(return_value == CURL_FORMADD_OK) {
299 /* first see if we have more parts of the array param */
300 if(array_state && forms) {
301 /* get the upcoming option from the given array */
302 option = forms->option;
303 array_value = (char *)forms->value;
305 forms++; /* advance this to next entry */
306 if(CURLFORM_END == option) {
307 /* end of array state */
313 /* This is not array-state, get next option */
314 option = va_arg(params, CURLformoption);
315 if(CURLFORM_END == option)
322 /* we don't support an array from within an array */
323 return_value = CURL_FORMADD_ILLEGAL_ARRAY;
325 forms = va_arg(params, struct curl_forms *);
329 return_value = CURL_FORMADD_NULL;
334 * Set the Name property.
336 case CURLFORM_PTRNAME:
337 #ifdef CURL_DOES_CONVERSIONS
338 /* Treat CURLFORM_PTR like CURLFORM_COPYNAME so that libcurl will copy
339 * the data in all cases so that we'll have safe memory for the eventual
343 current_form->flags |= HTTPPOST_PTRNAME; /* fall through */
345 case CURLFORM_COPYNAME:
346 if(current_form->name)
347 return_value = CURL_FORMADD_OPTION_TWICE;
349 char *name = array_state?
350 array_value:va_arg(params, char *);
352 current_form->name = name; /* store for the moment */
354 return_value = CURL_FORMADD_NULL;
357 case CURLFORM_NAMELENGTH:
358 if(current_form->namelength)
359 return_value = CURL_FORMADD_OPTION_TWICE;
361 current_form->namelength =
362 array_state?(size_t)array_value:(size_t)va_arg(params, long);
366 * Set the contents property.
368 case CURLFORM_PTRCONTENTS:
369 current_form->flags |= HTTPPOST_PTRCONTENTS; /* fall through */
370 case CURLFORM_COPYCONTENTS:
371 if(current_form->value)
372 return_value = CURL_FORMADD_OPTION_TWICE;
375 array_state?array_value:va_arg(params, char *);
377 current_form->value = value; /* store for the moment */
379 return_value = CURL_FORMADD_NULL;
382 case CURLFORM_CONTENTSLENGTH:
383 current_form->contentslength =
384 array_state?(size_t)array_value:(size_t)va_arg(params, long);
387 case CURLFORM_CONTENTLEN:
388 current_form->flags |= CURL_HTTPPOST_LARGE;
389 current_form->contentslength =
390 array_state?(curl_off_t)(size_t)array_value:va_arg(params, curl_off_t);
393 /* Get contents from a given file name */
394 case CURLFORM_FILECONTENT:
395 if(current_form->flags & (HTTPPOST_PTRCONTENTS|HTTPPOST_READFILE))
396 return_value = CURL_FORMADD_OPTION_TWICE;
398 const char *filename = array_state?
399 array_value:va_arg(params, char *);
401 current_form->value = strdup(filename);
402 if(!current_form->value)
403 return_value = CURL_FORMADD_MEMORY;
405 current_form->flags |= HTTPPOST_READFILE;
406 current_form->value_alloc = TRUE;
410 return_value = CURL_FORMADD_NULL;
414 /* We upload a file */
417 const char *filename = array_state?array_value:
418 va_arg(params, char *);
420 if(current_form->value) {
421 if(current_form->flags & HTTPPOST_FILENAME) {
423 char *fname = strdup(filename);
425 return_value = CURL_FORMADD_MEMORY;
427 form = AddFormInfo(fname, NULL, current_form);
430 return_value = CURL_FORMADD_MEMORY;
433 form->value_alloc = TRUE;
440 return_value = CURL_FORMADD_NULL;
443 return_value = CURL_FORMADD_OPTION_TWICE;
447 current_form->value = strdup(filename);
448 if(!current_form->value)
449 return_value = CURL_FORMADD_MEMORY;
451 current_form->flags |= HTTPPOST_FILENAME;
452 current_form->value_alloc = TRUE;
456 return_value = CURL_FORMADD_NULL;
461 case CURLFORM_BUFFERPTR:
462 current_form->flags |= HTTPPOST_PTRBUFFER|HTTPPOST_BUFFER;
463 if(current_form->buffer)
464 return_value = CURL_FORMADD_OPTION_TWICE;
467 array_state?array_value:va_arg(params, char *);
469 current_form->buffer = buffer; /* store for the moment */
470 current_form->value = buffer; /* make it non-NULL to be accepted
474 return_value = CURL_FORMADD_NULL;
478 case CURLFORM_BUFFERLENGTH:
479 if(current_form->bufferlength)
480 return_value = CURL_FORMADD_OPTION_TWICE;
482 current_form->bufferlength =
483 array_state?(size_t)array_value:(size_t)va_arg(params, long);
486 case CURLFORM_STREAM:
487 current_form->flags |= HTTPPOST_CALLBACK;
488 if(current_form->userp)
489 return_value = CURL_FORMADD_OPTION_TWICE;
492 array_state?array_value:va_arg(params, char *);
494 current_form->userp = userp;
495 current_form->value = userp; /* this isn't strictly true but we
496 derive a value from this later on
497 and we need this non-NULL to be
498 accepted as a fine form part */
501 return_value = CURL_FORMADD_NULL;
505 case CURLFORM_CONTENTTYPE:
507 const char *contenttype =
508 array_state?array_value:va_arg(params, char *);
509 if(current_form->contenttype) {
510 if(current_form->flags & HTTPPOST_FILENAME) {
512 char *type = strdup(contenttype);
514 return_value = CURL_FORMADD_MEMORY;
516 form = AddFormInfo(NULL, type, current_form);
519 return_value = CURL_FORMADD_MEMORY;
522 form->contenttype_alloc = TRUE;
529 return_value = CURL_FORMADD_NULL;
532 return_value = CURL_FORMADD_OPTION_TWICE;
536 current_form->contenttype = strdup(contenttype);
537 if(!current_form->contenttype)
538 return_value = CURL_FORMADD_MEMORY;
540 current_form->contenttype_alloc = TRUE;
543 return_value = CURL_FORMADD_NULL;
547 case CURLFORM_CONTENTHEADER:
549 /* this "cast increases required alignment of target type" but
550 we consider it OK anyway */
551 struct curl_slist *list = array_state?
552 (struct curl_slist *)(void *)array_value:
553 va_arg(params, struct curl_slist *);
555 if(current_form->contentheader)
556 return_value = CURL_FORMADD_OPTION_TWICE;
558 current_form->contentheader = list;
562 case CURLFORM_FILENAME:
563 case CURLFORM_BUFFER:
565 const char *filename = array_state?array_value:
566 va_arg(params, char *);
567 if(current_form->showfilename)
568 return_value = CURL_FORMADD_OPTION_TWICE;
570 current_form->showfilename = strdup(filename);
571 if(!current_form->showfilename)
572 return_value = CURL_FORMADD_MEMORY;
574 current_form->showfilename_alloc = TRUE;
579 return_value = CURL_FORMADD_UNKNOWN_OPTION;
584 if(CURL_FORMADD_OK != return_value) {
585 /* On error, free allocated fields for all nodes of the FormInfo linked
586 list without deallocating nodes. List nodes are deallocated later on */
588 for(ptr = first_form; ptr != NULL; ptr = ptr->more) {
589 if(ptr->name_alloc) {
590 Curl_safefree(ptr->name);
591 ptr->name_alloc = FALSE;
593 if(ptr->value_alloc) {
594 Curl_safefree(ptr->value);
595 ptr->value_alloc = FALSE;
597 if(ptr->contenttype_alloc) {
598 Curl_safefree(ptr->contenttype);
599 ptr->contenttype_alloc = FALSE;
601 if(ptr->showfilename_alloc) {
602 Curl_safefree(ptr->showfilename);
603 ptr->showfilename_alloc = FALSE;
608 if(CURL_FORMADD_OK == return_value) {
609 /* go through the list, check for completeness and if everything is
610 * alright add the HttpPost item otherwise set return_value accordingly */
613 for(form = first_form;
616 if(((!form->name || !form->value) && !post) ||
617 ( (form->contentslength) &&
618 (form->flags & HTTPPOST_FILENAME) ) ||
619 ( (form->flags & HTTPPOST_FILENAME) &&
620 (form->flags & HTTPPOST_PTRCONTENTS) ) ||
623 (form->flags & HTTPPOST_BUFFER) &&
624 (form->flags & HTTPPOST_PTRBUFFER) ) ||
626 ( (form->flags & HTTPPOST_READFILE) &&
627 (form->flags & HTTPPOST_PTRCONTENTS) )
629 return_value = CURL_FORMADD_INCOMPLETE;
633 if(((form->flags & HTTPPOST_FILENAME) ||
634 (form->flags & HTTPPOST_BUFFER)) &&
635 !form->contenttype) {
636 char *f = form->flags & HTTPPOST_BUFFER?
637 form->showfilename : form->value;
639 /* our contenttype is missing */
640 form->contenttype = strdup(ContentTypeForFilename(f, prevtype));
641 if(!form->contenttype) {
642 return_value = CURL_FORMADD_MEMORY;
645 form->contenttype_alloc = TRUE;
647 if(!(form->flags & HTTPPOST_PTRNAME) &&
648 (form == first_form) ) {
649 /* Note that there's small risk that form->name is NULL here if the
650 app passed in a bad combo, so we better check for that first. */
652 /* copy name (without strdup; possibly contains null characters) */
653 form->name = Curl_memdup(form->name, form->namelength?
655 strlen(form->name)+1);
658 return_value = CURL_FORMADD_MEMORY;
661 form->name_alloc = TRUE;
663 if(!(form->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE |
664 HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER |
665 HTTPPOST_CALLBACK)) && form->value) {
666 /* copy value (without strdup; possibly contains null characters) */
667 size_t clen = (size_t) form->contentslength;
669 clen = strlen(form->value)+1;
671 form->value = Curl_memdup(form->value, clen);
674 return_value = CURL_FORMADD_MEMORY;
677 form->value_alloc = TRUE;
679 post = AddHttpPost(form->name, form->namelength,
680 form->value, form->contentslength,
681 form->buffer, form->bufferlength,
682 form->contenttype, form->flags,
683 form->contentheader, form->showfilename,
689 return_value = CURL_FORMADD_MEMORY;
693 if(form->contenttype)
694 prevtype = form->contenttype;
697 if(CURL_FORMADD_OK != return_value) {
698 /* On error, free allocated fields for nodes of the FormInfo linked
699 list which are not already owned by the httppost linked list
700 without deallocating nodes. List nodes are deallocated later on */
702 for(ptr = form; ptr != NULL; ptr = ptr->more) {
703 if(ptr->name_alloc) {
704 Curl_safefree(ptr->name);
705 ptr->name_alloc = FALSE;
707 if(ptr->value_alloc) {
708 Curl_safefree(ptr->value);
709 ptr->value_alloc = FALSE;
711 if(ptr->contenttype_alloc) {
712 Curl_safefree(ptr->contenttype);
713 ptr->contenttype_alloc = FALSE;
715 if(ptr->showfilename_alloc) {
716 Curl_safefree(ptr->showfilename);
717 ptr->showfilename_alloc = FALSE;
723 /* Always deallocate FormInfo linked list nodes without touching node
724 fields given that these have either been deallocated or are owned
725 now by the httppost linked list */
727 FormInfo *ptr = first_form->more;
736 * curl_formadd() is a public API to add a section to the multipart formpost.
741 CURLFORMcode curl_formadd(struct curl_httppost **httppost,
742 struct curl_httppost **last_post,
747 va_start(arg, last_post);
748 result = FormAdd(httppost, last_post, arg);
756 * get_vms_file_size does what it takes to get the real size of the file
758 * For fixed files, find out the size of the EOF block and adjust.
760 * For all others, have to read the entire file in, discarding the contents.
761 * Most posted text files will be small, and binary files like zlib archives
762 * and CD/DVD images should be either a STREAM_LF format or a fixed format.
765 curl_off_t VmsRealFileSize(const char *name,
766 const struct_stat *stat_buf)
773 file = fopen(name, FOPEN_READTEXT); /* VMS */
779 while(ret_stat > 0) {
780 ret_stat = fread(buffer, 1, sizeof(buffer), file);
791 * VmsSpecialSize checks to see if the stat st_size can be trusted and
792 * if not to call a routine to get the correct size.
795 static curl_off_t VmsSpecialSize(const char *name,
796 const struct_stat *stat_buf)
798 switch(stat_buf->st_fab_rfm) {
801 return VmsRealFileSize(name, stat_buf);
804 return stat_buf->st_size;
811 #define filesize(name, stat_data) (stat_data.st_size)
813 /* Getting the expected file size needs help on VMS */
814 #define filesize(name, stat_data) VmsSpecialSize(name, &stat_data)
818 * AddFormData() adds a chunk of data to the FormData linked list.
820 * size is incremented by the chunk length, unless it is NULL
822 static CURLcode AddFormData(struct FormData **formp,
828 struct FormData *newform;
830 CURLcode result = CURLE_OK;
831 if(length < 0 || (size && *size < 0))
832 return CURLE_BAD_FUNCTION_ARGUMENT;
834 newform = malloc(sizeof(struct FormData));
836 return CURLE_OUT_OF_MEMORY;
837 newform->next = NULL;
839 if(type <= FORM_CONTENT) {
840 /* we make it easier for plain strings: */
842 length = strlen((char *)line);
843 #if (SIZEOF_SIZE_T < CURL_SIZEOF_CURL_OFF_T)
844 else if(length >= (curl_off_t)(size_t)-1) {
845 result = CURLE_BAD_FUNCTION_ARGUMENT;
849 if(type != FORM_DATAMEM) {
850 newform->line = malloc((size_t)length+1);
852 result = CURLE_OUT_OF_MEMORY;
855 alloc2 = newform->line;
856 memcpy(newform->line, line, (size_t)length);
858 /* zero terminate for easier debugging */
859 newform->line[(size_t)length]=0;
862 newform->line = (char *)line;
863 type = FORM_DATA; /* in all other aspects this is just FORM_DATA */
865 newform->length = (size_t)length;
868 /* For callbacks and files we don't have any actual data so we just keep a
869 pointer to whatever this points to */
870 newform->line = (char *)line;
872 newform->type = type;
875 if(type != FORM_FILE)
876 /* for static content as well as callback data we add the size given
880 /* Since this is a file to be uploaded here, add the size of the actual
882 if(strcmp("-", newform->line)) {
884 if(!stat(newform->line, &file) && !S_ISDIR(file.st_mode))
885 *size += filesize(newform->line, file);
887 result = CURLE_BAD_FUNCTION_ARGUMENT;
895 (*formp)->next = newform;
911 * AddFormDataf() adds printf()-style formatted data to the formdata chain.
914 static CURLcode AddFormDataf(struct FormData **formp,
916 const char *fmt, ...)
922 s = curl_mvaprintf(fmt, ap);
926 return CURLE_OUT_OF_MEMORY;
928 result = AddFormData(formp, FORM_DATAMEM, s, 0, size);
936 * Curl_formclean() is used from http.c, this cleans a built FormData linked
939 void Curl_formclean(struct FormData **form_ptr)
941 struct FormData *next, *form;
948 next=form->next; /* the following form line */
949 if(form->type <= FORM_CONTENT)
950 free(form->line); /* free the line */
951 free(form); /* free the struct */
953 } while(form); /* continue */
960 * Serialize a curl_httppost struct.
961 * Returns 0 on success.
965 int curl_formget(struct curl_httppost *form, void *arg,
966 curl_formget_callback append)
970 struct FormData *data, *ptr;
972 result = Curl_getformdata(NULL, &data, form, NULL, &size);
976 for(ptr = data; ptr; ptr = ptr->next) {
977 if((ptr->type == FORM_FILE) || (ptr->type == FORM_CALLBACK)) {
982 Curl_FormInit(&temp, ptr);
985 nread = readfromfile(&temp, buffer, sizeof(buffer));
986 if((nread == (size_t) -1) ||
987 (nread > sizeof(buffer)) ||
988 (nread != append(arg, buffer, nread))) {
991 Curl_formclean(&data);
997 if(ptr->length != append(arg, ptr->line, ptr->length)) {
998 Curl_formclean(&data);
1003 Curl_formclean(&data);
1008 * curl_formfree() is an external function to free up a whole form post
1011 void curl_formfree(struct curl_httppost *form)
1013 struct curl_httppost *next;
1016 /* no form to free, just get out of this */
1020 next=form->next; /* the following form line */
1022 /* recurse to sub-contents */
1023 curl_formfree(form->more);
1025 if(!(form->flags & HTTPPOST_PTRNAME))
1026 free(form->name); /* free the name */
1028 (HTTPPOST_PTRCONTENTS|HTTPPOST_BUFFER|HTTPPOST_CALLBACK))
1030 free(form->contents); /* free the contents */
1031 free(form->contenttype); /* free the content type */
1032 free(form->showfilename); /* free the faked file name */
1033 free(form); /* free the struct */
1035 } while(form); /* continue */
1038 #ifndef HAVE_BASENAME
1040 (Quote from The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004
1043 The basename() function shall take the pathname pointed to by path and
1044 return a pointer to the final component of the pathname, deleting any
1045 trailing '/' characters.
1047 If the string pointed to by path consists entirely of the '/' character,
1048 basename() shall return a pointer to the string "/". If the string pointed
1049 to by path is exactly "//", it is implementation-defined whether '/' or "//"
1052 If path is a null pointer or points to an empty string, basename() shall
1053 return a pointer to the string ".".
1055 The basename() function may modify the string pointed to by path, and may
1056 return a pointer to static storage that may then be overwritten by a
1057 subsequent call to basename().
1059 The basename() function need not be reentrant. A function that is not
1060 required to be reentrant is not required to be thread-safe.
1063 static char *Curl_basename(char *path)
1065 /* Ignore all the details above for now and make a quick and simple
1066 implementaion here */
1070 s1=strrchr(path, '/');
1071 s2=strrchr(path, '\\');
1074 path = (s1 > s2? s1 : s2)+1;
1085 static char *strippath(const char *fullfile)
1089 filename = strdup(fullfile); /* duplicate since basename() may ruin the
1090 buffer it works on */
1093 base = strdup(basename(filename));
1095 free(filename); /* free temporary buffer */
1097 return base; /* returns an allocated string or NULL ! */
1100 static CURLcode formdata_add_filename(const struct curl_httppost *file,
1101 struct FormData **form,
1104 CURLcode result = CURLE_OK;
1105 char *filename = file->showfilename;
1106 char *filebasename = NULL;
1107 char *filename_escaped = NULL;
1110 filebasename = strippath(file->contents);
1112 return CURLE_OUT_OF_MEMORY;
1113 filename = filebasename;
1116 if(strchr(filename, '\\') || strchr(filename, '"')) {
1119 /* filename need be escaped */
1120 filename_escaped = malloc(strlen(filename)*2+1);
1121 if(!filename_escaped) {
1123 return CURLE_OUT_OF_MEMORY;
1125 p0 = filename_escaped;
1128 if(*p1 == '\\' || *p1 == '"')
1133 filename = filename_escaped;
1135 result = AddFormDataf(form, size,
1136 "; filename=\"%s\"",
1138 free(filename_escaped);
1144 * Curl_getformdata() converts a linked list of "meta data" into a complete
1145 * (possibly huge) multipart formdata. The input list is in 'post', while the
1146 * output resulting linked lists gets stored in '*finalform'. *sizep will get
1147 * the total size of the whole POST.
1148 * A multipart/form_data content-type is built, unless a custom content-type
1149 * is passed in 'custom_content_type'.
1151 * This function will not do a failf() for the potential memory failures but
1152 * should for all other errors it spots. Just note that this function MAY get
1153 * a NULL pointer in the 'data' argument.
1156 CURLcode Curl_getformdata(struct Curl_easy *data,
1157 struct FormData **finalform,
1158 struct curl_httppost *post,
1159 const char *custom_content_type,
1162 struct FormData *form = NULL;
1163 struct FormData *firstform;
1164 struct curl_httppost *file;
1165 CURLcode result = CURLE_OK;
1167 curl_off_t size = 0; /* support potentially ENORMOUS formposts */
1169 char *fileboundary = NULL;
1170 struct curl_slist *curList;
1172 *finalform = NULL; /* default form is empty */
1175 return result; /* no input => no output! */
1177 boundary = formboundary(data);
1179 return CURLE_OUT_OF_MEMORY;
1181 /* Make the first line of the output */
1182 result = AddFormDataf(&form, NULL,
1183 "%s; boundary=%s\r\n",
1184 custom_content_type?custom_content_type:
1185 "Content-Type: multipart/form-data",
1192 /* we DO NOT include that line in the total size of the POST, since it'll be
1193 part of the header! */
1200 result = AddFormDataf(&form, &size, "\r\n");
1206 result = AddFormDataf(&form, &size, "--%s\r\n", boundary);
1210 /* Maybe later this should be disabled when a custom_content_type is
1211 passed, since Content-Disposition is not meaningful for all multipart
1214 result = AddFormDataf(&form, &size,
1215 "Content-Disposition: form-data; name=\"");
1219 result = AddFormData(&form, FORM_DATA, post->name, post->namelength,
1224 result = AddFormDataf(&form, &size, "\"");
1229 /* If used, this is a link to more file names, we must then do
1230 the magic to include several files with the same field name */
1233 fileboundary = formboundary(data);
1235 result = CURLE_OUT_OF_MEMORY;
1239 result = AddFormDataf(&form, &size,
1240 "\r\nContent-Type: multipart/mixed;"
1251 /* If 'showfilename' is set, that is a faked name passed on to us
1252 to use to in the formpost. If that is not set, the actually used
1253 local file name should be added. */
1256 /* if multiple-file */
1257 result = AddFormDataf(&form, &size,
1258 "\r\n--%s\r\nContent-Disposition: "
1263 result = formdata_add_filename(file, &form, &size);
1267 else if(post->flags & (HTTPPOST_FILENAME|HTTPPOST_BUFFER|
1268 HTTPPOST_CALLBACK)) {
1269 /* it should be noted that for the HTTPPOST_FILENAME and
1270 HTTPPOST_CALLBACK cases the ->showfilename struct member is always
1271 assigned at this point */
1272 if(post->showfilename || (post->flags & HTTPPOST_FILENAME)) {
1273 result = formdata_add_filename(post, &form, &size);
1280 if(file->contenttype) {
1281 /* we have a specified type */
1282 result = AddFormDataf(&form, &size,
1283 "\r\nContent-Type: %s",
1289 curList = file->contentheader;
1291 /* Process the additional headers specified for this form */
1292 result = AddFormDataf(&form, &size, "\r\n%s", curList->data);
1295 curList = curList->next;
1300 result = AddFormDataf(&form, &size, "\r\n\r\n");
1304 if((post->flags & HTTPPOST_FILENAME) ||
1305 (post->flags & HTTPPOST_READFILE)) {
1306 /* we should include the contents from the specified file */
1309 fileread = !strcmp("-", file->contents)?
1310 stdin:fopen(file->contents, "rb"); /* binary read for win32 */
1313 * VMS: This only allows for stream files on VMS. Stream files are
1314 * OK, as are FIXED & VAR files WITHOUT implied CC For implied CC,
1315 * every record needs to have a \n appended & 1 added to SIZE
1319 if(fileread != stdin) {
1320 /* close the file */
1322 /* add the file name only - for later reading from this */
1323 result = AddFormData(&form, FORM_FILE, file->contents, 0, &size);
1326 /* When uploading from stdin, we can't know the size of the file,
1327 * thus must read the full file as before. We *could* use chunked
1328 * transfer-encoding, but that only works for HTTP 1.1 and we
1329 * can't be sure we work with such a server.
1333 while((nread = fread(buffer, 1, sizeof(buffer), fileread)) != 0) {
1334 result = AddFormData(&form, FORM_CONTENT, buffer, nread, &size);
1335 if(result || feof(fileread) || ferror(fileread))
1342 failf(data, "couldn't open file \"%s\"", file->contents);
1344 result = CURLE_READ_ERROR;
1347 else if(post->flags & HTTPPOST_BUFFER)
1348 /* include contents of buffer */
1349 result = AddFormData(&form, FORM_CONTENT, post->buffer,
1350 post->bufferlength, &size);
1351 else if(post->flags & HTTPPOST_CALLBACK)
1352 /* the contents should be read with the callback and the size is set
1353 with the contentslength */
1354 result = AddFormData(&form, FORM_CALLBACK, post->userp,
1355 post->flags&CURL_HTTPPOST_LARGE?
1356 post->contentlen:post->contentslength, &size);
1358 /* include the contents we got */
1359 result = AddFormData(&form, FORM_CONTENT, post->contents,
1360 post->flags&CURL_HTTPPOST_LARGE?
1361 post->contentlen:post->contentslength, &size);
1363 } while(file && !result); /* for each specified file for this field */
1369 /* this was a multiple-file inclusion, make a termination file
1371 result = AddFormDataf(&form, &size,
1378 } while(post); /* for each field */
1380 /* end-boundary for everything */
1382 result = AddFormDataf(&form, &size, "\r\n--%s--\r\n", boundary);
1385 Curl_formclean(&firstform);
1396 *finalform = firstform;
1402 * Curl_FormInit() inits the struct 'form' points to with the 'formdata'
1403 * and resets the 'sent' counter.
1405 int Curl_FormInit(struct Form *form, struct FormData *formdata)
1408 return 1; /* error */
1410 form->data = formdata;
1413 form->fread_func = ZERO_NULL;
1419 # define fopen_read fopen
1424 * For upload to work as expected on VMS, different optional
1425 * parameters must be added to the fopen command based on
1426 * record format of the file.
1429 # define fopen_read vmsfopenread
1430 static FILE * vmsfopenread(const char *file, const char *mode)
1432 struct_stat statbuf;
1435 result = stat(file, &statbuf);
1437 switch(statbuf.st_fab_rfm) {
1441 return fopen(file, FOPEN_READTEXT); /* VMS */
1444 return fopen(file, FOPEN_READTEXT, "rfm=stmlf", "ctx=stm");
1452 * The read callback that this function may use can return a value larger than
1453 * 'size' (which then this function returns) that indicates a problem and it
1454 * must be properly dealt with
1456 static size_t readfromfile(struct Form *form, char *buffer,
1460 bool callback = (form->data->type == FORM_CALLBACK)?TRUE:FALSE;
1463 if(form->fread_func == ZERO_NULL)
1466 nread = form->fread_func(buffer, 1, size, form->data->line);
1470 /* this file hasn't yet been opened */
1471 form->fp = fopen_read(form->data->line, "rb"); /* b is for binary */
1473 return (size_t)-1; /* failure */
1475 nread = fread(buffer, 1, size, form->fp);
1478 /* this is the last chunk from the file, move on */
1483 form->data = form->data->next;
1490 * Curl_FormReader() is the fread() emulation function that will be used to
1491 * deliver the formdata to the transfer loop and then sent away to the peer.
1493 size_t Curl_FormReader(char *buffer,
1502 form=(struct Form *)mydata;
1504 wantedsize = size * nitems;
1507 return 0; /* nothing, error, empty */
1509 if((form->data->type == FORM_FILE) ||
1510 (form->data->type == FORM_CALLBACK)) {
1511 gotsize = readfromfile(form, buffer, wantedsize);
1514 /* If positive or -1, return. If zero, continue! */
1519 if((form->data->length - form->sent) > wantedsize - gotsize) {
1521 memcpy(buffer + gotsize, form->data->line + form->sent,
1522 wantedsize - gotsize);
1524 form->sent += wantedsize-gotsize;
1529 memcpy(buffer+gotsize,
1530 form->data->line + form->sent,
1531 (form->data->length - form->sent) );
1532 gotsize += form->data->length - form->sent;
1536 form->data = form->data->next; /* advance */
1538 } while(form->data && (form->data->type < FORM_CALLBACK));
1539 /* If we got an empty line and we have more data, we proceed to the next
1540 line immediately to avoid returning zero before we've reached the end. */
1546 * Curl_formpostheader() returns the first line of the formpost, the
1547 * request-header part (which is not part of the request-body like the rest of
1550 char *Curl_formpostheader(void *formp, size_t *len)
1553 struct Form *form=(struct Form *)formp;
1556 return NULL; /* nothing, ERROR! */
1558 header = form->data->line;
1559 *len = form->data->length;
1561 form->data = form->data->next; /* advance */
1567 * formboundary() creates a suitable boundary string and returns an allocated
1570 static char *formboundary(struct Curl_easy *data)
1572 /* 24 dashes and 16 hexadecimal digits makes 64 bit (18446744073709551615)
1574 unsigned int rnd[2];
1575 CURLcode result = Curl_rand(data, &rnd[0], 2);
1579 return aprintf("------------------------%08x%08x", rnd[0], rnd[1]);
1582 #else /* CURL_DISABLE_HTTP */
1583 CURLFORMcode curl_formadd(struct curl_httppost **httppost,
1584 struct curl_httppost **last_post,
1589 return CURL_FORMADD_DISABLED;
1592 int curl_formget(struct curl_httppost *form, void *arg,
1593 curl_formget_callback append)
1598 return CURL_FORMADD_DISABLED;
1601 void curl_formfree(struct curl_httppost *form)
1604 /* does nothing HTTP is disabled */
1608 #endif /* !defined(CURL_DISABLE_HTTP) */