1 /*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel (at) 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.haxx.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 ***************************************************************************/ 22 23 #include "curl_setup.h" 24 25 #ifdef HAVE_NETINET_IN_H 26 #include <netinet/in.h> 27 #endif 28 29 #ifdef HAVE_LINUX_TCP_H 30 #include <linux/tcp.h> 31 #endif 32 33 #include <curl/curl.h> 34 35 #include "urldata.h" 36 #include "sendf.h" 37 #include "connect.h" 38 #include "vtls/vtls.h" 39 #include "ssh.h" 40 #include "multiif.h" 41 #include "non-ascii.h" 42 #include "strerror.h" 43 #include "select.h" 44 #include "strdup.h" 45 46 /* The last 3 #include files should be in this order */ 47 #include "curl_printf.h" 48 #include "curl_memory.h" 49 #include "memdebug.h" 50 51 #ifdef CURL_DO_LINEEND_CONV 52 /* 53 * convert_lineends() changes CRLF (\r\n) end-of-line markers to a single LF 54 * (\n), with special processing for CRLF sequences that are split between two 55 * blocks of data. Remaining, bare CRs are changed to LFs. The possibly new 56 * size of the data is returned. 57 */ 58 static size_t convert_lineends(struct Curl_easy *data, 59 char *startPtr, size_t size) 60 { 61 char *inPtr, *outPtr; 62 63 /* sanity check */ 64 if((startPtr == NULL) || (size < 1)) { 65 return size; 66 } 67 68 if(data->state.prev_block_had_trailing_cr) { 69 /* The previous block of incoming data 70 had a trailing CR, which was turned into a LF. */ 71 if(*startPtr == '\n') { 72 /* This block of incoming data starts with the 73 previous block's LF so get rid of it */ 74 memmove(startPtr, startPtr + 1, size-1); 75 size--; 76 /* and it wasn't a bare CR but a CRLF conversion instead */ 77 data->state.crlf_conversions++; 78 } 79 data->state.prev_block_had_trailing_cr = FALSE; /* reset the flag */ 80 } 81 82 /* find 1st CR, if any */ 83 inPtr = outPtr = memchr(startPtr, '\r', size); 84 if(inPtr) { 85 /* at least one CR, now look for CRLF */ 86 while(inPtr < (startPtr + size-1)) { 87 /* note that it's size-1, so we'll never look past the last byte */ 88 if(memcmp(inPtr, "\r\n", 2) == 0) { 89 /* CRLF found, bump past the CR and copy the NL */ 90 inPtr++; 91 *outPtr = *inPtr; 92 /* keep track of how many CRLFs we converted */ 93 data->state.crlf_conversions++; 94 } 95 else { 96 if(*inPtr == '\r') { 97 /* lone CR, move LF instead */ 98 *outPtr = '\n'; 99 } 100 else { 101 /* not a CRLF nor a CR, just copy whatever it is */ 102 *outPtr = *inPtr; 103 } 104 } 105 outPtr++; 106 inPtr++; 107 } /* end of while loop */ 108 109 if(inPtr < startPtr + size) { 110 /* handle last byte */ 111 if(*inPtr == '\r') { 112 /* deal with a CR at the end of the buffer */ 113 *outPtr = '\n'; /* copy a NL instead */ 114 /* note that a CRLF might be split across two blocks */ 115 data->state.prev_block_had_trailing_cr = TRUE; 116 } 117 else { 118 /* copy last byte */ 119 *outPtr = *inPtr; 120 } 121 outPtr++; 122 } 123 if(outPtr < startPtr + size) 124 /* tidy up by null terminating the now shorter data */ 125 *outPtr = '\0'; 126 127 return (outPtr - startPtr); 128 } 129 return size; 130 } 131 #endif /* CURL_DO_LINEEND_CONV */ 132 133 #ifdef USE_RECV_BEFORE_SEND_WORKAROUND 134 bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex) 135 { 136 struct postponed_data * const psnd = &(conn->postponed[sockindex]); 137 return psnd->buffer && psnd->allocated_size && 138 psnd->recv_size > psnd->recv_processed; 139 } 140 141 static void pre_receive_plain(struct connectdata *conn, int num) 142 { 143 const curl_socket_t sockfd = conn->sock[num]; 144 struct postponed_data * const psnd = &(conn->postponed[num]); 145 size_t bytestorecv = psnd->allocated_size - psnd->recv_size; 146 /* WinSock will destroy unread received data if send() is 147 failed. 148 To avoid lossage of received data, recv() must be 149 performed before every send() if any incoming data is 150 available. However, skip this, if buffer is already full. */ 151 if((conn->handler->protocol&PROTO_FAMILY_HTTP) != 0 && 152 conn->recv[num] == Curl_recv_plain && 153 (!psnd->buffer || bytestorecv)) { 154 const int readymask = Curl_socket_check(sockfd, CURL_SOCKET_BAD, 155 CURL_SOCKET_BAD, 0); 156 if(readymask != -1 && (readymask & CURL_CSELECT_IN) != 0) { 157 /* Have some incoming data */ 158 if(!psnd->buffer) { 159 /* Use buffer double default size for intermediate buffer */ 160 psnd->allocated_size = 2 * conn->data->set.buffer_size; 161 psnd->buffer = malloc(psnd->allocated_size); 162 psnd->recv_size = 0; 163 psnd->recv_processed = 0; 164 #ifdef DEBUGBUILD 165 psnd->bindsock = sockfd; /* Used only for DEBUGASSERT */ 166 #endif /* DEBUGBUILD */ 167 bytestorecv = psnd->allocated_size; 168 } 169 if(psnd->buffer) { 170 ssize_t recvedbytes; 171 DEBUGASSERT(psnd->bindsock == sockfd); 172 recvedbytes = sread(sockfd, psnd->buffer + psnd->recv_size, 173 bytestorecv); 174 if(recvedbytes > 0) 175 psnd->recv_size += recvedbytes; 176 } 177 else 178 psnd->allocated_size = 0; 179 } 180 } 181 } 182 183 static ssize_t get_pre_recved(struct connectdata *conn, int num, char *buf, 184 size_t len) 185 { 186 struct postponed_data * const psnd = &(conn->postponed[num]); 187 size_t copysize; 188 if(!psnd->buffer) 189 return 0; 190 191 DEBUGASSERT(psnd->allocated_size > 0); 192 DEBUGASSERT(psnd->recv_size <= psnd->allocated_size); 193 DEBUGASSERT(psnd->recv_processed <= psnd->recv_size); 194 /* Check and process data that already received and storied in internal 195 intermediate buffer */ 196 if(psnd->recv_size > psnd->recv_processed) { 197 DEBUGASSERT(psnd->bindsock == conn->sock[num]); 198 copysize = CURLMIN(len, psnd->recv_size - psnd->recv_processed); 199 memcpy(buf, psnd->buffer + psnd->recv_processed, copysize); 200 psnd->recv_processed += copysize; 201 } 202 else 203 copysize = 0; /* buffer was allocated, but nothing was received */ 204 205 /* Free intermediate buffer if it has no unprocessed data */ 206 if(psnd->recv_processed == psnd->recv_size) { 207 free(psnd->buffer); 208 psnd->buffer = NULL; 209 psnd->allocated_size = 0; 210 psnd->recv_size = 0; 211 psnd->recv_processed = 0; 212 #ifdef DEBUGBUILD 213 psnd->bindsock = CURL_SOCKET_BAD; 214 #endif /* DEBUGBUILD */ 215 } 216 return (ssize_t)copysize; 217 } 218 #else /* ! USE_RECV_BEFORE_SEND_WORKAROUND */ 219 /* Use "do-nothing" macros instead of functions when workaround not used */ 220 bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex) 221 { 222 (void)conn; 223 (void)sockindex; 224 return false; 225 } 226 #define pre_receive_plain(c,n) do {} WHILE_FALSE 227 #define get_pre_recved(c,n,b,l) 0 228 #endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */ 229 230 /* Curl_infof() is for info message along the way */ 231 232 void Curl_infof(struct Curl_easy *data, const char *fmt, ...) 233 { 234 if(data && data->set.verbose) { 235 va_list ap; 236 size_t len; 237 char print_buffer[2048 + 1]; 238 va_start(ap, fmt); 239 vsnprintf(print_buffer, sizeof(print_buffer), fmt, ap); 240 va_end(ap); 241 len = strlen(print_buffer); 242 Curl_debug(data, CURLINFO_TEXT, print_buffer, len, NULL); 243 } 244 } 245 246 /* Curl_failf() is for messages stating why we failed. 247 * The message SHALL NOT include any LF or CR. 248 */ 249 250 void Curl_failf(struct Curl_easy *data, const char *fmt, ...) 251 { 252 if(data->set.verbose || data->set.errorbuffer) { 253 va_list ap; 254 size_t len; 255 char error[CURL_ERROR_SIZE + 2]; 256 va_start(ap, fmt); 257 vsnprintf(error, CURL_ERROR_SIZE, fmt, ap); 258 len = strlen(error); 259 260 if(data->set.errorbuffer && !data->state.errorbuf) { 261 strcpy(data->set.errorbuffer, error); 262 data->state.errorbuf = TRUE; /* wrote error string */ 263 } 264 if(data->set.verbose) { 265 error[len] = '\n'; 266 error[++len] = '\0'; 267 Curl_debug(data, CURLINFO_TEXT, error, len, NULL); 268 } 269 va_end(ap); 270 } 271 } 272 273 /* Curl_sendf() sends formatted data to the server */ 274 CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn, 275 const char *fmt, ...) 276 { 277 struct Curl_easy *data = conn->data; 278 ssize_t bytes_written; 279 size_t write_len; 280 CURLcode result = CURLE_OK; 281 char *s; 282 char *sptr; 283 va_list ap; 284 va_start(ap, fmt); 285 s = vaprintf(fmt, ap); /* returns an allocated string */ 286 va_end(ap); 287 if(!s) 288 return CURLE_OUT_OF_MEMORY; /* failure */ 289 290 bytes_written = 0; 291 write_len = strlen(s); 292 sptr = s; 293 294 for(;;) { 295 /* Write the buffer to the socket */ 296 result = Curl_write(conn, sockfd, sptr, write_len, &bytes_written); 297 298 if(result) 299 break; 300 301 if(data->set.verbose) 302 Curl_debug(data, CURLINFO_DATA_OUT, sptr, (size_t)bytes_written, conn); 303 304 if((size_t)bytes_written != write_len) { 305 /* if not all was written at once, we must advance the pointer, decrease 306 the size left and try again! */ 307 write_len -= bytes_written; 308 sptr += bytes_written; 309 } 310 else 311 break; 312 } 313 314 free(s); /* free the output string */ 315 316 return result; 317 } 318 319 /* 320 * Curl_write() is an internal write function that sends data to the 321 * server. Works with plain sockets, SCP, SSL or kerberos. 322 * 323 * If the write would block (CURLE_AGAIN), we return CURLE_OK and 324 * (*written == 0). Otherwise we return regular CURLcode value. 325 */ 326 CURLcode Curl_write(struct connectdata *conn, 327 curl_socket_t sockfd, 328 const void *mem, 329 size_t len, 330 ssize_t *written) 331 { 332 ssize_t bytes_written; 333 CURLcode result = CURLE_OK; 334 int num = (sockfd == conn->sock[SECONDARYSOCKET]); 335 336 bytes_written = conn->send[num](conn, num, mem, len, &result); 337 338 *written = bytes_written; 339 if(bytes_written >= 0) 340 /* we completely ignore the curlcode value when subzero is not returned */ 341 return CURLE_OK; 342 343 /* handle CURLE_AGAIN or a send failure */ 344 switch(result) { 345 case CURLE_AGAIN: 346 *written = 0; 347 return CURLE_OK; 348 349 case CURLE_OK: 350 /* general send failure */ 351 return CURLE_SEND_ERROR; 352 353 default: 354 /* we got a specific curlcode, forward it */ 355 return result; 356 } 357 } 358 359 ssize_t Curl_send_plain(struct connectdata *conn, int num, 360 const void *mem, size_t len, CURLcode *code) 361 { 362 curl_socket_t sockfd = conn->sock[num]; 363 ssize_t bytes_written; 364 /* WinSock will destroy unread received data if send() is 365 failed. 366 To avoid lossage of received data, recv() must be 367 performed before every send() if any incoming data is 368 available. */ 369 pre_receive_plain(conn, num); 370 371 #if defined(MSG_FASTOPEN) && !defined(TCP_FASTOPEN_CONNECT) /* Linux */ 372 if(conn->bits.tcp_fastopen) { 373 bytes_written = sendto(sockfd, mem, len, MSG_FASTOPEN, 374 conn->ip_addr->ai_addr, conn->ip_addr->ai_addrlen); 375 conn->bits.tcp_fastopen = FALSE; 376 } 377 else 378 #endif 379 bytes_written = swrite(sockfd, mem, len); 380 381 *code = CURLE_OK; 382 if(-1 == bytes_written) { 383 int err = SOCKERRNO; 384 385 if( 386 #ifdef WSAEWOULDBLOCK 387 /* This is how Windows does it */ 388 (WSAEWOULDBLOCK == err) 389 #else 390 /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned 391 due to its inability to send off data without blocking. We therefor 392 treat both error codes the same here */ 393 (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err) || 394 (EINPROGRESS == err) 395 #endif 396 ) { 397 /* this is just a case of EWOULDBLOCK */ 398 bytes_written = 0; 399 *code = CURLE_AGAIN; 400 } 401 else { 402 failf(conn->data, "Send failure: %s", 403 Curl_strerror(conn, err)); 404 conn->data->state.os_errno = err; 405 *code = CURLE_SEND_ERROR; 406 } 407 } 408 return bytes_written; 409 } 410 411 /* 412 * Curl_write_plain() is an internal write function that sends data to the 413 * server using plain sockets only. Otherwise meant to have the exact same 414 * proto as Curl_write() 415 */ 416 CURLcode Curl_write_plain(struct connectdata *conn, 417 curl_socket_t sockfd, 418 const void *mem, 419 size_t len, 420 ssize_t *written) 421 { 422 ssize_t bytes_written; 423 CURLcode result; 424 int num = (sockfd == conn->sock[SECONDARYSOCKET]); 425 426 bytes_written = Curl_send_plain(conn, num, mem, len, &result); 427 428 *written = bytes_written; 429 430 return result; 431 } 432 433 ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf, 434 size_t len, CURLcode *code) 435 { 436 curl_socket_t sockfd = conn->sock[num]; 437 ssize_t nread; 438 /* Check and return data that already received and storied in internal 439 intermediate buffer */ 440 nread = get_pre_recved(conn, num, buf, len); 441 if(nread > 0) { 442 *code = CURLE_OK; 443 return nread; 444 } 445 446 nread = sread(sockfd, buf, len); 447 448 *code = CURLE_OK; 449 if(-1 == nread) { 450 int err = SOCKERRNO; 451 452 if( 453 #ifdef WSAEWOULDBLOCK 454 /* This is how Windows does it */ 455 (WSAEWOULDBLOCK == err) 456 #else 457 /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned 458 due to its inability to send off data without blocking. We therefor 459 treat both error codes the same here */ 460 (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err) 461 #endif 462 ) { 463 /* this is just a case of EWOULDBLOCK */ 464 *code = CURLE_AGAIN; 465 } 466 else { 467 failf(conn->data, "Recv failure: %s", 468 Curl_strerror(conn, err)); 469 conn->data->state.os_errno = err; 470 *code = CURLE_RECV_ERROR; 471 } 472 } 473 return nread; 474 } 475 476 static CURLcode pausewrite(struct Curl_easy *data, 477 int type, /* what type of data */ 478 const char *ptr, 479 size_t len) 480 { 481 /* signalled to pause sending on this connection, but since we have data 482 we want to send we need to dup it to save a copy for when the sending 483 is again enabled */ 484 struct SingleRequest *k = &data->req; 485 struct UrlState *s = &data->state; 486 char *dupl; 487 unsigned int i; 488 bool newtype = TRUE; 489 490 if(s->tempcount) { 491 for(i = 0; i< s->tempcount; i++) { 492 if(s->tempwrite[i].type == type) { 493 /* data for this type exists */ 494 newtype = FALSE; 495 break; 496 } 497 } 498 DEBUGASSERT(i < 3); 499 } 500 else 501 i = 0; 502 503 if(!newtype) { 504 /* append new data to old data */ 505 506 /* figure out the new size of the data to save */ 507 size_t newlen = len + s->tempwrite[i].len; 508 /* allocate the new memory area */ 509 char *newptr = realloc(s->tempwrite[i].buf, newlen); 510 if(!newptr) 511 return CURLE_OUT_OF_MEMORY; 512 /* copy the new data to the end of the new area */ 513 memcpy(newptr + s->tempwrite[i].len, ptr, len); 514 515 /* update the pointer and the size */ 516 s->tempwrite[i].buf = newptr; 517 s->tempwrite[i].len = newlen; 518 } 519 else { 520 dupl = Curl_memdup(ptr, len); 521 if(!dupl) 522 return CURLE_OUT_OF_MEMORY; 523 524 /* store this information in the state struct for later use */ 525 s->tempwrite[i].buf = dupl; 526 s->tempwrite[i].len = len; 527 s->tempwrite[i].type = type; 528 529 if(newtype) 530 s->tempcount++; 531 } 532 533 /* mark the connection as RECV paused */ 534 k->keepon |= KEEP_RECV_PAUSE; 535 536 DEBUGF(infof(data, "Paused %zu bytes in buffer for type %02x\n", 537 len, type)); 538 539 return CURLE_OK; 540 } 541 542 543 /* Curl_client_chop_write() writes chunks of data not larger than 544 * CURL_MAX_WRITE_SIZE via client write callback(s) and 545 * takes care of pause requests from the callbacks. 546 */ 547 CURLcode Curl_client_chop_write(struct connectdata *conn, 548 int type, 549 char *ptr, 550 size_t len) 551 { 552 struct Curl_easy *data = conn->data; 553 curl_write_callback writeheader = NULL; 554 curl_write_callback writebody = NULL; 555 556 if(!len) 557 return CURLE_OK; 558 559 /* If reading is paused, append this data to the already held data for this 560 type. */ 561 if(data->req.keepon & KEEP_RECV_PAUSE) 562 return pausewrite(data, type, ptr, len); 563 564 /* Determine the callback(s) to use. */ 565 if(type & CLIENTWRITE_BODY) 566 writebody = data->set.fwrite_func; 567 if((type & CLIENTWRITE_HEADER) && 568 (data->set.fwrite_header || data->set.writeheader)) { 569 /* 570 * Write headers to the same callback or to the especially setup 571 * header callback function (added after version 7.7.1). 572 */ 573 writeheader = 574 data->set.fwrite_header? data->set.fwrite_header: data->set.fwrite_func; 575 } 576 577 /* Chop data, write chunks. */ 578 while(len) { 579 size_t chunklen = len <= CURL_MAX_WRITE_SIZE? len: CURL_MAX_WRITE_SIZE; 580 581 if(writebody) { 582 size_t wrote = writebody(ptr, 1, chunklen, data->set.out); 583 584 if(CURL_WRITEFUNC_PAUSE == wrote) { 585 if(conn->handler->flags & PROTOPT_NONETWORK) { 586 /* Protocols that work without network cannot be paused. This is 587 actually only FILE:// just now, and it can't pause since the 588 transfer isn't done using the "normal" procedure. */ 589 failf(data, "Write callback asked for PAUSE when not supported!"); 590 return CURLE_WRITE_ERROR; 591 } 592 return pausewrite(data, type, ptr, len); 593 } 594 if(wrote != chunklen) { 595 failf(data, "Failed writing body (%zu != %zu)", wrote, chunklen); 596 return CURLE_WRITE_ERROR; 597 } 598 } 599 600 if(writeheader) { 601 size_t wrote = writeheader(ptr, 1, chunklen, data->set.writeheader); 602 603 if(CURL_WRITEFUNC_PAUSE == wrote) 604 /* here we pass in the HEADER bit only since if this was body as well 605 then it was passed already and clearly that didn't trigger the 606 pause, so this is saved for later with the HEADER bit only */ 607 return pausewrite(data, CLIENTWRITE_HEADER, ptr, len); 608 609 if(wrote != chunklen) { 610 failf(data, "Failed writing header"); 611 return CURLE_WRITE_ERROR; 612 } 613 } 614 615 ptr += chunklen; 616 len -= chunklen; 617 } 618 619 return CURLE_OK; 620 } 621 622 623 /* Curl_client_write() sends data to the write callback(s) 624 625 The bit pattern defines to what "streams" to write to. Body and/or header. 626 The defines are in sendf.h of course. 627 628 If CURL_DO_LINEEND_CONV is enabled, data is converted IN PLACE to the 629 local character encoding. This is a problem and should be changed in 630 the future to leave the original data alone. 631 */ 632 CURLcode Curl_client_write(struct connectdata *conn, 633 int type, 634 char *ptr, 635 size_t len) 636 { 637 struct Curl_easy *data = conn->data; 638 639 if(0 == len) 640 len = strlen(ptr); 641 642 DEBUGASSERT(type <= 3); 643 644 /* FTP data may need conversion. */ 645 if((type & CLIENTWRITE_BODY) && 646 (conn->handler->protocol & PROTO_FAMILY_FTP) && 647 conn->proto.ftpc.transfertype == 'A') { 648 /* convert from the network encoding */ 649 CURLcode result = Curl_convert_from_network(data, ptr, len); 650 /* Curl_convert_from_network calls failf if unsuccessful */ 651 if(result) 652 return result; 653 654 #ifdef CURL_DO_LINEEND_CONV 655 /* convert end-of-line markers */ 656 len = convert_lineends(data, ptr, len); 657 #endif /* CURL_DO_LINEEND_CONV */ 658 } 659 660 return Curl_client_chop_write(conn, type, ptr, len); 661 } 662 663 CURLcode Curl_read_plain(curl_socket_t sockfd, 664 char *buf, 665 size_t bytesfromsocket, 666 ssize_t *n) 667 { 668 ssize_t nread = sread(sockfd, buf, bytesfromsocket); 669 670 if(-1 == nread) { 671 int err = SOCKERRNO; 672 int return_error; 673 #ifdef USE_WINSOCK 674 return_error = WSAEWOULDBLOCK == err; 675 #else 676 return_error = EWOULDBLOCK == err || EAGAIN == err || EINTR == err; 677 #endif 678 if(return_error) 679 return CURLE_AGAIN; 680 return CURLE_RECV_ERROR; 681 } 682 683 /* we only return number of bytes read when we return OK */ 684 *n = nread; 685 return CURLE_OK; 686 } 687 688 /* 689 * Internal read-from-socket function. This is meant to deal with plain 690 * sockets, SSL sockets and kerberos sockets. 691 * 692 * Returns a regular CURLcode value. 693 */ 694 CURLcode Curl_read(struct connectdata *conn, /* connection data */ 695 curl_socket_t sockfd, /* read from this socket */ 696 char *buf, /* store read data here */ 697 size_t sizerequested, /* max amount to read */ 698 ssize_t *n) /* amount bytes read */ 699 { 700 CURLcode result = CURLE_RECV_ERROR; 701 ssize_t nread = 0; 702 size_t bytesfromsocket = 0; 703 char *buffertofill = NULL; 704 struct Curl_easy *data = conn->data; 705 706 /* if HTTP/1 pipelining is both wanted and possible */ 707 bool pipelining = Curl_pipeline_wanted(data->multi, CURLPIPE_HTTP1) && 708 (conn->bundle->multiuse == BUNDLE_PIPELINING); 709 710 /* Set 'num' to 0 or 1, depending on which socket that has been sent here. 711 If it is the second socket, we set num to 1. Otherwise to 0. This lets 712 us use the correct ssl handle. */ 713 int num = (sockfd == conn->sock[SECONDARYSOCKET]); 714 715 *n = 0; /* reset amount to zero */ 716 717 /* If session can pipeline, check connection buffer */ 718 if(pipelining) { 719 size_t bytestocopy = CURLMIN(conn->buf_len - conn->read_pos, 720 sizerequested); 721 722 /* Copy from our master buffer first if we have some unread data there*/ 723 if(bytestocopy > 0) { 724 memcpy(buf, conn->master_buffer + conn->read_pos, bytestocopy); 725 conn->read_pos += bytestocopy; 726 conn->bits.stream_was_rewound = FALSE; 727 728 *n = (ssize_t)bytestocopy; 729 return CURLE_OK; 730 } 731 /* If we come here, it means that there is no data to read from the buffer, 732 * so we read from the socket */ 733 bytesfromsocket = CURLMIN(sizerequested, MASTERBUF_SIZE); 734 buffertofill = conn->master_buffer; 735 } 736 else { 737 bytesfromsocket = CURLMIN(sizerequested, (size_t)data->set.buffer_size); 738 buffertofill = buf; 739 } 740 741 nread = conn->recv[num](conn, num, buffertofill, bytesfromsocket, &result); 742 if(nread < 0) 743 return result; 744 745 if(pipelining) { 746 memcpy(buf, conn->master_buffer, nread); 747 conn->buf_len = nread; 748 conn->read_pos = nread; 749 } 750 751 *n += nread; 752 753 return CURLE_OK; 754 } 755 756 /* return 0 on success */ 757 static int showit(struct Curl_easy *data, curl_infotype type, 758 char *ptr, size_t size) 759 { 760 static const char s_infotype[CURLINFO_END][3] = { 761 "* ", "< ", "> ", "{ ", "} ", "{ ", "} " }; 762 int rc = 0; 763 764 #ifdef CURL_DOES_CONVERSIONS 765 char *buf = NULL; 766 size_t conv_size = 0; 767 768 switch(type) { 769 case CURLINFO_HEADER_OUT: 770 buf = Curl_memdup(ptr, size); 771 if(!buf) 772 return 1; 773 conv_size = size; 774 775 /* Special processing is needed for this block if it 776 * contains both headers and data (separated by CRLFCRLF). 777 * We want to convert just the headers, leaving the data as-is. 778 */ 779 if(size > 4) { 780 size_t i; 781 for(i = 0; i < size-4; i++) { 782 if(memcmp(&buf[i], "\x0d\x0a\x0d\x0a", 4) == 0) { 783 /* convert everything through this CRLFCRLF but no further */ 784 conv_size = i + 4; 785 break; 786 } 787 } 788 } 789 790 Curl_convert_from_network(data, buf, conv_size); 791 /* Curl_convert_from_network calls failf if unsuccessful */ 792 /* we might as well continue even if it fails... */ 793 ptr = buf; /* switch pointer to use my buffer instead */ 794 break; 795 default: 796 /* leave everything else as-is */ 797 break; 798 } 799 #endif /* CURL_DOES_CONVERSIONS */ 800 801 if(data->set.fdebug) 802 rc = (*data->set.fdebug)(data, type, ptr, size, data->set.debugdata); 803 else { 804 switch(type) { 805 case CURLINFO_TEXT: 806 case CURLINFO_HEADER_OUT: 807 case CURLINFO_HEADER_IN: 808 fwrite(s_infotype[type], 2, 1, data->set.err); 809 fwrite(ptr, size, 1, data->set.err); 810 #ifdef CURL_DOES_CONVERSIONS 811 if(size != conv_size) { 812 /* we had untranslated data so we need an explicit newline */ 813 fwrite("\n", 1, 1, data->set.err); 814 } 815 #endif 816 break; 817 default: /* nada */ 818 break; 819 } 820 } 821 #ifdef CURL_DOES_CONVERSIONS 822 free(buf); 823 #endif 824 return rc; 825 } 826 827 int Curl_debug(struct Curl_easy *data, curl_infotype type, 828 char *ptr, size_t size, 829 struct connectdata *conn) 830 { 831 int rc; 832 if(data->set.printhost && conn && conn->host.dispname) { 833 char buffer[160]; 834 const char *t = NULL; 835 const char *w = "Data"; 836 switch(type) { 837 case CURLINFO_HEADER_IN: 838 w = "Header"; 839 /* FALLTHROUGH */ 840 case CURLINFO_DATA_IN: 841 t = "from"; 842 break; 843 case CURLINFO_HEADER_OUT: 844 w = "Header"; 845 /* FALLTHROUGH */ 846 case CURLINFO_DATA_OUT: 847 t = "to"; 848 break; 849 default: 850 break; 851 } 852 853 if(t) { 854 snprintf(buffer, sizeof(buffer), "[%s %s %s]", w, t, 855 conn->host.dispname); 856 rc = showit(data, CURLINFO_TEXT, buffer, strlen(buffer)); 857 if(rc) 858 return rc; 859 } 860 } 861 rc = showit(data, type, ptr, size); 862 return rc; 863 } 864