Lines Matching +full:mime +full:- +full:db
21 * SPDX-License-Identifier: curl
29 #include "mime.h"
59 #define READ_ERROR ((size_t) -1)
60 #define STOP_FILLING ((size_t) -2)
84 {"quoted-printable", encoder_qp_read, encoder_qp_size},
92 /* Quoted-printable character class table.
94 * We cannot rely on ctype functions since quoted-printable input data
95 * is assumed to be ascii-compatible, even on non-ascii platforms. */
99 #define QP_LF 4 /* Line-feed. */
101 0, 0, 0, 0, 0, 0, 0, 0, /* 00 - 07 */
102 0, QP_SP, QP_LF, 0, 0, QP_CR, 0, 0, /* 08 - 0F */
103 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 17 */
104 0, 0, 0, 0, 0, 0, 0, 0, /* 18 - 1F */
105 QP_SP, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 20 - 27 */
106 QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 28 - 2F */
107 QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 30 - 37 */
108 QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, 0 , QP_OK, QP_OK, /* 38 - 3F */
109 QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 40 - 47 */
110 QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 48 - 4F */
111 QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 50 - 57 */
112 QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 58 - 5F */
113 QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 60 - 67 */
114 QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 68 - 6F */
115 QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 70 - 77 */
116 QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, 0, /* 78 - 7F */
117 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */
118 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */
119 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */
120 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */
121 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */
122 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */
123 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0 - EF */
124 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* F0 - FF */
128 /* Binary --> hexadecimal ASCII table. */
184 switch(stat_buf->st_fab_rfm) { in VmsSpecialSize()
190 return stat_buf->st_size; in VmsSpecialSize()
237 to by path is exactly "//", it is implementation-defined whether '/' or "//"
248 required to be reentrant is not required to be thread-safe.
280 state->state = tok; in mimesetstate()
281 state->ptr = ptr; in mimesetstate()
282 state->offset = 0; in mimesetstate()
291 struct dynbuf db; in escape_string() local
316 if(strategy == MIMESTRATEGY_MAIL || (data && (data->set.mime_formescape))) in escape_string()
319 Curl_dyn_init(&db, CURL_MAX_INPUT_LENGTH); in escape_string()
321 for(result = Curl_dyn_addn(&db, STRCONST("")); !result && *src; src++) { in escape_string()
326 result = Curl_dyn_add(&db, *p + 1); in escape_string()
328 result = Curl_dyn_addn(&db, src, 1); in escape_string()
331 return Curl_dyn_ptr(&db); in escape_string()
339 if(strncasecompare(hdr->data, lbl, len) && hdr->data[len] == ':') in match_header()
340 for(value = hdr->data + len + 1; *value == ' '; value++) in match_header()
351 for(; !value && hdrlist; hdrlist = hdrlist->next) in search_header()
375 p->pos = 0; in cleanup_encoder_state()
376 p->bufbeg = 0; in cleanup_encoder_state()
377 p->bufend = 0; in cleanup_encoder_state()
385 struct mime_encoder_state *st = &part->encstate; in encoder_nop_read()
386 size_t insize = st->bufend - st->bufbeg; in encoder_nop_read()
397 memcpy(buffer, st->buf + st->bufbeg, size); in encoder_nop_read()
399 st->bufbeg += size; in encoder_nop_read()
405 return part->datasize; in encoder_nop_size()
413 struct mime_encoder_state *st = &part->encstate; in encoder_7bit_read()
414 size_t cursize = st->bufend - st->bufbeg; in encoder_7bit_read()
425 *buffer = st->buf[st->bufbeg]; in encoder_7bit_read()
428 st->bufbeg++; in encoder_7bit_read()
439 struct mime_encoder_state *st = &part->encstate; in encoder_base64_read()
444 while(st->bufbeg < st->bufend) { in encoder_base64_read()
446 if(st->pos > MAX_ENCODED_LINE_LENGTH - 4) { in encoder_base64_read()
455 st->pos = 0; in encoder_base64_read()
457 size -= 2; in encoder_base64_read()
466 if(st->bufend - st->bufbeg < 3) in encoder_base64_read()
470 i = st->buf[st->bufbeg++] & 0xFF; in encoder_base64_read()
471 i = (i << 8) | (st->buf[st->bufbeg++] & 0xFF); in encoder_base64_read()
472 i = (i << 8) | (st->buf[st->bufbeg++] & 0xFF); in encoder_base64_read()
478 st->pos += 4; in encoder_base64_read()
479 size -= 4; in encoder_base64_read()
494 if(st->bufend != st->bufbeg) { in encoder_base64_read()
496 if(st->bufend - st->bufbeg == 2) in encoder_base64_read()
497 i = (st->buf[st->bufbeg + 1] & 0xFF) << 8; in encoder_base64_read()
499 i |= (st->buf[st->bufbeg] & 0xFF) << 16; in encoder_base64_read()
502 if(++st->bufbeg != st->bufend) { in encoder_base64_read()
504 st->bufbeg++; in encoder_base64_read()
507 st->pos += 4; in encoder_base64_read()
517 curl_off_t size = part->datasize; in encoder_base64_size()
523 size = 4 * (1 + (size - 1) / 3); in encoder_base64_size()
526 return size + 2 * ((size - 1) / MAX_ENCODED_LINE_LENGTH); in encoder_base64_size()
530 /* Quoted-printable lookahead.
533 * Return -1 if more data needed, 1 if CRLF or end of data, else 0.
537 n += st->bufbeg; in qp_lookahead_eol()
538 if(n >= st->bufend && ateof) in qp_lookahead_eol()
540 if(n + 2 > st->bufend) in qp_lookahead_eol()
541 return ateof? 0: -1; in qp_lookahead_eol()
542 if(qp_class[st->buf[n] & 0xFF] == QP_CR && in qp_lookahead_eol()
543 qp_class[st->buf[n + 1] & 0xFF] == QP_LF) in qp_lookahead_eol()
548 /* Quoted-printable encoder. */
552 struct mime_encoder_state *st = &part->encstate; in encoder_qp_read()
560 character constants that can be interpreted as non-ascii on some in encoder_qp_read()
562 while(st->bufbeg < st->bufend) { in encoder_qp_read()
565 int i = st->buf[st->bufbeg]; in encoder_qp_read()
570 switch(qp_class[st->buf[st->bufbeg] & 0xFF]) { in encoder_qp_read()
576 case -1: /* More input data needed. */ in encoder_qp_read()
587 /* If followed by a line-feed, output the CRLF pair. in encoder_qp_read()
590 case -1: /* Need more data. */ in encoder_qp_read()
609 if(buf[len - 1] != '\x0A') { /* '\n' */ in encoder_qp_read()
610 softlinebreak = st->pos + len > MAX_ENCODED_LINE_LENGTH; in encoder_qp_read()
611 if(!softlinebreak && st->pos + len == MAX_ENCODED_LINE_LENGTH) { in encoder_qp_read()
615 case -1: /* Need more data. */ in encoder_qp_read()
640 size -= len; in encoder_qp_read()
641 st->pos += len; in encoder_qp_read()
642 if(buf[len - 1] == '\x0A') /* '\n' */ in encoder_qp_read()
643 st->pos = 0; in encoder_qp_read()
644 st->bufbeg += consumed; in encoder_qp_read()
653 data size is 0, we return it as unknown (-1). */ in encoder_qp_size()
654 return part->datasize? -1: 0; in encoder_qp_size()
658 /* In-memory data callbacks. */
659 /* Argument is a pointer to the mime part. */
664 size_t sz = curlx_sotouz(part->datasize - part->state.offset); in mime_mem_read()
674 memcpy(buffer, part->data + curlx_sotouz(part->state.offset), sz); in mime_mem_read()
685 offset += part->state.offset; in mime_mem_seek()
688 offset += part->datasize; in mime_mem_seek()
692 if(offset < 0 || offset > part->datasize) in mime_mem_seek()
695 part->state.offset = offset; in mime_mem_seek()
701 Curl_safefree(((curl_mimepart *) ptr)->data); in mime_mem_free()
706 /* Argument is a pointer to the mime part. */
711 if(part->fp) in mime_open_file()
713 part->fp = fopen_read(part->data, "rb"); in mime_open_file()
714 return part->fp? 0: -1; in mime_open_file()
728 return fread(buffer, size, nitems, part->fp); in mime_file_read()
735 if(whence == SEEK_SET && !offset && !part->fp) in mime_file_seek()
741 return fseek(part->fp, (long) offset, whence)? in mime_file_seek()
749 if(part->fp) { in mime_file_free()
750 fclose(part->fp); in mime_file_free()
751 part->fp = NULL; in mime_file_free()
753 Curl_safefree(part->data); in mime_file_free()
758 /* Argument is a pointer to the mime structure. */
767 size_t offset = curlx_sotouz(state->offset); in readback_bytes()
770 sz = numbytes - offset; in readback_bytes()
774 sz = offset - numbytes; in readback_bytes()
778 sz = traillen - sz; in readback_bytes()
785 state->offset += sz; in readback_bytes()
789 /* Read a non-encoded part content. */
795 switch(part->lastreadstatus) { in read_part_content()
800 return part->lastreadstatus; in read_part_content()
806 if(part->datasize != (curl_off_t) -1 && in read_part_content()
807 part->state.offset >= part->datasize) { in read_part_content()
811 switch(part->kind) { in read_part_content()
817 sz = mime_subparts_read(buffer, 1, bufsize, part->arg, hasread); in read_part_content()
820 if(part->fp && feof(part->fp)) in read_part_content()
824 if(part->readfunc) { in read_part_content()
825 if(!(part->flags & MIME_FAST_READ)) { in read_part_content()
830 sz = part->readfunc(buffer, 1, bufsize, part->arg); in read_part_content()
843 part->lastreadstatus = sz; in read_part_content()
846 part->state.offset += sz; in read_part_content()
847 part->lastreadstatus = sz; in read_part_content()
858 struct mime_encoder_state *st = &part->encstate; in read_encoded_part_content()
864 if(st->bufbeg < st->bufend || ateof) { in read_encoded_part_content()
866 sz = part->encoder->encodefunc(buffer, bufsize, ateof, part); in read_encoded_part_content()
878 bufsize -= sz; in read_encoded_part_content()
884 if(st->bufbeg) { in read_encoded_part_content()
885 size_t len = st->bufend - st->bufbeg; in read_encoded_part_content()
888 memmove(st->buf, st->buf + st->bufbeg, len); in read_encoded_part_content()
889 st->bufbeg = 0; in read_encoded_part_content()
890 st->bufend = len; in read_encoded_part_content()
892 if(st->bufend >= sizeof(st->buf)) in read_encoded_part_content()
894 sz = read_part_content(part, st->buf + st->bufend, in read_encoded_part_content()
895 sizeof(st->buf) - st->bufend, hasread); in read_encoded_part_content()
906 st->bufend += sz; in read_encoded_part_content()
914 /* Readback a mime part. */
924 struct curl_slist *hdr = (struct curl_slist *) part->state.ptr; in readback_part()
925 switch(part->state.state) { in readback_part()
927 mimesetstate(&part->state, in readback_part()
928 (part->flags & MIME_BODY_ONLY)? in readback_part()
930 part->curlheaders); in readback_part()
934 mimesetstate(&part->state, MIMESTATE_EOH, NULL); in readback_part()
937 if(match_header(hdr, "Content-Type", 12)) { in readback_part()
938 mimesetstate(&part->state, MIMESTATE_USERHEADERS, hdr->next); in readback_part()
944 mimesetstate(&part->state, MIMESTATE_USERHEADERS, part->userheaders); in readback_part()
946 sz = readback_bytes(&part->state, buffer, bufsize, in readback_part()
947 hdr->data, strlen(hdr->data), STRCONST("\r\n")); in readback_part()
949 mimesetstate(&part->state, part->state.state, hdr->next); in readback_part()
953 sz = readback_bytes(&part->state, buffer, bufsize, STRCONST("\r\n"), in readback_part()
956 mimesetstate(&part->state, MIMESTATE_BODY, NULL); in readback_part()
959 cleanup_encoder_state(&part->encstate); in readback_part()
960 mimesetstate(&part->state, MIMESTATE_CONTENT, NULL); in readback_part()
963 if(part->encoder) in readback_part()
969 mimesetstate(&part->state, MIMESTATE_END, NULL); in readback_part()
971 if(part->kind == MIMEKIND_FILE && part->fp) { in readback_part()
972 fclose(part->fp); in readback_part()
973 part->fp = NULL; in readback_part()
992 bufsize -= sz; in readback_part()
998 /* Readback from mime. Warning: not a read callback function. */
1002 curl_mime *mime = (curl_mime *) instream; in mime_subparts_read() local
1008 curl_mimepart *part = mime->state.ptr; in mime_subparts_read()
1009 switch(mime->state.state) { in mime_subparts_read()
1012 mimesetstate(&mime->state, MIMESTATE_BOUNDARY1, mime->firstpart); in mime_subparts_read()
1016 mime->state.offset += 2; in mime_subparts_read()
1019 sz = readback_bytes(&mime->state, buffer, nitems, STRCONST("\r\n--"), in mime_subparts_read()
1022 mimesetstate(&mime->state, MIMESTATE_BOUNDARY2, part); in mime_subparts_read()
1026 sz = readback_bytes(&mime->state, buffer, nitems, mime->boundary, in mime_subparts_read()
1029 sz = readback_bytes(&mime->state, buffer, nitems, mime->boundary, in mime_subparts_read()
1030 MIME_BOUNDARY_LEN, STRCONST("--\r\n")); in mime_subparts_read()
1032 mimesetstate(&mime->state, MIMESTATE_CONTENT, part); in mime_subparts_read()
1037 mimesetstate(&mime->state, MIMESTATE_END, NULL); in mime_subparts_read()
1048 mimesetstate(&mime->state, MIMESTATE_BOUNDARY1, part->nextpart); in mime_subparts_read()
1055 break; /* other values not used in mime state. */ in mime_subparts_read()
1061 nitems -= sz; in mime_subparts_read()
1072 if(part->flags & MIME_BODY_ONLY) in mime_part_rewind()
1074 cleanup_encoder_state(&part->encstate); in mime_part_rewind()
1075 if(part->state.state > targetstate) { in mime_part_rewind()
1077 if(part->seekfunc) { in mime_part_rewind()
1078 res = part->seekfunc(part->arg, (curl_off_t) 0, SEEK_SET); in mime_part_rewind()
1084 case -1: /* For fseek() error. */ in mime_part_rewind()
1095 mimesetstate(&part->state, targetstate, NULL); in mime_part_rewind()
1097 part->lastreadstatus = 1; /* Successful read status. */ in mime_part_rewind()
1103 curl_mime *mime = (curl_mime *) instream; in mime_subparts_seek() local
1110 if(mime->state.state == MIMESTATE_BEGIN) in mime_subparts_seek()
1113 for(part = mime->firstpart; part; part = part->nextpart) { in mime_subparts_seek()
1120 mimesetstate(&mime->state, MIMESTATE_BEGIN, NULL); in mime_subparts_seek()
1128 if(part->freefunc) in cleanup_part_content()
1129 part->freefunc(part->arg); in cleanup_part_content()
1131 part->readfunc = NULL; in cleanup_part_content()
1132 part->seekfunc = NULL; in cleanup_part_content()
1133 part->freefunc = NULL; in cleanup_part_content()
1134 part->arg = (void *) part; /* Defaults to part itself. */ in cleanup_part_content()
1135 part->data = NULL; in cleanup_part_content()
1136 part->fp = NULL; in cleanup_part_content()
1137 part->datasize = (curl_off_t) 0; /* No size yet. */ in cleanup_part_content()
1138 cleanup_encoder_state(&part->encstate); in cleanup_part_content()
1139 part->kind = MIMEKIND_NONE; in cleanup_part_content()
1140 part->flags &= ~MIME_FAST_READ; in cleanup_part_content()
1141 part->lastreadstatus = 1; /* Successful read status. */ in cleanup_part_content()
1142 part->state.state = MIMESTATE_BEGIN; in cleanup_part_content()
1147 curl_mime *mime = (curl_mime *) ptr; in mime_subparts_free() local
1149 if(mime && mime->parent) { in mime_subparts_free()
1150 mime->parent->freefunc = NULL; /* Be sure we won't be called again. */ in mime_subparts_free()
1151 cleanup_part_content(mime->parent); /* Avoid dangling pointer in part. */ in mime_subparts_free()
1153 curl_mime_free(mime); in mime_subparts_free()
1159 curl_mime *mime = (curl_mime *) ptr; in mime_subparts_unbind() local
1161 if(mime && mime->parent) { in mime_subparts_unbind()
1162 mime->parent->freefunc = NULL; /* Be sure we won't be called again. */ in mime_subparts_unbind()
1163 cleanup_part_content(mime->parent); /* Avoid dangling pointer in part. */ in mime_subparts_unbind()
1164 mime->parent = NULL; in mime_subparts_unbind()
1173 curl_slist_free_all(part->curlheaders); in Curl_mime_cleanpart()
1174 if(part->flags & MIME_USERHEADERS_OWNER) in Curl_mime_cleanpart()
1175 curl_slist_free_all(part->userheaders); in Curl_mime_cleanpart()
1176 Curl_safefree(part->mimetype); in Curl_mime_cleanpart()
1177 Curl_safefree(part->name); in Curl_mime_cleanpart()
1178 Curl_safefree(part->filename); in Curl_mime_cleanpart()
1183 /* Recursively delete a mime handle and its parts. */
1184 void curl_mime_free(curl_mime *mime) in curl_mime_free() argument
1188 if(mime) { in curl_mime_free()
1189 mime_subparts_unbind(mime); /* Be sure it's not referenced anymore. */ in curl_mime_free()
1190 while(mime->firstpart) { in curl_mime_free()
1191 part = mime->firstpart; in curl_mime_free()
1192 mime->firstpart = part->nextpart; in curl_mime_free()
1196 free(mime); in curl_mime_free()
1203 curl_mime *mime; in Curl_mime_duppart() local
1211 switch(src->kind) { in Curl_mime_duppart()
1215 res = curl_mime_data(dst, src->data, (size_t) src->datasize); in Curl_mime_duppart()
1218 res = curl_mime_filedata(dst, src->data); in Curl_mime_duppart()
1224 res = curl_mime_data_cb(dst, src->datasize, src->readfunc, in Curl_mime_duppart()
1225 src->seekfunc, src->freefunc, src->arg); in Curl_mime_duppart()
1230 mime = curl_mime_init(data); in Curl_mime_duppart()
1231 res = mime? curl_mime_subparts(dst, mime): CURLE_OUT_OF_MEMORY; in Curl_mime_duppart()
1234 for(s = ((curl_mime *) src->arg)->firstpart; !res && s; s = s->nextpart) { in Curl_mime_duppart()
1235 d = curl_mime_addpart(mime); in Curl_mime_duppart()
1246 if(!res && src->userheaders) { in Curl_mime_duppart()
1247 struct curl_slist *hdrs = Curl_slist_duplicate(src->userheaders); in Curl_mime_duppart()
1262 dst->encoder = src->encoder; in Curl_mime_duppart()
1263 res = curl_mime_type(dst, src->mimetype); in Curl_mime_duppart()
1266 res = curl_mime_name(dst, src->name); in Curl_mime_duppart()
1268 res = curl_mime_filename(dst, src->filename); in Curl_mime_duppart()
1278 * Mime build functions.
1281 /* Create a mime handle. */
1284 curl_mime *mime; in curl_mime_init() local
1286 mime = (curl_mime *) malloc(sizeof(*mime)); in curl_mime_init()
1288 if(mime) { in curl_mime_init()
1289 mime->parent = NULL; in curl_mime_init()
1290 mime->firstpart = NULL; in curl_mime_init()
1291 mime->lastpart = NULL; in curl_mime_init()
1293 memset(mime->boundary, '-', MIME_BOUNDARY_DASHES); in curl_mime_init()
1295 (unsigned char *) &mime->boundary[MIME_BOUNDARY_DASHES], in curl_mime_init()
1298 free(mime); in curl_mime_init()
1301 mimesetstate(&mime->state, MIMESTATE_BEGIN, NULL); in curl_mime_init()
1304 return mime; in curl_mime_init()
1307 /* Initialize a mime part. */
1311 part->lastreadstatus = 1; /* Successful read status. */ in Curl_mime_initpart()
1312 mimesetstate(&part->state, MIMESTATE_BEGIN, NULL); in Curl_mime_initpart()
1315 /* Create a mime part and append it to a mime handle's part list. */
1316 curl_mimepart *curl_mime_addpart(curl_mime *mime) in curl_mime_addpart() argument
1320 if(!mime) in curl_mime_addpart()
1327 part->parent = mime; in curl_mime_addpart()
1329 if(mime->lastpart) in curl_mime_addpart()
1330 mime->lastpart->nextpart = part; in curl_mime_addpart()
1332 mime->firstpart = part; in curl_mime_addpart()
1334 mime->lastpart = part; in curl_mime_addpart()
1340 /* Set mime part name. */
1346 Curl_safefree(part->name); in curl_mime_name()
1349 part->name = strdup(name); in curl_mime_name()
1350 if(!part->name) in curl_mime_name()
1357 /* Set mime part remote file name. */
1363 Curl_safefree(part->filename); in curl_mime_filename()
1366 part->filename = strdup(filename); in curl_mime_filename()
1367 if(!part->filename) in curl_mime_filename()
1374 /* Set mime part content from memory data. */
1387 part->data = Curl_memdup0(ptr, datasize); in curl_mime_data()
1388 if(!part->data) in curl_mime_data()
1391 part->datasize = datasize; in curl_mime_data()
1392 part->readfunc = mime_mem_read; in curl_mime_data()
1393 part->seekfunc = mime_mem_seek; in curl_mime_data()
1394 part->freefunc = mime_mem_free; in curl_mime_data()
1395 part->flags |= MIME_FAST_READ; in curl_mime_data()
1396 part->kind = MIMEKIND_DATA; in curl_mime_data()
1402 /* Set mime part content from named local file. */
1419 part->data = strdup(filename); in curl_mime_filedata()
1420 if(!part->data) in curl_mime_filedata()
1423 part->datasize = -1; in curl_mime_filedata()
1425 part->datasize = filesize(filename, sbuf); in curl_mime_filedata()
1426 part->seekfunc = mime_file_seek; in curl_mime_filedata()
1429 part->readfunc = mime_file_read; in curl_mime_filedata()
1430 part->freefunc = mime_file_free; in curl_mime_filedata()
1431 part->kind = MIMEKIND_FILE; in curl_mime_filedata()
1450 /* Set mime part type. */
1456 Curl_safefree(part->mimetype); in curl_mime_type()
1459 part->mimetype = strdup(mimetype); in curl_mime_type()
1460 if(!part->mimetype) in curl_mime_type()
1467 /* Set mime data transfer encoder. */
1476 part->encoder = NULL; in curl_mime_encoder()
1481 for(mep = encoders; mep->name; mep++) in curl_mime_encoder()
1482 if(strcasecompare(encoding, mep->name)) { in curl_mime_encoder()
1483 part->encoder = mep; in curl_mime_encoder()
1490 /* Set mime part headers. */
1497 if(part->flags & MIME_USERHEADERS_OWNER) { in curl_mime_headers()
1498 if(part->userheaders != headers) /* Allow setting twice the same list. */ in curl_mime_headers()
1499 curl_slist_free_all(part->userheaders); in curl_mime_headers()
1500 part->flags &= ~MIME_USERHEADERS_OWNER; in curl_mime_headers()
1502 part->userheaders = headers; in curl_mime_headers()
1504 part->flags |= MIME_USERHEADERS_OWNER; in curl_mime_headers()
1508 /* Set mime part content from callback. */
1520 part->readfunc = readfunc; in curl_mime_data_cb()
1521 part->seekfunc = seekfunc; in curl_mime_data_cb()
1522 part->freefunc = freefunc; in curl_mime_data_cb()
1523 part->arg = arg; in curl_mime_data_cb()
1524 part->datasize = datasize; in curl_mime_data_cb()
1525 part->kind = MIMEKIND_CALLBACK; in curl_mime_data_cb()
1531 /* Set mime part content from subparts. */
1541 if(part->kind == MIMEKIND_MULTIPART && part->arg == subparts) in Curl_mime_set_subparts()
1548 if(subparts->parent) in Curl_mime_set_subparts()
1552 root = part->parent; in Curl_mime_set_subparts()
1554 while(root->parent && root->parent->parent) in Curl_mime_set_subparts()
1555 root = root->parent->parent; in Curl_mime_set_subparts()
1562 subparts->parent = part; in Curl_mime_set_subparts()
1564 part->seekfunc = mime_subparts_seek; in Curl_mime_set_subparts()
1565 part->freefunc = take_ownership? mime_subparts_free: mime_subparts_unbind; in Curl_mime_set_subparts()
1566 part->arg = subparts; in Curl_mime_set_subparts()
1567 part->datasize = -1; in Curl_mime_set_subparts()
1568 part->kind = MIMEKIND_MULTIPART; in Curl_mime_set_subparts()
1580 /* Readback from top mime. */
1604 /* Rewind mime stream. */
1617 for(; s; s = s->next) in slist_size()
1619 size += strlen(s->data) + overhead; in slist_size()
1624 static curl_off_t multipart_size(curl_mime *mime) in multipart_size() argument
1630 if(!mime) in multipart_size()
1631 return 0; /* Not present -> empty. */ in multipart_size()
1634 size = boundarysize; /* Final boundary - CRLF after headers. */ in multipart_size()
1636 for(part = mime->firstpart; part; part = part->nextpart) { in multipart_size()
1649 /* Get/compute mime size. */
1654 if(part->kind == MIMEKIND_MULTIPART) in mime_size()
1655 part->datasize = multipart_size(part->arg); in mime_size()
1657 size = part->datasize; in mime_size()
1659 if(part->encoder) in mime_size()
1660 size = part->encoder->sizefunc(part); in mime_size()
1662 if(size >= 0 && !(part->flags & MIME_BODY_ONLY)) { in mime_size()
1664 size += slist_size(part->curlheaders, 2, NULL, 0); in mime_size()
1665 size += slist_size(part->userheaders, 2, STRCONST("Content-Type")); in mime_size()
1698 return Curl_mime_add_header(slp, "Content-Type: %s%s%s", type, in add_content_type()
1706 * If no content type was specified, we scan through a few well-known in Curl_mime_contenttype()
1734 if(len1 >= len2 && strcasecompare(nameend - len2, ctts[i].extension)) in Curl_mime_contenttype()
1763 curl_mime *mime = NULL; in Curl_mime_prepare_headers() local
1770 curl_slist_free_all(part->curlheaders); in Curl_mime_prepare_headers()
1771 part->curlheaders = NULL; in Curl_mime_prepare_headers()
1774 if(part->state.state == MIMESTATE_CURLHEADERS) in Curl_mime_prepare_headers()
1775 mimesetstate(&part->state, MIMESTATE_CURLHEADERS, NULL); in Curl_mime_prepare_headers()
1778 customct = part->mimetype; in Curl_mime_prepare_headers()
1780 customct = search_header(part->userheaders, STRCONST("Content-Type")); in Curl_mime_prepare_headers()
1786 switch(part->kind) { in Curl_mime_prepare_headers()
1791 contenttype = Curl_mime_contenttype(part->filename); in Curl_mime_prepare_headers()
1793 contenttype = Curl_mime_contenttype(part->data); in Curl_mime_prepare_headers()
1794 if(!contenttype && part->filename) in Curl_mime_prepare_headers()
1798 contenttype = Curl_mime_contenttype(part->filename); in Curl_mime_prepare_headers()
1803 if(part->kind == MIMEKIND_MULTIPART) { in Curl_mime_prepare_headers()
1804 mime = (curl_mime *) part->arg; in Curl_mime_prepare_headers()
1805 if(mime) in Curl_mime_prepare_headers()
1806 boundary = mime->boundary; in Curl_mime_prepare_headers()
1810 if(strategy == MIMESTRATEGY_MAIL || !part->filename) in Curl_mime_prepare_headers()
1813 /* Issue content-disposition header only if not already set by caller. */ in Curl_mime_prepare_headers()
1814 if(!search_header(part->userheaders, STRCONST("Content-Disposition"))) { in Curl_mime_prepare_headers()
1816 if(part->filename || part->name || in Curl_mime_prepare_headers()
1820 !part->name && !part->filename) in Curl_mime_prepare_headers()
1826 if(part->name) { in Curl_mime_prepare_headers()
1827 name = escape_string(data, part->name, strategy); in Curl_mime_prepare_headers()
1831 if(!ret && part->filename) { in Curl_mime_prepare_headers()
1832 filename = escape_string(data, part->filename, strategy); in Curl_mime_prepare_headers()
1837 ret = Curl_mime_add_header(&part->curlheaders, in Curl_mime_prepare_headers()
1838 "Content-Disposition: %s%s%s%s%s%s%s", in Curl_mime_prepare_headers()
1853 /* Issue Content-Type header. */ in Curl_mime_prepare_headers()
1855 ret = add_content_type(&part->curlheaders, contenttype, boundary); in Curl_mime_prepare_headers()
1860 /* Content-Transfer-Encoding header. */ in Curl_mime_prepare_headers()
1861 if(!search_header(part->userheaders, in Curl_mime_prepare_headers()
1862 STRCONST("Content-Transfer-Encoding"))) { in Curl_mime_prepare_headers()
1863 if(part->encoder) in Curl_mime_prepare_headers()
1864 cte = part->encoder->name; in Curl_mime_prepare_headers()
1866 part->kind != MIMEKIND_MULTIPART) in Curl_mime_prepare_headers()
1869 ret = Curl_mime_add_header(&part->curlheaders, in Curl_mime_prepare_headers()
1870 "Content-Transfer-Encoding: %s", cte); in Curl_mime_prepare_headers()
1876 /* If we were reading curl-generated headers, restart with new ones (this in Curl_mime_prepare_headers()
1878 if(part->state.state == MIMESTATE_CURLHEADERS) in Curl_mime_prepare_headers()
1879 mimesetstate(&part->state, MIMESTATE_CURLHEADERS, part->curlheaders); in Curl_mime_prepare_headers()
1882 if(part->kind == MIMEKIND_MULTIPART && mime) { in Curl_mime_prepare_headers()
1886 if(content_type_match(contenttype, STRCONST("multipart/form-data"))) in Curl_mime_prepare_headers()
1887 disposition = "form-data"; in Curl_mime_prepare_headers()
1888 for(subpart = mime->firstpart; subpart; subpart = subpart->nextpart) { in Curl_mime_prepare_headers()
1902 if(part->lastreadstatus == CURL_READFUNC_PAUSE) in mime_unpause()
1903 part->lastreadstatus = 1; /* Successful read status. */ in mime_unpause()
1904 if(part->kind == MIMEKIND_MULTIPART) { in mime_unpause()
1905 curl_mime *mime = (curl_mime *) part->arg; in mime_unpause() local
1907 if(mime) { in mime_unpause()
1910 for(subpart = mime->firstpart; subpart; subpart = subpart->nextpart) in mime_unpause()
1930 struct cr_mime_ctx *ctx = reader->ctx; in cr_mime_init()
1932 ctx->total_len = -1; in cr_mime_init()
1933 ctx->read_len = 0; in cr_mime_init()
1943 struct cr_mime_ctx *ctx = reader->ctx; in cr_mime_read()
1947 if(ctx->errored) { in cr_mime_read()
1950 return ctx->error_result; in cr_mime_read()
1952 if(ctx->seen_eos) { in cr_mime_read()
1958 if(ctx->total_len >= 0) { in cr_mime_read()
1959 curl_off_t remain = ctx->total_len - ctx->read_len; in cr_mime_read()
1967 nread = Curl_mime_read(buf, 1, blen, ctx->part); in cr_mime_read()
1972 if((ctx->total_len >= 0) && (ctx->read_len < ctx->total_len)) { in cr_mime_read()
1973 failf(data, "client mime read EOF fail, " in cr_mime_read()
1975 " of needed bytes read", ctx->read_len, ctx->total_len); in cr_mime_read()
1980 ctx->seen_eos = TRUE; in cr_mime_read()
1987 ctx->errored = TRUE; in cr_mime_read()
1988 ctx->error_result = CURLE_ABORTED_BY_CALLBACK; in cr_mime_read()
1993 data->req.keepon |= KEEP_SEND_PAUSE; /* mark socket send as paused */ in cr_mime_read()
2004 ctx->errored = TRUE; in cr_mime_read()
2005 ctx->error_result = CURLE_READ_ERROR; in cr_mime_read()
2008 ctx->read_len += nread; in cr_mime_read()
2009 if(ctx->total_len >= 0) in cr_mime_read()
2010 ctx->seen_eos = (ctx->read_len >= ctx->total_len); in cr_mime_read()
2012 *peos = ctx->seen_eos; in cr_mime_read()
2016 ", read=%"CURL_FORMAT_CURL_OFF_T") -> %d, %zu, %d", in cr_mime_read()
2017 blen, ctx->total_len, ctx->read_len, CURLE_OK, *pnread, *peos)); in cr_mime_read()
2024 struct cr_mime_ctx *ctx = reader->ctx; in cr_mime_needs_rewind()
2026 return ctx->read_len > 0; in cr_mime_needs_rewind()
2032 struct cr_mime_ctx *ctx = reader->ctx; in cr_mime_total_length()
2034 return ctx->total_len; in cr_mime_total_length()
2041 struct cr_mime_ctx *ctx = reader->ctx; in cr_mime_resume_from()
2049 (offset - passed > (curl_off_t)sizeof(scratch)) ? in cr_mime_resume_from()
2051 curlx_sotouz(offset - passed); in cr_mime_resume_from()
2054 nread = Curl_mime_read(scratch, 1, readthisamountnow, ctx->part); in cr_mime_resume_from()
2057 /* this checks for greater-than only to make sure that the in cr_mime_resume_from()
2060 " bytes from the mime post", passed); in cr_mime_resume_from()
2066 if(ctx->total_len > 0) { in cr_mime_resume_from()
2067 ctx->total_len -= offset; in cr_mime_resume_from()
2069 if(ctx->total_len <= 0) { in cr_mime_resume_from()
2070 failf(data, "Mime post already completely uploaded"); in cr_mime_resume_from()
2082 struct cr_mime_ctx *ctx = reader->ctx; in cr_mime_rewind()
2083 CURLcode result = mime_rewind(ctx->part); in cr_mime_rewind()
2085 failf(data, "Cannot rewind mime/post data"); in cr_mime_rewind()
2092 struct cr_mime_ctx *ctx = reader->ctx; in cr_mime_unpause()
2094 mime_unpause(ctx->part); in cr_mime_unpause()
2099 "cr-mime",
2121 ctx = r->ctx; in Curl_creader_set_mime()
2122 ctx->part = part; in Curl_creader_set_mime()
2123 /* Make sure we will read the entire mime structure. */ in Curl_creader_set_mime()
2124 result = mime_rewind(ctx->part); in Curl_creader_set_mime()
2129 ctx->total_len = mime_size(ctx->part); in Curl_creader_set_mime()
2137 /* Mime not compiled in: define stubs for externally-referenced functions. */
2144 void curl_mime_free(curl_mime *mime) in curl_mime_free() argument
2146 (void) mime; in curl_mime_free()
2149 curl_mimepart *curl_mime_addpart(curl_mime *mime) in curl_mime_addpart() argument
2151 (void) mime; in curl_mime_addpart()