30 #if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_SMTP) || \ 31 !defined(CURL_DISABLE_IMAP) 33 #if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME) 52 #define FILE_CONTENTTYPE_DEFAULT "application/octet-stream" 53 #define MULTIPART_CONTENTTYPE_DEFAULT "multipart/mixed" 54 #define DISPOSITION_DEFAULT "attachment" 56 #define READ_ERROR ((size_t) -1) 82 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
93 0, 0, 0, 0, 0, 0, 0, 0,
95 0, 0, 0, 0, 0, 0, 0, 0,
96 0, 0, 0, 0, 0, 0, 0, 0,
109 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
110 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
111 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
112 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
113 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
114 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
115 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
116 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
122 "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x41\x42\x43\x44\x45\x46";
127 #define filesize(name, stat_data) (stat_data.st_size) 128 #define fopen_read fopen 157 while(ret_stat > 0) {
158 ret_stat =
fread(buffer, 1,
sizeof(buffer), file);
176 switch(stat_buf->st_fab_rfm) {
179 return VmsRealFileSize(
name, stat_buf);
182 return stat_buf->st_size;
186 #define filesize(name, stat_data) VmsSpecialSize(name, &stat_data) 196 static FILE * vmsfopenread(
const char *file,
const char *mode)
201 result =
stat(file, &statbuf);
203 switch(statbuf.st_fab_rfm) {
214 #define fopen_read vmsfopenread 218 #ifndef HAVE_BASENAME 250 s1 = strrchr(path,
'/');
251 s2 = strrchr(path,
'\\');
254 path = (s1 > s2? s1 : s2) + 1;
264 #define basename(x) Curl_basename((x)) 280 size_t bytecount = 0;
284 for(i = 0; src[
i]; i++)
285 if(src[i] ==
'"' || src[i] ==
'\\')
289 dst =
malloc(bytecount + 1);
293 for(i = 0; *src; src++) {
294 if(*src ==
'"' || *src ==
'\\')
309 for(value = hdr->
data + len + 1; *value ==
' '; value++)
317 size_t len = strlen(hdr);
320 for(; !value && hdrlist; hdrlist = hdrlist->
next)
330 filename =
strdup(fullfile);
385 for(cursize = 0; cursize <
size; cursize++) {
419 if(size < 4 || st->bufend - st->
bufbeg < 3)
424 i = (i << 8) | (st->
buf[st->
bufbeg++] & 0xFF);
425 i = (i << 8) | (st->
buf[st->
bufbeg++] & 0xFF);
426 *ptr++ =
base64[(i >> 18) & 0x3F];
427 *ptr++ =
base64[(i >> 12) & 0x3F];
428 *ptr++ =
base64[(i >> 6) & 0x3F];
429 *ptr++ =
base64[i & 0x3F];
436 if(ateof && size >= 4) {
438 ptr[2] = ptr[3] =
'=';
442 i = (st->
buf[st->
bufbeg + 1] & 0xFF) << 8;
446 ptr[0] =
base64[(i >> 18) & 0x3F];
447 ptr[1] =
base64[(i >> 12) & 0x3F];
449 ptr[2] =
base64[(i >> 6) & 0x3F];
458 #ifdef CURL_DOES_CONVERSIONS 460 if(part->
easy && cursize) {
478 size = 4 * (1 + (size - 1) / 3);
493 if(n >= st->
bufend && ateof)
525 buf[1] =
aschex[(i >> 4) & 0xF];
567 if(buf[len - 1] !=
'\x0A') {
569 if(!softlinebreak && st->
pos + len == MAX_ENCODED_LINE_LENGTH) {
582 strcpy(buf,
"\x3D\x0D\x0A");
598 if(buf[len - 1] ==
'\x0A')
647 if(offset < 0 || offset > part->
datasize)
669 return part->
fp? 0: -1;
680 return fread(buffer, size, nitems, part->
fp);
687 if(whence == SEEK_SET && !offset && !part->
fp)
693 return fseek(part->
fp, (
long) offset, whence)?
715 char *
buffer,
size_t bufsize,
716 const char *bytes,
size_t numbytes,
721 sz = numbytes - state->
offset;
723 if(numbytes > state->
offset) {
724 sz = numbytes - state->
offset;
728 size_t tsz = strlen(trail);
730 sz = state->
offset - numbytes;
740 memcpy(buffer, bytes, sz);
747 char *
buffer,
size_t bufsize)
752 sz = part->
readfunc(buffer, 1, bufsize, part->
arg);
758 char *
buffer,
size_t bufsize)
777 return cursize? cursize: sz;
806 return cursize? cursize: sz;
818 char *
buffer,
size_t bufsize)
823 #ifdef CURL_DOES_CONVERSIONS 847 case MIMESTATE_CURLHEADERS:
852 hdr->
data, strlen(hdr->
data),
"\r\n");
863 #ifdef CURL_DOES_CONVERSIONS 864 if(part->
easy && convbuf < buffer) {
892 return cursize? cursize: sz;
907 #ifdef CURL_DOES_CONVERSIONS 908 if(part->
easy && convbuf < buffer &&
928 #ifdef CURL_DOES_CONVERSIONS 940 #ifdef CURL_DOES_CONVERSIONS 956 strlen(mime->
boundary), part?
"\r\n":
"--\r\n");
958 #ifdef CURL_DOES_CONVERSIONS 959 if(mime->
easy && convbuf < buffer) {
980 return cursize? cursize: sz;
982 #ifdef CURL_DOES_CONVERSIONS 1001 #ifdef CURL_DOES_CONVERSIONS 1002 if(mime->
easy && convbuf < buffer &&
1054 if(whence != SEEK_SET || offset)
1088 part->
arg = (
void *) part;
1163 memset((
char *) part, 0,
sizeof *part);
1231 const char *
data,
size_t datasize)
1240 datasize = strlen(data);
1250 part->
data[datasize] =
'\0';
1275 if(
stat(filename, &sbuf) || access(filename, R_OK))
1283 if(!result && S_ISREG(sbuf.st_mode)) {
1342 for(mep = encoders; mep->
name; mep++)
1353 struct curl_slist *headers,
int take_ownership)
1363 if(headers && take_ownership)
1417 part->
arg = subparts;
1445 size_t overhead,
const char *
skip)
1448 size_t skiplen = skip? strlen(skip): 0;
1450 for(; s; s = s->
next)
1452 size += strlen(s->
data) + overhead;
1461 size_t boundarysize;
1467 boundarysize = 4 + strlen(mime->
boundary) + 2;
1468 size = boundarysize;
1477 size += boundarysize + sz;
1530 const char *type,
const char *boundary)
1533 boundary?
"; boundary=":
"",
1534 boundary? boundary:
"");
1546 struct ContentType {
1550 static const struct ContentType ctts[] = {
1551 {
".gif",
"image/gif"},
1552 {
".jpg",
"image/jpeg"},
1553 {
".jpeg",
"image/jpeg"},
1554 {
".png",
"image/png"},
1555 {
".svg",
"image/svg+xml"},
1556 {
".txt",
"text/plain"},
1557 {
".htm",
"text/html"},
1558 {
".html",
"text/html"},
1559 {
".pdf",
"application/pdf"},
1560 {
".xml",
"application/xml"}
1564 size_t len1 = strlen(filename);
1565 const char *nameend = filename + len1;
1567 for(i = 0; i <
sizeof ctts /
sizeof ctts[0]; i++) {
1568 size_t len2 = strlen(ctts[i].
extension);
1570 if(len1 >= len2 &&
strcasecompare(nameend - len2, ctts[i].extension))
1571 return ctts[
i].type;
1578 const char *contenttype,
1579 const char *disposition,
1583 const char *boundary = NULL;
1585 const char *cte = NULL;
1603 switch(part->
kind) {
1625 else if(contenttype &&
strcasecompare(contenttype,
"text/plain"))
1635 if(disposition &&
curl_strequal(disposition,
"attachment") &&
1654 "Content-Disposition: %s%s%s%s%s%s%s",
1656 name?
"; name=\"":
"",
1659 filename?
"; filename=\"":
"",
1660 filename? filename:
"",
1661 filename?
"\"":
"");
1685 "Content-Transfer-Encoding: %s", cte);
1702 disposition =
"form-data";
1761 const char *
data,
size_t datasize)
1800 struct curl_slist *headers,
int take_ownership)
1804 (void) take_ownership;
1820 const char *contenttype,
1821 const char *disposition,
#define MIME_RAND_BOUNDARY_CHARS
static const char * ContentTypeForFilename(const char *filename)
static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems, void *instream)
#define filesize(name, stat_data)
static size_t mime_file_read(char *buffer, size_t size, size_t nitems, void *instream)
static int mime_file_seek(void *instream, curl_off_t offset, int whence)
int stat(const char *path, struct stat *buffer)
struct curl_slist * Curl_slist_append_nodup(struct curl_slist *list, char *data)
#define CURL_SEEKFUNC_CANTSEEK
static void cleanup_encoder_state(mime_encoder_state *p)
static size_t read_part_content(curl_mimepart *part, char *buffer, size_t bufsize)
mime_encoder_state encstate
void Curl_mime_cleanpart(curl_mimepart *part)
static int mime_open_file(curl_mimepart *part)
static size_t mime_mem_read(char *buffer, size_t size, size_t nitems, void *instream)
static size_t encoder_7bit_read(char *buffer, size_t size, bool ateof, curl_mimepart *part)
static size_t encoder_base64_read(char *buffer, size_t size, bool ateof, curl_mimepart *part)
size_t(* encodefunc)(char *buffer, size_t size, bool ateof, curl_mimepart *part)
UNITTEST_START char * ptr
#define CURL_SEEKFUNC_FAIL
CURLcode curl_mime_name(curl_mimepart *part, const char *name)
CURLcode Curl_mime_prepare_headers(curl_mimepart *part, const char *contenttype, const char *disposition, enum mimestrategy strategy)
static int mime_mem_seek(void *instream, curl_off_t offset, int whence)
#define strcasecompare(a, b)
static void mime_file_free(void *ptr)
static void mime_subparts_free(void *ptr)
UNITTEST_START int result
curl_read_callback readfunc
int(* curl_seek_callback)(void *instream, curl_off_t offset, int origin)
curl_off_t(* sizefunc)(curl_mimepart *part)
CURLcode curl_mime_encoder(curl_mimepart *part, const char *encoding)
static void mime_mem_free(void *ptr)
static curl_off_t encoder_nop_size(curl_mimepart *part)
static size_t encoder_nop_read(char *buffer, size_t size, bool ateof, curl_mimepart *part)
memcpy(filename, filename1, strlen(filename1))
CURLcode curl_mime_filedata(curl_mimepart *part, const char *filename)
size_t Curl_mime_read(char *buffer, size_t size, size_t nitems, void *instream)
CURLcode curl_mime_data(curl_mimepart *part, const char *data, size_t datasize)
static int mime_part_rewind(curl_mimepart *part)
static void mimesetstate(mime_state *state, enum mimestate tok, void *ptr)
curl_easy_setopt expects a curl_off_t argument for this option curl_easy_setopt expects a curl_write_callback argument for this option curl_easy_setopt expects a curl_ioctl_callback argument for this option curl_easy_setopt expects a curl_opensocket_callback argument for this option curl_easy_setopt expects a curl_debug_callback argument for this option curl_easy_setopt expects a curl_conv_callback argument for this option curl_easy_setopt expects a private data pointer as argument for this option curl_easy_setopt expects a FILE *argument for this option curl_easy_setopt expects a struct curl_httppost *argument for this option curl_easy_setopt expects a struct curl_slist *argument for this option curl_easy_getinfo expects a pointer to char *for this info curl_easy_getinfo expects a pointer to double for this info curl_easy_getinfo expects a pointer to struct curl_tlssessioninfo *for this info curl_easy_getinfo expects a pointer to curl_socket_t for this info size_t
static const unsigned char qp_class[]
CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt,...)
static const mime_encoder encoders[]
CURLcode Curl_mime_rewind(curl_mimepart *part)
static int qp_lookahead_eol(mime_encoder_state *st, int ateof, size_t n)
static const char aschex[]
#define MIME_USERHEADERS_OWNER
CURLcode Curl_rand_hex(struct Curl_easy *data, unsigned char *rnd, size_t num)
static size_t readback_part(curl_mimepart *part, char *buffer, size_t bufsize)
static curl_off_t encoder_base64_size(curl_mimepart *part)
static char * match_header(struct curl_slist *hdr, const char *lbl, size_t len)
static char * strippath(const char *fullfile)
#define strncasecompare(a, b, c)
static size_t read_encoded_part_content(curl_mimepart *part, char *buffer, size_t bufsize)
static size_t encoder_qp_read(char *buffer, size_t size, bool ateof, curl_mimepart *part)
char buf[ENCODING_BUFFER_SIZE]
#define Curl_convert_to_network(a, b, c)
static char * escape_string(const char *src)
curl_free_callback freefunc
curl_seek_callback seekfunc
static curl_off_t encoder_qp_size(curl_mimepart *part)
CURL_TYPEOF_CURL_OFF_T curl_off_t
size_t(* curl_read_callback)(char *buffer, size_t size, size_t nitems, void *instream)
CURL_EXTERN int curl_strequal(const char *s1, const char *s2)
curl_mimepart * curl_mime_addpart(curl_mime *mime)
curl_mimepart * firstpart
#define Curl_safefree(ptr)
#define MULTIPART_CONTENTTYPE_DEFAULT
CURLcode curl_mime_subparts(curl_mimepart *part, curl_mime *subparts)
curl_off_t Curl_mime_size(curl_mimepart *part)
#define CURL_READFUNC_ABORT
#define MAX_ENCODED_LINE_LENGTH
CURLcode curl_mime_filename(curl_mimepart *part, const char *filename)
static char * Curl_basename(char *path)
CURLcode curl_mime_data_cb(curl_mimepart *part, curl_off_t datasize, curl_read_callback readfunc, curl_seek_callback seekfunc, curl_free_callback freefunc, void *arg)
CURLcode curl_mime_type(curl_mimepart *part, const char *mimetype)
void Curl_mime_initpart(curl_mimepart *part, struct Curl_easy *easy)
static size_t slist_size(struct curl_slist *s, size_t overhead, const char *skip)
static char * search_header(struct curl_slist *hdrlist, const char *hdr)
static int mime_subparts_seek(void *instream, curl_off_t offset, int whence)
curl_mime * curl_mime_init(struct Curl_easy *easy)
#define CURL_READFUNC_PAUSE
UNITTEST_START int * value
struct curl_slist * curlheaders
#define DISPOSITION_DEFAULT
#define CURL_ZERO_TERMINATED
struct curl_slist * userheaders
static void skip(const char **date)
#define FILE_CONTENTTYPE_DEFAULT
static CURL * easy[MAX_EASY_HANDLES]
static void cleanup_part_content(curl_mimepart *part)
static size_t readback_bytes(mime_state *state, char *buffer, size_t bufsize, const char *bytes, size_t numbytes, const char *trail)
static size_t readfunc(void *ptr, size_t size, size_t nmemb, void *stream)
CURL_EXTERN char * curl_mvaprintf(const char *format, va_list args)
void(* curl_free_callback)(void *ptr)
CURL_EXTERN void curl_slist_free_all(struct curl_slist *)
const mime_encoder * encoder
static CURLcode add_content_type(struct curl_slist **slp, const char *type, const char *boundary)
static curl_off_t multipart_size(curl_mime *mime)
CURLcode curl_mime_headers(curl_mimepart *part, struct curl_slist *headers, int take_ownership)
void curl_mime_free(curl_mime *mime)