Commit ca5f9341 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

formadd: support >2GB files on windows

Closes #425
parent 49a99134
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -83,7 +83,18 @@ to send away. libcurl will use the pointer and refer to the data in your
application, so you must make sure it remains until curl no longer needs it.
If the data isn't NUL-terminated, or if you'd like it to contain zero bytes,
you must set its length  with \fBCURLFORM_CONTENTSLENGTH\fP.
.IP CURLFORM_CONTENTLEN
followed by a curl_off_t value giving the length of the contents. Note that
for \fICURLFORM_STREAM\fP contents, this option is mandatory.

If you pass a 0 (zero) for this option, libcurl will instead do a strlen() on
the contents to figure out the size. If you really want to send a zero byte
content then you must make sure strlen() on the data pointer returns zero.

(Option added in 7.46.0)
.IP CURLFORM_CONTENTSLENGTH
(This option is deprecated. Use \fICURLFORM_CONTENTLEN\fP instead!)

followed by a long giving the length of the contents. Note that for
\fICURLFORM_STREAM\fP contents, this option is mandatory.

+2 −0
Original line number Diff line number Diff line
@@ -164,6 +164,7 @@ CURLFORM_BUFFER 7.9.8
CURLFORM_BUFFERLENGTH           7.9.8
CURLFORM_BUFFERPTR              7.9.8
CURLFORM_CONTENTHEADER          7.9.3
CURLFORM_CONTENTLEN             7.46.0
CURLFORM_CONTENTSLENGTH         7.9
CURLFORM_CONTENTTYPE            7.9
CURLFORM_COPYCONTENTS           7.9
@@ -678,6 +679,7 @@ CURL_GLOBAL_DEFAULT 7.8
CURL_GLOBAL_NOTHING             7.8
CURL_GLOBAL_SSL                 7.8
CURL_GLOBAL_WIN32               7.8.1
CURL_HTTPPOST_LARGE             7.46.0
CURL_HTTP_VERSION_1_0           7.9.1
CURL_HTTP_VERSION_1_1           7.9.1
CURL_HTTP_VERSION_2             7.43.0
+8 −1
Original line number Diff line number Diff line
@@ -127,7 +127,8 @@ struct curl_httppost {
  char *name;                       /* pointer to allocated name */
  long namelength;                  /* length of name length */
  char *contents;                   /* pointer to allocated data contents */
  long contentslength;              /* length of contents field */
  long contentslength;              /* length of contents field, see also
                                       CURL_HTTPPOST_LARGE */
  char *buffer;                     /* pointer to allocated buffer contents */
  long bufferlength;                /* length of buffer field */
  char *contenttype;                /* Content-Type */
@@ -152,12 +153,17 @@ struct curl_httppost {
/* upload file contents by using the regular read callback to get the data and
   pass the given pointer as custom pointer */
#define CURL_HTTPPOST_CALLBACK (1<<6)
/* use size in 'contentlen', added in 7.46.0 */
#define CURL_HTTPPOST_LARGE (1<<7)

  char *showfilename;               /* The file name to show. If not set, the
                                       actual file name will be used (if this
                                       is a file part) */
  void *userp;                      /* custom pointer used for
                                       HTTPPOST_CALLBACK posts */
  curl_off_t contentlen;            /* alternative length of contents
                                       field. Used if CURL_HTTPPOST_LARGE is
                                       set. Added in 7.46.0 */
};

/* This is the CURLOPT_PROGRESSFUNCTION callback proto. It is now considered
@@ -1835,6 +1841,7 @@ typedef enum {
  CFINIT(OBSOLETE2),

  CFINIT(STREAM),
  CFINIT(CONTENTLEN), /* added in 7.46.0, provide a curl_off_t length */

  CURLFORM_LASTENTRY /* the last unused */
} CURLformoption;
+24 −17
Original line number Diff line number Diff line
@@ -77,7 +77,7 @@ static char *formboundary(struct SessionHandle *data);
 ***************************************************************************/
static struct curl_httppost *
AddHttpPost(char *name, size_t namelength,
            char *value, size_t contentslength,
            char *value, curl_off_t contentslength,
            char *buffer, size_t bufferlength,
            char *contenttype,
            long flags,
@@ -93,14 +93,14 @@ AddHttpPost(char *name, size_t namelength,
    post->name = name;
    post->namelength = (long)(name?(namelength?namelength:strlen(name)):0);
    post->contents = value;
    post->contentslength = (long)contentslength;
    post->contentlen = contentslength;
    post->buffer = buffer;
    post->bufferlength = (long)bufferlength;
    post->contenttype = contenttype;
    post->contentheader = contentHeader;
    post->showfilename = showfilename;
    post->userp = userp,
    post->flags = flags;
    post->flags = flags | CURL_HTTPPOST_LARGE;
  }
  else
    return NULL;
@@ -380,13 +380,16 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
      }
      break;
    case CURLFORM_CONTENTSLENGTH:
      if(current_form->contentslength)
        return_value = CURL_FORMADD_OPTION_TWICE;
      else
      current_form->contentslength =
        array_state?(size_t)array_value:(size_t)va_arg(params, long);
      break;

    case CURLFORM_CONTENTLEN:
      current_form->flags |= CURL_HTTPPOST_LARGE;
      current_form->contentslength =
        array_state?(curl_off_t)array_value:va_arg(params, curl_off_t);
      break;

      /* Get contents from a given file name */
    case CURLFORM_FILECONTENT:
      if(current_form->flags & (HTTPPOST_PTRCONTENTS|HTTPPOST_READFILE))
@@ -661,9 +664,12 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
                            HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER |
                            HTTPPOST_CALLBACK)) && form->value) {
          /* copy value (without strdup; possibly contains null characters) */
          form->value = Curl_memdup(form->value, form->contentslength?
                                    form->contentslength:
                                    strlen(form->value)+1);
          size_t clen  = (size_t) form->contentslength;
          if(!clen)
            clen = strlen(form->value)+1;

          form->value = Curl_memdup(form->value, clen);

          if(!form->value) {
            return_value = CURL_FORMADD_MEMORY;
            break;
@@ -816,7 +822,7 @@ static curl_off_t VmsSpecialSize(const char * name,
static CURLcode AddFormData(struct FormData **formp,
                            enum formtype type,
                            const void *line,
                            size_t length,
                            curl_off_t length,
                            curl_off_t *size)
{
  struct FormData *newform = malloc(sizeof(struct FormData));
@@ -1306,15 +1312,16 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
        result = AddFormData(&form, FORM_CONTENT, post->buffer,
                             post->bufferlength, &size);
      else if(post->flags & HTTPPOST_CALLBACK)
        /* the contents should be read with the callback and the size
           is set with the contentslength */
        /* the contents should be read with the callback and the size is set
           with the contentslength */
        result = AddFormData(&form, FORM_CALLBACK, post->userp,
                             post->contentslength, &size);
                             post->flags&CURL_HTTPPOST_LARGE?
                             post->contentlen:post->contentslength, &size);
      else
        /* include the contents we got */
        result = AddFormData(&form, FORM_CONTENT, post->contents,
                             post->contentslength, &size);

                             post->flags&CURL_HTTPPOST_LARGE?
                             post->contentlen:post->contentslength, &size);
      file = file->more;
    } while(file && !result); /* for each specified file for this field */

+2 −2
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
 * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
@@ -54,7 +54,7 @@ typedef struct FormInfo {
  size_t namelength;
  char *value;
  bool value_alloc;
  size_t contentslength;
  curl_off_t contentslength;
  char *contenttype;
  bool contenttype_alloc;
  long flags;
Loading