1/*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 9 * 10 * This software is licensed as described in the file COPYING, which 11 * you should have received as part of this distribution. The terms 12 * are also available at https://curl.se/docs/copyright.html. 13 * 14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15 * copies of the Software, and permit persons to whom the Software is 16 * furnished to do so, under the terms of the COPYING file. 17 * 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 * KIND, either express or implied. 20 * 21 * SPDX-License-Identifier: curl 22 * 23 ***************************************************************************/ 24 25#include "curl_setup.h" 26 27#include <curl/curl.h> 28 29#include "mime.h" 30#include "warnless.h" 31#include "urldata.h" 32#include "sendf.h" 33#include "strdup.h" 34 35#if !defined(CURL_DISABLE_MIME) && (!defined(CURL_DISABLE_HTTP) || \ 36 !defined(CURL_DISABLE_SMTP) || \ 37 !defined(CURL_DISABLE_IMAP)) 38 39#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME) 40#include <libgen.h> 41#endif 42 43#include "rand.h" 44#include "slist.h" 45#include "strcase.h" 46#include "dynbuf.h" 47/* The last 3 #include files should be in this order */ 48#include "curl_printf.h" 49#include "curl_memory.h" 50#include "memdebug.h" 51 52#ifdef _WIN32 53# ifndef R_OK 54# define R_OK 4 55# endif 56#endif 57 58 59#define READ_ERROR ((size_t) -1) 60#define STOP_FILLING ((size_t) -2) 61 62static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems, 63 void *instream, bool *hasread); 64 65/* Encoders. */ 66static size_t encoder_nop_read(char *buffer, size_t size, bool ateof, 67 curl_mimepart *part); 68static curl_off_t encoder_nop_size(curl_mimepart *part); 69static size_t encoder_7bit_read(char *buffer, size_t size, bool ateof, 70 curl_mimepart *part); 71static size_t encoder_base64_read(char *buffer, size_t size, bool ateof, 72 curl_mimepart *part); 73static curl_off_t encoder_base64_size(curl_mimepart *part); 74static size_t encoder_qp_read(char *buffer, size_t size, bool ateof, 75 curl_mimepart *part); 76static curl_off_t encoder_qp_size(curl_mimepart *part); 77 78static const struct mime_encoder encoders[] = { 79 {"binary", encoder_nop_read, encoder_nop_size}, 80 {"8bit", encoder_nop_read, encoder_nop_size}, 81 {"7bit", encoder_7bit_read, encoder_nop_size}, 82 {"base64", encoder_base64_read, encoder_base64_size}, 83 {"quoted-printable", encoder_qp_read, encoder_qp_size}, 84 {ZERO_NULL, ZERO_NULL, ZERO_NULL} 85}; 86 87/* Base64 encoding table */ 88static const char base64enc[] = 89 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 90 91/* Quoted-printable character class table. 92 * 93 * We cannot rely on ctype functions since quoted-printable input data 94 * is assumed to be ascii-compatible, even on non-ascii platforms. */ 95#define QP_OK 1 /* Can be represented by itself. */ 96#define QP_SP 2 /* Space or tab. */ 97#define QP_CR 3 /* Carriage return. */ 98#define QP_LF 4 /* Line-feed. */ 99static const unsigned char qp_class[] = { 100 0, 0, 0, 0, 0, 0, 0, 0, /* 00 - 07 */ 101 0, QP_SP, QP_LF, 0, 0, QP_CR, 0, 0, /* 08 - 0F */ 102 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 17 */ 103 0, 0, 0, 0, 0, 0, 0, 0, /* 18 - 1F */ 104 QP_SP, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 20 - 27 */ 105 QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 28 - 2F */ 106 QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 30 - 37 */ 107 QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, 0 , QP_OK, QP_OK, /* 38 - 3F */ 108 QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 40 - 47 */ 109 QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 48 - 4F */ 110 QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 50 - 57 */ 111 QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 58 - 5F */ 112 QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 60 - 67 */ 113 QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 68 - 6F */ 114 QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 70 - 77 */ 115 QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, 0, /* 78 - 7F */ 116 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */ 117 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */ 118 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */ 119 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */ 120 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */ 121 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */ 122 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0 - EF */ 123 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* F0 - FF */ 124}; 125 126 127/* Binary --> hexadecimal ASCII table. */ 128static const char aschex[] = 129 "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x41\x42\x43\x44\x45\x46"; 130 131 132 133#ifndef __VMS 134#define filesize(name, stat_data) (stat_data.st_size) 135#define fopen_read fopen 136 137#else 138 139#include <fabdef.h> 140/* 141 * get_vms_file_size does what it takes to get the real size of the file 142 * 143 * For fixed files, find out the size of the EOF block and adjust. 144 * 145 * For all others, have to read the entire file in, discarding the contents. 146 * Most posted text files will be small, and binary files like zlib archives 147 * and CD/DVD images should be either a STREAM_LF format or a fixed format. 148 * 149 */ 150curl_off_t VmsRealFileSize(const char *name, 151 const struct_stat *stat_buf) 152{ 153 char buffer[8192]; 154 curl_off_t count; 155 int ret_stat; 156 FILE * file; 157 158 file = fopen(name, FOPEN_READTEXT); /* VMS */ 159 if(!file) 160 return 0; 161 162 count = 0; 163 ret_stat = 1; 164 while(ret_stat > 0) { 165 ret_stat = fread(buffer, 1, sizeof(buffer), file); 166 if(ret_stat) 167 count += ret_stat; 168 } 169 fclose(file); 170 171 return count; 172} 173 174/* 175 * 176 * VmsSpecialSize checks to see if the stat st_size can be trusted and 177 * if not to call a routine to get the correct size. 178 * 179 */ 180static curl_off_t VmsSpecialSize(const char *name, 181 const struct_stat *stat_buf) 182{ 183 switch(stat_buf->st_fab_rfm) { 184 case FAB$C_VAR: 185 case FAB$C_VFC: 186 return VmsRealFileSize(name, stat_buf); 187 break; 188 default: 189 return stat_buf->st_size; 190 } 191} 192 193#define filesize(name, stat_data) VmsSpecialSize(name, &stat_data) 194 195/* 196 * vmsfopenread 197 * 198 * For upload to work as expected on VMS, different optional 199 * parameters must be added to the fopen command based on 200 * record format of the file. 201 * 202 */ 203static FILE * vmsfopenread(const char *file, const char *mode) 204{ 205 struct_stat statbuf; 206 int result; 207 208 result = stat(file, &statbuf); 209 210 switch(statbuf.st_fab_rfm) { 211 case FAB$C_VAR: 212 case FAB$C_VFC: 213 case FAB$C_STMCR: 214 return fopen(file, FOPEN_READTEXT); /* VMS */ 215 break; 216 default: 217 return fopen(file, FOPEN_READTEXT, "rfm=stmlf", "ctx=stm"); 218 } 219} 220 221#define fopen_read vmsfopenread 222#endif 223 224 225#ifndef HAVE_BASENAME 226/* 227 (Quote from The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004 228 Edition) 229 230 The basename() function shall take the pathname pointed to by path and 231 return a pointer to the final component of the pathname, deleting any 232 trailing '/' characters. 233 234 If the string pointed to by path consists entirely of the '/' character, 235 basename() shall return a pointer to the string "/". If the string pointed 236 to by path is exactly "//", it is implementation-defined whether '/' or "//" 237 is returned. 238 239 If path is a null pointer or points to an empty string, basename() shall 240 return a pointer to the string ".". 241 242 The basename() function may modify the string pointed to by path, and may 243 return a pointer to static storage that may then be overwritten by a 244 subsequent call to basename(). 245 246 The basename() function need not be reentrant. A function that is not 247 required to be reentrant is not required to be thread-safe. 248 249*/ 250static char *Curl_basename(char *path) 251{ 252 /* Ignore all the details above for now and make a quick and simple 253 implementation here */ 254 char *s1; 255 char *s2; 256 257 s1 = strrchr(path, '/'); 258 s2 = strrchr(path, '\\'); 259 260 if(s1 && s2) { 261 path = (s1 > s2? s1 : s2) + 1; 262 } 263 else if(s1) 264 path = s1 + 1; 265 else if(s2) 266 path = s2 + 1; 267 268 return path; 269} 270 271#define basename(x) Curl_basename((x)) 272#endif 273 274 275/* Set readback state. */ 276static void mimesetstate(struct mime_state *state, 277 enum mimestate tok, void *ptr) 278{ 279 state->state = tok; 280 state->ptr = ptr; 281 state->offset = 0; 282} 283 284 285/* Escape header string into allocated memory. */ 286static char *escape_string(struct Curl_easy *data, 287 const char *src, enum mimestrategy strategy) 288{ 289 CURLcode result; 290 struct dynbuf db; 291 const char * const *table; 292 const char * const *p; 293 /* replace first character by rest of string. */ 294 static const char * const mimetable[] = { 295 "\\\\\\", 296 "\"\\\"", 297 NULL 298 }; 299 /* WHATWG HTML living standard 4.10.21.8 2 specifies: 300 For field names and filenames for file fields, the result of the 301 encoding in the previous bullet point must be escaped by replacing 302 any 0x0A (LF) bytes with the byte sequence `%0A`, 0x0D (CR) with `%0D` 303 and 0x22 (") with `%22`. 304 The user agent must not perform any other escapes. */ 305 static const char * const formtable[] = { 306 "\"%22", 307 "\r%0D", 308 "\n%0A", 309 NULL 310 }; 311 312 table = formtable; 313 /* data can be NULL when this function is called indirectly from 314 curl_formget(). */ 315 if(strategy == MIMESTRATEGY_MAIL || (data && (data->set.mime_formescape))) 316 table = mimetable; 317 318 Curl_dyn_init(&db, CURL_MAX_INPUT_LENGTH); 319 320 for(result = Curl_dyn_addn(&db, STRCONST("")); !result && *src; src++) { 321 for(p = table; *p && **p != *src; p++) 322 ; 323 324 if(*p) 325 result = Curl_dyn_add(&db, *p + 1); 326 else 327 result = Curl_dyn_addn(&db, src, 1); 328 } 329 330 return Curl_dyn_ptr(&db); 331} 332 333/* Check if header matches. */ 334static char *match_header(struct curl_slist *hdr, const char *lbl, size_t len) 335{ 336 char *value = NULL; 337 338 if(strncasecompare(hdr->data, lbl, len) && hdr->data[len] == ':') 339 for(value = hdr->data + len + 1; *value == ' '; value++) 340 ; 341 return value; 342} 343 344/* Get a header from an slist. */ 345static char *search_header(struct curl_slist *hdrlist, 346 const char *hdr, size_t len) 347{ 348 char *value = NULL; 349 350 for(; !value && hdrlist; hdrlist = hdrlist->next) 351 value = match_header(hdrlist, hdr, len); 352 353 return value; 354} 355 356static char *strippath(const char *fullfile) 357{ 358 char *filename; 359 char *base; 360 filename = strdup(fullfile); /* duplicate since basename() may ruin the 361 buffer it works on */ 362 if(!filename) 363 return NULL; 364 base = strdup(basename(filename)); 365 366 free(filename); /* free temporary buffer */ 367 368 return base; /* returns an allocated string or NULL ! */ 369} 370 371/* Initialize data encoder state. */ 372static void cleanup_encoder_state(struct mime_encoder_state *p) 373{ 374 p->pos = 0; 375 p->bufbeg = 0; 376 p->bufend = 0; 377} 378 379 380/* Dummy encoder. This is used for 8bit and binary content encodings. */ 381static size_t encoder_nop_read(char *buffer, size_t size, bool ateof, 382 struct curl_mimepart *part) 383{ 384 struct mime_encoder_state *st = &part->encstate; 385 size_t insize = st->bufend - st->bufbeg; 386 387 (void) ateof; 388 389 if(!size) 390 return STOP_FILLING; 391 392 if(size > insize) 393 size = insize; 394 395 if(size) 396 memcpy(buffer, st->buf + st->bufbeg, size); 397 398 st->bufbeg += size; 399 return size; 400} 401 402static curl_off_t encoder_nop_size(curl_mimepart *part) 403{ 404 return part->datasize; 405} 406 407 408/* 7bit encoder: the encoder is just a data validity check. */ 409static size_t encoder_7bit_read(char *buffer, size_t size, bool ateof, 410 curl_mimepart *part) 411{ 412 struct mime_encoder_state *st = &part->encstate; 413 size_t cursize = st->bufend - st->bufbeg; 414 415 (void) ateof; 416 417 if(!size) 418 return STOP_FILLING; 419 420 if(size > cursize) 421 size = cursize; 422 423 for(cursize = 0; cursize < size; cursize++) { 424 *buffer = st->buf[st->bufbeg]; 425 if(*buffer++ & 0x80) 426 return cursize? cursize: READ_ERROR; 427 st->bufbeg++; 428 } 429 430 return cursize; 431} 432 433 434/* Base64 content encoder. */ 435static size_t encoder_base64_read(char *buffer, size_t size, bool ateof, 436 curl_mimepart *part) 437{ 438 struct mime_encoder_state *st = &part->encstate; 439 size_t cursize = 0; 440 int i; 441 char *ptr = buffer; 442 443 while(st->bufbeg < st->bufend) { 444 /* Line full ? */ 445 if(st->pos > MAX_ENCODED_LINE_LENGTH - 4) { 446 /* Yes, we need 2 characters for CRLF. */ 447 if(size < 2) { 448 if(!cursize) 449 return STOP_FILLING; 450 break; 451 } 452 *ptr++ = '\r'; 453 *ptr++ = '\n'; 454 st->pos = 0; 455 cursize += 2; 456 size -= 2; 457 } 458 459 /* Be sure there is enough space and input data for a base64 group. */ 460 if(size < 4) { 461 if(!cursize) 462 return STOP_FILLING; 463 break; 464 } 465 if(st->bufend - st->bufbeg < 3) 466 break; 467 468 /* Encode three bytes as four characters. */ 469 i = st->buf[st->bufbeg++] & 0xFF; 470 i = (i << 8) | (st->buf[st->bufbeg++] & 0xFF); 471 i = (i << 8) | (st->buf[st->bufbeg++] & 0xFF); 472 *ptr++ = base64enc[(i >> 18) & 0x3F]; 473 *ptr++ = base64enc[(i >> 12) & 0x3F]; 474 *ptr++ = base64enc[(i >> 6) & 0x3F]; 475 *ptr++ = base64enc[i & 0x3F]; 476 cursize += 4; 477 st->pos += 4; 478 size -= 4; 479 } 480 481 /* If at eof, we have to flush the buffered data. */ 482 if(ateof) { 483 if(size < 4) { 484 if(!cursize) 485 return STOP_FILLING; 486 } 487 else { 488 /* Buffered data size can only be 0, 1 or 2. */ 489 ptr[2] = ptr[3] = '='; 490 i = 0; 491 492 /* If there is buffered data */ 493 if(st->bufend != st->bufbeg) { 494 495 if(st->bufend - st->bufbeg == 2) 496 i = (st->buf[st->bufbeg + 1] & 0xFF) << 8; 497 498 i |= (st->buf[st->bufbeg] & 0xFF) << 16; 499 ptr[0] = base64enc[(i >> 18) & 0x3F]; 500 ptr[1] = base64enc[(i >> 12) & 0x3F]; 501 if(++st->bufbeg != st->bufend) { 502 ptr[2] = base64enc[(i >> 6) & 0x3F]; 503 st->bufbeg++; 504 } 505 cursize += 4; 506 st->pos += 4; 507 } 508 } 509 } 510 511 return cursize; 512} 513 514static curl_off_t encoder_base64_size(curl_mimepart *part) 515{ 516 curl_off_t size = part->datasize; 517 518 if(size <= 0) 519 return size; /* Unknown size or no data. */ 520 521 /* Compute base64 character count. */ 522 size = 4 * (1 + (size - 1) / 3); 523 524 /* Effective character count must include CRLFs. */ 525 return size + 2 * ((size - 1) / MAX_ENCODED_LINE_LENGTH); 526} 527 528 529/* Quoted-printable lookahead. 530 * 531 * Check if a CRLF or end of data is in input buffer at current position + n. 532 * Return -1 if more data needed, 1 if CRLF or end of data, else 0. 533 */ 534static int qp_lookahead_eol(struct mime_encoder_state *st, int ateof, size_t n) 535{ 536 n += st->bufbeg; 537 if(n >= st->bufend && ateof) 538 return 1; 539 if(n + 2 > st->bufend) 540 return ateof? 0: -1; 541 if(qp_class[st->buf[n] & 0xFF] == QP_CR && 542 qp_class[st->buf[n + 1] & 0xFF] == QP_LF) 543 return 1; 544 return 0; 545} 546 547/* Quoted-printable encoder. */ 548static size_t encoder_qp_read(char *buffer, size_t size, bool ateof, 549 curl_mimepart *part) 550{ 551 struct mime_encoder_state *st = &part->encstate; 552 char *ptr = buffer; 553 size_t cursize = 0; 554 int softlinebreak; 555 char buf[4]; 556 557 /* On all platforms, input is supposed to be ASCII compatible: for this 558 reason, we use hexadecimal ASCII codes in this function rather than 559 character constants that can be interpreted as non-ascii on some 560 platforms. Preserve ASCII encoding on output too. */ 561 while(st->bufbeg < st->bufend) { 562 size_t len = 1; 563 size_t consumed = 1; 564 int i = st->buf[st->bufbeg]; 565 buf[0] = (char) i; 566 buf[1] = aschex[(i >> 4) & 0xF]; 567 buf[2] = aschex[i & 0xF]; 568 569 switch(qp_class[st->buf[st->bufbeg] & 0xFF]) { 570 case QP_OK: /* Not a special character. */ 571 break; 572 case QP_SP: /* Space or tab. */ 573 /* Spacing must be escaped if followed by CRLF. */ 574 switch(qp_lookahead_eol(st, ateof, 1)) { 575 case -1: /* More input data needed. */ 576 return cursize; 577 case 0: /* No encoding needed. */ 578 break; 579 default: /* CRLF after space or tab. */ 580 buf[0] = '\x3D'; /* '=' */ 581 len = 3; 582 break; 583 } 584 break; 585 case QP_CR: /* Carriage return. */ 586 /* If followed by a line-feed, output the CRLF pair. 587 Else escape it. */ 588 switch(qp_lookahead_eol(st, ateof, 0)) { 589 case -1: /* Need more data. */ 590 return cursize; 591 case 1: /* CRLF found. */ 592 buf[len++] = '\x0A'; /* Append '\n'. */ 593 consumed = 2; 594 break; 595 default: /* Not followed by LF: escape. */ 596 buf[0] = '\x3D'; /* '=' */ 597 len = 3; 598 break; 599 } 600 break; 601 default: /* Character must be escaped. */ 602 buf[0] = '\x3D'; /* '=' */ 603 len = 3; 604 break; 605 } 606 607 /* Be sure the encoded character fits within maximum line length. */ 608 if(buf[len - 1] != '\x0A') { /* '\n' */ 609 softlinebreak = st->pos + len > MAX_ENCODED_LINE_LENGTH; 610 if(!softlinebreak && st->pos + len == MAX_ENCODED_LINE_LENGTH) { 611 /* We may use the current line only if end of data or followed by 612 a CRLF. */ 613 switch(qp_lookahead_eol(st, ateof, consumed)) { 614 case -1: /* Need more data. */ 615 return cursize; 616 case 0: /* Not followed by a CRLF. */ 617 softlinebreak = 1; 618 break; 619 } 620 } 621 if(softlinebreak) { 622 strcpy(buf, "\x3D\x0D\x0A"); /* "=\r\n" */ 623 len = 3; 624 consumed = 0; 625 } 626 } 627 628 /* If the output buffer would overflow, do not store. */ 629 if(len > size) { 630 if(!cursize) 631 return STOP_FILLING; 632 break; 633 } 634 635 /* Append to output buffer. */ 636 memcpy(ptr, buf, len); 637 cursize += len; 638 ptr += len; 639 size -= len; 640 st->pos += len; 641 if(buf[len - 1] == '\x0A') /* '\n' */ 642 st->pos = 0; 643 st->bufbeg += consumed; 644 } 645 646 return cursize; 647} 648 649static curl_off_t encoder_qp_size(curl_mimepart *part) 650{ 651 /* Determining the size can only be done by reading the data: unless the 652 data size is 0, we return it as unknown (-1). */ 653 return part->datasize? -1: 0; 654} 655 656 657/* In-memory data callbacks. */ 658/* Argument is a pointer to the mime part. */ 659static size_t mime_mem_read(char *buffer, size_t size, size_t nitems, 660 void *instream) 661{ 662 curl_mimepart *part = (curl_mimepart *) instream; 663 size_t sz = curlx_sotouz(part->datasize - part->state.offset); 664 (void) size; /* Always 1.*/ 665 666 if(!nitems) 667 return STOP_FILLING; 668 669 if(sz > nitems) 670 sz = nitems; 671 672 if(sz) 673 memcpy(buffer, part->data + curlx_sotouz(part->state.offset), sz); 674 675 return sz; 676} 677 678static int mime_mem_seek(void *instream, curl_off_t offset, int whence) 679{ 680 curl_mimepart *part = (curl_mimepart *) instream; 681 682 switch(whence) { 683 case SEEK_CUR: 684 offset += part->state.offset; 685 break; 686 case SEEK_END: 687 offset += part->datasize; 688 break; 689 } 690 691 if(offset < 0 || offset > part->datasize) 692 return CURL_SEEKFUNC_FAIL; 693 694 part->state.offset = offset; 695 return CURL_SEEKFUNC_OK; 696} 697 698static void mime_mem_free(void *ptr) 699{ 700 Curl_safefree(((curl_mimepart *) ptr)->data); 701} 702 703 704/* Named file callbacks. */ 705/* Argument is a pointer to the mime part. */ 706static int mime_open_file(curl_mimepart *part) 707{ 708 /* Open a MIMEKIND_FILE part. */ 709 710 if(part->fp) 711 return 0; 712 part->fp = fopen_read(part->data, "rb"); 713 return part->fp? 0: -1; 714} 715 716static size_t mime_file_read(char *buffer, size_t size, size_t nitems, 717 void *instream) 718{ 719 curl_mimepart *part = (curl_mimepart *) instream; 720 721 if(!nitems) 722 return STOP_FILLING; 723 724 if(mime_open_file(part)) 725 return READ_ERROR; 726 727 return fread(buffer, size, nitems, part->fp); 728} 729 730static int mime_file_seek(void *instream, curl_off_t offset, int whence) 731{ 732 curl_mimepart *part = (curl_mimepart *) instream; 733 734 if(whence == SEEK_SET && !offset && !part->fp) 735 return CURL_SEEKFUNC_OK; /* Not open: implicitly already at BOF. */ 736 737 if(mime_open_file(part)) 738 return CURL_SEEKFUNC_FAIL; 739 740 return fseek(part->fp, (long) offset, whence)? 741 CURL_SEEKFUNC_CANTSEEK: CURL_SEEKFUNC_OK; 742} 743 744static void mime_file_free(void *ptr) 745{ 746 curl_mimepart *part = (curl_mimepart *) ptr; 747 748 if(part->fp) { 749 fclose(part->fp); 750 part->fp = NULL; 751 } 752 Curl_safefree(part->data); 753} 754 755 756/* Subparts callbacks. */ 757/* Argument is a pointer to the mime structure. */ 758 759/* Readback a byte string segment. */ 760static size_t readback_bytes(struct mime_state *state, 761 char *buffer, size_t bufsize, 762 const char *bytes, size_t numbytes, 763 const char *trail, size_t traillen) 764{ 765 size_t sz; 766 size_t offset = curlx_sotouz(state->offset); 767 768 if(numbytes > offset) { 769 sz = numbytes - offset; 770 bytes += offset; 771 } 772 else { 773 sz = offset - numbytes; 774 if(sz >= traillen) 775 return 0; 776 bytes = trail + sz; 777 sz = traillen - sz; 778 } 779 780 if(sz > bufsize) 781 sz = bufsize; 782 783 memcpy(buffer, bytes, sz); 784 state->offset += sz; 785 return sz; 786} 787 788/* Read a non-encoded part content. */ 789static size_t read_part_content(curl_mimepart *part, 790 char *buffer, size_t bufsize, bool *hasread) 791{ 792 size_t sz = 0; 793 794 switch(part->lastreadstatus) { 795 case 0: 796 case CURL_READFUNC_ABORT: 797 case CURL_READFUNC_PAUSE: 798 case READ_ERROR: 799 return part->lastreadstatus; 800 default: 801 break; 802 } 803 804 /* If we can determine we are at end of part data, spare a read. */ 805 if(part->datasize != (curl_off_t) -1 && 806 part->state.offset >= part->datasize) { 807 /* sz is already zero. */ 808 } 809 else { 810 switch(part->kind) { 811 case MIMEKIND_MULTIPART: 812 /* 813 * Cannot be processed as other kinds since read function requires 814 * an additional parameter and is highly recursive. 815 */ 816 sz = mime_subparts_read(buffer, 1, bufsize, part->arg, hasread); 817 break; 818 case MIMEKIND_FILE: 819 if(part->fp && feof(part->fp)) 820 break; /* At EOF. */ 821 FALLTHROUGH(); 822 default: 823 if(part->readfunc) { 824 if(!(part->flags & MIME_FAST_READ)) { 825 if(*hasread) 826 return STOP_FILLING; 827 *hasread = TRUE; 828 } 829 sz = part->readfunc(buffer, 1, bufsize, part->arg); 830 } 831 break; 832 } 833 } 834 835 switch(sz) { 836 case STOP_FILLING: 837 break; 838 case 0: 839 case CURL_READFUNC_ABORT: 840 case CURL_READFUNC_PAUSE: 841 case READ_ERROR: 842 part->lastreadstatus = sz; 843 break; 844 default: 845 part->state.offset += sz; 846 part->lastreadstatus = sz; 847 break; 848 } 849 850 return sz; 851} 852 853/* Read and encode part content. */ 854static size_t read_encoded_part_content(curl_mimepart *part, char *buffer, 855 size_t bufsize, bool *hasread) 856{ 857 struct mime_encoder_state *st = &part->encstate; 858 size_t cursize = 0; 859 size_t sz; 860 bool ateof = FALSE; 861 862 for(;;) { 863 if(st->bufbeg < st->bufend || ateof) { 864 /* Encode buffered data. */ 865 sz = part->encoder->encodefunc(buffer, bufsize, ateof, part); 866 switch(sz) { 867 case 0: 868 if(ateof) 869 return cursize; 870 break; 871 case READ_ERROR: 872 case STOP_FILLING: 873 return cursize? cursize: sz; 874 default: 875 cursize += sz; 876 buffer += sz; 877 bufsize -= sz; 878 continue; 879 } 880 } 881 882 /* We need more data in input buffer. */ 883 if(st->bufbeg) { 884 size_t len = st->bufend - st->bufbeg; 885 886 if(len) 887 memmove(st->buf, st->buf + st->bufbeg, len); 888 st->bufbeg = 0; 889 st->bufend = len; 890 } 891 if(st->bufend >= sizeof(st->buf)) 892 return cursize? cursize: READ_ERROR; /* Buffer full. */ 893 sz = read_part_content(part, st->buf + st->bufend, 894 sizeof(st->buf) - st->bufend, hasread); 895 switch(sz) { 896 case 0: 897 ateof = TRUE; 898 break; 899 case CURL_READFUNC_ABORT: 900 case CURL_READFUNC_PAUSE: 901 case READ_ERROR: 902 case STOP_FILLING: 903 return cursize? cursize: sz; 904 default: 905 st->bufend += sz; 906 break; 907 } 908 } 909 910 /* NOTREACHED */ 911} 912 913/* Readback a mime part. */ 914static size_t readback_part(curl_mimepart *part, 915 char *buffer, size_t bufsize, bool *hasread) 916{ 917 size_t cursize = 0; 918 919 /* Readback from part. */ 920 921 while(bufsize) { 922 size_t sz = 0; 923 struct curl_slist *hdr = (struct curl_slist *) part->state.ptr; 924 switch(part->state.state) { 925 case MIMESTATE_BEGIN: 926 mimesetstate(&part->state, 927 (part->flags & MIME_BODY_ONLY)? 928 MIMESTATE_BODY: MIMESTATE_CURLHEADERS, 929 part->curlheaders); 930 break; 931 case MIMESTATE_USERHEADERS: 932 if(!hdr) { 933 mimesetstate(&part->state, MIMESTATE_EOH, NULL); 934 break; 935 } 936 if(match_header(hdr, "Content-Type", 12)) { 937 mimesetstate(&part->state, MIMESTATE_USERHEADERS, hdr->next); 938 break; 939 } 940 FALLTHROUGH(); 941 case MIMESTATE_CURLHEADERS: 942 if(!hdr) 943 mimesetstate(&part->state, MIMESTATE_USERHEADERS, part->userheaders); 944 else { 945 sz = readback_bytes(&part->state, buffer, bufsize, 946 hdr->data, strlen(hdr->data), STRCONST("\r\n")); 947 if(!sz) 948 mimesetstate(&part->state, part->state.state, hdr->next); 949 } 950 break; 951 case MIMESTATE_EOH: 952 sz = readback_bytes(&part->state, buffer, bufsize, STRCONST("\r\n"), 953 STRCONST("")); 954 if(!sz) 955 mimesetstate(&part->state, MIMESTATE_BODY, NULL); 956 break; 957 case MIMESTATE_BODY: 958 cleanup_encoder_state(&part->encstate); 959 mimesetstate(&part->state, MIMESTATE_CONTENT, NULL); 960 break; 961 case MIMESTATE_CONTENT: 962 if(part->encoder) 963 sz = read_encoded_part_content(part, buffer, bufsize, hasread); 964 else 965 sz = read_part_content(part, buffer, bufsize, hasread); 966 switch(sz) { 967 case 0: 968 mimesetstate(&part->state, MIMESTATE_END, NULL); 969 /* Try sparing open file descriptors. */ 970 if(part->kind == MIMEKIND_FILE && part->fp) { 971 fclose(part->fp); 972 part->fp = NULL; 973 } 974 FALLTHROUGH(); 975 case CURL_READFUNC_ABORT: 976 case CURL_READFUNC_PAUSE: 977 case READ_ERROR: 978 case STOP_FILLING: 979 return cursize? cursize: sz; 980 } 981 break; 982 case MIMESTATE_END: 983 return cursize; 984 default: 985 break; /* Other values not in part state. */ 986 } 987 988 /* Bump buffer and counters according to read size. */ 989 cursize += sz; 990 buffer += sz; 991 bufsize -= sz; 992 } 993 994 return cursize; 995} 996 997/* Readback from mime. Warning: not a read callback function. */ 998static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems, 999 void *instream, bool *hasread) 1000{ 1001 curl_mime *mime = (curl_mime *) instream; 1002 size_t cursize = 0; 1003 (void) size; /* Always 1. */ 1004 1005 while(nitems) { 1006 size_t sz = 0; 1007 curl_mimepart *part = mime->state.ptr; 1008 switch(mime->state.state) { 1009 case MIMESTATE_BEGIN: 1010 case MIMESTATE_BODY: 1011 mimesetstate(&mime->state, MIMESTATE_BOUNDARY1, mime->firstpart); 1012 /* The first boundary always follows the header termination empty line, 1013 so is always preceded by a CRLF. We can then spare 2 characters 1014 by skipping the leading CRLF in boundary. */ 1015 mime->state.offset += 2; 1016 break; 1017 case MIMESTATE_BOUNDARY1: 1018 sz = readback_bytes(&mime->state, buffer, nitems, STRCONST("\r\n--"), 1019 STRCONST("")); 1020 if(!sz) 1021 mimesetstate(&mime->state, MIMESTATE_BOUNDARY2, part); 1022 break; 1023 case MIMESTATE_BOUNDARY2: 1024 if(part) 1025 sz = readback_bytes(&mime->state, buffer, nitems, mime->boundary, 1026 MIME_BOUNDARY_LEN, STRCONST("\r\n")); 1027 else 1028 sz = readback_bytes(&mime->state, buffer, nitems, mime->boundary, 1029 MIME_BOUNDARY_LEN, STRCONST("--\r\n")); 1030 if(!sz) { 1031 mimesetstate(&mime->state, MIMESTATE_CONTENT, part); 1032 } 1033 break; 1034 case MIMESTATE_CONTENT: 1035 if(!part) { 1036 mimesetstate(&mime->state, MIMESTATE_END, NULL); 1037 break; 1038 } 1039 sz = readback_part(part, buffer, nitems, hasread); 1040 switch(sz) { 1041 case CURL_READFUNC_ABORT: 1042 case CURL_READFUNC_PAUSE: 1043 case READ_ERROR: 1044 case STOP_FILLING: 1045 return cursize? cursize: sz; 1046 case 0: 1047 mimesetstate(&mime->state, MIMESTATE_BOUNDARY1, part->nextpart); 1048 break; 1049 } 1050 break; 1051 case MIMESTATE_END: 1052 return cursize; 1053 default: 1054 break; /* other values not used in mime state. */ 1055 } 1056 1057 /* Bump buffer and counters according to read size. */ 1058 cursize += sz; 1059 buffer += sz; 1060 nitems -= sz; 1061 } 1062 1063 return cursize; 1064} 1065 1066static int mime_part_rewind(curl_mimepart *part) 1067{ 1068 int res = CURL_SEEKFUNC_OK; 1069 enum mimestate targetstate = MIMESTATE_BEGIN; 1070 1071 if(part->flags & MIME_BODY_ONLY) 1072 targetstate = MIMESTATE_BODY; 1073 cleanup_encoder_state(&part->encstate); 1074 if(part->state.state > targetstate) { 1075 res = CURL_SEEKFUNC_CANTSEEK; 1076 if(part->seekfunc) { 1077 res = part->seekfunc(part->arg, (curl_off_t) 0, SEEK_SET); 1078 switch(res) { 1079 case CURL_SEEKFUNC_OK: 1080 case CURL_SEEKFUNC_FAIL: 1081 case CURL_SEEKFUNC_CANTSEEK: 1082 break; 1083 case -1: /* For fseek() error. */ 1084 res = CURL_SEEKFUNC_CANTSEEK; 1085 break; 1086 default: 1087 res = CURL_SEEKFUNC_FAIL; 1088 break; 1089 } 1090 } 1091 } 1092 1093 if(res == CURL_SEEKFUNC_OK) 1094 mimesetstate(&part->state, targetstate, NULL); 1095 1096 part->lastreadstatus = 1; /* Successful read status. */ 1097 return res; 1098} 1099 1100static int mime_subparts_seek(void *instream, curl_off_t offset, int whence) 1101{ 1102 curl_mime *mime = (curl_mime *) instream; 1103 curl_mimepart *part; 1104 int result = CURL_SEEKFUNC_OK; 1105 1106 if(whence != SEEK_SET || offset) 1107 return CURL_SEEKFUNC_CANTSEEK; /* Only support full rewind. */ 1108 1109 if(mime->state.state == MIMESTATE_BEGIN) 1110 return CURL_SEEKFUNC_OK; /* Already rewound. */ 1111 1112 for(part = mime->firstpart; part; part = part->nextpart) { 1113 int res = mime_part_rewind(part); 1114 if(res != CURL_SEEKFUNC_OK) 1115 result = res; 1116 } 1117 1118 if(result == CURL_SEEKFUNC_OK) 1119 mimesetstate(&mime->state, MIMESTATE_BEGIN, NULL); 1120 1121 return result; 1122} 1123 1124/* Release part content. */ 1125static void cleanup_part_content(curl_mimepart *part) 1126{ 1127 if(part->freefunc) 1128 part->freefunc(part->arg); 1129 1130 part->readfunc = NULL; 1131 part->seekfunc = NULL; 1132 part->freefunc = NULL; 1133 part->arg = (void *) part; /* Defaults to part itself. */ 1134 part->data = NULL; 1135 part->fp = NULL; 1136 part->datasize = (curl_off_t) 0; /* No size yet. */ 1137 cleanup_encoder_state(&part->encstate); 1138 part->kind = MIMEKIND_NONE; 1139 part->flags &= ~MIME_FAST_READ; 1140 part->lastreadstatus = 1; /* Successful read status. */ 1141 part->state.state = MIMESTATE_BEGIN; 1142} 1143 1144static void mime_subparts_free(void *ptr) 1145{ 1146 curl_mime *mime = (curl_mime *) ptr; 1147 1148 if(mime && mime->parent) { 1149 mime->parent->freefunc = NULL; /* Be sure we won't be called again. */ 1150 cleanup_part_content(mime->parent); /* Avoid dangling pointer in part. */ 1151 } 1152 curl_mime_free(mime); 1153} 1154 1155/* Do not free subparts: unbind them. This is used for the top level only. */ 1156static void mime_subparts_unbind(void *ptr) 1157{ 1158 curl_mime *mime = (curl_mime *) ptr; 1159 1160 if(mime && mime->parent) { 1161 mime->parent->freefunc = NULL; /* Be sure we won't be called again. */ 1162 cleanup_part_content(mime->parent); /* Avoid dangling pointer in part. */ 1163 mime->parent = NULL; 1164 } 1165} 1166 1167 1168void Curl_mime_cleanpart(curl_mimepart *part) 1169{ 1170 if(part) { 1171 cleanup_part_content(part); 1172 curl_slist_free_all(part->curlheaders); 1173 if(part->flags & MIME_USERHEADERS_OWNER) 1174 curl_slist_free_all(part->userheaders); 1175 Curl_safefree(part->mimetype); 1176 Curl_safefree(part->name); 1177 Curl_safefree(part->filename); 1178 Curl_mime_initpart(part); 1179 } 1180} 1181 1182/* Recursively delete a mime handle and its parts. */ 1183void curl_mime_free(curl_mime *mime) 1184{ 1185 curl_mimepart *part; 1186 1187 if(mime) { 1188 mime_subparts_unbind(mime); /* Be sure it's not referenced anymore. */ 1189 while(mime->firstpart) { 1190 part = mime->firstpart; 1191 mime->firstpart = part->nextpart; 1192 Curl_mime_cleanpart(part); 1193 free(part); 1194 } 1195 free(mime); 1196 } 1197} 1198 1199CURLcode Curl_mime_duppart(struct Curl_easy *data, 1200 curl_mimepart *dst, const curl_mimepart *src) 1201{ 1202 curl_mime *mime; 1203 curl_mimepart *d; 1204 const curl_mimepart *s; 1205 CURLcode res = CURLE_OK; 1206 1207 DEBUGASSERT(dst); 1208 1209 /* Duplicate content. */ 1210 switch(src->kind) { 1211 case MIMEKIND_NONE: 1212 break; 1213 case MIMEKIND_DATA: 1214 res = curl_mime_data(dst, src->data, (size_t) src->datasize); 1215 break; 1216 case MIMEKIND_FILE: 1217 res = curl_mime_filedata(dst, src->data); 1218 /* Do not abort duplication if file is not readable. */ 1219 if(res == CURLE_READ_ERROR) 1220 res = CURLE_OK; 1221 break; 1222 case MIMEKIND_CALLBACK: 1223 res = curl_mime_data_cb(dst, src->datasize, src->readfunc, 1224 src->seekfunc, src->freefunc, src->arg); 1225 break; 1226 case MIMEKIND_MULTIPART: 1227 /* No one knows about the cloned subparts, thus always attach ownership 1228 to the part. */ 1229 mime = curl_mime_init(data); 1230 res = mime? curl_mime_subparts(dst, mime): CURLE_OUT_OF_MEMORY; 1231 1232 /* Duplicate subparts. */ 1233 for(s = ((curl_mime *) src->arg)->firstpart; !res && s; s = s->nextpart) { 1234 d = curl_mime_addpart(mime); 1235 res = d? Curl_mime_duppart(data, d, s): CURLE_OUT_OF_MEMORY; 1236 } 1237 break; 1238 default: /* Invalid kind: should not occur. */ 1239 DEBUGF(infof(data, "invalid MIMEKIND* attempt")); 1240 res = CURLE_BAD_FUNCTION_ARGUMENT; /* Internal error? */ 1241 break; 1242 } 1243 1244 /* Duplicate headers. */ 1245 if(!res && src->userheaders) { 1246 struct curl_slist *hdrs = Curl_slist_duplicate(src->userheaders); 1247 1248 if(!hdrs) 1249 res = CURLE_OUT_OF_MEMORY; 1250 else { 1251 /* No one but this procedure knows about the new header list, 1252 so always take ownership. */ 1253 res = curl_mime_headers(dst, hdrs, TRUE); 1254 if(res) 1255 curl_slist_free_all(hdrs); 1256 } 1257 } 1258 1259 if(!res) { 1260 /* Duplicate other fields. */ 1261 dst->encoder = src->encoder; 1262 res = curl_mime_type(dst, src->mimetype); 1263 } 1264 if(!res) 1265 res = curl_mime_name(dst, src->name); 1266 if(!res) 1267 res = curl_mime_filename(dst, src->filename); 1268 1269 /* If an error occurred, rollback. */ 1270 if(res) 1271 Curl_mime_cleanpart(dst); 1272 1273 return res; 1274} 1275 1276/* 1277 * Mime build functions. 1278 */ 1279 1280/* Create a mime handle. */ 1281curl_mime *curl_mime_init(struct Curl_easy *easy) 1282{ 1283 curl_mime *mime; 1284 1285 mime = (curl_mime *) malloc(sizeof(*mime)); 1286 1287 if(mime) { 1288 mime->parent = NULL; 1289 mime->firstpart = NULL; 1290 mime->lastpart = NULL; 1291 1292 memset(mime->boundary, '-', MIME_BOUNDARY_DASHES); 1293 if(Curl_rand_alnum(easy, 1294 (unsigned char *) &mime->boundary[MIME_BOUNDARY_DASHES], 1295 MIME_RAND_BOUNDARY_CHARS + 1)) { 1296 /* failed to get random separator, bail out */ 1297 free(mime); 1298 return NULL; 1299 } 1300 mimesetstate(&mime->state, MIMESTATE_BEGIN, NULL); 1301 } 1302 1303 return mime; 1304} 1305 1306/* Initialize a mime part. */ 1307void Curl_mime_initpart(curl_mimepart *part) 1308{ 1309 memset((char *) part, 0, sizeof(*part)); 1310 part->lastreadstatus = 1; /* Successful read status. */ 1311 mimesetstate(&part->state, MIMESTATE_BEGIN, NULL); 1312} 1313 1314/* Create a mime part and append it to a mime handle's part list. */ 1315curl_mimepart *curl_mime_addpart(curl_mime *mime) 1316{ 1317 curl_mimepart *part; 1318 1319 if(!mime) 1320 return NULL; 1321 1322 part = (curl_mimepart *) malloc(sizeof(*part)); 1323 1324 if(part) { 1325 Curl_mime_initpart(part); 1326 part->parent = mime; 1327 1328 if(mime->lastpart) 1329 mime->lastpart->nextpart = part; 1330 else 1331 mime->firstpart = part; 1332 1333 mime->lastpart = part; 1334 } 1335 1336 return part; 1337} 1338 1339/* Set mime part name. */ 1340CURLcode curl_mime_name(curl_mimepart *part, const char *name) 1341{ 1342 if(!part) 1343 return CURLE_BAD_FUNCTION_ARGUMENT; 1344 1345 Curl_safefree(part->name); 1346 1347 if(name) { 1348 part->name = strdup(name); 1349 if(!part->name) 1350 return CURLE_OUT_OF_MEMORY; 1351 } 1352 1353 return CURLE_OK; 1354} 1355 1356/* Set mime part remote file name. */ 1357CURLcode curl_mime_filename(curl_mimepart *part, const char *filename) 1358{ 1359 if(!part) 1360 return CURLE_BAD_FUNCTION_ARGUMENT; 1361 1362 Curl_safefree(part->filename); 1363 1364 if(filename) { 1365 part->filename = strdup(filename); 1366 if(!part->filename) 1367 return CURLE_OUT_OF_MEMORY; 1368 } 1369 1370 return CURLE_OK; 1371} 1372 1373/* Set mime part content from memory data. */ 1374CURLcode curl_mime_data(curl_mimepart *part, 1375 const char *ptr, size_t datasize) 1376{ 1377 if(!part) 1378 return CURLE_BAD_FUNCTION_ARGUMENT; 1379 1380 cleanup_part_content(part); 1381 1382 if(ptr) { 1383 if(datasize == CURL_ZERO_TERMINATED) 1384 datasize = strlen(ptr); 1385 1386 part->data = Curl_memdup0(ptr, datasize); 1387 if(!part->data) 1388 return CURLE_OUT_OF_MEMORY; 1389 1390 part->datasize = datasize; 1391 part->readfunc = mime_mem_read; 1392 part->seekfunc = mime_mem_seek; 1393 part->freefunc = mime_mem_free; 1394 part->flags |= MIME_FAST_READ; 1395 part->kind = MIMEKIND_DATA; 1396 } 1397 1398 return CURLE_OK; 1399} 1400 1401/* Set mime part content from named local file. */ 1402CURLcode curl_mime_filedata(curl_mimepart *part, const char *filename) 1403{ 1404 CURLcode result = CURLE_OK; 1405 1406 if(!part) 1407 return CURLE_BAD_FUNCTION_ARGUMENT; 1408 1409 cleanup_part_content(part); 1410 1411 if(filename) { 1412 char *base; 1413 struct_stat sbuf; 1414 1415 if(stat(filename, &sbuf) || access(filename, R_OK)) 1416 result = CURLE_READ_ERROR; 1417 1418 part->data = strdup(filename); 1419 if(!part->data) 1420 result = CURLE_OUT_OF_MEMORY; 1421 1422 part->datasize = -1; 1423 if(!result && S_ISREG(sbuf.st_mode)) { 1424 part->datasize = filesize(filename, sbuf); 1425 part->seekfunc = mime_file_seek; 1426 } 1427 1428 part->readfunc = mime_file_read; 1429 part->freefunc = mime_file_free; 1430 part->kind = MIMEKIND_FILE; 1431 1432 /* As a side effect, set the filename to the current file's base name. 1433 It is possible to withdraw this by explicitly calling 1434 curl_mime_filename() with a NULL filename argument after the current 1435 call. */ 1436 base = strippath(filename); 1437 if(!base) 1438 result = CURLE_OUT_OF_MEMORY; 1439 else { 1440 CURLcode res = curl_mime_filename(part, base); 1441 1442 if(res) 1443 result = res; 1444 free(base); 1445 } 1446 } 1447 return result; 1448} 1449 1450/* Set mime part type. */ 1451CURLcode curl_mime_type(curl_mimepart *part, const char *mimetype) 1452{ 1453 if(!part) 1454 return CURLE_BAD_FUNCTION_ARGUMENT; 1455 1456 Curl_safefree(part->mimetype); 1457 1458 if(mimetype) { 1459 part->mimetype = strdup(mimetype); 1460 if(!part->mimetype) 1461 return CURLE_OUT_OF_MEMORY; 1462 } 1463 1464 return CURLE_OK; 1465} 1466 1467/* Set mime data transfer encoder. */ 1468CURLcode curl_mime_encoder(curl_mimepart *part, const char *encoding) 1469{ 1470 CURLcode result = CURLE_BAD_FUNCTION_ARGUMENT; 1471 const struct mime_encoder *mep; 1472 1473 if(!part) 1474 return result; 1475 1476 part->encoder = NULL; 1477 1478 if(!encoding) 1479 return CURLE_OK; /* Removing current encoder. */ 1480 1481 for(mep = encoders; mep->name; mep++) 1482 if(strcasecompare(encoding, mep->name)) { 1483 part->encoder = mep; 1484 result = CURLE_OK; 1485 } 1486 1487 return result; 1488} 1489 1490/* Set mime part headers. */ 1491CURLcode curl_mime_headers(curl_mimepart *part, 1492 struct curl_slist *headers, int take_ownership) 1493{ 1494 if(!part) 1495 return CURLE_BAD_FUNCTION_ARGUMENT; 1496 1497 if(part->flags & MIME_USERHEADERS_OWNER) { 1498 if(part->userheaders != headers) /* Allow setting twice the same list. */ 1499 curl_slist_free_all(part->userheaders); 1500 part->flags &= ~MIME_USERHEADERS_OWNER; 1501 } 1502 part->userheaders = headers; 1503 if(headers && take_ownership) 1504 part->flags |= MIME_USERHEADERS_OWNER; 1505 return CURLE_OK; 1506} 1507 1508/* Set mime part content from callback. */ 1509CURLcode curl_mime_data_cb(curl_mimepart *part, curl_off_t datasize, 1510 curl_read_callback readfunc, 1511 curl_seek_callback seekfunc, 1512 curl_free_callback freefunc, void *arg) 1513{ 1514 if(!part) 1515 return CURLE_BAD_FUNCTION_ARGUMENT; 1516 1517 cleanup_part_content(part); 1518 1519 if(readfunc) { 1520 part->readfunc = readfunc; 1521 part->seekfunc = seekfunc; 1522 part->freefunc = freefunc; 1523 part->arg = arg; 1524 part->datasize = datasize; 1525 part->kind = MIMEKIND_CALLBACK; 1526 } 1527 1528 return CURLE_OK; 1529} 1530 1531/* Set mime part content from subparts. */ 1532CURLcode Curl_mime_set_subparts(curl_mimepart *part, 1533 curl_mime *subparts, int take_ownership) 1534{ 1535 curl_mime *root; 1536 1537 if(!part) 1538 return CURLE_BAD_FUNCTION_ARGUMENT; 1539 1540 /* Accept setting twice the same subparts. */ 1541 if(part->kind == MIMEKIND_MULTIPART && part->arg == subparts) 1542 return CURLE_OK; 1543 1544 cleanup_part_content(part); 1545 1546 if(subparts) { 1547 /* Should not have been attached already. */ 1548 if(subparts->parent) 1549 return CURLE_BAD_FUNCTION_ARGUMENT; 1550 1551 /* Should not be the part's root. */ 1552 root = part->parent; 1553 if(root) { 1554 while(root->parent && root->parent->parent) 1555 root = root->parent->parent; 1556 if(subparts == root) { 1557 /* Can't add as a subpart of itself. */ 1558 return CURLE_BAD_FUNCTION_ARGUMENT; 1559 } 1560 } 1561 1562 subparts->parent = part; 1563 /* Subparts are processed internally: no read callback. */ 1564 part->seekfunc = mime_subparts_seek; 1565 part->freefunc = take_ownership? mime_subparts_free: mime_subparts_unbind; 1566 part->arg = subparts; 1567 part->datasize = -1; 1568 part->kind = MIMEKIND_MULTIPART; 1569 } 1570 1571 return CURLE_OK; 1572} 1573 1574CURLcode curl_mime_subparts(curl_mimepart *part, curl_mime *subparts) 1575{ 1576 return Curl_mime_set_subparts(part, subparts, TRUE); 1577} 1578 1579 1580/* Readback from top mime. */ 1581/* Argument is the dummy top part. */ 1582size_t Curl_mime_read(char *buffer, size_t size, size_t nitems, void *instream) 1583{ 1584 curl_mimepart *part = (curl_mimepart *) instream; 1585 size_t ret; 1586 bool hasread; 1587 1588 (void) size; /* Always 1. */ 1589 1590 do { 1591 hasread = FALSE; 1592 ret = readback_part(part, buffer, nitems, &hasread); 1593 /* 1594 * If this is not possible to get some data without calling more than 1595 * one read callback (probably because a content encoder is not able to 1596 * deliver a new bunch for the few data accumulated so far), force another 1597 * read until we get enough data or a special exit code. 1598 */ 1599 } while(ret == STOP_FILLING); 1600 1601 return ret; 1602} 1603 1604/* Rewind mime stream. */ 1605CURLcode Curl_mime_rewind(curl_mimepart *part) 1606{ 1607 return mime_part_rewind(part) == CURL_SEEKFUNC_OK? 1608 CURLE_OK: CURLE_SEND_FAIL_REWIND; 1609} 1610 1611/* Compute header list size. */ 1612static size_t slist_size(struct curl_slist *s, 1613 size_t overhead, const char *skip, size_t skiplen) 1614{ 1615 size_t size = 0; 1616 1617 for(; s; s = s->next) 1618 if(!skip || !match_header(s, skip, skiplen)) 1619 size += strlen(s->data) + overhead; 1620 return size; 1621} 1622 1623/* Get/compute multipart size. */ 1624static curl_off_t multipart_size(curl_mime *mime) 1625{ 1626 curl_off_t size; 1627 curl_off_t boundarysize; 1628 curl_mimepart *part; 1629 1630 if(!mime) 1631 return 0; /* Not present -> empty. */ 1632 1633 boundarysize = 4 + MIME_BOUNDARY_LEN + 2; 1634 size = boundarysize; /* Final boundary - CRLF after headers. */ 1635 1636 for(part = mime->firstpart; part; part = part->nextpart) { 1637 curl_off_t sz = Curl_mime_size(part); 1638 1639 if(sz < 0) 1640 size = sz; 1641 1642 if(size >= 0) 1643 size += boundarysize + sz; 1644 } 1645 1646 return size; 1647} 1648 1649/* Get/compute mime size. */ 1650curl_off_t Curl_mime_size(curl_mimepart *part) 1651{ 1652 curl_off_t size; 1653 1654 if(part->kind == MIMEKIND_MULTIPART) 1655 part->datasize = multipart_size(part->arg); 1656 1657 size = part->datasize; 1658 1659 if(part->encoder) 1660 size = part->encoder->sizefunc(part); 1661 1662 if(size >= 0 && !(part->flags & MIME_BODY_ONLY)) { 1663 /* Compute total part size. */ 1664 size += slist_size(part->curlheaders, 2, NULL, 0); 1665 size += slist_size(part->userheaders, 2, STRCONST("Content-Type")); 1666 size += 2; /* CRLF after headers. */ 1667 } 1668 return size; 1669} 1670 1671/* Add a header. */ 1672/* VARARGS2 */ 1673CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...) 1674{ 1675 struct curl_slist *hdr = NULL; 1676 char *s = NULL; 1677 va_list ap; 1678 1679 va_start(ap, fmt); 1680 s = curl_mvaprintf(fmt, ap); 1681 va_end(ap); 1682 1683 if(s) { 1684 hdr = Curl_slist_append_nodup(*slp, s); 1685 if(hdr) 1686 *slp = hdr; 1687 else 1688 free(s); 1689 } 1690 1691 return hdr? CURLE_OK: CURLE_OUT_OF_MEMORY; 1692} 1693 1694/* Add a content type header. */ 1695static CURLcode add_content_type(struct curl_slist **slp, 1696 const char *type, const char *boundary) 1697{ 1698 return Curl_mime_add_header(slp, "Content-Type: %s%s%s", type, 1699 boundary? "; boundary=": "", 1700 boundary? boundary: ""); 1701} 1702 1703const char *Curl_mime_contenttype(const char *filename) 1704{ 1705 /* 1706 * If no content type was specified, we scan through a few well-known 1707 * extensions and pick the first we match! 1708 */ 1709 struct ContentType { 1710 const char *extension; 1711 const char *type; 1712 }; 1713 static const struct ContentType ctts[] = { 1714 {".gif", "image/gif"}, 1715 {".jpg", "image/jpeg"}, 1716 {".jpeg", "image/jpeg"}, 1717 {".png", "image/png"}, 1718 {".svg", "image/svg+xml"}, 1719 {".txt", "text/plain"}, 1720 {".htm", "text/html"}, 1721 {".html", "text/html"}, 1722 {".pdf", "application/pdf"}, 1723 {".xml", "application/xml"} 1724 }; 1725 1726 if(filename) { 1727 size_t len1 = strlen(filename); 1728 const char *nameend = filename + len1; 1729 unsigned int i; 1730 1731 for(i = 0; i < sizeof(ctts) / sizeof(ctts[0]); i++) { 1732 size_t len2 = strlen(ctts[i].extension); 1733 1734 if(len1 >= len2 && strcasecompare(nameend - len2, ctts[i].extension)) 1735 return ctts[i].type; 1736 } 1737 } 1738 return NULL; 1739} 1740 1741static bool content_type_match(const char *contenttype, 1742 const char *target, size_t len) 1743{ 1744 if(contenttype && strncasecompare(contenttype, target, len)) 1745 switch(contenttype[len]) { 1746 case '\0': 1747 case '\t': 1748 case '\r': 1749 case '\n': 1750 case ' ': 1751 case ';': 1752 return TRUE; 1753 } 1754 return FALSE; 1755} 1756 1757CURLcode Curl_mime_prepare_headers(struct Curl_easy *data, 1758 curl_mimepart *part, 1759 const char *contenttype, 1760 const char *disposition, 1761 enum mimestrategy strategy) 1762{ 1763 curl_mime *mime = NULL; 1764 const char *boundary = NULL; 1765 char *customct; 1766 const char *cte = NULL; 1767 CURLcode ret = CURLE_OK; 1768 1769 /* Get rid of previously prepared headers. */ 1770 curl_slist_free_all(part->curlheaders); 1771 part->curlheaders = NULL; 1772 1773 /* Be sure we won't access old headers later. */ 1774 if(part->state.state == MIMESTATE_CURLHEADERS) 1775 mimesetstate(&part->state, MIMESTATE_CURLHEADERS, NULL); 1776 1777 /* Check if content type is specified. */ 1778 customct = part->mimetype; 1779 if(!customct) 1780 customct = search_header(part->userheaders, STRCONST("Content-Type")); 1781 if(customct) 1782 contenttype = customct; 1783 1784 /* If content type is not specified, try to determine it. */ 1785 if(!contenttype) { 1786 switch(part->kind) { 1787 case MIMEKIND_MULTIPART: 1788 contenttype = MULTIPART_CONTENTTYPE_DEFAULT; 1789 break; 1790 case MIMEKIND_FILE: 1791 contenttype = Curl_mime_contenttype(part->filename); 1792 if(!contenttype) 1793 contenttype = Curl_mime_contenttype(part->data); 1794 if(!contenttype && part->filename) 1795 contenttype = FILE_CONTENTTYPE_DEFAULT; 1796 break; 1797 default: 1798 contenttype = Curl_mime_contenttype(part->filename); 1799 break; 1800 } 1801 } 1802 1803 if(part->kind == MIMEKIND_MULTIPART) { 1804 mime = (curl_mime *) part->arg; 1805 if(mime) 1806 boundary = mime->boundary; 1807 } 1808 else if(contenttype && !customct && 1809 content_type_match(contenttype, STRCONST("text/plain"))) 1810 if(strategy == MIMESTRATEGY_MAIL || !part->filename) 1811 contenttype = NULL; 1812 1813 /* Issue content-disposition header only if not already set by caller. */ 1814 if(!search_header(part->userheaders, STRCONST("Content-Disposition"))) { 1815 if(!disposition) 1816 if(part->filename || part->name || 1817 (contenttype && !strncasecompare(contenttype, "multipart/", 10))) 1818 disposition = DISPOSITION_DEFAULT; 1819 if(disposition && curl_strequal(disposition, "attachment") && 1820 !part->name && !part->filename) 1821 disposition = NULL; 1822 if(disposition) { 1823 char *name = NULL; 1824 char *filename = NULL; 1825 1826 if(part->name) { 1827 name = escape_string(data, part->name, strategy); 1828 if(!name) 1829 ret = CURLE_OUT_OF_MEMORY; 1830 } 1831 if(!ret && part->filename) { 1832 filename = escape_string(data, part->filename, strategy); 1833 if(!filename) 1834 ret = CURLE_OUT_OF_MEMORY; 1835 } 1836 if(!ret) 1837 ret = Curl_mime_add_header(&part->curlheaders, 1838 "Content-Disposition: %s%s%s%s%s%s%s", 1839 disposition, 1840 name? "; name=\"": "", 1841 name? name: "", 1842 name? "\"": "", 1843 filename? "; filename=\"": "", 1844 filename? filename: "", 1845 filename? "\"": ""); 1846 Curl_safefree(name); 1847 Curl_safefree(filename); 1848 if(ret) 1849 return ret; 1850 } 1851 } 1852 1853 /* Issue Content-Type header. */ 1854 if(contenttype) { 1855 ret = add_content_type(&part->curlheaders, contenttype, boundary); 1856 if(ret) 1857 return ret; 1858 } 1859 1860 /* Content-Transfer-Encoding header. */ 1861 if(!search_header(part->userheaders, 1862 STRCONST("Content-Transfer-Encoding"))) { 1863 if(part->encoder) 1864 cte = part->encoder->name; 1865 else if(contenttype && strategy == MIMESTRATEGY_MAIL && 1866 part->kind != MIMEKIND_MULTIPART) 1867 cte = "8bit"; 1868 if(cte) { 1869 ret = Curl_mime_add_header(&part->curlheaders, 1870 "Content-Transfer-Encoding: %s", cte); 1871 if(ret) 1872 return ret; 1873 } 1874 } 1875 1876 /* If we were reading curl-generated headers, restart with new ones (this 1877 should not occur). */ 1878 if(part->state.state == MIMESTATE_CURLHEADERS) 1879 mimesetstate(&part->state, MIMESTATE_CURLHEADERS, part->curlheaders); 1880 1881 /* Process subparts. */ 1882 if(part->kind == MIMEKIND_MULTIPART && mime) { 1883 curl_mimepart *subpart; 1884 1885 disposition = NULL; 1886 if(content_type_match(contenttype, STRCONST("multipart/form-data"))) 1887 disposition = "form-data"; 1888 for(subpart = mime->firstpart; subpart; subpart = subpart->nextpart) { 1889 ret = Curl_mime_prepare_headers(data, subpart, NULL, 1890 disposition, strategy); 1891 if(ret) 1892 return ret; 1893 } 1894 } 1895 return ret; 1896} 1897 1898/* Recursively reset paused status in the given part. */ 1899void Curl_mime_unpause(curl_mimepart *part) 1900{ 1901 if(part) { 1902 if(part->lastreadstatus == CURL_READFUNC_PAUSE) 1903 part->lastreadstatus = 1; /* Successful read status. */ 1904 if(part->kind == MIMEKIND_MULTIPART) { 1905 curl_mime *mime = (curl_mime *) part->arg; 1906 1907 if(mime) { 1908 curl_mimepart *subpart; 1909 1910 for(subpart = mime->firstpart; subpart; subpart = subpart->nextpart) 1911 Curl_mime_unpause(subpart); 1912 } 1913 } 1914 } 1915} 1916 1917 1918#else /* !CURL_DISABLE_MIME && (!CURL_DISABLE_HTTP || 1919 !CURL_DISABLE_SMTP || !CURL_DISABLE_IMAP) */ 1920 1921/* Mime not compiled in: define stubs for externally-referenced functions. */ 1922curl_mime *curl_mime_init(CURL *easy) 1923{ 1924 (void) easy; 1925 return NULL; 1926} 1927 1928void curl_mime_free(curl_mime *mime) 1929{ 1930 (void) mime; 1931} 1932 1933curl_mimepart *curl_mime_addpart(curl_mime *mime) 1934{ 1935 (void) mime; 1936 return NULL; 1937} 1938 1939CURLcode curl_mime_name(curl_mimepart *part, const char *name) 1940{ 1941 (void) part; 1942 (void) name; 1943 return CURLE_NOT_BUILT_IN; 1944} 1945 1946CURLcode curl_mime_filename(curl_mimepart *part, const char *filename) 1947{ 1948 (void) part; 1949 (void) filename; 1950 return CURLE_NOT_BUILT_IN; 1951} 1952 1953CURLcode curl_mime_type(curl_mimepart *part, const char *mimetype) 1954{ 1955 (void) part; 1956 (void) mimetype; 1957 return CURLE_NOT_BUILT_IN; 1958} 1959 1960CURLcode curl_mime_encoder(curl_mimepart *part, const char *encoding) 1961{ 1962 (void) part; 1963 (void) encoding; 1964 return CURLE_NOT_BUILT_IN; 1965} 1966 1967CURLcode curl_mime_data(curl_mimepart *part, 1968 const char *data, size_t datasize) 1969{ 1970 (void) part; 1971 (void) data; 1972 (void) datasize; 1973 return CURLE_NOT_BUILT_IN; 1974} 1975 1976CURLcode curl_mime_filedata(curl_mimepart *part, const char *filename) 1977{ 1978 (void) part; 1979 (void) filename; 1980 return CURLE_NOT_BUILT_IN; 1981} 1982 1983CURLcode curl_mime_data_cb(curl_mimepart *part, 1984 curl_off_t datasize, 1985 curl_read_callback readfunc, 1986 curl_seek_callback seekfunc, 1987 curl_free_callback freefunc, 1988 void *arg) 1989{ 1990 (void) part; 1991 (void) datasize; 1992 (void) readfunc; 1993 (void) seekfunc; 1994 (void) freefunc; 1995 (void) arg; 1996 return CURLE_NOT_BUILT_IN; 1997} 1998 1999CURLcode curl_mime_subparts(curl_mimepart *part, curl_mime *subparts) 2000{ 2001 (void) part; 2002 (void) subparts; 2003 return CURLE_NOT_BUILT_IN; 2004} 2005 2006CURLcode curl_mime_headers(curl_mimepart *part, 2007 struct curl_slist *headers, int take_ownership) 2008{ 2009 (void) part; 2010 (void) headers; 2011 (void) take_ownership; 2012 return CURLE_NOT_BUILT_IN; 2013} 2014 2015CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...) 2016{ 2017 (void)slp; 2018 (void)fmt; 2019 return CURLE_NOT_BUILT_IN; 2020} 2021 2022#endif /* if disabled */ 2023