1/*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 1998 - 2014, 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 http://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#include <curl/curl.h> 26 27#include "urldata.h" 28#include "sendf.h" 29#include "connect.h" 30#include "vtls/vtls.h" 31#include "ssh.h" 32#include "multiif.h" 33#include "non-ascii.h" 34 35#define _MPRINTF_REPLACE /* use the internal *printf() functions */ 36#include <curl/mprintf.h> 37 38#include "curl_memory.h" 39#include "strerror.h" 40 41/* The last #include file should be: */ 42#include "memdebug.h" 43 44#ifdef CURL_DO_LINEEND_CONV 45/* 46 * convert_lineends() changes CRLF (\r\n) end-of-line markers to a single LF 47 * (\n), with special processing for CRLF sequences that are split between two 48 * blocks of data. Remaining, bare CRs are changed to LFs. The possibly new 49 * size of the data is returned. 50 */ 51static size_t convert_lineends(struct SessionHandle *data, 52 char *startPtr, size_t size) 53{ 54 char *inPtr, *outPtr; 55 56 /* sanity check */ 57 if((startPtr == NULL) || (size < 1)) { 58 return(size); 59 } 60 61 if(data->state.prev_block_had_trailing_cr) { 62 /* The previous block of incoming data 63 had a trailing CR, which was turned into a LF. */ 64 if(*startPtr == '\n') { 65 /* This block of incoming data starts with the 66 previous block's LF so get rid of it */ 67 memmove(startPtr, startPtr+1, size-1); 68 size--; 69 /* and it wasn't a bare CR but a CRLF conversion instead */ 70 data->state.crlf_conversions++; 71 } 72 data->state.prev_block_had_trailing_cr = FALSE; /* reset the flag */ 73 } 74 75 /* find 1st CR, if any */ 76 inPtr = outPtr = memchr(startPtr, '\r', size); 77 if(inPtr) { 78 /* at least one CR, now look for CRLF */ 79 while(inPtr < (startPtr+size-1)) { 80 /* note that it's size-1, so we'll never look past the last byte */ 81 if(memcmp(inPtr, "\r\n", 2) == 0) { 82 /* CRLF found, bump past the CR and copy the NL */ 83 inPtr++; 84 *outPtr = *inPtr; 85 /* keep track of how many CRLFs we converted */ 86 data->state.crlf_conversions++; 87 } 88 else { 89 if(*inPtr == '\r') { 90 /* lone CR, move LF instead */ 91 *outPtr = '\n'; 92 } 93 else { 94 /* not a CRLF nor a CR, just copy whatever it is */ 95 *outPtr = *inPtr; 96 } 97 } 98 outPtr++; 99 inPtr++; 100 } /* end of while loop */ 101 102 if(inPtr < startPtr+size) { 103 /* handle last byte */ 104 if(*inPtr == '\r') { 105 /* deal with a CR at the end of the buffer */ 106 *outPtr = '\n'; /* copy a NL instead */ 107 /* note that a CRLF might be split across two blocks */ 108 data->state.prev_block_had_trailing_cr = TRUE; 109 } 110 else { 111 /* copy last byte */ 112 *outPtr = *inPtr; 113 } 114 outPtr++; 115 } 116 if(outPtr < startPtr+size) 117 /* tidy up by null terminating the now shorter data */ 118 *outPtr = '\0'; 119 120 return(outPtr - startPtr); 121 } 122 return(size); 123} 124#endif /* CURL_DO_LINEEND_CONV */ 125 126/* Curl_infof() is for info message along the way */ 127 128void Curl_infof(struct SessionHandle *data, const char *fmt, ...) 129{ 130 if(data && data->set.verbose) { 131 va_list ap; 132 size_t len; 133 char print_buffer[2048 + 1]; 134 va_start(ap, fmt); 135 vsnprintf(print_buffer, sizeof(print_buffer), fmt, ap); 136 va_end(ap); 137 len = strlen(print_buffer); 138 Curl_debug(data, CURLINFO_TEXT, print_buffer, len, NULL); 139 } 140} 141 142/* Curl_failf() is for messages stating why we failed. 143 * The message SHALL NOT include any LF or CR. 144 */ 145 146void Curl_failf(struct SessionHandle *data, const char *fmt, ...) 147{ 148 va_list ap; 149 size_t len; 150 va_start(ap, fmt); 151 152 vsnprintf(data->state.buffer, BUFSIZE, fmt, ap); 153 154 if(data->set.errorbuffer && !data->state.errorbuf) { 155 snprintf(data->set.errorbuffer, CURL_ERROR_SIZE, "%s", data->state.buffer); 156 data->state.errorbuf = TRUE; /* wrote error string */ 157 } 158 if(data->set.verbose) { 159 len = strlen(data->state.buffer); 160 if(len < BUFSIZE - 1) { 161 data->state.buffer[len] = '\n'; 162 data->state.buffer[++len] = '\0'; 163 } 164 Curl_debug(data, CURLINFO_TEXT, data->state.buffer, len, NULL); 165 } 166 167 va_end(ap); 168} 169 170/* Curl_sendf() sends formated data to the server */ 171CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn, 172 const char *fmt, ...) 173{ 174 struct SessionHandle *data = conn->data; 175 ssize_t bytes_written; 176 size_t write_len; 177 CURLcode res = CURLE_OK; 178 char *s; 179 char *sptr; 180 va_list ap; 181 va_start(ap, fmt); 182 s = vaprintf(fmt, ap); /* returns an allocated string */ 183 va_end(ap); 184 if(!s) 185 return CURLE_OUT_OF_MEMORY; /* failure */ 186 187 bytes_written=0; 188 write_len = strlen(s); 189 sptr = s; 190 191 for(;;) { 192 /* Write the buffer to the socket */ 193 res = Curl_write(conn, sockfd, sptr, write_len, &bytes_written); 194 195 if(CURLE_OK != res) 196 break; 197 198 if(data->set.verbose) 199 Curl_debug(data, CURLINFO_DATA_OUT, sptr, (size_t)bytes_written, conn); 200 201 if((size_t)bytes_written != write_len) { 202 /* if not all was written at once, we must advance the pointer, decrease 203 the size left and try again! */ 204 write_len -= bytes_written; 205 sptr += bytes_written; 206 } 207 else 208 break; 209 } 210 211 free(s); /* free the output string */ 212 213 return res; 214} 215 216/* 217 * Curl_write() is an internal write function that sends data to the 218 * server. Works with plain sockets, SCP, SSL or kerberos. 219 * 220 * If the write would block (CURLE_AGAIN), we return CURLE_OK and 221 * (*written == 0). Otherwise we return regular CURLcode value. 222 */ 223CURLcode Curl_write(struct connectdata *conn, 224 curl_socket_t sockfd, 225 const void *mem, 226 size_t len, 227 ssize_t *written) 228{ 229 ssize_t bytes_written; 230 CURLcode curlcode = CURLE_OK; 231 int num = (sockfd == conn->sock[SECONDARYSOCKET]); 232 233 bytes_written = conn->send[num](conn, num, mem, len, &curlcode); 234 235 *written = bytes_written; 236 if(bytes_written >= 0) 237 /* we completely ignore the curlcode value when subzero is not returned */ 238 return CURLE_OK; 239 240 /* handle CURLE_AGAIN or a send failure */ 241 switch(curlcode) { 242 case CURLE_AGAIN: 243 *written = 0; 244 return CURLE_OK; 245 246 case CURLE_OK: 247 /* general send failure */ 248 return CURLE_SEND_ERROR; 249 250 default: 251 /* we got a specific curlcode, forward it */ 252 return curlcode; 253 } 254} 255 256ssize_t Curl_send_plain(struct connectdata *conn, int num, 257 const void *mem, size_t len, CURLcode *code) 258{ 259 curl_socket_t sockfd = conn->sock[num]; 260 ssize_t bytes_written = swrite(sockfd, mem, len); 261 262 *code = CURLE_OK; 263 if(-1 == bytes_written) { 264 int err = SOCKERRNO; 265 266 if( 267#ifdef WSAEWOULDBLOCK 268 /* This is how Windows does it */ 269 (WSAEWOULDBLOCK == err) 270#else 271 /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned 272 due to its inability to send off data without blocking. We therefor 273 treat both error codes the same here */ 274 (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err) 275#endif 276 ) { 277 /* this is just a case of EWOULDBLOCK */ 278 bytes_written=0; 279 *code = CURLE_AGAIN; 280 } 281 else { 282 failf(conn->data, "Send failure: %s", 283 Curl_strerror(conn, err)); 284 conn->data->state.os_errno = err; 285 *code = CURLE_SEND_ERROR; 286 } 287 } 288 return bytes_written; 289} 290 291/* 292 * Curl_write_plain() is an internal write function that sends data to the 293 * server using plain sockets only. Otherwise meant to have the exact same 294 * proto as Curl_write() 295 */ 296CURLcode Curl_write_plain(struct connectdata *conn, 297 curl_socket_t sockfd, 298 const void *mem, 299 size_t len, 300 ssize_t *written) 301{ 302 ssize_t bytes_written; 303 CURLcode retcode; 304 int num = (sockfd == conn->sock[SECONDARYSOCKET]); 305 306 bytes_written = Curl_send_plain(conn, num, mem, len, &retcode); 307 308 *written = bytes_written; 309 310 return retcode; 311} 312 313ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf, 314 size_t len, CURLcode *code) 315{ 316 curl_socket_t sockfd = conn->sock[num]; 317 ssize_t nread = sread(sockfd, buf, len); 318 319 *code = CURLE_OK; 320 if(-1 == nread) { 321 int err = SOCKERRNO; 322 323 if( 324#ifdef WSAEWOULDBLOCK 325 /* This is how Windows does it */ 326 (WSAEWOULDBLOCK == err) 327#else 328 /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned 329 due to its inability to send off data without blocking. We therefor 330 treat both error codes the same here */ 331 (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err) 332#endif 333 ) { 334 /* this is just a case of EWOULDBLOCK */ 335 *code = CURLE_AGAIN; 336 } 337 else { 338 failf(conn->data, "Recv failure: %s", 339 Curl_strerror(conn, err)); 340 conn->data->state.os_errno = err; 341 *code = CURLE_RECV_ERROR; 342 } 343 } 344 return nread; 345} 346 347static CURLcode pausewrite(struct SessionHandle *data, 348 int type, /* what type of data */ 349 const char *ptr, 350 size_t len) 351{ 352 /* signalled to pause sending on this connection, but since we have data 353 we want to send we need to dup it to save a copy for when the sending 354 is again enabled */ 355 struct SingleRequest *k = &data->req; 356 char *dupl = malloc(len); 357 if(!dupl) 358 return CURLE_OUT_OF_MEMORY; 359 360 memcpy(dupl, ptr, len); 361 362 /* store this information in the state struct for later use */ 363 data->state.tempwrite = dupl; 364 data->state.tempwritesize = len; 365 data->state.tempwritetype = type; 366 367 /* mark the connection as RECV paused */ 368 k->keepon |= KEEP_RECV_PAUSE; 369 370 DEBUGF(infof(data, "Pausing with %zu bytes in buffer for type %02x\n", 371 len, type)); 372 373 return CURLE_OK; 374} 375 376 377/* Curl_client_write() sends data to the write callback(s) 378 379 The bit pattern defines to what "streams" to write to. Body and/or header. 380 The defines are in sendf.h of course. 381 382 If CURL_DO_LINEEND_CONV is enabled, data is converted IN PLACE to the 383 local character encoding. This is a problem and should be changed in 384 the future to leave the original data alone. 385 */ 386CURLcode Curl_client_write(struct connectdata *conn, 387 int type, 388 char *ptr, 389 size_t len) 390{ 391 struct SessionHandle *data = conn->data; 392 size_t wrote; 393 394 if(0 == len) 395 len = strlen(ptr); 396 397 /* If reading is actually paused, we're forced to append this chunk of data 398 to the already held data, but only if it is the same type as otherwise it 399 can't work and it'll return error instead. */ 400 if(data->req.keepon & KEEP_RECV_PAUSE) { 401 size_t newlen; 402 char *newptr; 403 if(type != data->state.tempwritetype) 404 /* major internal confusion */ 405 return CURLE_RECV_ERROR; 406 407 DEBUGASSERT(data->state.tempwrite); 408 409 /* figure out the new size of the data to save */ 410 newlen = len + data->state.tempwritesize; 411 /* allocate the new memory area */ 412 newptr = realloc(data->state.tempwrite, newlen); 413 if(!newptr) 414 return CURLE_OUT_OF_MEMORY; 415 /* copy the new data to the end of the new area */ 416 memcpy(newptr + data->state.tempwritesize, ptr, len); 417 /* update the pointer and the size */ 418 data->state.tempwrite = newptr; 419 data->state.tempwritesize = newlen; 420 421 return CURLE_OK; 422 } 423 424 if(type & CLIENTWRITE_BODY) { 425 if((conn->handler->protocol&PROTO_FAMILY_FTP) && 426 conn->proto.ftpc.transfertype == 'A') { 427 /* convert from the network encoding */ 428 CURLcode rc = Curl_convert_from_network(data, ptr, len); 429 /* Curl_convert_from_network calls failf if unsuccessful */ 430 if(rc) 431 return rc; 432 433#ifdef CURL_DO_LINEEND_CONV 434 /* convert end-of-line markers */ 435 len = convert_lineends(data, ptr, len); 436#endif /* CURL_DO_LINEEND_CONV */ 437 } 438 /* If the previous block of data ended with CR and this block of data is 439 just a NL, then the length might be zero */ 440 if(len) { 441 wrote = data->set.fwrite_func(ptr, 1, len, data->set.out); 442 } 443 else { 444 wrote = len; 445 } 446 447 if(CURL_WRITEFUNC_PAUSE == wrote) { 448 if(conn->handler->flags & PROTOPT_NONETWORK) { 449 /* Protocols that work without network cannot be paused. This is 450 actually only FILE:// just now, and it can't pause since the 451 transfer isn't done using the "normal" procedure. */ 452 failf(data, "Write callback asked for PAUSE when not supported!"); 453 return CURLE_WRITE_ERROR; 454 } 455 else 456 return pausewrite(data, type, ptr, len); 457 } 458 else if(wrote != len) { 459 failf(data, "Failed writing body (%zu != %zu)", wrote, len); 460 return CURLE_WRITE_ERROR; 461 } 462 } 463 464 if((type & CLIENTWRITE_HEADER) && 465 (data->set.fwrite_header || data->set.writeheader) ) { 466 /* 467 * Write headers to the same callback or to the especially setup 468 * header callback function (added after version 7.7.1). 469 */ 470 curl_write_callback writeit= 471 data->set.fwrite_header?data->set.fwrite_header:data->set.fwrite_func; 472 473 /* Note: The header is in the host encoding 474 regardless of the ftp transfer mode (ASCII/Image) */ 475 476 wrote = writeit(ptr, 1, len, data->set.writeheader); 477 if(CURL_WRITEFUNC_PAUSE == wrote) 478 /* here we pass in the HEADER bit only since if this was body as well 479 then it was passed already and clearly that didn't trigger the pause, 480 so this is saved for later with the HEADER bit only */ 481 return pausewrite(data, CLIENTWRITE_HEADER, ptr, len); 482 483 if(wrote != len) { 484 failf (data, "Failed writing header"); 485 return CURLE_WRITE_ERROR; 486 } 487 } 488 489 return CURLE_OK; 490} 491 492CURLcode Curl_read_plain(curl_socket_t sockfd, 493 char *buf, 494 size_t bytesfromsocket, 495 ssize_t *n) 496{ 497 ssize_t nread = sread(sockfd, buf, bytesfromsocket); 498 499 if(-1 == nread) { 500 int err = SOCKERRNO; 501#ifdef USE_WINSOCK 502 if(WSAEWOULDBLOCK == err) 503#else 504 if((EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)) 505#endif 506 return CURLE_AGAIN; 507 else 508 return CURLE_RECV_ERROR; 509 } 510 511 /* we only return number of bytes read when we return OK */ 512 *n = nread; 513 return CURLE_OK; 514} 515 516/* 517 * Internal read-from-socket function. This is meant to deal with plain 518 * sockets, SSL sockets and kerberos sockets. 519 * 520 * Returns a regular CURLcode value. 521 */ 522CURLcode Curl_read(struct connectdata *conn, /* connection data */ 523 curl_socket_t sockfd, /* read from this socket */ 524 char *buf, /* store read data here */ 525 size_t sizerequested, /* max amount to read */ 526 ssize_t *n) /* amount bytes read */ 527{ 528 CURLcode curlcode = CURLE_RECV_ERROR; 529 ssize_t nread = 0; 530 size_t bytesfromsocket = 0; 531 char *buffertofill = NULL; 532 bool pipelining = Curl_multi_pipeline_enabled(conn->data->multi); 533 534 /* Set 'num' to 0 or 1, depending on which socket that has been sent here. 535 If it is the second socket, we set num to 1. Otherwise to 0. This lets 536 us use the correct ssl handle. */ 537 int num = (sockfd == conn->sock[SECONDARYSOCKET]); 538 539 *n=0; /* reset amount to zero */ 540 541 /* If session can pipeline, check connection buffer */ 542 if(pipelining) { 543 size_t bytestocopy = CURLMIN(conn->buf_len - conn->read_pos, 544 sizerequested); 545 546 /* Copy from our master buffer first if we have some unread data there*/ 547 if(bytestocopy > 0) { 548 memcpy(buf, conn->master_buffer + conn->read_pos, bytestocopy); 549 conn->read_pos += bytestocopy; 550 conn->bits.stream_was_rewound = FALSE; 551 552 *n = (ssize_t)bytestocopy; 553 return CURLE_OK; 554 } 555 /* If we come here, it means that there is no data to read from the buffer, 556 * so we read from the socket */ 557 bytesfromsocket = CURLMIN(sizerequested, BUFSIZE * sizeof (char)); 558 buffertofill = conn->master_buffer; 559 } 560 else { 561 bytesfromsocket = CURLMIN((long)sizerequested, 562 conn->data->set.buffer_size ? 563 conn->data->set.buffer_size : BUFSIZE); 564 buffertofill = buf; 565 } 566 567 nread = conn->recv[num](conn, num, buffertofill, bytesfromsocket, &curlcode); 568 if(nread < 0) 569 return curlcode; 570 571 if(pipelining) { 572 memcpy(buf, conn->master_buffer, nread); 573 conn->buf_len = nread; 574 conn->read_pos = nread; 575 } 576 577 *n += nread; 578 579 return CURLE_OK; 580} 581 582/* return 0 on success */ 583static int showit(struct SessionHandle *data, curl_infotype type, 584 char *ptr, size_t size) 585{ 586 static const char s_infotype[CURLINFO_END][3] = { 587 "* ", "< ", "> ", "{ ", "} ", "{ ", "} " }; 588 589#ifdef CURL_DOES_CONVERSIONS 590 char buf[BUFSIZE+1]; 591 size_t conv_size = 0; 592 593 switch(type) { 594 case CURLINFO_HEADER_OUT: 595 /* assume output headers are ASCII */ 596 /* copy the data into my buffer so the original is unchanged */ 597 if(size > BUFSIZE) { 598 size = BUFSIZE; /* truncate if necessary */ 599 buf[BUFSIZE] = '\0'; 600 } 601 conv_size = size; 602 memcpy(buf, ptr, size); 603 /* Special processing is needed for this block if it 604 * contains both headers and data (separated by CRLFCRLF). 605 * We want to convert just the headers, leaving the data as-is. 606 */ 607 if(size > 4) { 608 size_t i; 609 for(i = 0; i < size-4; i++) { 610 if(memcmp(&buf[i], "\x0d\x0a\x0d\x0a", 4) == 0) { 611 /* convert everything through this CRLFCRLF but no further */ 612 conv_size = i + 4; 613 break; 614 } 615 } 616 } 617 618 Curl_convert_from_network(data, buf, conv_size); 619 /* Curl_convert_from_network calls failf if unsuccessful */ 620 /* we might as well continue even if it fails... */ 621 ptr = buf; /* switch pointer to use my buffer instead */ 622 break; 623 default: 624 /* leave everything else as-is */ 625 break; 626 } 627#endif /* CURL_DOES_CONVERSIONS */ 628 629 if(data->set.fdebug) 630 return (*data->set.fdebug)(data, type, ptr, size, 631 data->set.debugdata); 632 633 switch(type) { 634 case CURLINFO_TEXT: 635 case CURLINFO_HEADER_OUT: 636 case CURLINFO_HEADER_IN: 637 fwrite(s_infotype[type], 2, 1, data->set.err); 638 fwrite(ptr, size, 1, data->set.err); 639#ifdef CURL_DOES_CONVERSIONS 640 if(size != conv_size) { 641 /* we had untranslated data so we need an explicit newline */ 642 fwrite("\n", 1, 1, data->set.err); 643 } 644#endif 645 break; 646 default: /* nada */ 647 break; 648 } 649 return 0; 650} 651 652int Curl_debug(struct SessionHandle *data, curl_infotype type, 653 char *ptr, size_t size, 654 struct connectdata *conn) 655{ 656 int rc; 657 if(data->set.printhost && conn && conn->host.dispname) { 658 char buffer[160]; 659 const char *t=NULL; 660 const char *w="Data"; 661 switch (type) { 662 case CURLINFO_HEADER_IN: 663 w = "Header"; 664 case CURLINFO_DATA_IN: 665 t = "from"; 666 break; 667 case CURLINFO_HEADER_OUT: 668 w = "Header"; 669 case CURLINFO_DATA_OUT: 670 t = "to"; 671 break; 672 default: 673 break; 674 } 675 676 if(t) { 677 snprintf(buffer, sizeof(buffer), "[%s %s %s]", w, t, 678 conn->host.dispname); 679 rc = showit(data, CURLINFO_TEXT, buffer, strlen(buffer)); 680 if(rc) 681 return rc; 682 } 683 } 684 rc = showit(data, type, ptr, size); 685 return rc; 686} 687