1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
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.
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.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ***************************************************************************/
23 #include "curl_setup.h"
25 #include <curl/curl.h>
27 #ifdef USE_TIZEN_FEATURE_DLP
28 #include "extensions/curl_extensions.h"
33 #include "vtls/vtls.h"
36 #include "non-ascii.h"
40 /* The last 3 #include files should be in this order */
41 #include "curl_printf.h"
42 #include "curl_memory.h"
45 #ifdef CURL_DO_LINEEND_CONV
47 * convert_lineends() changes CRLF (\r\n) end-of-line markers to a single LF
48 * (\n), with special processing for CRLF sequences that are split between two
49 * blocks of data. Remaining, bare CRs are changed to LFs. The possibly new
50 * size of the data is returned.
52 static size_t convert_lineends(struct Curl_easy *data,
53 char *startPtr, size_t size)
58 if((startPtr == NULL) || (size < 1)) {
62 if(data->state.prev_block_had_trailing_cr) {
63 /* The previous block of incoming data
64 had a trailing CR, which was turned into a LF. */
65 if(*startPtr == '\n') {
66 /* This block of incoming data starts with the
67 previous block's LF so get rid of it */
68 memmove(startPtr, startPtr+1, size-1);
70 /* and it wasn't a bare CR but a CRLF conversion instead */
71 data->state.crlf_conversions++;
73 data->state.prev_block_had_trailing_cr = FALSE; /* reset the flag */
76 /* find 1st CR, if any */
77 inPtr = outPtr = memchr(startPtr, '\r', size);
79 /* at least one CR, now look for CRLF */
80 while(inPtr < (startPtr+size-1)) {
81 /* note that it's size-1, so we'll never look past the last byte */
82 if(memcmp(inPtr, "\r\n", 2) == 0) {
83 /* CRLF found, bump past the CR and copy the NL */
86 /* keep track of how many CRLFs we converted */
87 data->state.crlf_conversions++;
91 /* lone CR, move LF instead */
95 /* not a CRLF nor a CR, just copy whatever it is */
101 } /* end of while loop */
103 if(inPtr < startPtr+size) {
104 /* handle last byte */
106 /* deal with a CR at the end of the buffer */
107 *outPtr = '\n'; /* copy a NL instead */
108 /* note that a CRLF might be split across two blocks */
109 data->state.prev_block_had_trailing_cr = TRUE;
117 if(outPtr < startPtr+size)
118 /* tidy up by null terminating the now shorter data */
121 return (outPtr - startPtr);
125 #endif /* CURL_DO_LINEEND_CONV */
127 #ifdef USE_RECV_BEFORE_SEND_WORKAROUND
128 bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex)
130 struct postponed_data * const psnd = &(conn->postponed[sockindex]);
131 return psnd->buffer && psnd->allocated_size &&
132 psnd->recv_size > psnd->recv_processed;
135 static void pre_receive_plain(struct connectdata *conn, int num)
137 const curl_socket_t sockfd = conn->sock[num];
138 struct postponed_data * const psnd = &(conn->postponed[num]);
139 size_t bytestorecv = psnd->allocated_size - psnd->recv_size;
140 /* WinSock will destroy unread received data if send() is
142 To avoid lossage of received data, recv() must be
143 performed before every send() if any incoming data is
144 available. However, skip this, if buffer is already full. */
145 if((conn->handler->protocol&PROTO_FAMILY_HTTP) != 0 &&
146 conn->recv[num] == Curl_recv_plain &&
147 (!psnd->buffer || bytestorecv)) {
148 const int readymask = Curl_socket_check(sockfd, CURL_SOCKET_BAD,
150 if(readymask != -1 && (readymask & CURL_CSELECT_IN) != 0) {
151 /* Have some incoming data */
153 /* Use buffer double default size for intermediate buffer */
154 psnd->allocated_size = 2 * BUFSIZE;
155 psnd->buffer = malloc(psnd->allocated_size);
157 psnd->recv_processed = 0;
159 psnd->bindsock = sockfd; /* Used only for DEBUGASSERT */
160 #endif /* DEBUGBUILD */
161 bytestorecv = psnd->allocated_size;
165 DEBUGASSERT(psnd->bindsock == sockfd);
166 recvedbytes = sread(sockfd, psnd->buffer + psnd->recv_size,
169 psnd->recv_size += recvedbytes;
172 psnd->allocated_size = 0;
177 static ssize_t get_pre_recved(struct connectdata *conn, int num, char *buf,
180 struct postponed_data * const psnd = &(conn->postponed[num]);
185 DEBUGASSERT(psnd->allocated_size > 0);
186 DEBUGASSERT(psnd->recv_size <= psnd->allocated_size);
187 DEBUGASSERT(psnd->recv_processed <= psnd->recv_size);
188 /* Check and process data that already received and storied in internal
189 intermediate buffer */
190 if(psnd->recv_size > psnd->recv_processed) {
191 DEBUGASSERT(psnd->bindsock == conn->sock[num]);
192 copysize = CURLMIN(len, psnd->recv_size - psnd->recv_processed);
193 memcpy(buf, psnd->buffer + psnd->recv_processed, copysize);
194 psnd->recv_processed += copysize;
197 copysize = 0; /* buffer was allocated, but nothing was received */
199 /* Free intermediate buffer if it has no unprocessed data */
200 if(psnd->recv_processed == psnd->recv_size) {
203 psnd->allocated_size = 0;
205 psnd->recv_processed = 0;
207 psnd->bindsock = CURL_SOCKET_BAD;
208 #endif /* DEBUGBUILD */
210 return (ssize_t)copysize;
212 #else /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
213 /* Use "do-nothing" macros instead of functions when workaround not used */
214 bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex)
220 #define pre_receive_plain(c,n) do {} WHILE_FALSE
221 #define get_pre_recved(c,n,b,l) 0
222 #endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
224 /* Curl_infof() is for info message along the way */
226 void Curl_infof(struct Curl_easy *data, const char *fmt, ...)
228 if(data && data->set.verbose) {
231 char print_buffer[2048 + 1];
233 vsnprintf(print_buffer, sizeof(print_buffer), fmt, ap);
235 len = strlen(print_buffer);
236 Curl_debug(data, CURLINFO_TEXT, print_buffer, len, NULL);
240 /* Curl_failf() is for messages stating why we failed.
241 * The message SHALL NOT include any LF or CR.
244 void Curl_failf(struct Curl_easy *data, const char *fmt, ...)
250 vsnprintf(data->state.buffer, BUFSIZE, fmt, ap);
252 if(data->set.errorbuffer && !data->state.errorbuf) {
253 snprintf(data->set.errorbuffer, CURL_ERROR_SIZE, "%s", data->state.buffer);
254 data->state.errorbuf = TRUE; /* wrote error string */
256 if(data->set.verbose) {
257 len = strlen(data->state.buffer);
258 if(len < BUFSIZE - 1) {
259 data->state.buffer[len] = '\n';
260 data->state.buffer[++len] = '\0';
262 Curl_debug(data, CURLINFO_TEXT, data->state.buffer, len, NULL);
268 /* Curl_sendf() sends formated data to the server */
269 CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn,
270 const char *fmt, ...)
272 struct Curl_easy *data = conn->data;
273 ssize_t bytes_written;
275 CURLcode result = CURLE_OK;
280 s = vaprintf(fmt, ap); /* returns an allocated string */
283 return CURLE_OUT_OF_MEMORY; /* failure */
286 write_len = strlen(s);
290 /* Write the buffer to the socket */
291 result = Curl_write(conn, sockfd, sptr, write_len, &bytes_written);
296 if(data->set.verbose)
297 Curl_debug(data, CURLINFO_DATA_OUT, sptr, (size_t)bytes_written, conn);
299 if((size_t)bytes_written != write_len) {
300 /* if not all was written at once, we must advance the pointer, decrease
301 the size left and try again! */
302 write_len -= bytes_written;
303 sptr += bytes_written;
309 free(s); /* free the output string */
315 * Curl_write() is an internal write function that sends data to the
316 * server. Works with plain sockets, SCP, SSL or kerberos.
318 * If the write would block (CURLE_AGAIN), we return CURLE_OK and
319 * (*written == 0). Otherwise we return regular CURLcode value.
321 CURLcode Curl_write(struct connectdata *conn,
322 curl_socket_t sockfd,
327 ssize_t bytes_written;
328 CURLcode result = CURLE_OK;
329 int num = (sockfd == conn->sock[SECONDARYSOCKET]);
331 #ifdef USE_TIZEN_FEATURE_DLP
333 * Send data to Tizen DLP verification
335 curl_extensions_tizen_dlp_check_leak(conn->host.dispname, (char *const)mem,
339 bytes_written = conn->send[num](conn, num, mem, len, &result);
341 *written = bytes_written;
342 if(bytes_written >= 0)
343 /* we completely ignore the curlcode value when subzero is not returned */
346 /* handle CURLE_AGAIN or a send failure */
353 /* general send failure */
354 return CURLE_SEND_ERROR;
357 /* we got a specific curlcode, forward it */
362 ssize_t Curl_send_plain(struct connectdata *conn, int num,
363 const void *mem, size_t len, CURLcode *code)
365 curl_socket_t sockfd = conn->sock[num];
366 ssize_t bytes_written;
367 /* WinSock will destroy unread received data if send() is
369 To avoid lossage of received data, recv() must be
370 performed before every send() if any incoming data is
372 pre_receive_plain(conn, num);
374 #ifdef MSG_FASTOPEN /* Linux */
375 if(conn->bits.tcp_fastopen) {
376 bytes_written = sendto(sockfd, mem, len, MSG_FASTOPEN,
377 conn->ip_addr->ai_addr, conn->ip_addr->ai_addrlen);
378 conn->bits.tcp_fastopen = FALSE;
382 bytes_written = swrite(sockfd, mem, len);
385 if(-1 == bytes_written) {
389 #ifdef WSAEWOULDBLOCK
390 /* This is how Windows does it */
391 (WSAEWOULDBLOCK == err)
393 /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
394 due to its inability to send off data without blocking. We therefor
395 treat both error codes the same here */
396 (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err) ||
400 /* this is just a case of EWOULDBLOCK */
405 failf(conn->data, "Send failure: %s",
406 Curl_strerror(conn, err));
407 conn->data->state.os_errno = err;
408 *code = CURLE_SEND_ERROR;
411 return bytes_written;
415 * Curl_write_plain() is an internal write function that sends data to the
416 * server using plain sockets only. Otherwise meant to have the exact same
417 * proto as Curl_write()
419 CURLcode Curl_write_plain(struct connectdata *conn,
420 curl_socket_t sockfd,
425 ssize_t bytes_written;
427 int num = (sockfd == conn->sock[SECONDARYSOCKET]);
429 bytes_written = Curl_send_plain(conn, num, mem, len, &result);
431 *written = bytes_written;
436 ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf,
437 size_t len, CURLcode *code)
439 curl_socket_t sockfd = conn->sock[num];
441 /* Check and return data that already received and storied in internal
442 intermediate buffer */
443 nread = get_pre_recved(conn, num, buf, len);
449 nread = sread(sockfd, buf, len);
456 #ifdef WSAEWOULDBLOCK
457 /* This is how Windows does it */
458 (WSAEWOULDBLOCK == err)
460 /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
461 due to its inability to send off data without blocking. We therefor
462 treat both error codes the same here */
463 (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)
466 /* this is just a case of EWOULDBLOCK */
470 failf(conn->data, "Recv failure: %s",
471 Curl_strerror(conn, err));
472 conn->data->state.os_errno = err;
473 *code = CURLE_RECV_ERROR;
479 static CURLcode pausewrite(struct Curl_easy *data,
480 int type, /* what type of data */
484 /* signalled to pause sending on this connection, but since we have data
485 we want to send we need to dup it to save a copy for when the sending
487 struct SingleRequest *k = &data->req;
488 char *dupl = malloc(len);
490 return CURLE_OUT_OF_MEMORY;
492 memcpy(dupl, ptr, len);
494 /* store this information in the state struct for later use */
495 data->state.tempwrite = dupl;
496 data->state.tempwritesize = len;
497 data->state.tempwritetype = type;
499 /* mark the connection as RECV paused */
500 k->keepon |= KEEP_RECV_PAUSE;
502 DEBUGF(infof(data, "Pausing with %zu bytes in buffer for type %02x\n",
509 /* Curl_client_chop_write() writes chunks of data not larger than
510 * CURL_MAX_WRITE_SIZE via client write callback(s) and
511 * takes care of pause requests from the callbacks.
513 CURLcode Curl_client_chop_write(struct connectdata *conn,
518 struct Curl_easy *data = conn->data;
519 curl_write_callback writeheader = NULL;
520 curl_write_callback writebody = NULL;
525 /* If reading is actually paused, we're forced to append this chunk of data
526 to the already held data, but only if it is the same type as otherwise it
527 can't work and it'll return error instead. */
528 if(data->req.keepon & KEEP_RECV_PAUSE) {
531 if(type != data->state.tempwritetype)
532 /* major internal confusion */
533 return CURLE_RECV_ERROR;
535 DEBUGASSERT(data->state.tempwrite);
537 /* figure out the new size of the data to save */
538 newlen = len + data->state.tempwritesize;
539 /* allocate the new memory area */
540 newptr = realloc(data->state.tempwrite, newlen);
542 return CURLE_OUT_OF_MEMORY;
543 /* copy the new data to the end of the new area */
544 memcpy(newptr + data->state.tempwritesize, ptr, len);
545 /* update the pointer and the size */
546 data->state.tempwrite = newptr;
547 data->state.tempwritesize = newlen;
551 /* Determine the callback(s) to use. */
552 if(type & CLIENTWRITE_BODY)
553 writebody = data->set.fwrite_func;
554 if((type & CLIENTWRITE_HEADER) &&
555 (data->set.fwrite_header || data->set.writeheader)) {
557 * Write headers to the same callback or to the especially setup
558 * header callback function (added after version 7.7.1).
561 data->set.fwrite_header? data->set.fwrite_header: data->set.fwrite_func;
564 /* Chop data, write chunks. */
566 size_t chunklen = len <= CURL_MAX_WRITE_SIZE? len: CURL_MAX_WRITE_SIZE;
569 size_t wrote = writebody(ptr, 1, chunklen, data->set.out);
571 if(CURL_WRITEFUNC_PAUSE == wrote) {
572 if(conn->handler->flags & PROTOPT_NONETWORK) {
573 /* Protocols that work without network cannot be paused. This is
574 actually only FILE:// just now, and it can't pause since the
575 transfer isn't done using the "normal" procedure. */
576 failf(data, "Write callback asked for PAUSE when not supported!");
577 return CURLE_WRITE_ERROR;
580 return pausewrite(data, type, ptr, len);
582 else if(wrote != chunklen) {
583 failf(data, "Failed writing body (%zu != %zu)", wrote, chunklen);
584 return CURLE_WRITE_ERROR;
589 size_t wrote = writeheader(ptr, 1, chunklen, data->set.writeheader);
591 if(CURL_WRITEFUNC_PAUSE == wrote)
592 /* here we pass in the HEADER bit only since if this was body as well
593 then it was passed already and clearly that didn't trigger the
594 pause, so this is saved for later with the HEADER bit only */
595 return pausewrite(data, CLIENTWRITE_HEADER, ptr, len);
597 if(wrote != chunklen) {
598 failf(data, "Failed writing header");
599 return CURLE_WRITE_ERROR;
611 /* Curl_client_write() sends data to the write callback(s)
613 The bit pattern defines to what "streams" to write to. Body and/or header.
614 The defines are in sendf.h of course.
616 If CURL_DO_LINEEND_CONV is enabled, data is converted IN PLACE to the
617 local character encoding. This is a problem and should be changed in
618 the future to leave the original data alone.
620 CURLcode Curl_client_write(struct connectdata *conn,
625 struct Curl_easy *data = conn->data;
630 /* FTP data may need conversion. */
631 if((type & CLIENTWRITE_BODY) &&
632 (conn->handler->protocol & PROTO_FAMILY_FTP) &&
633 conn->proto.ftpc.transfertype == 'A') {
634 /* convert from the network encoding */
635 CURLcode result = Curl_convert_from_network(data, ptr, len);
636 /* Curl_convert_from_network calls failf if unsuccessful */
640 #ifdef CURL_DO_LINEEND_CONV
641 /* convert end-of-line markers */
642 len = convert_lineends(data, ptr, len);
643 #endif /* CURL_DO_LINEEND_CONV */
646 return Curl_client_chop_write(conn, type, ptr, len);
649 CURLcode Curl_read_plain(curl_socket_t sockfd,
651 size_t bytesfromsocket,
654 ssize_t nread = sread(sockfd, buf, bytesfromsocket);
660 return_error = WSAEWOULDBLOCK == err;
662 return_error = EWOULDBLOCK == err || EAGAIN == err || EINTR == err;
667 return CURLE_RECV_ERROR;
670 /* we only return number of bytes read when we return OK */
676 * Internal read-from-socket function. This is meant to deal with plain
677 * sockets, SSL sockets and kerberos sockets.
679 * Returns a regular CURLcode value.
681 CURLcode Curl_read(struct connectdata *conn, /* connection data */
682 curl_socket_t sockfd, /* read from this socket */
683 char *buf, /* store read data here */
684 size_t sizerequested, /* max amount to read */
685 ssize_t *n) /* amount bytes read */
687 CURLcode result = CURLE_RECV_ERROR;
689 size_t bytesfromsocket = 0;
690 char *buffertofill = NULL;
692 /* if HTTP/1 pipelining is both wanted and possible */
693 bool pipelining = Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1) &&
694 (conn->bundle->multiuse == BUNDLE_PIPELINING);
696 /* Set 'num' to 0 or 1, depending on which socket that has been sent here.
697 If it is the second socket, we set num to 1. Otherwise to 0. This lets
698 us use the correct ssl handle. */
699 int num = (sockfd == conn->sock[SECONDARYSOCKET]);
701 *n=0; /* reset amount to zero */
703 /* If session can pipeline, check connection buffer */
705 size_t bytestocopy = CURLMIN(conn->buf_len - conn->read_pos,
708 /* Copy from our master buffer first if we have some unread data there*/
709 if(bytestocopy > 0) {
710 memcpy(buf, conn->master_buffer + conn->read_pos, bytestocopy);
711 conn->read_pos += bytestocopy;
712 conn->bits.stream_was_rewound = FALSE;
714 *n = (ssize_t)bytestocopy;
717 /* If we come here, it means that there is no data to read from the buffer,
718 * so we read from the socket */
719 bytesfromsocket = CURLMIN(sizerequested, BUFSIZE * sizeof(char));
720 buffertofill = conn->master_buffer;
723 bytesfromsocket = CURLMIN((long)sizerequested,
724 conn->data->set.buffer_size ?
725 conn->data->set.buffer_size : BUFSIZE);
729 nread = conn->recv[num](conn, num, buffertofill, bytesfromsocket, &result);
734 memcpy(buf, conn->master_buffer, nread);
735 conn->buf_len = nread;
736 conn->read_pos = nread;
744 /* return 0 on success */
745 static int showit(struct Curl_easy *data, curl_infotype type,
746 char *ptr, size_t size)
748 static const char s_infotype[CURLINFO_END][3] = {
749 "* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
751 #ifdef CURL_DOES_CONVERSIONS
753 size_t conv_size = 0;
756 case CURLINFO_HEADER_OUT:
757 /* assume output headers are ASCII */
758 /* copy the data into my buffer so the original is unchanged */
760 size = BUFSIZE; /* truncate if necessary */
764 memcpy(buf, ptr, size);
765 /* Special processing is needed for this block if it
766 * contains both headers and data (separated by CRLFCRLF).
767 * We want to convert just the headers, leaving the data as-is.
771 for(i = 0; i < size-4; i++) {
772 if(memcmp(&buf[i], "\x0d\x0a\x0d\x0a", 4) == 0) {
773 /* convert everything through this CRLFCRLF but no further */
780 Curl_convert_from_network(data, buf, conv_size);
781 /* Curl_convert_from_network calls failf if unsuccessful */
782 /* we might as well continue even if it fails... */
783 ptr = buf; /* switch pointer to use my buffer instead */
786 /* leave everything else as-is */
789 #endif /* CURL_DOES_CONVERSIONS */
792 return (*data->set.fdebug)(data, type, ptr, size,
793 data->set.debugdata);
797 case CURLINFO_HEADER_OUT:
798 case CURLINFO_HEADER_IN:
799 fwrite(s_infotype[type], 2, 1, data->set.err);
800 fwrite(ptr, size, 1, data->set.err);
801 #ifdef CURL_DOES_CONVERSIONS
802 if(size != conv_size) {
803 /* we had untranslated data so we need an explicit newline */
804 fwrite("\n", 1, 1, data->set.err);
814 int Curl_debug(struct Curl_easy *data, curl_infotype type,
815 char *ptr, size_t size,
816 struct connectdata *conn)
819 if(data->set.printhost && conn && conn->host.dispname) {
822 const char *w="Data";
824 case CURLINFO_HEADER_IN:
827 case CURLINFO_DATA_IN:
830 case CURLINFO_HEADER_OUT:
833 case CURLINFO_DATA_OUT:
841 snprintf(buffer, sizeof(buffer), "[%s %s %s]", w, t,
842 conn->host.dispname);
843 rc = showit(data, CURLINFO_TEXT, buffer, strlen(buffer));
848 rc = showit(data, type, ptr, size);