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