cURL / Mailing Lists / curl-library / Single Mail

curl-library

Upload Buffer Patch - curl-7.9.7

From: Combes, Chris M. <ccombes_at_northropgrumman.com>
Date: Tue, 11 Jun 2002 16:26:57 -0400

Hello,

Attached is a diff file containing changes to support the
operation of uploading data from a buffer, instead of from
a file.

Comment lines with "CMC:" can be removed. They exist
to support local identification of changes.

Please let me know if there are problems incorporating.

Also included is some documentation on using a buffer.

Thanks,
Chris Combes

The following information is provided to the libcurl community for documentation
and source inclusion.

curl "tutorial"
---------------

The following example sets two buffer contents for upload:

struct curl_httppost *post=NULL;
struct curl_httppost *last=NULL;
curl_formadd(&post, &last,
             CURLFORM_BUFFER, "buffer1",
             CURLFORM_PTRBUFFER, record,
             CURLFORM_BUFFERLENGTH, record_length,
             CURLFORM_END);
curl_formadd(&post, &last,
             CURLFORM_BUFFER, "buffer2",
             CURLFORM_PTRBUFFER, object,
             CURLFORM_BUFFERLENGTH, object_length,
             CURLFORM_END);

/* Set the form info */
curl_easy_setopt(easyhandle, CURLOPT_HTTPPOST, post);
                      
curl_easy_perform(easyhandle); /* post away! */
                      
/* free the post data again */
curl_formfree(post);

curl_formadd()
--------------

CURLFORM_BUFFER
Tells libcurl that a buffer is to be used to upload data
instead of using a file. The value of the next parameter
is used as the value of the "filename" parameter in the
content header.

CURLFORM_PTRBUFFER
Tells libcurl that the address of the next parameter is
a pointer to the buffer containing data to upload. The buffer
containing this data must not be freed until after curl_easy_cleanup
is called.

CURLFORM_BUFFERLENGTH
Tells libcurl that the length of the buffer to upload is
the value of the next parameter.

EXAMPLE

/* Add a buffer to upload */
curl_formadd(&post, &last,
             CURLFORM_BUFFER, "data",
             CURLFORM_PTRBUFFER, record,
             CURLFORM_BUFFERLENGTH, record_length,
             CURLFORM_END);

File buffer_mod.txt contains modifications made to curl-7.9.7 to support file uploads
using a buffer instead of having curl read the data from a file.

Only in curl-7.9.7/: #junk2#
Only in /h/src/curl-7.9.7: Makefile
Only in curl-7.9.7/: Makefile.HP-UX.B.11.00
Only in curl-7.9.7/: config.log
Only in curl-7.9.7/: config.status
Only in curl-7.9.7/: configure~
Only in curl-7.9.7/: curl-config
Only in curl-7.9.7/docs: Makefile.HP-UX.B.11.00
Only in curl-7.9.7/docs/examples: Makefile
Only in curl-7.9.7/docs/libcurl: Makefile.HP-UX.B.11.00
Only in curl-7.9.7/include: Makefile.HP-UX.B.11.00
Only in curl-7.9.7/include/curl: Makefile.HP-UX.B.11.00
diff -ru /h/src/curl-7.9.7/include/curl/curl.h curl-7.9.7/include/curl/curl.h
--- /h/src/curl-7.9.7/include/curl/curl.h Mon May 13 05:33:54 2002
+++ curl-7.9.7/include/curl/curl.h Mon Jun 10 15:06:24 2002
@@ -65,6 +65,11 @@
   long namelength; /* length of name length */
   char *contents; /* pointer to allocated data contents */
   long contentslength; /* length of contents field */
+
+ /* CMC: Added support for buffer uploads */
+ char *buffer; /* pointer to allocated buffer contents */
+ long bufferlength; /* length of buffer field */
+
   char *contenttype; /* Content-Type */
   struct curl_slist* contentheader; /* list of extra headers for this form */
   struct curl_httppost *more; /* if one field name has more than one file, this
@@ -76,6 +81,11 @@
                                    do not free in formfree */
 #define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer
                                        do not free in formfree */
+
+/* CMC: Added support for buffer uploads */
+#define HTTPPOST_BUFFER (1<<4) /* upload file from buffer */
+#define HTTPPOST_PTRBUFFER (1<<5) /* upload file from pointer contents */
+
   char *showfilename; /* The file name to show. If not set, the actual
                          file name will be used (if this is a file part) */
 };
@@ -638,6 +648,12 @@
   CFINIT(ARRAY),
   CFINIT(OBSOLETE),
   CFINIT(FILE),
+
+ /* CMC: Added to support file upload from a buffer */
+ CFINIT(BUFFER),
+ CFINIT(PTRBUFFER),
+ CFINIT(BUFFERLENGTH),
+
   CFINIT(CONTENTTYPE),
   CFINIT(CONTENTHEADER),
   CFINIT(FILENAME),
Only in curl-7.9.7/include/curl: curl.h~
Only in curl-7.9.7/lib: .deps
Only in curl-7.9.7/lib: Makefile.HP-UX.B.11.00
Only in curl-7.9.7/lib: config.h.HP-UX.B.11.00
diff -ru /h/src/curl-7.9.7/lib/formdata.c curl-7.9.7/lib/formdata.c
--- /h/src/curl-7.9.7/lib/formdata.c Mon Apr 15 07:19:03 2002
+++ curl-7.9.7/lib/formdata.c Mon Jun 10 15:05:32 2002
@@ -398,6 +398,10 @@
 static struct curl_httppost *
 AddHttpPost(char * name, long namelength,
             char * value, long contentslength,
+
+ /* CMC: Added support for buffer uploads */
+ char * buffer, long bufferlength,
+
             char *contenttype,
             long flags,
             struct curl_slist* contentHeader,
@@ -414,6 +418,11 @@
     post->namelength = name?(namelength?namelength:(long)strlen(name)):0;
     post->contents = value;
     post->contentslength = contentslength;
+
+ /* CMC: Added support for buffer uploads */
+ post->buffer = buffer;
+ post->bufferlength = bufferlength;
+
     post->contenttype = contenttype;
     post->contentheader = contentHeader;
     post->showfilename = showfilename;
@@ -794,9 +803,63 @@
         }
         break;
       }
+
+ /* CMC: Added support for buffer uploads */
+ case CURLFORM_BUFFER:
+ {
+ char *filename = array_state?array_value:
+ va_arg(params, char *);
+
+ if (current_form->value) {
+ if (current_form->flags & HTTPPOST_BUFFER) {
+ if (filename) {
+ if (!(current_form = AddFormInfo(strdup(filename),
+ NULL, current_form)))
+ return_value = FORMADD_MEMORY;
+ }
+ else
+ return_value = FORMADD_NULL;
+ }
+ else
+ return_value = FORMADD_OPTION_TWICE;
+ }
+ else {
+ if (filename)
+ current_form->value = strdup(filename);
+ else
+ return_value = FORMADD_NULL;
+ current_form->flags |= HTTPPOST_BUFFER;
+ }
+ break;
+ }
+
+ /* CMC: Added support for buffer uploads */
+ case CURLFORM_PTRBUFFER:
+ current_form->flags |= HTTPPOST_PTRBUFFER;
+ if (current_form->buffer)
+ return_value = FORMADD_OPTION_TWICE;
+ else {
+ char *buffer =
+ array_state?array_value:va_arg(params, char *);
+ if (buffer)
+ current_form->buffer = buffer; /* store for the moment */
+ else
+ return_value = FORMADD_NULL;
+ }
+ break;
+
+ /* CMC: Added support for buffer uploads */
+ case CURLFORM_BUFFERLENGTH:
+ if (current_form->bufferlength)
+ return_value = FORMADD_OPTION_TWICE;
+ else
+ current_form->bufferlength =
+ array_state?(long)array_value:va_arg(params, long);
+ break;
+
     case CURLFORM_CONTENTTYPE:
       {
- char *contenttype =
+ char *contenttype =
           array_state?array_value:va_arg(params, char *);
         if (current_form->contenttype) {
           if (current_form->flags & HTTPPOST_FILENAME) {
@@ -806,18 +869,18 @@
                                                current_form)))
                 return_value = FORMADD_MEMORY;
             }
- else
- return_value = FORMADD_NULL;
+ else
+ return_value = FORMADD_NULL;
           }
           else
             return_value = FORMADD_OPTION_TWICE;
         }
         else {
- if (contenttype)
- current_form->contenttype = strdup(contenttype);
- else
- return_value = FORMADD_NULL;
- }
+ if (contenttype)
+ current_form->contenttype = strdup(contenttype);
+ else
+ return_value = FORMADD_NULL;
+ }
         break;
       }
     case CURLFORM_CONTENTHEADER:
@@ -863,6 +926,12 @@
              (form->flags & HTTPPOST_FILENAME) ) ||
            ( (form->flags & HTTPPOST_FILENAME) &&
              (form->flags & HTTPPOST_PTRCONTENTS) ) ||
+
+ /* CMC: Added support for buffer uploads */
+ ( (!form->buffer) &&
+ (form->flags & HTTPPOST_BUFFER) &&
+ (form->flags & HTTPPOST_PTRBUFFER) ) ||
+
            ( (form->flags & HTTPPOST_READFILE) &&
              (form->flags & HTTPPOST_PTRCONTENTS) )
            ) {
@@ -870,7 +939,9 @@
         break;
       }
       else {
- if ( (form->flags & HTTPPOST_FILENAME) &&
+ if ( (form->flags & HTTPPOST_FILENAME) ||
+ /* CMC: Added support for buffer uploads */
+ (form->flags & HTTPPOST_BUFFER) &&
              !form->contenttype ) {
           /* our contenttype is missing */
           form->contenttype
@@ -886,7 +957,11 @@
         }
         if ( !(form->flags & HTTPPOST_FILENAME) &&
              !(form->flags & HTTPPOST_READFILE) &&
- !(form->flags & HTTPPOST_PTRCONTENTS) ) {
+ !(form->flags & HTTPPOST_PTRCONTENTS) &&
+
+ /* CMC: Added support for buffer uploads */
+ !(form->flags & HTTPPOST_PTRBUFFER) ) {
+
           /* copy value (without strdup; possibly contains null characters) */
           if (AllocAndCopy(&form->value, form->contentslength)) {
             return_value = FORMADD_MEMORY;
@@ -895,6 +970,10 @@
         }
         post = AddHttpPost(form->name, form->namelength,
                            form->value, form->contentslength,
+
+ /* CMC: Added support for buffer uploads */
+ form->buffer, form->bufferlength,
+
                            form->contenttype, form->flags,
                            form->contentheader, form->showfilename,
                            post, httppost,
@@ -1096,9 +1175,9 @@
       fileboundary = Curl_FormBoundary();
 
       size += AddFormDataf(&form,
- "\r\nContent-Type: multipart/mixed,"
- " boundary=%s\r\n",
- fileboundary);
+ "\r\nContent-Type: multipart/mixed,"
+ " boundary=%s\r\n",
+ fileboundary);
     }
 
     file = post;
@@ -1110,26 +1189,30 @@
          local file name should be added. */
 
       if(post->more) {
- /* if multiple-file */
- size += AddFormDataf(&form,
- "\r\n--%s\r\nContent-Disposition: "
+ /* if multiple-file */
+ size += AddFormDataf(&form,
+ "\r\n--%s\r\nContent-Disposition: "
                              "attachment; filename=\"%s\"",
- fileboundary,
+ fileboundary,
                              (file->showfilename?file->showfilename:
                               file->contents));
       }
- else if(post->flags & HTTPPOST_FILENAME) {
- size += AddFormDataf(&form,
- "; filename=\"%s\"",
- (post->showfilename?post->showfilename:
+ else if((post->flags & HTTPPOST_FILENAME) ||
+
+ /* CMC: Added support for buffer uploads */
+ (post->flags & HTTPPOST_BUFFER)) {
+
+ size += AddFormDataf(&form,
+ "; filename=\"%s\"",
+ (post->showfilename?post->showfilename:
                               post->contents));
       }
       
       if(file->contenttype) {
- /* we have a specified type */
- size += AddFormDataf(&form,
- "\r\nContent-Type: %s",
- file->contenttype);
+ /* we have a specified type */
+ size += AddFormDataf(&form,
+ "\r\nContent-Type: %s",
+ file->contenttype);
       }
 
       curList = file->contentheader;
@@ -1147,47 +1230,53 @@
        */
       
       if(file->contenttype &&
- !strnequal("text/", file->contenttype, 5)) {
- /* this is not a text content, mention our binary encoding */
- size += AddFormData(&form, "\r\nContent-Transfer-Encoding: binary", 0);
+ !strnequal("text/", file->contenttype, 5)) {
+ /* this is not a text content, mention our binary encoding */
+ size += AddFormData(&form, "\r\nContent-Transfer-Encoding: binary", 0);
       }
 #endif
 
       size += AddFormData(&form, "\r\n\r\n", 0);
 
       if((post->flags & HTTPPOST_FILENAME) ||
- (post->flags & HTTPPOST_READFILE)) {
- /* we should include the contents from the specified file */
- FILE *fileread;
- char buffer[1024];
- int nread;
+ (post->flags & HTTPPOST_READFILE)) {
+ /* we should include the contents from the specified file */
+ FILE *fileread;
+ char buffer[1024];
+ int nread;
 
- fileread = strequal("-", file->contents)?stdin:
+ fileread = strequal("-", file->contents)?stdin:
           /* binary read for win32 crap */
-/*VMS??*/ fopen(file->contents, "rb"); /* ONLY ALLOWS FOR STREAM FILES ON VMS */
-/*VMS?? Stream files are OK, as are FIXED & VAR files WITHOUT implied CC */
-/*VMS?? For implied CC, every record needs to have a \n appended & 1 added to SIZE */
- if(fileread) {
- while((nread = fread(buffer, 1, 1024, fileread)))
- size += AddFormData(&form, buffer, nread);
+ /*VMS??*/ fopen(file->contents, "rb"); /* ONLY ALLOWS FOR STREAM FILES ON VMS */
+ /*VMS?? Stream files are OK, as are FIXED & VAR files WITHOUT implied CC */
+ /*VMS?? For implied CC, every record needs to have a \n appended & 1 added to SIZE */
+ if(fileread) {
+ while((nread = fread(buffer, 1, 1024, fileread)))
+ size += AddFormData(&form, buffer, nread);
 
           if(fileread != stdin)
             fclose(fileread);
- }
+ }
         else {
 #if 0
           /* File wasn't found, add a nothing field! */
- size += AddFormData(&form, "", 0);
+ size += AddFormData(&form, "", 0);
 #endif
           Curl_formclean(firstform);
           free(boundary);
           *finalform = NULL;
           return CURLE_READ_ERROR;
- }
+ }
+
+ /* CMC: Added support for buffer uploads */
+ } else if (post->flags & HTTPPOST_BUFFER) {
+ /* include contents of buffer */
+ size += AddFormData(&form, post->buffer, post->bufferlength);
       }
+
       else {
- /* include the contents we got */
- size += AddFormData(&form, post->contents, post->contentslength);
+ /* include the contents we got */
+ size += AddFormData(&form, post->contents, post->contentslength);
       }
     } while((file = file->more)); /* for each specified file for this field */
 
@@ -1195,8 +1284,8 @@
       /* this was a multiple-file inclusion, make a termination file
          boundary: */
       size += AddFormDataf(&form,
- "\r\n--%s--",
- fileboundary);
+ "\r\n--%s--",
+ fileboundary);
       free(fileboundary);
     }
 
@@ -1204,8 +1293,8 @@
 
   /* end-boundary for everything */
   size += AddFormDataf(&form,
- "\r\n--%s--\r\n",
- boundary);
+ "\r\n--%s--\r\n",
+ boundary);
 
   *sizep = size;
 
Only in curl-7.9.7/lib: formdata.c~
diff -ru /h/src/curl-7.9.7/lib/formdata.h curl-7.9.7/lib/formdata.h
--- /h/src/curl-7.9.7/lib/formdata.h Mon Apr 15 07:19:03 2002
+++ curl-7.9.7/lib/formdata.h Mon Jun 10 15:05:41 2002
@@ -45,6 +45,10 @@
   char *contenttype;
   long flags;
 
+ /* CMC: Added support for buffer uploads */
+ char *buffer; /* pointer to existing buffer used for file upload */
+ long bufferlength;
+
   char *showfilename; /* The file name to show. If not set, the actual
                          file name will be used */
   struct curl_slist* contentheader;
Only in curl-7.9.7/lib: formdata.h~
Only in curl-7.9.7/lib: stamp-h1
Only in curl-7.9.7/: libtool
Only in curl-7.9.7/packages/EPM: Makefile.HP-UX.B.11.00
Only in curl-7.9.7/packages/EPM: curl.list
Only in curl-7.9.7/packages/Linux: Makefile
Only in curl-7.9.7/packages/Linux/RPM: Makefile
Only in curl-7.9.7/packages/Linux/RPM: curl-ssl.spec
Only in curl-7.9.7/packages/Linux/RPM: curl.spec
Only in curl-7.9.7/packages: Makefile.HP-UX.B.11.00
Only in curl-7.9.7/packages/Solaris: Makefile
Only in curl-7.9.7/packages/Win32: Makefile
Only in curl-7.9.7/packages/Win32/cygwin: Makefile
Only in curl-7.9.7/src: .deps
Only in curl-7.9.7/src: Makefile.HP-UX.B.11.00
Only in curl-7.9.7/src: config.h.HP-UX.B.11.00
Only in /h/src/curl-7.9.7/src: hugehelp.c
Only in curl-7.9.7/src: stamp-h2
diff -ru /h/src/curl-7.9.7/src/stamp-h2.in curl-7.9.7/src/stamp-h2.in
--- /h/src/curl-7.9.7/src/stamp-h2.in Mon Apr 8 18:36:54 2002
+++ curl-7.9.7/src/stamp-h2.in Tue Jun 4 15:51:14 2002
@@ -0,0 +1 @@
+timestamp
Only in curl-7.9.7/tests: Makefile.HP-UX.B.11.00
Only in curl-7.9.7/tests/data: Makefile.HP-UX.B.11.00
Only in curl-7.9.7/tests/server: .deps
Only in curl-7.9.7/tests/server: Makefile.HP-UX.B.11.00
Only in curl-7.9.7/tests/server: config.h.HP-UX.B.11.00
Only in curl-7.9.7/tests/server: stamp-h3

_______________________________________________________________

Multimillion Dollar Computer Inventory
Live Webcast Auctions Thru Aug. 2002 - http://www.cowanalexander.com/calendar
Received on 2002-06-11