Commit c96d96bc authored by Patrick Monnerat's avatar Patrick Monnerat
Browse files

mime: drop internal FILE * support.

- The part kind MIMEKIND_FILE and associated code are suppressed.
- Seek data origin offset not used anymore: suppressed.
- MIMEKIND_NAMEDFILE renamed MIMEKIND_FILE; associated fields/functions
  renamed accordingly.
- Curl_getformdata() processes stdin via a callback.
parent d1da545a
Loading
Loading
Loading
Loading
+10 −2
Original line number Original line Diff line number Diff line
@@ -897,8 +897,16 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
          clen = -1;
          clen = -1;


        if(post->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE)) {
        if(post->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE)) {
          if(!strcmp(file->contents, "-"))
          if(!strcmp(file->contents, "-")) {
            result = Curl_mime_file(part, stdin, 0);
            /* There are a few cases where the code below won't work; in
               particular, freopen(stdin) by the caller is not guaranteed
               to result as expected. This feature has been kept for backward
               compatibility: use of "-" pseudo file name should be avoided. */
            result = curl_mime_data_cb(part, (curl_off_t) -1,
                                       (curl_read_callback) fread,
                                       (curl_seek_callback) fseek,
                                       NULL, (void *) stdin);
          }
          else
          else
            result = curl_mime_filedata(part, file->contents);
            result = curl_mime_filedata(part, file->contents);
          if(!result && (post->flags & HTTPPOST_READFILE))
          if(!result && (post->flags & HTTPPOST_READFILE))
+58 −127
Original line number Original line Diff line number Diff line
@@ -662,76 +662,50 @@ static void mime_mem_free(void *ptr)
}
}




/* Open file callbacks. */
/* Argument is the FILE pointer. */
static size_t mime_file_read(char *buffer, size_t size, size_t nitems,
                             void *instream)
{
  return (size_t) fread(buffer, size, nitems, instream);
}

static int mime_file_seek(void *instream, curl_off_t offset, int whence)
{
  FILE *fp = (FILE *) instream;

  return fseek(fp, (long) offset, whence)?
         CURL_SEEKFUNC_CANTSEEK: CURL_SEEKFUNC_OK;
}


/* Named file callbacks. */
/* Named file callbacks. */
/* Argument is a pointer to the mime part. */
/* Argument is a pointer to the mime part. */
static int mime_open_namedfile(curl_mimepart * part)
static int mime_open_file(curl_mimepart * part)
{
{
  /* Open a MIMEKIND_NAMEDFILE part. */
  /* Open a MIMEKIND_FILE part. */


  if(part->namedfp)
  if(part->fp)
    return 0;
    return 0;
  part->namedfp = fopen_read(part->data, "rb");
  part->fp = fopen_read(part->data, "rb");
  return part->namedfp? 0: -1;
  return part->fp? 0: -1;
}
}


static size_t mime_namedfile_read(char *buffer, size_t size, size_t nitems,
static size_t mime_file_read(char *buffer, size_t size, size_t nitems,
                             void *instream)
                             void *instream)
{
{
  curl_mimepart *part = (curl_mimepart *) instream;
  curl_mimepart *part = (curl_mimepart *) instream;


  if(mime_open_namedfile(part))
  if(mime_open_file(part))
    return READ_ERROR;
    return READ_ERROR;


  return mime_file_read(buffer, size, nitems, part->namedfp);
  return fread(buffer, size, nitems, part->fp);
}
}


static int mime_namedfile_seek(void *instream, curl_off_t offset, int whence)
static int mime_file_seek(void *instream, curl_off_t offset, int whence)
{
{
  curl_mimepart *part = (curl_mimepart *) instream;
  curl_mimepart *part = (curl_mimepart *) instream;


  switch(whence) {
  if(whence == SEEK_SET && !offset && !part->fp)
  case SEEK_CUR:
    return CURL_SEEKFUNC_OK;   /* Not open: implicitly already at BOF. */
    if(part->namedfp)
      offset += ftell(part->namedfp);
    break;
  case SEEK_END:
    offset += part->datasize;
    break;
  }

  if(!offset && !part->namedfp)
    return CURL_SEEKFUNC_OK;


  if(mime_open_namedfile(part))
  if(mime_open_file(part))
    return CURL_SEEKFUNC_FAIL;
    return CURL_SEEKFUNC_FAIL;


  return mime_file_seek(part->namedfp, offset, SEEK_SET);
  return fseek(part->fp, (long) offset, whence)?
               CURL_SEEKFUNC_CANTSEEK: CURL_SEEKFUNC_OK;
}
}


static void mime_namedfile_free(void *ptr)
static void mime_file_free(void *ptr)
{
{
  curl_mimepart *part = (curl_mimepart *) ptr;
  curl_mimepart *part = (curl_mimepart *) ptr;


  if(part->namedfp) {
  if(part->fp) {
    fclose(part->namedfp);
    fclose(part->fp);
    part->namedfp = NULL;
    part->fp = NULL;
  }
  }
  Curl_safefree(part->data);
  Curl_safefree(part->data);
  part->data = NULL;
  part->data = NULL;
@@ -912,9 +886,9 @@ static size_t readback_part(curl_mimepart *part,
      case 0:
      case 0:
        mimesetstate(&part->state, MIMESTATE_END, NULL);
        mimesetstate(&part->state, MIMESTATE_END, NULL);
        /* Try sparing open file descriptors. */
        /* Try sparing open file descriptors. */
        if(part->kind == MIMEKIND_NAMEDFILE && part->namedfp) {
        if(part->kind == MIMEKIND_FILE && part->fp) {
          fclose(part->namedfp);
          fclose(part->fp);
          part->namedfp = NULL;
          part->fp = NULL;
        }
        }
        /* FALLTHROUGH */
        /* FALLTHROUGH */
      case CURL_READFUNC_ABORT:
      case CURL_READFUNC_ABORT:
@@ -1050,7 +1024,7 @@ static int mime_part_rewind(curl_mimepart *part)
  if(part->state.state > targetstate) {
  if(part->state.state > targetstate) {
    res = CURL_SEEKFUNC_CANTSEEK;
    res = CURL_SEEKFUNC_CANTSEEK;
    if(part->seekfunc) {
    if(part->seekfunc) {
      res = part->seekfunc(part->arg, part->origin, SEEK_SET);
      res = part->seekfunc(part->arg, (curl_off_t) 0, SEEK_SET);
      switch(res) {
      switch(res) {
      case CURL_SEEKFUNC_OK:
      case CURL_SEEKFUNC_OK:
      case CURL_SEEKFUNC_FAIL:
      case CURL_SEEKFUNC_FAIL:
@@ -1113,10 +1087,9 @@ static void cleanup_part_content(curl_mimepart *part)
  part->readfunc = NULL;
  part->readfunc = NULL;
  part->seekfunc = NULL;
  part->seekfunc = NULL;
  part->freefunc = NULL;
  part->freefunc = NULL;
  part->arg = NULL;
  part->arg = (void *) part;          /* Defaults to part itself. */
  part->data = NULL;
  part->data = NULL;
  part->namedfp = NULL;
  part->fp = NULL;
  part->origin = 0;
  part->datasize = (curl_off_t) 0;    /* No size yet. */
  part->datasize = (curl_off_t) 0;    /* No size yet. */
  part->encoder = NULL;
  part->encoder = NULL;
  cleanup_encoder_state(&part->encstate);
  cleanup_encoder_state(&part->encstate);
@@ -1289,59 +1262,29 @@ CURLcode curl_mime_data(curl_mimepart *part,
    part->readfunc = mime_mem_read;
    part->readfunc = mime_mem_read;
    part->seekfunc = mime_mem_seek;
    part->seekfunc = mime_mem_seek;
    part->freefunc = mime_mem_free;
    part->freefunc = mime_mem_free;
    part->arg = part;
    part->kind = MIMEKIND_DATA;
    part->kind = MIMEKIND_DATA;
  }
  }


  return CURLE_OK;
  return CURLE_OK;
}
}


/* Set mime part content from opened file. */
CURLcode Curl_mime_file(curl_mimepart *part,
                        FILE *fp, int closewhendone)
{
  if(!part || !fp)
    return CURLE_BAD_FUNCTION_ARGUMENT;

  cleanup_part_content(part);

  part->arg = fp;
  part->readfunc = (curl_read_callback) mime_file_read;
  if(closewhendone)
    part->freefunc = (curl_free_callback) fclose;
  part->origin = ftell(fp);
  /* Check if file is seekable and get its size. */
  part->datasize = (curl_off_t) -1;    /* Unknown size. */
  if(!fseek(fp, 0L, SEEK_END)) {
    part->datasize = ftell(fp);
    if(part->datasize >= 0) {
      if(part->datasize < part->origin)
        part->datasize = 0;
      else
        part->datasize -= part->origin;
      part->seekfunc = mime_file_seek;
    }
    fseek(fp, (long) part->origin, SEEK_SET);
  }
  part->kind = MIMEKIND_FILE;
  return CURLE_OK;
}

/* Set mime part content from named local file. */
/* Set mime part content from named local file. */
CURLcode curl_mime_filedata(curl_mimepart *part, const char *filename)
CURLcode curl_mime_filedata(curl_mimepart *part, const char *filename)
{
{
  CURLcode result = CURLE_OK;
  CURLcode result = CURLE_OK;
  struct_stat sbuf;
  char *base;
  char *base;


  if(!part || !filename)
  if(!part)
    return CURLE_BAD_FUNCTION_ARGUMENT;
    return CURLE_BAD_FUNCTION_ARGUMENT;


  cleanup_part_content(part);

  if(filename) {
    struct_stat sbuf;

    if(stat(filename, &sbuf) || access(filename, R_OK))
    if(stat(filename, &sbuf) || access(filename, R_OK))
      result = CURLE_READ_ERROR;
      result = CURLE_READ_ERROR;


  cleanup_part_content(part);

    part->data = strdup(filename);
    part->data = strdup(filename);
    if(!part->data)
    if(!part->data)
      result = CURLE_OUT_OF_MEMORY;
      result = CURLE_OUT_OF_MEMORY;
@@ -1349,17 +1292,17 @@ CURLcode curl_mime_filedata(curl_mimepart *part, const char *filename)
    part->datasize = -1;
    part->datasize = -1;
    if(!result && S_ISREG(sbuf.st_mode)) {
    if(!result && S_ISREG(sbuf.st_mode)) {
      part->datasize = filesize(filename, sbuf);
      part->datasize = filesize(filename, sbuf);
    part->seekfunc = mime_namedfile_seek;
      part->seekfunc = mime_file_seek;
    }
    }


  part->readfunc = mime_namedfile_read;
    part->readfunc = mime_file_read;
  part->freefunc = mime_namedfile_free;
    part->freefunc = mime_file_free;
  part->arg = part;
    part->kind = MIMEKIND_FILE;
  part->kind = MIMEKIND_NAMEDFILE;


    /* As a side effect, set the filename to the current file's base name.
    /* As a side effect, set the filename to the current file's base name.
     It is possible to withdraw this by explicitly calling curl_mime_filename()
       It is possible to withdraw this by explicitly calling
     with a NULL filename argument after the current call. */
       curl_mime_filename() with a NULL filename argument after the current
       call. */
    base = strippath(filename);
    base = strippath(filename);
    if(!base)
    if(!base)
      result = CURLE_OUT_OF_MEMORY;
      result = CURLE_OUT_OF_MEMORY;
@@ -1370,6 +1313,7 @@ CURLcode curl_mime_filedata(curl_mimepart *part, const char *filename)
        result = res;
        result = res;
      free(base);
      free(base);
    }
    }
  }
  return result;
  return result;
}
}


@@ -1670,18 +1614,13 @@ CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
    case MIMEKIND_MULTIPART:
    case MIMEKIND_MULTIPART:
      contenttype = MULTIPART_CONTENTTYPE_DEFAULT;
      contenttype = MULTIPART_CONTENTTYPE_DEFAULT;
      break;
      break;
    case MIMEKIND_NAMEDFILE:
    case MIMEKIND_FILE:
      contenttype = ContentTypeForFilename(part->filename);
      contenttype = ContentTypeForFilename(part->filename);
      if(!contenttype)
      if(!contenttype)
        contenttype = ContentTypeForFilename(part->data);
        contenttype = ContentTypeForFilename(part->data);
      if(!contenttype && part->filename)
      if(!contenttype && part->filename)
        contenttype = FILE_CONTENTTYPE_DEFAULT;
        contenttype = FILE_CONTENTTYPE_DEFAULT;
      break;
      break;
    case MIMEKIND_FILE:
      contenttype = ContentTypeForFilename(part->filename);
      if(!contenttype && part->filename)
        contenttype = FILE_CONTENTTYPE_DEFAULT;
      break;
    default:
    default:
      contenttype = ContentTypeForFilename(part->filename);
      contenttype = ContentTypeForFilename(part->filename);
      break;
      break;
@@ -1839,14 +1778,6 @@ CURLcode curl_mime_data(curl_mimepart *part,
  return CURLE_NOT_BUILT_IN;
  return CURLE_NOT_BUILT_IN;
}
}


CURLcode Curl_mime_file(curl_mimepart *part, FILE *fp, int closewhendone)
{
  (void) part;
  (void) fp;
  (void) closewhendone;
  return CURLE_NOT_BUILT_IN;
}

CURLcode curl_mime_filedata(curl_mimepart *part, const char *filename)
CURLcode curl_mime_filedata(curl_mimepart *part, const char *filename)
{
{
  (void) part;
  (void) part;
+2 −5
Original line number Original line Diff line number Diff line
@@ -34,8 +34,7 @@
enum mimekind {
enum mimekind {
  MIMEKIND_NONE = 0,            /* Part not set. */
  MIMEKIND_NONE = 0,            /* Part not set. */
  MIMEKIND_DATA,                /* Allocated mime data. */
  MIMEKIND_DATA,                /* Allocated mime data. */
  MIMEKIND_NAMEDFILE,           /* Data from named file. */
  MIMEKIND_FILE,                /* Data from file. */
  MIMEKIND_FILE,                /* Data from file pointer. */
  MIMEKIND_CALLBACK,            /* Data from `read' callback. */
  MIMEKIND_CALLBACK,            /* Data from `read' callback. */
  MIMEKIND_MULTIPART,           /* Data is a mime subpart. */
  MIMEKIND_MULTIPART,           /* Data is a mime subpart. */
  MIMEKIND_LAST
  MIMEKIND_LAST
@@ -106,14 +105,13 @@ struct curl_mimepart_s {
  curl_seek_callback seekfunc;     /* Seek function. */
  curl_seek_callback seekfunc;     /* Seek function. */
  curl_free_callback freefunc;     /* Argument free function. */
  curl_free_callback freefunc;     /* Argument free function. */
  void *arg;                       /* Argument to callback functions. */
  void *arg;                       /* Argument to callback functions. */
  FILE *namedfp;                   /* Named file pointer. */
  FILE *fp;                        /* File pointer. */
  struct curl_slist *curlheaders;  /* Part headers. */
  struct curl_slist *curlheaders;  /* Part headers. */
  struct curl_slist *userheaders;  /* Part headers. */
  struct curl_slist *userheaders;  /* Part headers. */
  char *mimetype;                  /* Part mime type. */
  char *mimetype;                  /* Part mime type. */
  char *filename;                  /* Remote file name. */
  char *filename;                  /* Remote file name. */
  char *name;                      /* Data name. */
  char *name;                      /* Data name. */
  size_t namesize;                 /* Data name size. */
  size_t namesize;                 /* Data name size. */
  curl_off_t origin;               /* Origin file offset. */
  curl_off_t datasize;             /* Expected data size. */
  curl_off_t datasize;             /* Expected data size. */
  unsigned int flags;              /* Flags. */
  unsigned int flags;              /* Flags. */
  mime_state state;                /* Current readback state. */
  mime_state state;                /* Current readback state. */
@@ -134,6 +132,5 @@ size_t Curl_mime_read(char *buffer, size_t size, size_t nitems,
                      void *instream);
                      void *instream);
CURLcode Curl_mime_rewind(curl_mimepart *part);
CURLcode Curl_mime_rewind(curl_mimepart *part);
CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...);
CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...);
CURLcode Curl_mime_file(curl_mimepart *part, FILE *fp, int closewhendone);


#endif /* HEADER_CURL_MIME_H */
#endif /* HEADER_CURL_MIME_H */
+4 −3
Original line number Original line Diff line number Diff line
@@ -432,7 +432,7 @@ static CURLcode libcurl_generate_mime(curl_mime *mime, int *mimeno)
      CODE2("part%d = curl_mime_addpart(mime%d);", *mimeno, *mimeno);
      CODE2("part%d = curl_mime_addpart(mime%d);", *mimeno, *mimeno);
      filename = part->filename;
      filename = part->filename;
      switch(part->kind) {
      switch(part->kind) {
      case MIMEKIND_NAMEDFILE:
      case MIMEKIND_FILE:
        Curl_safefree(escaped);
        Curl_safefree(escaped);
        escaped = c_escape(part->data, CURL_ZERO_TERMINATED);
        escaped = c_escape(part->data, CURL_ZERO_TERMINATED);
        if(!escaped)
        if(!escaped)
@@ -483,8 +483,9 @@ static CURLcode libcurl_generate_mime(curl_mime *mime, int *mimeno)
        size = (cp == data + part->datasize)? (curl_off_t) -1: part->datasize;
        size = (cp == data + part->datasize)? (curl_off_t) -1: part->datasize;
        Curl_safefree(escaped);
        Curl_safefree(escaped);
        escaped = c_escape(data, (size_t) part->datasize);
        escaped = c_escape(data, (size_t) part->datasize);
        if(data != part->data)
#ifdef CURL_DOES_CONVERSIONS
        Curl_safefree(data);
        Curl_safefree(data);
#endif
        if(!escaped)
        if(!escaped)
          return CURLE_OUT_OF_MEMORY;
          return CURLE_OUT_OF_MEMORY;
        if(size >= 0)
        if(size >= 0)