1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2022, 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.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 * SPDX-License-Identifier: curl
23 ***************************************************************************/
25 #include "curl_setup.h"
27 #ifdef HAVE_NETINET_IN_H
28 #include <netinet/in.h>
31 #ifdef HAVE_LINUX_TCP_H
32 #include <linux/tcp.h>
33 #elif defined(HAVE_NETINET_TCP_H)
34 #include <netinet/tcp.h>
37 #include <curl/curl.h>
42 #include "vtls/vtls.h"
53 /* The last 3 #include files should be in this order */
54 #include "curl_printf.h"
55 #include "curl_memory.h"
58 #if defined(CURL_DO_LINEEND_CONV) && !defined(CURL_DISABLE_FTP)
60 * convert_lineends() changes CRLF (\r\n) end-of-line markers to a single LF
61 * (\n), with special processing for CRLF sequences that are split between two
62 * blocks of data. Remaining, bare CRs are changed to LFs. The possibly new
63 * size of the data is returned.
65 static size_t convert_lineends(struct Curl_easy *data,
66 char *startPtr, size_t size)
71 if(!startPtr || (size < 1)) {
75 if(data->state.prev_block_had_trailing_cr) {
76 /* The previous block of incoming data
77 had a trailing CR, which was turned into a LF. */
78 if(*startPtr == '\n') {
79 /* This block of incoming data starts with the
80 previous block's LF so get rid of it */
81 memmove(startPtr, startPtr + 1, size-1);
83 /* and it wasn't a bare CR but a CRLF conversion instead */
84 data->state.crlf_conversions++;
86 data->state.prev_block_had_trailing_cr = FALSE; /* reset the flag */
89 /* find 1st CR, if any */
90 inPtr = outPtr = memchr(startPtr, '\r', size);
92 /* at least one CR, now look for CRLF */
93 while(inPtr < (startPtr + size-1)) {
94 /* note that it's size-1, so we'll never look past the last byte */
95 if(memcmp(inPtr, "\r\n", 2) == 0) {
96 /* CRLF found, bump past the CR and copy the NL */
99 /* keep track of how many CRLFs we converted */
100 data->state.crlf_conversions++;
104 /* lone CR, move LF instead */
108 /* not a CRLF nor a CR, just copy whatever it is */
114 } /* end of while loop */
116 if(inPtr < startPtr + size) {
117 /* handle last byte */
119 /* deal with a CR at the end of the buffer */
120 *outPtr = '\n'; /* copy a NL instead */
121 /* note that a CRLF might be split across two blocks */
122 data->state.prev_block_had_trailing_cr = TRUE;
130 if(outPtr < startPtr + size)
131 /* tidy up by null terminating the now shorter data */
134 return (outPtr - startPtr);
138 #endif /* CURL_DO_LINEEND_CONV && !CURL_DISABLE_FTP */
140 #ifdef USE_RECV_BEFORE_SEND_WORKAROUND
141 bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex)
143 struct postponed_data * const psnd = &(conn->postponed[sockindex]);
144 return psnd->buffer && psnd->allocated_size &&
145 psnd->recv_size > psnd->recv_processed;
148 static CURLcode pre_receive_plain(struct Curl_easy *data,
149 struct connectdata *conn, int num)
151 const curl_socket_t sockfd = conn->sock[num];
152 struct postponed_data * const psnd = &(conn->postponed[num]);
153 size_t bytestorecv = psnd->allocated_size - psnd->recv_size;
154 /* WinSock will destroy unread received data if send() is
156 To avoid lossage of received data, recv() must be
157 performed before every send() if any incoming data is
158 available. However, skip this, if buffer is already full. */
159 if((conn->handler->protocol&PROTO_FAMILY_HTTP) != 0 &&
160 conn->recv[num] == Curl_recv_plain &&
161 (!psnd->buffer || bytestorecv)) {
162 const int readymask = Curl_socket_check(sockfd, CURL_SOCKET_BAD,
164 if(readymask != -1 && (readymask & CURL_CSELECT_IN) != 0) {
165 /* Have some incoming data */
167 /* Use buffer double default size for intermediate buffer */
168 psnd->allocated_size = 2 * data->set.buffer_size;
169 psnd->buffer = malloc(psnd->allocated_size);
171 return CURLE_OUT_OF_MEMORY;
173 psnd->recv_processed = 0;
175 psnd->bindsock = sockfd; /* Used only for DEBUGASSERT */
176 #endif /* DEBUGBUILD */
177 bytestorecv = psnd->allocated_size;
181 DEBUGASSERT(psnd->bindsock == sockfd);
182 recvedbytes = sread(sockfd, psnd->buffer + psnd->recv_size,
185 psnd->recv_size += recvedbytes;
188 psnd->allocated_size = 0;
194 static ssize_t get_pre_recved(struct connectdata *conn, int num, char *buf,
197 struct postponed_data * const psnd = &(conn->postponed[num]);
202 DEBUGASSERT(psnd->allocated_size > 0);
203 DEBUGASSERT(psnd->recv_size <= psnd->allocated_size);
204 DEBUGASSERT(psnd->recv_processed <= psnd->recv_size);
205 /* Check and process data that already received and storied in internal
206 intermediate buffer */
207 if(psnd->recv_size > psnd->recv_processed) {
208 DEBUGASSERT(psnd->bindsock == conn->sock[num]);
209 copysize = CURLMIN(len, psnd->recv_size - psnd->recv_processed);
210 memcpy(buf, psnd->buffer + psnd->recv_processed, copysize);
211 psnd->recv_processed += copysize;
214 copysize = 0; /* buffer was allocated, but nothing was received */
216 /* Free intermediate buffer if it has no unprocessed data */
217 if(psnd->recv_processed == psnd->recv_size) {
220 psnd->allocated_size = 0;
222 psnd->recv_processed = 0;
224 psnd->bindsock = CURL_SOCKET_BAD;
225 #endif /* DEBUGBUILD */
227 return (ssize_t)copysize;
229 #else /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
230 /* Use "do-nothing" macros instead of functions when workaround not used */
231 bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex)
237 #define pre_receive_plain(d,c,n) CURLE_OK
238 #define get_pre_recved(c,n,b,l) 0
239 #endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
241 /* Curl_infof() is for info message along the way */
244 void Curl_infof(struct Curl_easy *data, const char *fmt, ...)
246 DEBUGASSERT(!strchr(fmt, '\n'));
247 if(data && data->set.verbose) {
250 char buffer[MAXINFO + 2];
252 len = mvsnprintf(buffer, MAXINFO, fmt, ap);
254 buffer[len++] = '\n';
256 Curl_debug(data, CURLINFO_TEXT, buffer, len);
260 /* Curl_failf() is for messages stating why we failed.
261 * The message SHALL NOT include any LF or CR.
264 void Curl_failf(struct Curl_easy *data, const char *fmt, ...)
266 DEBUGASSERT(!strchr(fmt, '\n'));
267 if(data->set.verbose || data->set.errorbuffer) {
270 char error[CURL_ERROR_SIZE + 2];
272 len = mvsnprintf(error, CURL_ERROR_SIZE, fmt, ap);
274 if(data->set.errorbuffer && !data->state.errorbuf) {
275 strcpy(data->set.errorbuffer, error);
276 data->state.errorbuf = TRUE; /* wrote error string */
280 Curl_debug(data, CURLINFO_TEXT, error, len);
286 * Curl_write() is an internal write function that sends data to the
287 * server. Works with plain sockets, SCP, SSL or kerberos.
289 * If the write would block (CURLE_AGAIN), we return CURLE_OK and
290 * (*written == 0). Otherwise we return regular CURLcode value.
292 CURLcode Curl_write(struct Curl_easy *data,
293 curl_socket_t sockfd,
298 ssize_t bytes_written;
299 CURLcode result = CURLE_OK;
300 struct connectdata *conn;
303 DEBUGASSERT(data->conn);
305 num = (sockfd == conn->sock[SECONDARYSOCKET]);
309 /* Allow debug builds to override this logic to force short sends
311 char *p = getenv("CURL_SMALLSENDS");
313 size_t altsize = (size_t)strtoul(p, NULL, 10);
315 len = CURLMIN(len, altsize);
319 bytes_written = conn->send[num](data, num, mem, len, &result);
321 *written = bytes_written;
322 if(bytes_written >= 0)
323 /* we completely ignore the curlcode value when subzero is not returned */
326 /* handle CURLE_AGAIN or a send failure */
333 /* general send failure */
334 return CURLE_SEND_ERROR;
337 /* we got a specific curlcode, forward it */
342 ssize_t Curl_send_plain(struct Curl_easy *data, int num,
343 const void *mem, size_t len, CURLcode *code)
345 struct connectdata *conn;
346 curl_socket_t sockfd;
347 ssize_t bytes_written;
350 DEBUGASSERT(data->conn);
352 sockfd = conn->sock[num];
353 /* WinSock will destroy unread received data if send() is
355 To avoid lossage of received data, recv() must be
356 performed before every send() if any incoming data is
358 if(pre_receive_plain(data, conn, num)) {
359 *code = CURLE_OUT_OF_MEMORY;
363 #if defined(MSG_FASTOPEN) && !defined(TCP_FASTOPEN_CONNECT) /* Linux */
364 if(conn->bits.tcp_fastopen) {
365 bytes_written = sendto(sockfd, mem, len, MSG_FASTOPEN,
366 conn->ip_addr->ai_addr, conn->ip_addr->ai_addrlen);
367 conn->bits.tcp_fastopen = FALSE;
371 bytes_written = swrite(sockfd, mem, len);
374 if(-1 == bytes_written) {
378 #ifdef WSAEWOULDBLOCK
379 /* This is how Windows does it */
380 (WSAEWOULDBLOCK == err)
382 /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
383 due to its inability to send off data without blocking. We therefore
384 treat both error codes the same here */
385 (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err) ||
389 /* this is just a case of EWOULDBLOCK */
394 char buffer[STRERROR_LEN];
395 failf(data, "Send failure: %s",
396 Curl_strerror(err, buffer, sizeof(buffer)));
397 data->state.os_errno = err;
398 *code = CURLE_SEND_ERROR;
401 return bytes_written;
405 * Curl_write_plain() is an internal write function that sends data to the
406 * server using plain sockets only. Otherwise meant to have the exact same
407 * proto as Curl_write()
409 CURLcode Curl_write_plain(struct Curl_easy *data,
410 curl_socket_t sockfd,
416 struct connectdata *conn = data->conn;
419 num = (sockfd == conn->sock[SECONDARYSOCKET]);
421 *written = Curl_send_plain(data, num, mem, len, &result);
426 ssize_t Curl_recv_plain(struct Curl_easy *data, int num, char *buf,
427 size_t len, CURLcode *code)
429 struct connectdata *conn;
430 curl_socket_t sockfd;
433 DEBUGASSERT(data->conn);
435 sockfd = conn->sock[num];
436 /* Check and return data that already received and storied in internal
437 intermediate buffer */
438 nread = get_pre_recved(conn, num, buf, len);
444 nread = sread(sockfd, buf, len);
451 #ifdef WSAEWOULDBLOCK
452 /* This is how Windows does it */
453 (WSAEWOULDBLOCK == err)
455 /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
456 due to its inability to send off data without blocking. We therefore
457 treat both error codes the same here */
458 (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)
461 /* this is just a case of EWOULDBLOCK */
465 char buffer[STRERROR_LEN];
466 failf(data, "Recv failure: %s",
467 Curl_strerror(err, buffer, sizeof(buffer)));
468 data->state.os_errno = err;
469 *code = CURLE_RECV_ERROR;
475 static CURLcode pausewrite(struct Curl_easy *data,
476 int type, /* what type of data */
480 /* signalled to pause sending on this connection, but since we have data
481 we want to send we need to dup it to save a copy for when the sending
483 struct SingleRequest *k = &data->req;
484 struct UrlState *s = &data->state;
488 /* If this transfers over HTTP/2, pause the stream! */
489 Curl_http2_stream_pause(data, TRUE);
492 for(i = 0; i< s->tempcount; i++) {
493 if(s->tempwrite[i].type == type) {
494 /* data for this type exists */
501 /* There are more types to store than what fits: very bad */
502 return CURLE_OUT_OF_MEMORY;
508 /* store this information in the state struct for later use */
509 Curl_dyn_init(&s->tempwrite[i].b, DYN_PAUSE_BUFFER);
510 s->tempwrite[i].type = type;
514 if(Curl_dyn_addn(&s->tempwrite[i].b, (unsigned char *)ptr, len))
515 return CURLE_OUT_OF_MEMORY;
517 /* mark the connection as RECV paused */
518 k->keepon |= KEEP_RECV_PAUSE;
524 /* chop_write() writes chunks of data not larger than CURL_MAX_WRITE_SIZE via
525 * client write callback(s) and takes care of pause requests from the
528 static CURLcode chop_write(struct Curl_easy *data,
533 struct connectdata *conn = data->conn;
534 curl_write_callback writeheader = NULL;
535 curl_write_callback writebody = NULL;
538 void *writebody_ptr = data->set.out;
543 /* If reading is paused, append this data to the already held data for this
545 if(data->req.keepon & KEEP_RECV_PAUSE)
546 return pausewrite(data, type, ptr, len);
548 /* Determine the callback(s) to use. */
549 if(type & CLIENTWRITE_BODY) {
550 #ifdef USE_WEBSOCKETS
551 if(conn->handler->protocol & (CURLPROTO_WS|CURLPROTO_WSS)) {
552 struct HTTP *ws = data->req.p.http;
553 writebody = Curl_ws_writecb;
559 writebody = data->set.fwrite_func;
561 if((type & CLIENTWRITE_HEADER) &&
562 (data->set.fwrite_header || data->set.writeheader)) {
564 * Write headers to the same callback or to the especially setup
565 * header callback function (added after version 7.7.1).
568 data->set.fwrite_header? data->set.fwrite_header: data->set.fwrite_func;
571 /* Chop data, write chunks. */
573 size_t chunklen = len <= CURL_MAX_WRITE_SIZE? len: CURL_MAX_WRITE_SIZE;
577 Curl_set_in_callback(data, true);
578 wrote = writebody(ptr, 1, chunklen, writebody_ptr);
579 Curl_set_in_callback(data, false);
581 if(CURL_WRITEFUNC_PAUSE == wrote) {
582 if(conn->handler->flags & PROTOPT_NONETWORK) {
583 /* Protocols that work without network cannot be paused. This is
584 actually only FILE:// just now, and it can't pause since the
585 transfer isn't done using the "normal" procedure. */
586 failf(data, "Write callback asked for PAUSE when not supported");
587 return CURLE_WRITE_ERROR;
589 return pausewrite(data, type, ptr, len);
591 if(wrote != chunklen) {
592 failf(data, "Failure writing output to destination");
593 return CURLE_WRITE_ERROR;
601 #ifndef CURL_DISABLE_HTTP
602 /* HTTP header, but not status-line */
603 if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
604 (type & CLIENTWRITE_HEADER) && !(type & CLIENTWRITE_STATUS) ) {
605 unsigned char htype = (unsigned char)
606 (type & CLIENTWRITE_CONNECT ? CURLH_CONNECT :
607 (type & CLIENTWRITE_1XX ? CURLH_1XX :
608 (type & CLIENTWRITE_TRAILER ? CURLH_TRAILER :
610 CURLcode result = Curl_headers_push(data, optr, htype);
619 Curl_set_in_callback(data, true);
620 wrote = writeheader(optr, 1, olen, data->set.writeheader);
621 Curl_set_in_callback(data, false);
623 if(CURL_WRITEFUNC_PAUSE == wrote)
624 /* here we pass in the HEADER bit only since if this was body as well
625 then it was passed already and clearly that didn't trigger the
626 pause, so this is saved for later with the HEADER bit only */
627 return pausewrite(data, CLIENTWRITE_HEADER |
628 (type & (CLIENTWRITE_STATUS|CLIENTWRITE_CONNECT|
629 CLIENTWRITE_1XX|CLIENTWRITE_TRAILER)),
632 failf(data, "Failed writing header");
633 return CURLE_WRITE_ERROR;
641 /* Curl_client_write() sends data to the write callback(s)
643 The bit pattern defines to what "streams" to write to. Body and/or header.
644 The defines are in sendf.h of course.
646 If CURL_DO_LINEEND_CONV is enabled, data is converted IN PLACE to the
647 local character encoding. This is a problem and should be changed in
648 the future to leave the original data alone.
650 CURLcode Curl_client_write(struct Curl_easy *data,
655 #if !defined(CURL_DISABLE_FTP) && defined(CURL_DO_LINEEND_CONV)
656 /* FTP data may need conversion. */
657 if((type & CLIENTWRITE_BODY) &&
658 (data->conn->handler->protocol & PROTO_FAMILY_FTP) &&
659 data->conn->proto.ftpc.transfertype == 'A') {
660 /* convert end-of-line markers */
661 len = convert_lineends(data, ptr, len);
664 return chop_write(data, type, ptr, len);
667 CURLcode Curl_read_plain(curl_socket_t sockfd,
669 size_t bytesfromsocket,
672 ssize_t nread = sread(sockfd, buf, bytesfromsocket);
675 const int err = SOCKERRNO;
676 const bool return_error =
678 WSAEWOULDBLOCK == err
680 EWOULDBLOCK == err || EAGAIN == err || EINTR == err
683 *n = 0; /* no data returned */
686 return CURLE_RECV_ERROR;
694 * Internal read-from-socket function. This is meant to deal with plain
695 * sockets, SSL sockets and kerberos sockets.
697 * Returns a regular CURLcode value.
699 CURLcode Curl_read(struct Curl_easy *data, /* transfer */
700 curl_socket_t sockfd, /* read from this socket */
701 char *buf, /* store read data here */
702 size_t sizerequested, /* max amount to read */
703 ssize_t *n) /* amount bytes read */
705 CURLcode result = CURLE_RECV_ERROR;
707 size_t bytesfromsocket = 0;
708 char *buffertofill = NULL;
709 struct connectdata *conn = data->conn;
711 /* Set 'num' to 0 or 1, depending on which socket that has been sent here.
712 If it is the second socket, we set num to 1. Otherwise to 0. This lets
713 us use the correct ssl handle. */
714 int num = (sockfd == conn->sock[SECONDARYSOCKET]);
716 *n = 0; /* reset amount to zero */
718 bytesfromsocket = CURLMIN(sizerequested, (size_t)data->set.buffer_size);
721 nread = conn->recv[num](data, num, buffertofill, bytesfromsocket, &result);
730 /* return 0 on success */
731 void Curl_debug(struct Curl_easy *data, curl_infotype type,
732 char *ptr, size_t size)
734 if(data->set.verbose) {
735 static const char s_infotype[CURLINFO_END][3] = {
736 "* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
737 if(data->set.fdebug) {
738 bool inCallback = Curl_is_in_callback(data);
739 Curl_set_in_callback(data, true);
740 (void)(*data->set.fdebug)(data, type, ptr, size, data->set.debugdata);
741 Curl_set_in_callback(data, inCallback);
746 case CURLINFO_HEADER_OUT:
747 case CURLINFO_HEADER_IN:
748 fwrite(s_infotype[type], 2, 1, data->set.err);
749 fwrite(ptr, size, 1, data->set.err);