man_MANS = curl_easy_cleanup.3 curl_easy_getinfo.3 curl_easy_init.3 \
curl_easy_perform.3 curl_easy_setopt.3 curl_easy_duphandle.3 \
- curl_formparse.3 curl_formadd.3 curl_formfree.3 curl_getdate.3 \
- curl_getenv.3 curl_slist_append.3 curl_slist_free_all.3 \
- curl_version.3 curl_version_info.3 curl_escape.3 curl_unescape.3 \
- curl_free.3 curl_strequal.3 curl_mprintf.3 curl_global_init.3 \
+ curl_formadd.3 curl_formfree.3 curl_getdate.3 curl_getenv.3 \
+ curl_slist_append.3 curl_slist_free_all.3 curl_version.3 \
+ curl_version_info.3 curl_escape.3 curl_unescape.3 curl_free.3 \
+ curl_strequal.3 curl_mprintf.3 curl_global_init.3 \
curl_global_cleanup.3 curl_multi_add_handle.3 curl_multi_cleanup.3 \
curl_multi_fdset.3 curl_multi_info_read.3 curl_multi_init.3 \
curl_multi_perform.3 curl_multi_remove_handle.3 curl_share_cleanup.3 \
HTMLPAGES = curl_easy_cleanup.html curl_easy_getinfo.html \
curl_easy_init.html curl_easy_perform.html curl_easy_setopt.html \
- curl_easy_duphandle.html curl_formadd.html curl_formparse.html \
- curl_formfree.html curl_getdate.html curl_getenv.html \
- curl_slist_append.html curl_slist_free_all.html curl_version.html \
- curl_version_info.html curl_escape.html curl_unescape.html \
- curl_free.html curl_strequal.html curl_mprintf.html \
- curl_global_init.html curl_global_cleanup.html \
+ curl_easy_duphandle.html curl_formadd.html curl_formfree.html \
+ curl_getdate.html curl_getenv.html curl_slist_append.html \
+ curl_slist_free_all.html curl_version.html curl_version_info.html \
+ curl_escape.html curl_unescape.html curl_free.html curl_strequal.html \
+ curl_mprintf.html curl_global_init.html curl_global_cleanup.html \
curl_multi_add_handle.html curl_multi_cleanup.html \
curl_multi_fdset.html curl_multi_info_read.html curl_multi_init.html \
curl_multi_perform.html curl_multi_remove_handle.html \
curl_share_cleanup.html curl_share_init.html curl_share_setopt.html \
libcurl.html libcurl-multi.html libcurl-easy.html libcurl-share.html \
- libcurl-errors.html curl_easy_strerror.html curl_multi_strerror.html \
+ libcurl-errors.html curl_easy_strerror.html curl_multi_strerror.html \
curl_share_strerror.html
PDFPAGES = curl_easy_cleanup.pdf curl_easy_getinfo.pdf \
curl_easy_init.pdf curl_easy_perform.pdf curl_easy_setopt.pdf \
- curl_easy_duphandle.pdf curl_formadd.pdf curl_formparse.pdf \
- curl_formfree.pdf curl_getdate.pdf curl_getenv.pdf \
- curl_slist_append.pdf curl_slist_free_all.pdf curl_version.pdf \
- curl_version_info.pdf curl_escape.pdf curl_unescape.pdf curl_free.pdf \
- curl_strequal.pdf curl_mprintf.pdf curl_global_init.pdf \
- curl_global_cleanup.pdf curl_multi_add_handle.pdf \
- curl_multi_cleanup.pdf curl_multi_fdset.pdf curl_multi_info_read.pdf \
- curl_multi_init.pdf curl_multi_perform.pdf \
+ curl_easy_duphandle.pdf curl_formadd.pdf curl_formfree.pdf \
+ curl_getdate.pdf curl_getenv.pdf curl_slist_append.pdf \
+ curl_slist_free_all.pdf curl_version.pdf curl_version_info.pdf \
+ curl_escape.pdf curl_unescape.pdf curl_free.pdf curl_strequal.pdf \
+ curl_mprintf.pdf curl_global_init.pdf curl_global_cleanup.pdf \
+ curl_multi_add_handle.pdf curl_multi_cleanup.pdf curl_multi_fdset.pdf \
+ curl_multi_info_read.pdf curl_multi_init.pdf curl_multi_perform.pdf \
curl_multi_remove_handle.pdf curl_share_cleanup.pdf \
curl_share_init.pdf curl_share_setopt.pdf libcurl.pdf \
libcurl-multi.pdf libcurl-easy.pdf libcurl-share.pdf \
- libcurl-errors.pdf curl_easy_strerror.pdf curl_multi_strerror.pdf \
+ libcurl-errors.pdf curl_easy_strerror.pdf curl_multi_strerror.pdf \
curl_share_strerror.pdf
CLEANFILES = $(HTMLPAGES) $(PDFPAGES)
Content-Disposition: form-data; name="FILECONTENT"
...
- For the old FormParse used by curl_formparse use:
-
- gcc -DHAVE_CONFIG_H -I../ -g -D_OLD_FORM_DEBUG -o formdata -I../include formdata.c strequal.c
-
- run the 'formdata' executable and make sure the output is ok!
-
- try './formdata "name=Daniel" "poo=noo" "foo=bar"' and similarly
-
*/
#include "setup.h"
#include <time.h>
-#ifndef CURL_OLDSTYLE
-#define CURL_OLDSTYLE 1 /* enable deprecated prototype for curl_formparse */
-#endif
#include <curl/curl.h>
#include "formdata.h"
#define FORM_FILE_SEPARATOR ','
#define FORM_TYPE_SEPARATOR ';'
-static
-int FormParse(char *input,
- struct curl_httppost **httppost,
- struct curl_httppost **last_post)
-{
- /* 'input' MUST be a string in the format 'name=contents' and we'll
- build a linked list with the info */
- char name[256];
- char *contents;
- char major[128];
- char minor[128];
- long flags = 0;
- char *contp;
- const char *type = NULL;
- char *prevtype = NULL;
- char *sep;
- char *sep2;
- struct curl_httppost *post;
- struct curl_httppost *subpost; /* a sub-node */
- unsigned int i;
-
- /* Preallocate contents to the length of input to make sure we don't
- overwrite anything. */
- contents = malloc(strlen(input));
- contents[0] = '\000';
-
- if(1 <= sscanf(input, "%255[^=]=%[^\n]", name, contents)) {
- /* the input was using the correct format */
- contp = contents;
-
- if('@' == contp[0]) {
- /* we use the @-letter to indicate file name(s) */
-
- flags = HTTPPOST_FILENAME;
- contp++;
-
- post=NULL;
-
- do {
- /* since this was a file, it may have a content-type specifier
- at the end too */
-
- sep=strchr(contp, FORM_TYPE_SEPARATOR);
- sep2=strchr(contp, FORM_FILE_SEPARATOR);
-
- /* pick the closest */
- if(sep2 && (sep2 < sep)) {
- sep = sep2;
-
- /* no type was specified! */
- }
- if(sep) {
-
- /* if we got here on a comma, don't do much */
- if(FORM_FILE_SEPARATOR != *sep)
- type = strstr(sep+1, "type=");
- else
- type=NULL;
-
- *sep=0; /* terminate file name at separator */
-
- if(type) {
- type += strlen("type=");
-
- if(2 != sscanf(type, "%127[^/]/%127[^,\n]",
- major, minor)) {
- free(contents);
- return 2; /* illegal content-type syntax! */
- }
- /* now point beyond the content-type specifier */
- sep = (char *)type + strlen(major)+strlen(minor)+1;
-
- /* find the following comma */
- sep=strchr(sep, FORM_FILE_SEPARATOR);
- }
- }
- else {
- type=NULL;
- sep=strchr(contp, FORM_FILE_SEPARATOR);
- }
- if(sep) {
- /* the next file name starts here */
- *sep =0;
- sep++;
- }
- if(!type) {
- /*
- * No type was specified, we scan through a few well-known
- * extensions and pick the first we match!
- */
- struct ContentType {
- const char *extension;
- const char *type;
- };
- static struct ContentType ctts[]={
- {".gif", "image/gif"},
- {".jpg", "image/jpeg"},
- {".jpeg", "image/jpeg"},
- {".txt", "text/plain"},
- {".html", "text/html"}
- };
-
- if(prevtype)
- /* default to the previously set/used! */
- type = prevtype;
- else
- /* It seems RFC1867 defines no Content-Type to default to
- text/plain so we don't actually need to set this: */
- type = HTTPPOST_CONTENTTYPE_DEFAULT;
-
- for(i=0; i<sizeof(ctts)/sizeof(ctts[0]); i++) {
- if(strlen(contp) >= strlen(ctts[i].extension)) {
- if(strequal(contp +
- strlen(contp) - strlen(ctts[i].extension),
- ctts[i].extension)) {
- type = ctts[i].type;
- break;
- }
- }
- }
- /* we have a type by now */
- }
-
- if(NULL == post) {
- /* For the first file name, we allocate and initiate the main list
- node */
-
- post = (struct curl_httppost *)malloc(sizeof(struct curl_httppost));
- if(post) {
- memset(post, 0, sizeof(struct curl_httppost));
- GetStr(&post->name, name); /* get the name */
- GetStr(&post->contents, contp); /* get the contents */
- post->contentslength = 0;
- post->flags = flags;
- if(type) {
- GetStr(&post->contenttype, (char *)type); /* get type */
- prevtype=post->contenttype; /* point to the allocated string! */
- }
- /* make the previous point to this */
- if(*last_post)
- (*last_post)->next = post;
- else
- (*httppost) = post;
-
- (*last_post) = post;
- }
-
- }
- else {
- /* we add a file name to the previously allocated node, known as
- 'post' now */
- subpost =(struct curl_httppost *)
- malloc(sizeof(struct curl_httppost));
- if(subpost) {
- memset(subpost, 0, sizeof(struct curl_httppost));
- GetStr(&subpost->name, name); /* get the name */
- GetStr(&subpost->contents, contp); /* get the contents */
- subpost->contentslength = 0;
- subpost->flags = flags;
- if(type) {
- GetStr(&subpost->contenttype, (char *)type); /* get type */
- prevtype=subpost->contenttype; /* point to allocated string! */
- }
- /* now, point our 'more' to the original 'more' */
- subpost->more = post->more;
-
- /* then move the original 'more' to point to ourselves */
- post->more = subpost;
- }
- }
- contp = sep; /* move the contents pointer to after the separator */
- } while(sep && *sep); /* loop if there's another file name */
- }
- else {
- post = (struct curl_httppost *)malloc(sizeof(struct curl_httppost));
- if(post) {
- memset(post, 0, sizeof(struct curl_httppost));
- GetStr(&post->name, name); /* get the name */
- if( contp[0]=='<' ) {
- GetStr(&post->contents, contp+1); /* get the contents */
- post->contentslength = 0;
- post->flags = HTTPPOST_READFILE;
- }
- else {
- GetStr(&post->contents, contp); /* get the contents */
- post->contentslength = 0;
- post->flags = 0;
- }
-
- /* make the previous point to this */
- if(*last_post)
- (*last_post)->next = post;
- else
- (*httppost) = post;
-
- (*last_post) = post;
- }
-
- }
-
- }
- else {
- free(contents);
- return 1;
- }
- free(contents);
- return 0;
-}
-
-int curl_formparse(char *input,
- struct curl_httppost **httppost,
- struct curl_httppost **last_post)
-{
- return FormParse(input, httppost, last_post);
-}
-
/***************************************************************************
*
* AddHttpPost()