mirror of
https://github.com/moparisthebest/curl
synced 2025-03-11 07:39:50 -04:00
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.
This commit is contained in:
parent
d1da545a68
commit
c96d96bc5f
@ -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))
|
||||||
|
199
lib/mime.c
199
lib/mime.c
@ -662,76 +662,50 @@ static void mime_mem_free(void *ptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Open file callbacks. */
|
/* Named file callbacks. */
|
||||||
/* Argument is the FILE pointer. */
|
/* Argument is a pointer to the mime part. */
|
||||||
|
static int mime_open_file(curl_mimepart * part)
|
||||||
|
{
|
||||||
|
/* Open a MIMEKIND_FILE part. */
|
||||||
|
|
||||||
|
if(part->fp)
|
||||||
|
return 0;
|
||||||
|
part->fp = fopen_read(part->data, "rb");
|
||||||
|
return part->fp? 0: -1;
|
||||||
|
}
|
||||||
|
|
||||||
static size_t mime_file_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)
|
||||||
{
|
{
|
||||||
return (size_t) fread(buffer, size, nitems, instream);
|
curl_mimepart *part = (curl_mimepart *) instream;
|
||||||
|
|
||||||
|
if(mime_open_file(part))
|
||||||
|
return READ_ERROR;
|
||||||
|
|
||||||
|
return fread(buffer, size, nitems, part->fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mime_file_seek(void *instream, curl_off_t offset, int whence)
|
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. */
|
|
||||||
/* Argument is a pointer to the mime part. */
|
|
||||||
static int mime_open_namedfile(curl_mimepart * part)
|
|
||||||
{
|
|
||||||
/* Open a MIMEKIND_NAMEDFILE part. */
|
|
||||||
|
|
||||||
if(part->namedfp)
|
|
||||||
return 0;
|
|
||||||
part->namedfp = fopen_read(part->data, "rb");
|
|
||||||
return part->namedfp? 0: -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t mime_namedfile_read(char *buffer, size_t size, size_t nitems,
|
|
||||||
void *instream)
|
|
||||||
{
|
{
|
||||||
curl_mimepart *part = (curl_mimepart *) instream;
|
curl_mimepart *part = (curl_mimepart *) instream;
|
||||||
|
|
||||||
if(mime_open_namedfile(part))
|
if(whence == SEEK_SET && !offset && !part->fp)
|
||||||
return READ_ERROR;
|
return CURL_SEEKFUNC_OK; /* Not open: implicitly already at BOF. */
|
||||||
|
|
||||||
return mime_file_read(buffer, size, nitems, part->namedfp);
|
if(mime_open_file(part))
|
||||||
}
|
|
||||||
|
|
||||||
static int mime_namedfile_seek(void *instream, curl_off_t offset, int whence)
|
|
||||||
{
|
|
||||||
curl_mimepart *part = (curl_mimepart *) instream;
|
|
||||||
|
|
||||||
switch(whence) {
|
|
||||||
case SEEK_CUR:
|
|
||||||
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))
|
|
||||||
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,86 +1262,57 @@ 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;
|
||||||
|
|
||||||
if(stat(filename, &sbuf) || access(filename, R_OK))
|
|
||||||
result = CURLE_READ_ERROR;
|
|
||||||
|
|
||||||
cleanup_part_content(part);
|
cleanup_part_content(part);
|
||||||
|
|
||||||
part->data = strdup(filename);
|
if(filename) {
|
||||||
if(!part->data)
|
struct_stat sbuf;
|
||||||
result = CURLE_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
part->datasize = -1;
|
if(stat(filename, &sbuf) || access(filename, R_OK))
|
||||||
if(!result && S_ISREG(sbuf.st_mode)) {
|
result = CURLE_READ_ERROR;
|
||||||
part->datasize = filesize(filename, sbuf);
|
|
||||||
part->seekfunc = mime_namedfile_seek;
|
|
||||||
}
|
|
||||||
|
|
||||||
part->readfunc = mime_namedfile_read;
|
part->data = strdup(filename);
|
||||||
part->freefunc = mime_namedfile_free;
|
if(!part->data)
|
||||||
part->arg = part;
|
result = CURLE_OUT_OF_MEMORY;
|
||||||
part->kind = MIMEKIND_NAMEDFILE;
|
|
||||||
|
|
||||||
/* As a side effect, set the filename to the current file's base name.
|
part->datasize = -1;
|
||||||
It is possible to withdraw this by explicitly calling curl_mime_filename()
|
if(!result && S_ISREG(sbuf.st_mode)) {
|
||||||
with a NULL filename argument after the current call. */
|
part->datasize = filesize(filename, sbuf);
|
||||||
base = strippath(filename);
|
part->seekfunc = mime_file_seek;
|
||||||
if(!base)
|
}
|
||||||
result = CURLE_OUT_OF_MEMORY;
|
|
||||||
else {
|
|
||||||
CURLcode res = curl_mime_filename(part, base);
|
|
||||||
|
|
||||||
if(res)
|
part->readfunc = mime_file_read;
|
||||||
result = res;
|
part->freefunc = mime_file_free;
|
||||||
free(base);
|
part->kind = MIMEKIND_FILE;
|
||||||
|
|
||||||
|
/* 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() with a NULL filename argument after the current
|
||||||
|
call. */
|
||||||
|
base = strippath(filename);
|
||||||
|
if(!base)
|
||||||
|
result = CURLE_OUT_OF_MEMORY;
|
||||||
|
else {
|
||||||
|
CURLcode res = curl_mime_filename(part, base);
|
||||||
|
|
||||||
|
if(res)
|
||||||
|
result = res;
|
||||||
|
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;
|
||||||
|
@ -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 */
|
||||||
|
@ -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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user