sendf.c (39318B)
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 #ifdef HAVE_NETINET_IN_H 28 #include <netinet/in.h> 29 #endif 30 31 #ifdef HAVE_LINUX_TCP_H 32 #include <linux/tcp.h> 33 #elif defined(HAVE_NETINET_TCP_H) 34 #include <netinet/tcp.h> 35 #endif 36 37 #include <curl/curl.h> 38 39 #include "urldata.h" 40 #include "sendf.h" 41 #include "transfer.h" 42 #include "cfilters.h" 43 #include "connect.h" 44 #include "content_encoding.h" 45 #include "cw-out.h" 46 #include "cw-pause.h" 47 #include "vtls/vtls.h" 48 #include "vssh/ssh.h" 49 #include "easyif.h" 50 #include "multiif.h" 51 #include "strerror.h" 52 #include "select.h" 53 #include "strdup.h" 54 #include "http2.h" 55 #include "progress.h" 56 #include "curlx/warnless.h" 57 #include "ws.h" 58 59 /* The last 3 #include files should be in this order */ 60 #include "curl_printf.h" 61 #include "curl_memory.h" 62 #include "memdebug.h" 63 64 65 static CURLcode do_init_writer_stack(struct Curl_easy *data); 66 67 /* Curl_client_write() sends data to the write callback(s) 68 69 The bit pattern defines to what "streams" to write to. Body and/or header. 70 The defines are in sendf.h of course. 71 */ 72 CURLcode Curl_client_write(struct Curl_easy *data, 73 int type, const char *buf, size_t blen) 74 { 75 CURLcode result; 76 77 /* it is one of those, at least */ 78 DEBUGASSERT(type & (CLIENTWRITE_BODY|CLIENTWRITE_HEADER|CLIENTWRITE_INFO)); 79 /* BODY is only BODY (with optional EOS) */ 80 DEBUGASSERT(!(type & CLIENTWRITE_BODY) || 81 ((type & ~(CLIENTWRITE_BODY|CLIENTWRITE_EOS)) == 0)); 82 /* INFO is only INFO (with optional EOS) */ 83 DEBUGASSERT(!(type & CLIENTWRITE_INFO) || 84 ((type & ~(CLIENTWRITE_INFO|CLIENTWRITE_EOS)) == 0)); 85 86 if(!data->req.writer_stack) { 87 result = do_init_writer_stack(data); 88 if(result) 89 return result; 90 DEBUGASSERT(data->req.writer_stack); 91 } 92 93 result = Curl_cwriter_write(data, data->req.writer_stack, type, buf, blen); 94 CURL_TRC_WRITE(data, "client_write(type=%x, len=%zu) -> %d", 95 type, blen, result); 96 return result; 97 } 98 99 static void cl_reset_writer(struct Curl_easy *data) 100 { 101 struct Curl_cwriter *writer = data->req.writer_stack; 102 while(writer) { 103 data->req.writer_stack = writer->next; 104 writer->cwt->do_close(data, writer); 105 free(writer); 106 writer = data->req.writer_stack; 107 } 108 } 109 110 static void cl_reset_reader(struct Curl_easy *data) 111 { 112 struct Curl_creader *reader = data->req.reader_stack; 113 while(reader) { 114 data->req.reader_stack = reader->next; 115 reader->crt->do_close(data, reader); 116 free(reader); 117 reader = data->req.reader_stack; 118 } 119 } 120 121 void Curl_client_cleanup(struct Curl_easy *data) 122 { 123 cl_reset_reader(data); 124 cl_reset_writer(data); 125 126 data->req.bytecount = 0; 127 data->req.headerline = 0; 128 } 129 130 void Curl_client_reset(struct Curl_easy *data) 131 { 132 if(data->req.rewind_read) { 133 /* already requested */ 134 CURL_TRC_READ(data, "client_reset, will rewind reader"); 135 } 136 else { 137 CURL_TRC_READ(data, "client_reset, clear readers"); 138 cl_reset_reader(data); 139 } 140 cl_reset_writer(data); 141 142 data->req.bytecount = 0; 143 data->req.headerline = 0; 144 } 145 146 CURLcode Curl_client_start(struct Curl_easy *data) 147 { 148 if(data->req.rewind_read) { 149 struct Curl_creader *r = data->req.reader_stack; 150 CURLcode result = CURLE_OK; 151 152 CURL_TRC_READ(data, "client start, rewind readers"); 153 while(r) { 154 result = r->crt->rewind(data, r); 155 if(result) { 156 failf(data, "rewind of client reader '%s' failed: %d", 157 r->crt->name, result); 158 return result; 159 } 160 r = r->next; 161 } 162 data->req.rewind_read = FALSE; 163 cl_reset_reader(data); 164 } 165 return CURLE_OK; 166 } 167 168 bool Curl_creader_will_rewind(struct Curl_easy *data) 169 { 170 return data->req.rewind_read; 171 } 172 173 void Curl_creader_set_rewind(struct Curl_easy *data, bool enable) 174 { 175 data->req.rewind_read = !!enable; 176 } 177 178 /* Write data using an unencoding writer stack. */ 179 CURLcode Curl_cwriter_write(struct Curl_easy *data, 180 struct Curl_cwriter *writer, int type, 181 const char *buf, size_t nbytes) 182 { 183 if(!writer) 184 return CURLE_WRITE_ERROR; 185 return writer->cwt->do_write(data, writer, type, buf, nbytes); 186 } 187 188 CURLcode Curl_cwriter_def_init(struct Curl_easy *data, 189 struct Curl_cwriter *writer) 190 { 191 (void)data; 192 (void)writer; 193 return CURLE_OK; 194 } 195 196 CURLcode Curl_cwriter_def_write(struct Curl_easy *data, 197 struct Curl_cwriter *writer, int type, 198 const char *buf, size_t nbytes) 199 { 200 return Curl_cwriter_write(data, writer->next, type, buf, nbytes); 201 } 202 203 void Curl_cwriter_def_close(struct Curl_easy *data, 204 struct Curl_cwriter *writer) 205 { 206 (void) data; 207 (void) writer; 208 } 209 210 static size_t get_max_body_write_len(struct Curl_easy *data, curl_off_t limit) 211 { 212 if(limit != -1) { 213 /* How much more are we allowed to write? */ 214 curl_off_t remain_diff; 215 remain_diff = limit - data->req.bytecount; 216 if(remain_diff < 0) { 217 /* already written too much! */ 218 return 0; 219 } 220 #if SIZEOF_CURL_OFF_T > SIZEOF_SIZE_T 221 else if(remain_diff > SSIZE_T_MAX) { 222 return SIZE_T_MAX; 223 } 224 #endif 225 else { 226 return (size_t)remain_diff; 227 } 228 } 229 return SIZE_T_MAX; 230 } 231 232 struct cw_download_ctx { 233 struct Curl_cwriter super; 234 BIT(started_response); 235 }; 236 /* Download client writer in phase CURL_CW_PROTOCOL that 237 * sees the "real" download body data. */ 238 static CURLcode cw_download_write(struct Curl_easy *data, 239 struct Curl_cwriter *writer, int type, 240 const char *buf, size_t nbytes) 241 { 242 struct cw_download_ctx *ctx = writer->ctx; 243 CURLcode result; 244 size_t nwrite, excess_len = 0; 245 bool is_connect = !!(type & CLIENTWRITE_CONNECT); 246 247 if(!is_connect && !ctx->started_response) { 248 Curl_pgrsTime(data, TIMER_STARTTRANSFER); 249 ctx->started_response = TRUE; 250 } 251 252 if(!(type & CLIENTWRITE_BODY)) { 253 if(is_connect && data->set.suppress_connect_headers) 254 return CURLE_OK; 255 result = Curl_cwriter_write(data, writer->next, type, buf, nbytes); 256 CURL_TRC_WRITE(data, "download_write header(type=%x, blen=%zu) -> %d", 257 type, nbytes, result); 258 return result; 259 } 260 261 /* Here, we deal with REAL BODY bytes. All filtering and transfer 262 * encodings have been applied and only the true content, e.g. BODY, 263 * bytes are passed here. 264 * This allows us to check sizes, update stats, etc. independent 265 * from the protocol in play. */ 266 267 if(data->req.no_body && nbytes > 0) { 268 /* BODY arrives although we want none, bail out */ 269 streamclose(data->conn, "ignoring body"); 270 CURL_TRC_WRITE(data, "download_write body(type=%x, blen=%zu), " 271 "did not want a BODY", type, nbytes); 272 data->req.download_done = TRUE; 273 if(data->info.header_size) 274 /* if headers have been received, this is fine */ 275 return CURLE_OK; 276 return CURLE_WEIRD_SERVER_REPLY; 277 } 278 279 /* Determine if we see any bytes in excess to what is allowed. 280 * We write the allowed bytes and handle excess further below. 281 * This gives deterministic BODY writes on varying buffer receive 282 * lengths. */ 283 nwrite = nbytes; 284 if(-1 != data->req.maxdownload) { 285 size_t wmax = get_max_body_write_len(data, data->req.maxdownload); 286 if(nwrite > wmax) { 287 excess_len = nbytes - wmax; 288 nwrite = wmax; 289 } 290 291 if(nwrite == wmax) { 292 data->req.download_done = TRUE; 293 } 294 295 if((type & CLIENTWRITE_EOS) && !data->req.no_body && 296 (data->req.maxdownload > data->req.bytecount)) { 297 failf(data, "end of response with %" FMT_OFF_T " bytes missing", 298 data->req.maxdownload - data->req.bytecount); 299 return CURLE_PARTIAL_FILE; 300 } 301 } 302 303 /* Error on too large filesize is handled below, after writing 304 * the permitted bytes */ 305 if(data->set.max_filesize && !data->req.ignorebody) { 306 size_t wmax = get_max_body_write_len(data, data->set.max_filesize); 307 if(nwrite > wmax) { 308 nwrite = wmax; 309 } 310 } 311 312 if(!data->req.ignorebody && (nwrite || (type & CLIENTWRITE_EOS))) { 313 result = Curl_cwriter_write(data, writer->next, type, buf, nwrite); 314 CURL_TRC_WRITE(data, "download_write body(type=%x, blen=%zu) -> %d", 315 type, nbytes, result); 316 if(result) 317 return result; 318 } 319 /* Update stats, write and report progress */ 320 data->req.bytecount += nwrite; 321 result = Curl_pgrsSetDownloadCounter(data, data->req.bytecount); 322 if(result) 323 return result; 324 325 if(excess_len) { 326 if(!data->req.ignorebody) { 327 infof(data, 328 "Excess found writing body:" 329 " excess = %zu" 330 ", size = %" FMT_OFF_T 331 ", maxdownload = %" FMT_OFF_T 332 ", bytecount = %" FMT_OFF_T, 333 excess_len, data->req.size, data->req.maxdownload, 334 data->req.bytecount); 335 connclose(data->conn, "excess found in a read"); 336 } 337 } 338 else if((nwrite < nbytes) && !data->req.ignorebody) { 339 failf(data, "Exceeded the maximum allowed file size " 340 "(%" FMT_OFF_T ") with %" FMT_OFF_T " bytes", 341 data->set.max_filesize, data->req.bytecount); 342 return CURLE_FILESIZE_EXCEEDED; 343 } 344 345 return CURLE_OK; 346 } 347 348 static const struct Curl_cwtype cw_download = { 349 "protocol", 350 NULL, 351 Curl_cwriter_def_init, 352 cw_download_write, 353 Curl_cwriter_def_close, 354 sizeof(struct cw_download_ctx) 355 }; 356 357 /* RAW client writer in phase CURL_CW_RAW that 358 * enabled tracing of raw data. */ 359 static CURLcode cw_raw_write(struct Curl_easy *data, 360 struct Curl_cwriter *writer, int type, 361 const char *buf, size_t nbytes) 362 { 363 if(type & CLIENTWRITE_BODY && data->set.verbose && !data->req.ignorebody) { 364 Curl_debug(data, CURLINFO_DATA_IN, buf, nbytes); 365 } 366 return Curl_cwriter_write(data, writer->next, type, buf, nbytes); 367 } 368 369 static const struct Curl_cwtype cw_raw = { 370 "raw", 371 NULL, 372 Curl_cwriter_def_init, 373 cw_raw_write, 374 Curl_cwriter_def_close, 375 sizeof(struct Curl_cwriter) 376 }; 377 378 /* Create an unencoding writer stage using the given handler. */ 379 CURLcode Curl_cwriter_create(struct Curl_cwriter **pwriter, 380 struct Curl_easy *data, 381 const struct Curl_cwtype *cwt, 382 Curl_cwriter_phase phase) 383 { 384 struct Curl_cwriter *writer = NULL; 385 CURLcode result = CURLE_OUT_OF_MEMORY; 386 void *p; 387 388 DEBUGASSERT(cwt->cwriter_size >= sizeof(struct Curl_cwriter)); 389 p = calloc(1, cwt->cwriter_size); 390 if(!p) 391 goto out; 392 393 writer = (struct Curl_cwriter *)p; 394 writer->cwt = cwt; 395 writer->ctx = p; 396 writer->phase = phase; 397 result = cwt->do_init(data, writer); 398 399 out: 400 *pwriter = result ? NULL : writer; 401 if(result) 402 free(writer); 403 return result; 404 } 405 406 void Curl_cwriter_free(struct Curl_easy *data, 407 struct Curl_cwriter *writer) 408 { 409 if(writer) { 410 writer->cwt->do_close(data, writer); 411 free(writer); 412 } 413 } 414 415 size_t Curl_cwriter_count(struct Curl_easy *data, Curl_cwriter_phase phase) 416 { 417 struct Curl_cwriter *w; 418 size_t n = 0; 419 420 for(w = data->req.writer_stack; w; w = w->next) { 421 if(w->phase == phase) 422 ++n; 423 } 424 return n; 425 } 426 427 static CURLcode do_init_writer_stack(struct Curl_easy *data) 428 { 429 struct Curl_cwriter *writer; 430 CURLcode result; 431 432 DEBUGASSERT(!data->req.writer_stack); 433 result = Curl_cwriter_create(&data->req.writer_stack, 434 data, &Curl_cwt_out, CURL_CW_CLIENT); 435 if(result) 436 return result; 437 438 /* This places the "pause" writer behind the "download" writer that 439 * is added below. Meaning the "download" can do checks on content length 440 * and other things *before* write outs are buffered for paused transfers. */ 441 result = Curl_cwriter_create(&writer, data, &Curl_cwt_pause, 442 CURL_CW_PROTOCOL); 443 if(!result) { 444 result = Curl_cwriter_add(data, writer); 445 if(result) 446 Curl_cwriter_free(data, writer); 447 } 448 if(result) 449 return result; 450 451 result = Curl_cwriter_create(&writer, data, &cw_download, CURL_CW_PROTOCOL); 452 if(!result) { 453 result = Curl_cwriter_add(data, writer); 454 if(result) 455 Curl_cwriter_free(data, writer); 456 } 457 if(result) 458 return result; 459 460 result = Curl_cwriter_create(&writer, data, &cw_raw, CURL_CW_RAW); 461 if(!result) { 462 result = Curl_cwriter_add(data, writer); 463 if(result) 464 Curl_cwriter_free(data, writer); 465 } 466 if(result) 467 return result; 468 469 return result; 470 } 471 472 CURLcode Curl_cwriter_add(struct Curl_easy *data, 473 struct Curl_cwriter *writer) 474 { 475 CURLcode result; 476 struct Curl_cwriter **anchor = &data->req.writer_stack; 477 478 if(!*anchor) { 479 result = do_init_writer_stack(data); 480 if(result) 481 return result; 482 } 483 484 /* Insert the writer as first in its phase. 485 * Skip existing writers of lower phases. */ 486 while(*anchor && (*anchor)->phase < writer->phase) 487 anchor = &((*anchor)->next); 488 writer->next = *anchor; 489 *anchor = writer; 490 return CURLE_OK; 491 } 492 493 struct Curl_cwriter *Curl_cwriter_get_by_name(struct Curl_easy *data, 494 const char *name) 495 { 496 struct Curl_cwriter *writer; 497 for(writer = data->req.writer_stack; writer; writer = writer->next) { 498 if(!strcmp(name, writer->cwt->name)) 499 return writer; 500 } 501 return NULL; 502 } 503 504 struct Curl_cwriter *Curl_cwriter_get_by_type(struct Curl_easy *data, 505 const struct Curl_cwtype *cwt) 506 { 507 struct Curl_cwriter *writer; 508 for(writer = data->req.writer_stack; writer; writer = writer->next) { 509 if(writer->cwt == cwt) 510 return writer; 511 } 512 return NULL; 513 } 514 515 bool Curl_cwriter_is_content_decoding(struct Curl_easy *data) 516 { 517 struct Curl_cwriter *writer; 518 for(writer = data->req.writer_stack; writer; writer = writer->next) { 519 if(writer->phase == CURL_CW_CONTENT_DECODE) 520 return TRUE; 521 } 522 return FALSE; 523 } 524 525 bool Curl_cwriter_is_paused(struct Curl_easy *data) 526 { 527 return Curl_cw_out_is_paused(data); 528 } 529 530 CURLcode Curl_cwriter_unpause(struct Curl_easy *data) 531 { 532 return Curl_cw_out_unpause(data); 533 } 534 535 CURLcode Curl_creader_read(struct Curl_easy *data, 536 struct Curl_creader *reader, 537 char *buf, size_t blen, size_t *nread, bool *eos) 538 { 539 *nread = 0; 540 *eos = FALSE; 541 if(!reader) 542 return CURLE_READ_ERROR; 543 return reader->crt->do_read(data, reader, buf, blen, nread, eos); 544 } 545 546 CURLcode Curl_creader_def_init(struct Curl_easy *data, 547 struct Curl_creader *reader) 548 { 549 (void)data; 550 (void)reader; 551 return CURLE_OK; 552 } 553 554 void Curl_creader_def_close(struct Curl_easy *data, 555 struct Curl_creader *reader) 556 { 557 (void)data; 558 (void)reader; 559 } 560 561 CURLcode Curl_creader_def_read(struct Curl_easy *data, 562 struct Curl_creader *reader, 563 char *buf, size_t blen, 564 size_t *nread, bool *eos) 565 { 566 if(reader->next) 567 return reader->next->crt->do_read(data, reader->next, buf, blen, 568 nread, eos); 569 else { 570 *nread = 0; 571 *eos = FALSE; 572 return CURLE_READ_ERROR; 573 } 574 } 575 576 bool Curl_creader_def_needs_rewind(struct Curl_easy *data, 577 struct Curl_creader *reader) 578 { 579 (void)data; 580 (void)reader; 581 return FALSE; 582 } 583 584 curl_off_t Curl_creader_def_total_length(struct Curl_easy *data, 585 struct Curl_creader *reader) 586 { 587 return reader->next ? 588 reader->next->crt->total_length(data, reader->next) : -1; 589 } 590 591 CURLcode Curl_creader_def_resume_from(struct Curl_easy *data, 592 struct Curl_creader *reader, 593 curl_off_t offset) 594 { 595 (void)data; 596 (void)reader; 597 (void)offset; 598 return CURLE_READ_ERROR; 599 } 600 601 CURLcode Curl_creader_def_rewind(struct Curl_easy *data, 602 struct Curl_creader *reader) 603 { 604 (void)data; 605 (void)reader; 606 return CURLE_OK; 607 } 608 609 CURLcode Curl_creader_def_unpause(struct Curl_easy *data, 610 struct Curl_creader *reader) 611 { 612 (void)data; 613 (void)reader; 614 return CURLE_OK; 615 } 616 617 bool Curl_creader_def_is_paused(struct Curl_easy *data, 618 struct Curl_creader *reader) 619 { 620 (void)data; 621 (void)reader; 622 return FALSE; 623 } 624 625 void Curl_creader_def_done(struct Curl_easy *data, 626 struct Curl_creader *reader, int premature) 627 { 628 (void)data; 629 (void)reader; 630 (void)premature; 631 } 632 633 struct cr_in_ctx { 634 struct Curl_creader super; 635 curl_read_callback read_cb; 636 void *cb_user_data; 637 curl_off_t total_len; 638 curl_off_t read_len; 639 CURLcode error_result; 640 BIT(seen_eos); 641 BIT(errored); 642 BIT(has_used_cb); 643 BIT(is_paused); 644 }; 645 646 static CURLcode cr_in_init(struct Curl_easy *data, struct Curl_creader *reader) 647 { 648 struct cr_in_ctx *ctx = reader->ctx; 649 (void)data; 650 ctx->read_cb = data->state.fread_func; 651 ctx->cb_user_data = data->state.in; 652 ctx->total_len = -1; 653 ctx->read_len = 0; 654 return CURLE_OK; 655 } 656 657 /* Real client reader to installed client callbacks. */ 658 static CURLcode cr_in_read(struct Curl_easy *data, 659 struct Curl_creader *reader, 660 char *buf, size_t blen, 661 size_t *pnread, bool *peos) 662 { 663 struct cr_in_ctx *ctx = reader->ctx; 664 CURLcode result = CURLE_OK; 665 size_t nread; 666 667 ctx->is_paused = FALSE; 668 669 /* Once we have errored, we will return the same error forever */ 670 if(ctx->errored) { 671 *pnread = 0; 672 *peos = FALSE; 673 return ctx->error_result; 674 } 675 if(ctx->seen_eos) { 676 *pnread = 0; 677 *peos = TRUE; 678 return CURLE_OK; 679 } 680 /* respect length limitations */ 681 if(ctx->total_len >= 0) { 682 curl_off_t remain = ctx->total_len - ctx->read_len; 683 if(remain <= 0) 684 blen = 0; 685 else if(remain < (curl_off_t)blen) 686 blen = (size_t)remain; 687 } 688 nread = 0; 689 if(ctx->read_cb && blen) { 690 Curl_set_in_callback(data, TRUE); 691 nread = ctx->read_cb(buf, 1, blen, ctx->cb_user_data); 692 Curl_set_in_callback(data, FALSE); 693 ctx->has_used_cb = TRUE; 694 } 695 696 switch(nread) { 697 case 0: 698 if((ctx->total_len >= 0) && (ctx->read_len < ctx->total_len)) { 699 failf(data, "client read function EOF fail, " 700 "only %"FMT_OFF_T"/%"FMT_OFF_T " of needed bytes read", 701 ctx->read_len, ctx->total_len); 702 result = CURLE_READ_ERROR; 703 break; 704 } 705 *pnread = 0; 706 *peos = TRUE; 707 ctx->seen_eos = TRUE; 708 break; 709 710 case CURL_READFUNC_ABORT: 711 failf(data, "operation aborted by callback"); 712 *pnread = 0; 713 *peos = FALSE; 714 ctx->errored = TRUE; 715 ctx->error_result = CURLE_ABORTED_BY_CALLBACK; 716 result = CURLE_ABORTED_BY_CALLBACK; 717 break; 718 719 case CURL_READFUNC_PAUSE: 720 if(data->conn->handler->flags & PROTOPT_NONETWORK) { 721 /* protocols that work without network cannot be paused. This is 722 actually only FILE:// just now, and it cannot pause since the transfer 723 is not done using the "normal" procedure. */ 724 failf(data, "Read callback asked for PAUSE when not supported"); 725 result = CURLE_READ_ERROR; 726 break; 727 } 728 /* CURL_READFUNC_PAUSE pauses read callbacks that feed socket writes */ 729 CURL_TRC_READ(data, "cr_in_read, callback returned CURL_READFUNC_PAUSE"); 730 ctx->is_paused = TRUE; 731 *pnread = 0; 732 *peos = FALSE; 733 result = Curl_xfer_pause_send(data, TRUE); 734 break; /* nothing was read */ 735 736 default: 737 if(nread > blen) { 738 /* the read function returned a too large value */ 739 failf(data, "read function returned funny value"); 740 *pnread = 0; 741 *peos = FALSE; 742 ctx->errored = TRUE; 743 ctx->error_result = CURLE_READ_ERROR; 744 result = CURLE_READ_ERROR; 745 break; 746 } 747 ctx->read_len += nread; 748 if(ctx->total_len >= 0) 749 ctx->seen_eos = (ctx->read_len >= ctx->total_len); 750 *pnread = nread; 751 *peos = ctx->seen_eos; 752 break; 753 } 754 CURL_TRC_READ(data, "cr_in_read(len=%zu, total=%"FMT_OFF_T 755 ", read=%"FMT_OFF_T") -> %d, nread=%zu, eos=%d", 756 blen, ctx->total_len, ctx->read_len, result, 757 *pnread, *peos); 758 return result; 759 } 760 761 static bool cr_in_needs_rewind(struct Curl_easy *data, 762 struct Curl_creader *reader) 763 { 764 struct cr_in_ctx *ctx = reader->ctx; 765 (void)data; 766 return ctx->has_used_cb; 767 } 768 769 static curl_off_t cr_in_total_length(struct Curl_easy *data, 770 struct Curl_creader *reader) 771 { 772 struct cr_in_ctx *ctx = reader->ctx; 773 (void)data; 774 return ctx->total_len; 775 } 776 777 static CURLcode cr_in_resume_from(struct Curl_easy *data, 778 struct Curl_creader *reader, 779 curl_off_t offset) 780 { 781 struct cr_in_ctx *ctx = reader->ctx; 782 int seekerr = CURL_SEEKFUNC_CANTSEEK; 783 784 DEBUGASSERT(data->conn); 785 /* already started reading? */ 786 if(ctx->read_len) 787 return CURLE_READ_ERROR; 788 789 if(data->set.seek_func) { 790 Curl_set_in_callback(data, TRUE); 791 seekerr = data->set.seek_func(data->set.seek_client, offset, SEEK_SET); 792 Curl_set_in_callback(data, FALSE); 793 } 794 795 if(seekerr != CURL_SEEKFUNC_OK) { 796 curl_off_t passed = 0; 797 798 if(seekerr != CURL_SEEKFUNC_CANTSEEK) { 799 failf(data, "Could not seek stream"); 800 return CURLE_READ_ERROR; 801 } 802 /* when seekerr == CURL_SEEKFUNC_CANTSEEK (cannot seek to offset) */ 803 do { 804 char scratch[4*1024]; 805 size_t readthisamountnow = 806 (offset - passed > (curl_off_t)sizeof(scratch)) ? 807 sizeof(scratch) : 808 curlx_sotouz(offset - passed); 809 size_t actuallyread; 810 811 Curl_set_in_callback(data, TRUE); 812 actuallyread = ctx->read_cb(scratch, 1, readthisamountnow, 813 ctx->cb_user_data); 814 Curl_set_in_callback(data, FALSE); 815 816 passed += actuallyread; 817 if((actuallyread == 0) || (actuallyread > readthisamountnow)) { 818 /* this checks for greater-than only to make sure that the 819 CURL_READFUNC_ABORT return code still aborts */ 820 failf(data, "Could only read %" FMT_OFF_T " bytes from the input", 821 passed); 822 return CURLE_READ_ERROR; 823 } 824 } while(passed < offset); 825 } 826 827 /* now, decrease the size of the read */ 828 if(ctx->total_len > 0) { 829 ctx->total_len -= offset; 830 831 if(ctx->total_len <= 0) { 832 failf(data, "File already completely uploaded"); 833 return CURLE_PARTIAL_FILE; 834 } 835 } 836 /* we have passed, proceed as normal */ 837 return CURLE_OK; 838 } 839 840 static CURLcode cr_in_rewind(struct Curl_easy *data, 841 struct Curl_creader *reader) 842 { 843 struct cr_in_ctx *ctx = reader->ctx; 844 845 /* If we never invoked the callback, there is noting to rewind */ 846 if(!ctx->has_used_cb) 847 return CURLE_OK; 848 849 if(data->set.seek_func) { 850 int err; 851 852 Curl_set_in_callback(data, TRUE); 853 err = (data->set.seek_func)(data->set.seek_client, 0, SEEK_SET); 854 Curl_set_in_callback(data, FALSE); 855 CURL_TRC_READ(data, "cr_in, rewind via set.seek_func -> %d", err); 856 if(err) { 857 failf(data, "seek callback returned error %d", (int)err); 858 return CURLE_SEND_FAIL_REWIND; 859 } 860 } 861 else if(data->set.ioctl_func) { 862 curlioerr err; 863 864 Curl_set_in_callback(data, TRUE); 865 err = (data->set.ioctl_func)(data, CURLIOCMD_RESTARTREAD, 866 data->set.ioctl_client); 867 Curl_set_in_callback(data, FALSE); 868 CURL_TRC_READ(data, "cr_in, rewind via set.ioctl_func -> %d", (int)err); 869 if(err) { 870 failf(data, "ioctl callback returned error %d", (int)err); 871 return CURLE_SEND_FAIL_REWIND; 872 } 873 } 874 else { 875 /* If no CURLOPT_READFUNCTION is used, we know that we operate on a 876 given FILE * stream and we can actually attempt to rewind that 877 ourselves with fseek() */ 878 if(data->state.fread_func == (curl_read_callback)fread) { 879 int err = fseek(data->state.in, 0, SEEK_SET); 880 CURL_TRC_READ(data, "cr_in, rewind via fseek -> %d(%d)", 881 (int)err, (int)errno); 882 if(-1 != err) 883 /* successful rewind */ 884 return CURLE_OK; 885 } 886 887 /* no callback set or failure above, makes us fail at once */ 888 failf(data, "necessary data rewind was not possible"); 889 return CURLE_SEND_FAIL_REWIND; 890 } 891 return CURLE_OK; 892 } 893 894 static CURLcode cr_in_unpause(struct Curl_easy *data, 895 struct Curl_creader *reader) 896 { 897 struct cr_in_ctx *ctx = reader->ctx; 898 (void)data; 899 ctx->is_paused = FALSE; 900 return CURLE_OK; 901 } 902 903 static bool cr_in_is_paused(struct Curl_easy *data, 904 struct Curl_creader *reader) 905 { 906 struct cr_in_ctx *ctx = reader->ctx; 907 (void)data; 908 return ctx->is_paused; 909 } 910 911 static const struct Curl_crtype cr_in = { 912 "cr-in", 913 cr_in_init, 914 cr_in_read, 915 Curl_creader_def_close, 916 cr_in_needs_rewind, 917 cr_in_total_length, 918 cr_in_resume_from, 919 cr_in_rewind, 920 cr_in_unpause, 921 cr_in_is_paused, 922 Curl_creader_def_done, 923 sizeof(struct cr_in_ctx) 924 }; 925 926 CURLcode Curl_creader_create(struct Curl_creader **preader, 927 struct Curl_easy *data, 928 const struct Curl_crtype *crt, 929 Curl_creader_phase phase) 930 { 931 struct Curl_creader *reader = NULL; 932 CURLcode result = CURLE_OUT_OF_MEMORY; 933 void *p; 934 935 DEBUGASSERT(crt->creader_size >= sizeof(struct Curl_creader)); 936 p = calloc(1, crt->creader_size); 937 if(!p) 938 goto out; 939 940 reader = (struct Curl_creader *)p; 941 reader->crt = crt; 942 reader->ctx = p; 943 reader->phase = phase; 944 result = crt->do_init(data, reader); 945 946 out: 947 *preader = result ? NULL : reader; 948 if(result) 949 free(reader); 950 return result; 951 } 952 953 void Curl_creader_free(struct Curl_easy *data, struct Curl_creader *reader) 954 { 955 if(reader) { 956 reader->crt->do_close(data, reader); 957 free(reader); 958 } 959 } 960 961 struct cr_lc_ctx { 962 struct Curl_creader super; 963 struct bufq buf; 964 BIT(read_eos); /* we read an EOS from the next reader */ 965 BIT(eos); /* we have returned an EOS */ 966 BIT(prev_cr); /* the last byte was a CR */ 967 }; 968 969 static CURLcode cr_lc_init(struct Curl_easy *data, struct Curl_creader *reader) 970 { 971 struct cr_lc_ctx *ctx = reader->ctx; 972 (void)data; 973 Curl_bufq_init2(&ctx->buf, (16 * 1024), 1, BUFQ_OPT_SOFT_LIMIT); 974 return CURLE_OK; 975 } 976 977 static void cr_lc_close(struct Curl_easy *data, struct Curl_creader *reader) 978 { 979 struct cr_lc_ctx *ctx = reader->ctx; 980 (void)data; 981 Curl_bufq_free(&ctx->buf); 982 } 983 984 /* client reader doing line end conversions. */ 985 static CURLcode cr_lc_read(struct Curl_easy *data, 986 struct Curl_creader *reader, 987 char *buf, size_t blen, 988 size_t *pnread, bool *peos) 989 { 990 struct cr_lc_ctx *ctx = reader->ctx; 991 CURLcode result; 992 size_t nread, i, start, n; 993 bool eos; 994 995 if(ctx->eos) { 996 *pnread = 0; 997 *peos = TRUE; 998 return CURLE_OK; 999 } 1000 1001 if(Curl_bufq_is_empty(&ctx->buf)) { 1002 if(ctx->read_eos) { 1003 ctx->eos = TRUE; 1004 *pnread = 0; 1005 *peos = TRUE; 1006 return CURLE_OK; 1007 } 1008 /* Still getting data form the next reader, ctx->buf is empty */ 1009 result = Curl_creader_read(data, reader->next, buf, blen, &nread, &eos); 1010 if(result) 1011 return result; 1012 ctx->read_eos = eos; 1013 1014 if(!nread || !memchr(buf, '\n', nread)) { 1015 /* nothing to convert, return this right away */ 1016 if(ctx->read_eos) 1017 ctx->eos = TRUE; 1018 *pnread = nread; 1019 *peos = ctx->eos; 1020 goto out; 1021 } 1022 1023 /* at least one \n might need conversion to '\r\n', place into ctx->buf */ 1024 for(i = start = 0; i < nread; ++i) { 1025 /* if this byte is not an LF character, or if the preceding character is 1026 a CR (meaning this already is a CRLF pair), go to next */ 1027 if((buf[i] != '\n') || ctx->prev_cr) { 1028 ctx->prev_cr = (buf[i] == '\r'); 1029 continue; 1030 } 1031 ctx->prev_cr = FALSE; 1032 /* on a soft limit bufq, we do not need to check length */ 1033 result = Curl_bufq_cwrite(&ctx->buf, buf + start, i - start, &n); 1034 if(!result) 1035 result = Curl_bufq_cwrite(&ctx->buf, STRCONST("\r\n"), &n); 1036 if(result) 1037 return result; 1038 start = i + 1; 1039 } 1040 1041 if(start < i) { /* leftover */ 1042 result = Curl_bufq_cwrite(&ctx->buf, buf + start, i - start, &n); 1043 if(result) 1044 return result; 1045 } 1046 } 1047 1048 DEBUGASSERT(!Curl_bufq_is_empty(&ctx->buf)); 1049 *peos = FALSE; 1050 result = Curl_bufq_cread(&ctx->buf, buf, blen, pnread); 1051 if(!result && ctx->read_eos && Curl_bufq_is_empty(&ctx->buf)) { 1052 /* no more data, read all, done. */ 1053 ctx->eos = TRUE; 1054 *peos = TRUE; 1055 } 1056 1057 out: 1058 CURL_TRC_READ(data, "cr_lc_read(len=%zu) -> %d, nread=%zu, eos=%d", 1059 blen, result, *pnread, *peos); 1060 return result; 1061 } 1062 1063 static curl_off_t cr_lc_total_length(struct Curl_easy *data, 1064 struct Curl_creader *reader) 1065 { 1066 /* this reader changes length depending on input */ 1067 (void)data; 1068 (void)reader; 1069 return -1; 1070 } 1071 1072 static const struct Curl_crtype cr_lc = { 1073 "cr-lineconv", 1074 cr_lc_init, 1075 cr_lc_read, 1076 cr_lc_close, 1077 Curl_creader_def_needs_rewind, 1078 cr_lc_total_length, 1079 Curl_creader_def_resume_from, 1080 Curl_creader_def_rewind, 1081 Curl_creader_def_unpause, 1082 Curl_creader_def_is_paused, 1083 Curl_creader_def_done, 1084 sizeof(struct cr_lc_ctx) 1085 }; 1086 1087 static CURLcode cr_lc_add(struct Curl_easy *data) 1088 { 1089 struct Curl_creader *reader = NULL; 1090 CURLcode result; 1091 1092 result = Curl_creader_create(&reader, data, &cr_lc, 1093 CURL_CR_CONTENT_ENCODE); 1094 if(!result) 1095 result = Curl_creader_add(data, reader); 1096 1097 if(result && reader) 1098 Curl_creader_free(data, reader); 1099 return result; 1100 } 1101 1102 static CURLcode do_init_reader_stack(struct Curl_easy *data, 1103 struct Curl_creader *r) 1104 { 1105 CURLcode result = CURLE_OK; 1106 curl_off_t clen; 1107 1108 DEBUGASSERT(r); 1109 DEBUGASSERT(r->crt); 1110 DEBUGASSERT(r->phase == CURL_CR_CLIENT); 1111 DEBUGASSERT(!data->req.reader_stack); 1112 1113 data->req.reader_stack = r; 1114 clen = r->crt->total_length(data, r); 1115 /* if we do not have 0 length init, and crlf conversion is wanted, 1116 * add the reader for it */ 1117 if(clen && (data->set.crlf 1118 #ifdef CURL_PREFER_LF_LINEENDS 1119 || data->state.prefer_ascii 1120 #endif 1121 )) { 1122 result = cr_lc_add(data); 1123 if(result) 1124 return result; 1125 } 1126 1127 return result; 1128 } 1129 1130 CURLcode Curl_creader_set_fread(struct Curl_easy *data, curl_off_t len) 1131 { 1132 CURLcode result; 1133 struct Curl_creader *r; 1134 struct cr_in_ctx *ctx; 1135 1136 result = Curl_creader_create(&r, data, &cr_in, CURL_CR_CLIENT); 1137 if(result) 1138 goto out; 1139 ctx = r->ctx; 1140 ctx->total_len = len; 1141 1142 cl_reset_reader(data); 1143 result = do_init_reader_stack(data, r); 1144 out: 1145 CURL_TRC_READ(data, "add fread reader, len=%"FMT_OFF_T " -> %d", 1146 len, result); 1147 return result; 1148 } 1149 1150 CURLcode Curl_creader_add(struct Curl_easy *data, 1151 struct Curl_creader *reader) 1152 { 1153 CURLcode result; 1154 struct Curl_creader **anchor = &data->req.reader_stack; 1155 1156 if(!*anchor) { 1157 result = Curl_creader_set_fread(data, data->state.infilesize); 1158 if(result) 1159 return result; 1160 } 1161 1162 /* Insert the writer as first in its phase. 1163 * Skip existing readers of lower phases. */ 1164 while(*anchor && (*anchor)->phase < reader->phase) 1165 anchor = &((*anchor)->next); 1166 reader->next = *anchor; 1167 *anchor = reader; 1168 return CURLE_OK; 1169 } 1170 1171 CURLcode Curl_creader_set(struct Curl_easy *data, struct Curl_creader *r) 1172 { 1173 CURLcode result; 1174 1175 DEBUGASSERT(r); 1176 DEBUGASSERT(r->crt); 1177 DEBUGASSERT(r->phase == CURL_CR_CLIENT); 1178 1179 cl_reset_reader(data); 1180 result = do_init_reader_stack(data, r); 1181 if(result) 1182 Curl_creader_free(data, r); 1183 return result; 1184 } 1185 1186 CURLcode Curl_client_read(struct Curl_easy *data, char *buf, size_t blen, 1187 size_t *nread, bool *eos) 1188 { 1189 CURLcode result; 1190 1191 DEBUGASSERT(buf); 1192 DEBUGASSERT(blen); 1193 DEBUGASSERT(nread); 1194 DEBUGASSERT(eos); 1195 1196 if(!data->req.reader_stack) { 1197 result = Curl_creader_set_fread(data, data->state.infilesize); 1198 if(result) 1199 return result; 1200 DEBUGASSERT(data->req.reader_stack); 1201 } 1202 1203 result = Curl_creader_read(data, data->req.reader_stack, buf, blen, 1204 nread, eos); 1205 CURL_TRC_READ(data, "client_read(len=%zu) -> %d, nread=%zu, eos=%d", 1206 blen, result, *nread, *eos); 1207 return result; 1208 } 1209 1210 bool Curl_creader_needs_rewind(struct Curl_easy *data) 1211 { 1212 struct Curl_creader *reader = data->req.reader_stack; 1213 while(reader) { 1214 if(reader->crt->needs_rewind(data, reader)) { 1215 CURL_TRC_READ(data, "client reader needs rewind before next request"); 1216 return TRUE; 1217 } 1218 reader = reader->next; 1219 } 1220 return FALSE; 1221 } 1222 1223 static CURLcode cr_null_read(struct Curl_easy *data, 1224 struct Curl_creader *reader, 1225 char *buf, size_t blen, 1226 size_t *pnread, bool *peos) 1227 { 1228 (void)data; 1229 (void)reader; 1230 (void)buf; 1231 (void)blen; 1232 *pnread = 0; 1233 *peos = TRUE; 1234 return CURLE_OK; 1235 } 1236 1237 static curl_off_t cr_null_total_length(struct Curl_easy *data, 1238 struct Curl_creader *reader) 1239 { 1240 /* this reader changes length depending on input */ 1241 (void)data; 1242 (void)reader; 1243 return 0; 1244 } 1245 1246 static const struct Curl_crtype cr_null = { 1247 "cr-null", 1248 Curl_creader_def_init, 1249 cr_null_read, 1250 Curl_creader_def_close, 1251 Curl_creader_def_needs_rewind, 1252 cr_null_total_length, 1253 Curl_creader_def_resume_from, 1254 Curl_creader_def_rewind, 1255 Curl_creader_def_unpause, 1256 Curl_creader_def_is_paused, 1257 Curl_creader_def_done, 1258 sizeof(struct Curl_creader) 1259 }; 1260 1261 CURLcode Curl_creader_set_null(struct Curl_easy *data) 1262 { 1263 struct Curl_creader *r; 1264 CURLcode result; 1265 1266 result = Curl_creader_create(&r, data, &cr_null, CURL_CR_CLIENT); 1267 if(result) 1268 return result; 1269 1270 cl_reset_reader(data); 1271 return do_init_reader_stack(data, r); 1272 } 1273 1274 struct cr_buf_ctx { 1275 struct Curl_creader super; 1276 const char *buf; 1277 size_t blen; 1278 size_t index; 1279 }; 1280 1281 static CURLcode cr_buf_read(struct Curl_easy *data, 1282 struct Curl_creader *reader, 1283 char *buf, size_t blen, 1284 size_t *pnread, bool *peos) 1285 { 1286 struct cr_buf_ctx *ctx = reader->ctx; 1287 size_t nread = ctx->blen - ctx->index; 1288 1289 (void)data; 1290 if(!nread || !ctx->buf) { 1291 *pnread = 0; 1292 *peos = TRUE; 1293 } 1294 else { 1295 if(nread > blen) 1296 nread = blen; 1297 memcpy(buf, ctx->buf + ctx->index, nread); 1298 *pnread = nread; 1299 ctx->index += nread; 1300 *peos = (ctx->index == ctx->blen); 1301 } 1302 CURL_TRC_READ(data, "cr_buf_read(len=%zu) -> 0, nread=%zu, eos=%d", 1303 blen, *pnread, *peos); 1304 return CURLE_OK; 1305 } 1306 1307 static bool cr_buf_needs_rewind(struct Curl_easy *data, 1308 struct Curl_creader *reader) 1309 { 1310 struct cr_buf_ctx *ctx = reader->ctx; 1311 (void)data; 1312 return ctx->index > 0; 1313 } 1314 1315 static CURLcode cr_buf_rewind(struct Curl_easy *data, 1316 struct Curl_creader *reader) 1317 { 1318 struct cr_buf_ctx *ctx = reader->ctx; 1319 (void)data; 1320 ctx->index = 0; 1321 return CURLE_OK; 1322 } 1323 1324 static curl_off_t cr_buf_total_length(struct Curl_easy *data, 1325 struct Curl_creader *reader) 1326 { 1327 struct cr_buf_ctx *ctx = reader->ctx; 1328 (void)data; 1329 return (curl_off_t)ctx->blen; 1330 } 1331 1332 static CURLcode cr_buf_resume_from(struct Curl_easy *data, 1333 struct Curl_creader *reader, 1334 curl_off_t offset) 1335 { 1336 struct cr_buf_ctx *ctx = reader->ctx; 1337 size_t boffset; 1338 1339 (void)data; 1340 DEBUGASSERT(data->conn); 1341 /* already started reading? */ 1342 if(ctx->index) 1343 return CURLE_READ_ERROR; 1344 if(offset <= 0) 1345 return CURLE_OK; 1346 boffset = (size_t)offset; 1347 if(boffset > ctx->blen) 1348 return CURLE_READ_ERROR; 1349 1350 ctx->buf += boffset; 1351 ctx->blen -= boffset; 1352 return CURLE_OK; 1353 } 1354 1355 static const struct Curl_crtype cr_buf = { 1356 "cr-buf", 1357 Curl_creader_def_init, 1358 cr_buf_read, 1359 Curl_creader_def_close, 1360 cr_buf_needs_rewind, 1361 cr_buf_total_length, 1362 cr_buf_resume_from, 1363 cr_buf_rewind, 1364 Curl_creader_def_unpause, 1365 Curl_creader_def_is_paused, 1366 Curl_creader_def_done, 1367 sizeof(struct cr_buf_ctx) 1368 }; 1369 1370 CURLcode Curl_creader_set_buf(struct Curl_easy *data, 1371 const char *buf, size_t blen) 1372 { 1373 CURLcode result; 1374 struct Curl_creader *r; 1375 struct cr_buf_ctx *ctx; 1376 1377 result = Curl_creader_create(&r, data, &cr_buf, CURL_CR_CLIENT); 1378 if(result) 1379 goto out; 1380 ctx = r->ctx; 1381 ctx->buf = buf; 1382 ctx->blen = blen; 1383 ctx->index = 0; 1384 1385 cl_reset_reader(data); 1386 result = do_init_reader_stack(data, r); 1387 out: 1388 CURL_TRC_READ(data, "add buf reader, len=%zu -> %d", blen, result); 1389 return result; 1390 } 1391 1392 curl_off_t Curl_creader_total_length(struct Curl_easy *data) 1393 { 1394 struct Curl_creader *r = data->req.reader_stack; 1395 return r ? r->crt->total_length(data, r) : -1; 1396 } 1397 1398 curl_off_t Curl_creader_client_length(struct Curl_easy *data) 1399 { 1400 struct Curl_creader *r = data->req.reader_stack; 1401 while(r && r->phase != CURL_CR_CLIENT) 1402 r = r->next; 1403 return r ? r->crt->total_length(data, r) : -1; 1404 } 1405 1406 CURLcode Curl_creader_resume_from(struct Curl_easy *data, curl_off_t offset) 1407 { 1408 struct Curl_creader *r = data->req.reader_stack; 1409 while(r && r->phase != CURL_CR_CLIENT) 1410 r = r->next; 1411 return r ? r->crt->resume_from(data, r, offset) : CURLE_READ_ERROR; 1412 } 1413 1414 CURLcode Curl_creader_unpause(struct Curl_easy *data) 1415 { 1416 struct Curl_creader *reader = data->req.reader_stack; 1417 CURLcode result = CURLE_OK; 1418 1419 while(reader) { 1420 result = reader->crt->unpause(data, reader); 1421 if(result) 1422 break; 1423 reader = reader->next; 1424 } 1425 return result; 1426 } 1427 1428 bool Curl_creader_is_paused(struct Curl_easy *data) 1429 { 1430 struct Curl_creader *reader = data->req.reader_stack; 1431 1432 while(reader) { 1433 if(reader->crt->is_paused(data, reader)) 1434 return TRUE; 1435 reader = reader->next; 1436 } 1437 return FALSE; 1438 } 1439 1440 void Curl_creader_done(struct Curl_easy *data, int premature) 1441 { 1442 struct Curl_creader *reader = data->req.reader_stack; 1443 while(reader) { 1444 reader->crt->done(data, reader, premature); 1445 reader = reader->next; 1446 } 1447 } 1448 1449 struct Curl_creader *Curl_creader_get_by_type(struct Curl_easy *data, 1450 const struct Curl_crtype *crt) 1451 { 1452 struct Curl_creader *r; 1453 for(r = data->req.reader_stack; r; r = r->next) { 1454 if(r->crt == crt) 1455 return r; 1456 } 1457 return NULL; 1458 1459 }