Unverified Commit 84ad1fd3 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

formdata: use the mime-content type function

Reduce code duplication by making Curl_mime_contenttype available and
used by the formdata function. This also makes the formdata function
recognize a set of more file extensions by default.

PR #2280 brought this to my attention.

Closes #2282
parent a19afacc
Loading
Loading
Loading
Loading
+8 −56
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
 * Copyright (C) 1998 - 2018, 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
@@ -153,60 +153,6 @@ static FormInfo * AddFormInfo(char *value,
  return form_info;
}

/***************************************************************************
 *
 * ContentTypeForFilename()
 *
 * Provides content type for filename if one of the known types (else
 * (either the prevtype or the default is returned).
 *
 * Returns some valid contenttype for filename.
 *
 ***************************************************************************/
static const char *ContentTypeForFilename(const char *filename,
                                          const char *prevtype)
{
  const char *contenttype = NULL;
  unsigned int i;
  /*
   * 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 const struct ContentType ctts[]={
    {".gif",  "image/gif"},
    {".jpg",  "image/jpeg"},
    {".jpeg", "image/jpeg"},
    {".txt",  "text/plain"},
    {".html", "text/html"},
    {".xml", "application/xml"}
  };

  if(prevtype)
    /* default to the previously set/used! */
    contenttype = prevtype;
  else
    contenttype = HTTPPOST_CONTENTTYPE_DEFAULT;

  if(filename) { /* in case a NULL was passed in */
    for(i = 0; i<sizeof(ctts)/sizeof(ctts[0]); i++) {
      if(strlen(filename) >= strlen(ctts[i].extension)) {
        if(strcasecompare(filename +
                          strlen(filename) - strlen(ctts[i].extension),
                          ctts[i].extension)) {
          contenttype = ctts[i].type;
          break;
        }
      }
    }
  }
  /* we have a contenttype by now */
  return contenttype;
}

/***************************************************************************
 *
 * FormAdd()
@@ -627,9 +573,15 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
         !form->contenttype) {
        char *f = form->flags & HTTPPOST_BUFFER?
          form->showfilename : form->value;
        char const *type;
        type = Curl_mime_contenttype(f);
        if(!type)
          type = prevtype;
        if(!type)
          type = FILE_CONTENTTYPE_DEFAULT;

        /* our contenttype is missing */
        form->contenttype = strdup(ContentTypeForFilename(f, prevtype));
        form->contenttype = strdup(type);
        if(!form->contenttype) {
          return_value = CURL_FORMADD_MEMORY;
          break;
+4 −9
Original line number Diff line number Diff line
@@ -51,10 +51,6 @@
#endif


#define FILE_CONTENTTYPE_DEFAULT        "application/octet-stream"
#define MULTIPART_CONTENTTYPE_DEFAULT   "multipart/mixed"
#define DISPOSITION_DEFAULT             "attachment"

#define READ_ERROR                      ((size_t) -1)

/* Encoders. */
@@ -1642,8 +1638,7 @@ static CURLcode add_content_type(struct curl_slist **slp,
                              boundary? boundary: "");
}


static const char *ContentTypeForFilename(const char *filename)
const char *Curl_mime_contenttype(const char *filename)
{
  unsigned int i;

@@ -1715,14 +1710,14 @@ CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
      contenttype = MULTIPART_CONTENTTYPE_DEFAULT;
      break;
    case MIMEKIND_FILE:
      contenttype = ContentTypeForFilename(part->filename);
      contenttype = Curl_mime_contenttype(part->filename);
      if(!contenttype)
        contenttype = ContentTypeForFilename(part->data);
        contenttype = Curl_mime_contenttype(part->data);
      if(!contenttype && part->filename)
        contenttype = FILE_CONTENTTYPE_DEFAULT;
      break;
    default:
      contenttype = ContentTypeForFilename(part->filename);
      contenttype = Curl_mime_contenttype(part->filename);
      break;
    }
  }
+5 −0
Original line number Diff line number Diff line
@@ -30,6 +30,10 @@
#define MIME_USERHEADERS_OWNER  (1 << 0)
#define MIME_BODY_ONLY          (1 << 1)

#define FILE_CONTENTTYPE_DEFAULT        "application/octet-stream"
#define MULTIPART_CONTENTTYPE_DEFAULT   "multipart/mixed"
#define DISPOSITION_DEFAULT             "attachment"

/* Part source kinds. */
enum mimekind {
  MIMEKIND_NONE = 0,            /* Part not set. */
@@ -134,5 +138,6 @@ size_t Curl_mime_read(char *buffer, size_t size, size_t nitems,
                      void *instream);
CURLcode Curl_mime_rewind(curl_mimepart *part);
CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...);
const char *Curl_mime_contenttype(const char *filename);

#endif /* HEADER_CURL_MIME_H */