blob: 14ca84bfe5bf5dd634f13ebe7bb725c40a0dfe47 [file] [log] [blame]
Kristian Monsen5ab50182010-05-14 18:53:44 +01001/***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
Elliott Hughes34dd5f42021-08-10 13:01:18 -07008 * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
Kristian Monsen5ab50182010-05-14 18:53:44 +01009 *
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
Elliott Hughes34dd5f42021-08-10 13:01:18 -070012 * are also available at https://curl.se/docs/copyright.html.
Kristian Monsen5ab50182010-05-14 18:53:44 +010013 *
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
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -070023#include "curl_setup.h"
Kristian Monsen5ab50182010-05-14 18:53:44 +010024
Elliott Hughes0128fe42018-02-27 14:57:55 -080025#ifdef HAVE_NETINET_IN_H
26#include <netinet/in.h>
27#endif
28
Alex Deymo486467e2017-12-19 19:04:07 +010029#ifdef HAVE_LINUX_TCP_H
30#include <linux/tcp.h>
Elliott Hughes34dd5f42021-08-10 13:01:18 -070031#elif defined(HAVE_NETINET_TCP_H)
32#include <netinet/tcp.h>
Alex Deymo486467e2017-12-19 19:04:07 +010033#endif
34
Kristian Monsen5ab50182010-05-14 18:53:44 +010035#include <curl/curl.h>
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -070036
Kristian Monsen5ab50182010-05-14 18:53:44 +010037#include "urldata.h"
38#include "sendf.h"
39#include "connect.h"
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -070040#include "vtls/vtls.h"
Haibo Huangb51266f2020-03-04 02:22:48 -080041#include "vssh/ssh.h"
Elliott Hughescac39802018-04-27 16:19:43 -070042#include "easyif.h"
Kristian Monsen5ab50182010-05-14 18:53:44 +010043#include "multiif.h"
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -070044#include "non-ascii.h"
Kristian Monsen5ab50182010-05-14 18:53:44 +010045#include "strerror.h"
Alex Deymod15eaac2016-06-28 14:49:26 -070046#include "select.h"
Elliott Hughes82be86d2017-09-20 17:00:17 -070047#include "strdup.h"
Haibo Huangb51266f2020-03-04 02:22:48 -080048#include "http2.h"
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -070049
Alex Deymod15eaac2016-06-28 14:49:26 -070050/* The last 3 #include files should be in this order */
51#include "curl_printf.h"
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -070052#include "curl_memory.h"
Kristian Monsen5ab50182010-05-14 18:53:44 +010053#include "memdebug.h"
54
55#ifdef CURL_DO_LINEEND_CONV
56/*
57 * convert_lineends() changes CRLF (\r\n) end-of-line markers to a single LF
58 * (\n), with special processing for CRLF sequences that are split between two
59 * blocks of data. Remaining, bare CRs are changed to LFs. The possibly new
60 * size of the data is returned.
61 */
Alex Deymoe3149cc2016-10-05 11:18:42 -070062static size_t convert_lineends(struct Curl_easy *data,
Kristian Monsen5ab50182010-05-14 18:53:44 +010063 char *startPtr, size_t size)
64{
65 char *inPtr, *outPtr;
66
67 /* sanity check */
Elliott Hughes34dd5f42021-08-10 13:01:18 -070068 if(!startPtr || (size < 1)) {
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -070069 return size;
Kristian Monsen5ab50182010-05-14 18:53:44 +010070 }
71
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -070072 if(data->state.prev_block_had_trailing_cr) {
Kristian Monsen5ab50182010-05-14 18:53:44 +010073 /* The previous block of incoming data
74 had a trailing CR, which was turned into a LF. */
75 if(*startPtr == '\n') {
76 /* This block of incoming data starts with the
77 previous block's LF so get rid of it */
Alex Deymo486467e2017-12-19 19:04:07 +010078 memmove(startPtr, startPtr + 1, size-1);
Kristian Monsen5ab50182010-05-14 18:53:44 +010079 size--;
80 /* and it wasn't a bare CR but a CRLF conversion instead */
81 data->state.crlf_conversions++;
82 }
83 data->state.prev_block_had_trailing_cr = FALSE; /* reset the flag */
84 }
85
86 /* find 1st CR, if any */
87 inPtr = outPtr = memchr(startPtr, '\r', size);
88 if(inPtr) {
89 /* at least one CR, now look for CRLF */
Alex Deymo486467e2017-12-19 19:04:07 +010090 while(inPtr < (startPtr + size-1)) {
Kristian Monsen5ab50182010-05-14 18:53:44 +010091 /* note that it's size-1, so we'll never look past the last byte */
92 if(memcmp(inPtr, "\r\n", 2) == 0) {
93 /* CRLF found, bump past the CR and copy the NL */
94 inPtr++;
95 *outPtr = *inPtr;
96 /* keep track of how many CRLFs we converted */
97 data->state.crlf_conversions++;
98 }
99 else {
100 if(*inPtr == '\r') {
101 /* lone CR, move LF instead */
102 *outPtr = '\n';
103 }
104 else {
105 /* not a CRLF nor a CR, just copy whatever it is */
106 *outPtr = *inPtr;
107 }
108 }
109 outPtr++;
110 inPtr++;
111 } /* end of while loop */
112
Alex Deymo486467e2017-12-19 19:04:07 +0100113 if(inPtr < startPtr + size) {
Kristian Monsen5ab50182010-05-14 18:53:44 +0100114 /* handle last byte */
115 if(*inPtr == '\r') {
116 /* deal with a CR at the end of the buffer */
117 *outPtr = '\n'; /* copy a NL instead */
118 /* note that a CRLF might be split across two blocks */
119 data->state.prev_block_had_trailing_cr = TRUE;
120 }
121 else {
122 /* copy last byte */
123 *outPtr = *inPtr;
124 }
125 outPtr++;
126 }
Alex Deymo486467e2017-12-19 19:04:07 +0100127 if(outPtr < startPtr + size)
Kristian Monsen5ab50182010-05-14 18:53:44 +0100128 /* tidy up by null terminating the now shorter data */
129 *outPtr = '\0';
130
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700131 return (outPtr - startPtr);
Kristian Monsen5ab50182010-05-14 18:53:44 +0100132 }
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700133 return size;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100134}
135#endif /* CURL_DO_LINEEND_CONV */
136
Alex Deymod15eaac2016-06-28 14:49:26 -0700137#ifdef USE_RECV_BEFORE_SEND_WORKAROUND
Elliott Hughes82be86d2017-09-20 17:00:17 -0700138bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex)
139{
140 struct postponed_data * const psnd = &(conn->postponed[sockindex]);
141 return psnd->buffer && psnd->allocated_size &&
142 psnd->recv_size > psnd->recv_processed;
143}
144
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700145static CURLcode pre_receive_plain(struct Curl_easy *data,
146 struct connectdata *conn, int num)
Alex Deymod15eaac2016-06-28 14:49:26 -0700147{
148 const curl_socket_t sockfd = conn->sock[num];
149 struct postponed_data * const psnd = &(conn->postponed[num]);
150 size_t bytestorecv = psnd->allocated_size - psnd->recv_size;
151 /* WinSock will destroy unread received data if send() is
152 failed.
153 To avoid lossage of received data, recv() must be
154 performed before every send() if any incoming data is
155 available. However, skip this, if buffer is already full. */
156 if((conn->handler->protocol&PROTO_FAMILY_HTTP) != 0 &&
157 conn->recv[num] == Curl_recv_plain &&
158 (!psnd->buffer || bytestorecv)) {
159 const int readymask = Curl_socket_check(sockfd, CURL_SOCKET_BAD,
160 CURL_SOCKET_BAD, 0);
161 if(readymask != -1 && (readymask & CURL_CSELECT_IN) != 0) {
162 /* Have some incoming data */
163 if(!psnd->buffer) {
164 /* Use buffer double default size for intermediate buffer */
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700165 psnd->allocated_size = 2 * data->set.buffer_size;
Alex Deymod15eaac2016-06-28 14:49:26 -0700166 psnd->buffer = malloc(psnd->allocated_size);
Haibo Huangb5a52b92020-10-28 22:18:23 -0700167 if(!psnd->buffer)
168 return CURLE_OUT_OF_MEMORY;
Alex Deymod15eaac2016-06-28 14:49:26 -0700169 psnd->recv_size = 0;
170 psnd->recv_processed = 0;
171#ifdef DEBUGBUILD
172 psnd->bindsock = sockfd; /* Used only for DEBUGASSERT */
173#endif /* DEBUGBUILD */
174 bytestorecv = psnd->allocated_size;
175 }
176 if(psnd->buffer) {
177 ssize_t recvedbytes;
178 DEBUGASSERT(psnd->bindsock == sockfd);
179 recvedbytes = sread(sockfd, psnd->buffer + psnd->recv_size,
180 bytestorecv);
181 if(recvedbytes > 0)
182 psnd->recv_size += recvedbytes;
183 }
184 else
185 psnd->allocated_size = 0;
186 }
187 }
Haibo Huangb5a52b92020-10-28 22:18:23 -0700188 return CURLE_OK;
Alex Deymod15eaac2016-06-28 14:49:26 -0700189}
190
191static ssize_t get_pre_recved(struct connectdata *conn, int num, char *buf,
192 size_t len)
193{
194 struct postponed_data * const psnd = &(conn->postponed[num]);
195 size_t copysize;
196 if(!psnd->buffer)
197 return 0;
198
199 DEBUGASSERT(psnd->allocated_size > 0);
200 DEBUGASSERT(psnd->recv_size <= psnd->allocated_size);
201 DEBUGASSERT(psnd->recv_processed <= psnd->recv_size);
202 /* Check and process data that already received and storied in internal
203 intermediate buffer */
204 if(psnd->recv_size > psnd->recv_processed) {
205 DEBUGASSERT(psnd->bindsock == conn->sock[num]);
206 copysize = CURLMIN(len, psnd->recv_size - psnd->recv_processed);
207 memcpy(buf, psnd->buffer + psnd->recv_processed, copysize);
208 psnd->recv_processed += copysize;
209 }
210 else
211 copysize = 0; /* buffer was allocated, but nothing was received */
212
213 /* Free intermediate buffer if it has no unprocessed data */
214 if(psnd->recv_processed == psnd->recv_size) {
215 free(psnd->buffer);
216 psnd->buffer = NULL;
217 psnd->allocated_size = 0;
218 psnd->recv_size = 0;
219 psnd->recv_processed = 0;
220#ifdef DEBUGBUILD
221 psnd->bindsock = CURL_SOCKET_BAD;
222#endif /* DEBUGBUILD */
223 }
224 return (ssize_t)copysize;
225}
226#else /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
227/* Use "do-nothing" macros instead of functions when workaround not used */
Elliott Hughes82be86d2017-09-20 17:00:17 -0700228bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex)
229{
230 (void)conn;
231 (void)sockindex;
232 return false;
233}
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700234#define pre_receive_plain(d,c,n) CURLE_OK
Alex Deymod15eaac2016-06-28 14:49:26 -0700235#define get_pre_recved(c,n,b,l) 0
236#endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
237
Kristian Monsen5ab50182010-05-14 18:53:44 +0100238/* Curl_infof() is for info message along the way */
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700239#define MAXINFO 2048
Kristian Monsen5ab50182010-05-14 18:53:44 +0100240
Alex Deymoe3149cc2016-10-05 11:18:42 -0700241void Curl_infof(struct Curl_easy *data, const char *fmt, ...)
Kristian Monsen5ab50182010-05-14 18:53:44 +0100242{
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700243 DEBUGASSERT(!strchr(fmt, '\n'));
Kristian Monsen5ab50182010-05-14 18:53:44 +0100244 if(data && data->set.verbose) {
245 va_list ap;
246 size_t len;
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700247 char buffer[MAXINFO + 2];
Kristian Monsen5ab50182010-05-14 18:53:44 +0100248 va_start(ap, fmt);
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700249 len = mvsnprintf(buffer, MAXINFO, fmt, ap);
Kristian Monsen5ab50182010-05-14 18:53:44 +0100250 va_end(ap);
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700251 buffer[len++] = '\n';
252 buffer[len] = '\0';
253 Curl_debug(data, CURLINFO_TEXT, buffer, len);
Kristian Monsen5ab50182010-05-14 18:53:44 +0100254 }
255}
256
257/* Curl_failf() is for messages stating why we failed.
258 * The message SHALL NOT include any LF or CR.
259 */
260
Alex Deymoe3149cc2016-10-05 11:18:42 -0700261void Curl_failf(struct Curl_easy *data, const char *fmt, ...)
Kristian Monsen5ab50182010-05-14 18:53:44 +0100262{
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700263 DEBUGASSERT(!strchr(fmt, '\n'));
Alex Deymo486467e2017-12-19 19:04:07 +0100264 if(data->set.verbose || data->set.errorbuffer) {
265 va_list ap;
266 size_t len;
267 char error[CURL_ERROR_SIZE + 2];
268 va_start(ap, fmt);
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700269 len = mvsnprintf(error, CURL_ERROR_SIZE, fmt, ap);
Kristian Monsen5ab50182010-05-14 18:53:44 +0100270
Alex Deymo486467e2017-12-19 19:04:07 +0100271 if(data->set.errorbuffer && !data->state.errorbuf) {
272 strcpy(data->set.errorbuffer, error);
273 data->state.errorbuf = TRUE; /* wrote error string */
274 }
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700275 error[len++] = '\n';
276 error[len] = '\0';
277 Curl_debug(data, CURLINFO_TEXT, error, len);
Alex Deymo486467e2017-12-19 19:04:07 +0100278 va_end(ap);
Kristian Monsen5ab50182010-05-14 18:53:44 +0100279 }
Kristian Monsen5ab50182010-05-14 18:53:44 +0100280}
281
Lucas Eckels9bd90e62012-08-06 15:07:02 -0700282/*
283 * Curl_write() is an internal write function that sends data to the
284 * server. Works with plain sockets, SCP, SSL or kerberos.
285 *
286 * If the write would block (CURLE_AGAIN), we return CURLE_OK and
287 * (*written == 0). Otherwise we return regular CURLcode value.
288 */
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700289CURLcode Curl_write(struct Curl_easy *data,
Lucas Eckels9bd90e62012-08-06 15:07:02 -0700290 curl_socket_t sockfd,
291 const void *mem,
292 size_t len,
293 ssize_t *written)
294{
295 ssize_t bytes_written;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700296 CURLcode result = CURLE_OK;
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700297 struct connectdata *conn;
298 int num;
299 DEBUGASSERT(data);
300 DEBUGASSERT(data->conn);
301 conn = data->conn;
302 num = (sockfd == conn->sock[SECONDARYSOCKET]);
Lucas Eckels9bd90e62012-08-06 15:07:02 -0700303
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700304#ifdef CURLDEBUG
305 {
306 /* Allow debug builds to override this logic to force short sends
307 */
308 char *p = getenv("CURL_SMALLSENDS");
309 if(p) {
310 size_t altsize = (size_t)strtoul(p, NULL, 10);
311 if(altsize)
312 len = CURLMIN(len, altsize);
313 }
314 }
315#endif
316 bytes_written = conn->send[num](data, num, mem, len, &result);
Lucas Eckels9bd90e62012-08-06 15:07:02 -0700317
318 *written = bytes_written;
319 if(bytes_written >= 0)
320 /* we completely ignore the curlcode value when subzero is not returned */
321 return CURLE_OK;
322
323 /* handle CURLE_AGAIN or a send failure */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700324 switch(result) {
Lucas Eckels9bd90e62012-08-06 15:07:02 -0700325 case CURLE_AGAIN:
326 *written = 0;
327 return CURLE_OK;
328
329 case CURLE_OK:
330 /* general send failure */
331 return CURLE_SEND_ERROR;
332
333 default:
334 /* we got a specific curlcode, forward it */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700335 return result;
Lucas Eckels9bd90e62012-08-06 15:07:02 -0700336 }
337}
338
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700339ssize_t Curl_send_plain(struct Curl_easy *data, int num,
Lucas Eckels9bd90e62012-08-06 15:07:02 -0700340 const void *mem, size_t len, CURLcode *code)
Kristian Monsen5ab50182010-05-14 18:53:44 +0100341{
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700342 struct connectdata *conn;
343 curl_socket_t sockfd;
Alex Deymod15eaac2016-06-28 14:49:26 -0700344 ssize_t bytes_written;
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700345
346 DEBUGASSERT(data);
347 DEBUGASSERT(data->conn);
348 conn = data->conn;
349 sockfd = conn->sock[num];
Alex Deymod15eaac2016-06-28 14:49:26 -0700350 /* WinSock will destroy unread received data if send() is
351 failed.
352 To avoid lossage of received data, recv() must be
353 performed before every send() if any incoming data is
354 available. */
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700355 if(pre_receive_plain(data, conn, num)) {
Haibo Huangb5a52b92020-10-28 22:18:23 -0700356 *code = CURLE_OUT_OF_MEMORY;
357 return -1;
358 }
Alex Deymod15eaac2016-06-28 14:49:26 -0700359
Alex Deymo486467e2017-12-19 19:04:07 +0100360#if defined(MSG_FASTOPEN) && !defined(TCP_FASTOPEN_CONNECT) /* Linux */
Alex Deymod15eaac2016-06-28 14:49:26 -0700361 if(conn->bits.tcp_fastopen) {
362 bytes_written = sendto(sockfd, mem, len, MSG_FASTOPEN,
363 conn->ip_addr->ai_addr, conn->ip_addr->ai_addrlen);
364 conn->bits.tcp_fastopen = FALSE;
365 }
366 else
367#endif
368 bytes_written = swrite(sockfd, mem, len);
Kristian Monsen5ab50182010-05-14 18:53:44 +0100369
Lucas Eckels9bd90e62012-08-06 15:07:02 -0700370 *code = CURLE_OK;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100371 if(-1 == bytes_written) {
372 int err = SOCKERRNO;
373
374 if(
375#ifdef WSAEWOULDBLOCK
376 /* This is how Windows does it */
377 (WSAEWOULDBLOCK == err)
378#else
379 /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
Elliott Hughescac39802018-04-27 16:19:43 -0700380 due to its inability to send off data without blocking. We therefore
Kristian Monsen5ab50182010-05-14 18:53:44 +0100381 treat both error codes the same here */
Alex Deymod15eaac2016-06-28 14:49:26 -0700382 (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err) ||
383 (EINPROGRESS == err)
Kristian Monsen5ab50182010-05-14 18:53:44 +0100384#endif
Lucas Eckels9bd90e62012-08-06 15:07:02 -0700385 ) {
Kristian Monsen5ab50182010-05-14 18:53:44 +0100386 /* this is just a case of EWOULDBLOCK */
Alex Deymo486467e2017-12-19 19:04:07 +0100387 bytes_written = 0;
Lucas Eckels9bd90e62012-08-06 15:07:02 -0700388 *code = CURLE_AGAIN;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700389 }
390 else {
Haibo Huang65021c72019-03-27 15:37:23 -0700391 char buffer[STRERROR_LEN];
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700392 failf(data, "Send failure: %s",
Haibo Huang65021c72019-03-27 15:37:23 -0700393 Curl_strerror(err, buffer, sizeof(buffer)));
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700394 data->state.os_errno = err;
Lucas Eckels9bd90e62012-08-06 15:07:02 -0700395 *code = CURLE_SEND_ERROR;
396 }
Kristian Monsen5ab50182010-05-14 18:53:44 +0100397 }
398 return bytes_written;
399}
400
401/*
Kristian Monsen5ab50182010-05-14 18:53:44 +0100402 * Curl_write_plain() is an internal write function that sends data to the
403 * server using plain sockets only. Otherwise meant to have the exact same
404 * proto as Curl_write()
405 */
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700406CURLcode Curl_write_plain(struct Curl_easy *data,
Kristian Monsen5ab50182010-05-14 18:53:44 +0100407 curl_socket_t sockfd,
408 const void *mem,
409 size_t len,
410 ssize_t *written)
411{
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700412 CURLcode result;
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700413 struct connectdata *conn = data->conn;
414 int num;
415 DEBUGASSERT(conn);
416 num = (sockfd == conn->sock[SECONDARYSOCKET]);
Kristian Monsen5ab50182010-05-14 18:53:44 +0100417
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700418 *written = Curl_send_plain(data, num, mem, len, &result);
Kristian Monsen5ab50182010-05-14 18:53:44 +0100419
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700420 return result;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100421}
422
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700423ssize_t Curl_recv_plain(struct Curl_easy *data, int num, char *buf,
Lucas Eckels9bd90e62012-08-06 15:07:02 -0700424 size_t len, CURLcode *code)
425{
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700426 struct connectdata *conn;
427 curl_socket_t sockfd;
Alex Deymod15eaac2016-06-28 14:49:26 -0700428 ssize_t nread;
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700429 DEBUGASSERT(data);
430 DEBUGASSERT(data->conn);
431 conn = data->conn;
432 sockfd = conn->sock[num];
Alex Deymod15eaac2016-06-28 14:49:26 -0700433 /* Check and return data that already received and storied in internal
434 intermediate buffer */
435 nread = get_pre_recved(conn, num, buf, len);
436 if(nread > 0) {
437 *code = CURLE_OK;
438 return nread;
439 }
440
441 nread = sread(sockfd, buf, len);
Lucas Eckels9bd90e62012-08-06 15:07:02 -0700442
443 *code = CURLE_OK;
444 if(-1 == nread) {
445 int err = SOCKERRNO;
446
447 if(
448#ifdef WSAEWOULDBLOCK
449 /* This is how Windows does it */
450 (WSAEWOULDBLOCK == err)
451#else
452 /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
Elliott Hughescac39802018-04-27 16:19:43 -0700453 due to its inability to send off data without blocking. We therefore
Lucas Eckels9bd90e62012-08-06 15:07:02 -0700454 treat both error codes the same here */
455 (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)
456#endif
457 ) {
458 /* this is just a case of EWOULDBLOCK */
459 *code = CURLE_AGAIN;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700460 }
461 else {
Haibo Huang65021c72019-03-27 15:37:23 -0700462 char buffer[STRERROR_LEN];
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700463 failf(data, "Recv failure: %s",
Haibo Huang65021c72019-03-27 15:37:23 -0700464 Curl_strerror(err, buffer, sizeof(buffer)));
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700465 data->state.os_errno = err;
Lucas Eckels9bd90e62012-08-06 15:07:02 -0700466 *code = CURLE_RECV_ERROR;
467 }
468 }
469 return nread;
470}
471
Alex Deymoe3149cc2016-10-05 11:18:42 -0700472static CURLcode pausewrite(struct Curl_easy *data,
Kristian Monsen5ab50182010-05-14 18:53:44 +0100473 int type, /* what type of data */
474 const char *ptr,
475 size_t len)
476{
477 /* signalled to pause sending on this connection, but since we have data
478 we want to send we need to dup it to save a copy for when the sending
479 is again enabled */
480 struct SingleRequest *k = &data->req;
Elliott Hughes82be86d2017-09-20 17:00:17 -0700481 struct UrlState *s = &data->state;
Elliott Hughes82be86d2017-09-20 17:00:17 -0700482 unsigned int i;
483 bool newtype = TRUE;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100484
Haibo Huangb51266f2020-03-04 02:22:48 -0800485 /* If this transfers over HTTP/2, pause the stream! */
486 Curl_http2_stream_pause(data, TRUE);
487
Elliott Hughes82be86d2017-09-20 17:00:17 -0700488 if(s->tempcount) {
Alex Deymo486467e2017-12-19 19:04:07 +0100489 for(i = 0; i< s->tempcount; i++) {
Elliott Hughes82be86d2017-09-20 17:00:17 -0700490 if(s->tempwrite[i].type == type) {
491 /* data for this type exists */
492 newtype = FALSE;
493 break;
494 }
495 }
496 DEBUGASSERT(i < 3);
497 }
498 else
499 i = 0;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100500
Haibo Huangca2a8022020-07-10 20:17:42 -0700501 if(newtype) {
Elliott Hughes82be86d2017-09-20 17:00:17 -0700502 /* store this information in the state struct for later use */
Haibo Huangca2a8022020-07-10 20:17:42 -0700503 Curl_dyn_init(&s->tempwrite[i].b, DYN_PAUSE_BUFFER);
Elliott Hughes82be86d2017-09-20 17:00:17 -0700504 s->tempwrite[i].type = type;
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700505 s->tempcount++;
Elliott Hughes82be86d2017-09-20 17:00:17 -0700506 }
Kristian Monsen5ab50182010-05-14 18:53:44 +0100507
Haibo Huangca2a8022020-07-10 20:17:42 -0700508 if(Curl_dyn_addn(&s->tempwrite[i].b, (unsigned char *)ptr, len))
509 return CURLE_OUT_OF_MEMORY;
510
Kristian Monsen5ab50182010-05-14 18:53:44 +0100511 /* mark the connection as RECV paused */
512 k->keepon |= KEEP_RECV_PAUSE;
513
Kristian Monsen5ab50182010-05-14 18:53:44 +0100514 return CURLE_OK;
515}
516
517
Elliott Hughescac39802018-04-27 16:19:43 -0700518/* chop_write() writes chunks of data not larger than CURL_MAX_WRITE_SIZE via
519 * client write callback(s) and takes care of pause requests from the
520 * callbacks.
Kristian Monsen5ab50182010-05-14 18:53:44 +0100521 */
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700522static CURLcode chop_write(struct Curl_easy *data,
Elliott Hughescac39802018-04-27 16:19:43 -0700523 int type,
524 char *optr,
525 size_t olen)
Kristian Monsen5ab50182010-05-14 18:53:44 +0100526{
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700527 struct connectdata *conn = data->conn;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700528 curl_write_callback writeheader = NULL;
529 curl_write_callback writebody = NULL;
Elliott Hughescac39802018-04-27 16:19:43 -0700530 char *ptr = optr;
531 size_t len = olen;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100532
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700533 if(!len)
534 return CURLE_OK;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100535
Elliott Hughes82be86d2017-09-20 17:00:17 -0700536 /* If reading is paused, append this data to the already held data for this
537 type. */
538 if(data->req.keepon & KEEP_RECV_PAUSE)
539 return pausewrite(data, type, ptr, len);
Kristian Monsen5ab50182010-05-14 18:53:44 +0100540
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700541 /* Determine the callback(s) to use. */
542 if(type & CLIENTWRITE_BODY)
543 writebody = data->set.fwrite_func;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100544 if((type & CLIENTWRITE_HEADER) &&
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700545 (data->set.fwrite_header || data->set.writeheader)) {
Kristian Monsen5ab50182010-05-14 18:53:44 +0100546 /*
547 * Write headers to the same callback or to the especially setup
548 * header callback function (added after version 7.7.1).
549 */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700550 writeheader =
551 data->set.fwrite_header? data->set.fwrite_header: data->set.fwrite_func;
552 }
Kristian Monsen5ab50182010-05-14 18:53:44 +0100553
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700554 /* Chop data, write chunks. */
555 while(len) {
556 size_t chunklen = len <= CURL_MAX_WRITE_SIZE? len: CURL_MAX_WRITE_SIZE;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100557
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700558 if(writebody) {
Haibo Huang34ab3462019-05-22 00:50:27 -0700559 size_t wrote;
560 Curl_set_in_callback(data, true);
561 wrote = writebody(ptr, 1, chunklen, data->set.out);
562 Curl_set_in_callback(data, false);
Kristian Monsen5ab50182010-05-14 18:53:44 +0100563
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700564 if(CURL_WRITEFUNC_PAUSE == wrote) {
565 if(conn->handler->flags & PROTOPT_NONETWORK) {
566 /* Protocols that work without network cannot be paused. This is
567 actually only FILE:// just now, and it can't pause since the
568 transfer isn't done using the "normal" procedure. */
569 failf(data, "Write callback asked for PAUSE when not supported!");
570 return CURLE_WRITE_ERROR;
571 }
Elliott Hughes82be86d2017-09-20 17:00:17 -0700572 return pausewrite(data, type, ptr, len);
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700573 }
Elliott Hughes82be86d2017-09-20 17:00:17 -0700574 if(wrote != chunklen) {
Haibo Huangca2a8022020-07-10 20:17:42 -0700575 failf(data, "Failure writing output to destination");
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700576 return CURLE_WRITE_ERROR;
577 }
Kristian Monsen5ab50182010-05-14 18:53:44 +0100578 }
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700579
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700580 ptr += chunklen;
581 len -= chunklen;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100582 }
583
Elliott Hughescac39802018-04-27 16:19:43 -0700584 if(writeheader) {
585 size_t wrote;
586 ptr = optr;
587 len = olen;
588 Curl_set_in_callback(data, true);
589 wrote = writeheader(ptr, 1, len, data->set.writeheader);
590 Curl_set_in_callback(data, false);
591
592 if(CURL_WRITEFUNC_PAUSE == wrote)
593 /* here we pass in the HEADER bit only since if this was body as well
594 then it was passed already and clearly that didn't trigger the
595 pause, so this is saved for later with the HEADER bit only */
596 return pausewrite(data, CLIENTWRITE_HEADER, ptr, len);
597
598 if(wrote != len) {
599 failf(data, "Failed writing header");
600 return CURLE_WRITE_ERROR;
601 }
602 }
603
Kristian Monsen5ab50182010-05-14 18:53:44 +0100604 return CURLE_OK;
605}
606
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700607
608/* Curl_client_write() sends data to the write callback(s)
609
610 The bit pattern defines to what "streams" to write to. Body and/or header.
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700611 The defines are in sendf.h of course. "len" is not allowed to be 0.
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700612
613 If CURL_DO_LINEEND_CONV is enabled, data is converted IN PLACE to the
614 local character encoding. This is a problem and should be changed in
615 the future to leave the original data alone.
616 */
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700617CURLcode Curl_client_write(struct Curl_easy *data,
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700618 int type,
619 char *ptr,
620 size_t len)
621{
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700622 struct connectdata *conn = data->conn;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700623
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700624 DEBUGASSERT(len);
Elliott Hughes82be86d2017-09-20 17:00:17 -0700625 DEBUGASSERT(type <= 3);
626
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700627 /* FTP data may need conversion. */
628 if((type & CLIENTWRITE_BODY) &&
629 (conn->handler->protocol & PROTO_FAMILY_FTP) &&
630 conn->proto.ftpc.transfertype == 'A') {
631 /* convert from the network encoding */
632 CURLcode result = Curl_convert_from_network(data, ptr, len);
633 /* Curl_convert_from_network calls failf if unsuccessful */
634 if(result)
635 return result;
636
637#ifdef CURL_DO_LINEEND_CONV
638 /* convert end-of-line markers */
639 len = convert_lineends(data, ptr, len);
640#endif /* CURL_DO_LINEEND_CONV */
641 }
642
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700643 return chop_write(data, type, ptr, len);
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700644}
645
Lucas Eckels9bd90e62012-08-06 15:07:02 -0700646CURLcode Curl_read_plain(curl_socket_t sockfd,
Kristian Monsen5ab50182010-05-14 18:53:44 +0100647 char *buf,
648 size_t bytesfromsocket,
649 ssize_t *n)
650{
651 ssize_t nread = sread(sockfd, buf, bytesfromsocket);
652
653 if(-1 == nread) {
Haibo Huangb51266f2020-03-04 02:22:48 -0800654 const int err = SOCKERRNO;
655 const bool return_error =
Kristian Monsen5ab50182010-05-14 18:53:44 +0100656#ifdef USE_WINSOCK
Haibo Huangb51266f2020-03-04 02:22:48 -0800657 WSAEWOULDBLOCK == err
Kristian Monsen5ab50182010-05-14 18:53:44 +0100658#else
Haibo Huangb51266f2020-03-04 02:22:48 -0800659 EWOULDBLOCK == err || EAGAIN == err || EINTR == err
Kristian Monsen5ab50182010-05-14 18:53:44 +0100660#endif
Haibo Huangb51266f2020-03-04 02:22:48 -0800661 ;
662 *n = 0; /* no data returned */
Alex Deymod15eaac2016-06-28 14:49:26 -0700663 if(return_error)
Lucas Eckels9bd90e62012-08-06 15:07:02 -0700664 return CURLE_AGAIN;
Elliott Hughes82be86d2017-09-20 17:00:17 -0700665 return CURLE_RECV_ERROR;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100666 }
667
Kristian Monsen5ab50182010-05-14 18:53:44 +0100668 *n = nread;
669 return CURLE_OK;
670}
671
672/*
673 * Internal read-from-socket function. This is meant to deal with plain
674 * sockets, SSL sockets and kerberos sockets.
675 *
Lucas Eckels9bd90e62012-08-06 15:07:02 -0700676 * Returns a regular CURLcode value.
Kristian Monsen5ab50182010-05-14 18:53:44 +0100677 */
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700678CURLcode Curl_read(struct Curl_easy *data, /* transfer */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700679 curl_socket_t sockfd, /* read from this socket */
680 char *buf, /* store read data here */
681 size_t sizerequested, /* max amount to read */
682 ssize_t *n) /* amount bytes read */
Kristian Monsen5ab50182010-05-14 18:53:44 +0100683{
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700684 CURLcode result = CURLE_RECV_ERROR;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100685 ssize_t nread = 0;
686 size_t bytesfromsocket = 0;
687 char *buffertofill = NULL;
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700688 struct connectdata *conn = data->conn;
Alex Deymod15eaac2016-06-28 14:49:26 -0700689
Kristian Monsen5ab50182010-05-14 18:53:44 +0100690 /* Set 'num' to 0 or 1, depending on which socket that has been sent here.
691 If it is the second socket, we set num to 1. Otherwise to 0. This lets
692 us use the correct ssl handle. */
693 int num = (sockfd == conn->sock[SECONDARYSOCKET]);
694
Alex Deymo486467e2017-12-19 19:04:07 +0100695 *n = 0; /* reset amount to zero */
Kristian Monsen5ab50182010-05-14 18:53:44 +0100696
Haibo Huang34ab3462019-05-22 00:50:27 -0700697 bytesfromsocket = CURLMIN(sizerequested, (size_t)data->set.buffer_size);
698 buffertofill = buf;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100699
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700700 nread = conn->recv[num](data, num, buffertofill, bytesfromsocket, &result);
Lucas Eckels9bd90e62012-08-06 15:07:02 -0700701 if(nread < 0)
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700702 return result;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100703
Lucas Eckels9bd90e62012-08-06 15:07:02 -0700704 *n += nread;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100705
706 return CURLE_OK;
707}
708
709/* return 0 on success */
Elliott Hughes72d948d2018-08-03 14:37:21 -0700710int Curl_debug(struct Curl_easy *data, curl_infotype type,
711 char *ptr, size_t size)
Kristian Monsen5ab50182010-05-14 18:53:44 +0100712{
Elliott Hughes82be86d2017-09-20 17:00:17 -0700713 int rc = 0;
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700714 if(data->set.verbose) {
715 static const char s_infotype[CURLINFO_END][3] = {
716 "* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
Kristian Monsen5ab50182010-05-14 18:53:44 +0100717
718#ifdef CURL_DOES_CONVERSIONS
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700719 char *buf = NULL;
720 size_t conv_size = 0;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100721
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700722 switch(type) {
723 case CURLINFO_HEADER_OUT:
724 buf = Curl_memdup(ptr, size);
725 if(!buf)
726 return 1;
727 conv_size = size;
Elliott Hughes82be86d2017-09-20 17:00:17 -0700728
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700729 /* Special processing is needed for this block if it
730 * contains both headers and data (separated by CRLFCRLF).
731 * We want to convert just the headers, leaving the data as-is.
732 */
733 if(size > 4) {
734 size_t i;
735 for(i = 0; i < size-4; i++) {
736 if(memcmp(&buf[i], "\x0d\x0a\x0d\x0a", 4) == 0) {
737 /* convert everything through this CRLFCRLF but no further */
738 conv_size = i + 4;
739 break;
740 }
Kristian Monsen5ab50182010-05-14 18:53:44 +0100741 }
742 }
Kristian Monsen5ab50182010-05-14 18:53:44 +0100743
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700744 Curl_convert_from_network(data, buf, conv_size);
745 /* Curl_convert_from_network calls failf if unsuccessful */
746 /* we might as well continue even if it fails... */
747 ptr = buf; /* switch pointer to use my buffer instead */
748 break;
749 default:
750 /* leave everything else as-is */
751 break;
752 }
Kristian Monsen5ab50182010-05-14 18:53:44 +0100753#endif /* CURL_DOES_CONVERSIONS */
754
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700755 if(data->set.fdebug) {
756 Curl_set_in_callback(data, true);
757 rc = (*data->set.fdebug)(data, type, ptr, size, data->set.debugdata);
758 Curl_set_in_callback(data, false);
Elliott Hughes82be86d2017-09-20 17:00:17 -0700759 }
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700760 else {
761 switch(type) {
762 case CURLINFO_TEXT:
763 case CURLINFO_HEADER_OUT:
764 case CURLINFO_HEADER_IN:
765 fwrite(s_infotype[type], 2, 1, data->set.err);
766 fwrite(ptr, size, 1, data->set.err);
Elliott Hughes82be86d2017-09-20 17:00:17 -0700767#ifdef CURL_DOES_CONVERSIONS
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700768 if(size != conv_size) {
769 /* we had untranslated data so we need an explicit newline */
770 fwrite("\n", 1, 1, data->set.err);
771 }
Elliott Hughes82be86d2017-09-20 17:00:17 -0700772#endif
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700773 break;
774 default: /* nada */
775 break;
776 }
777 }
778#ifdef CURL_DOES_CONVERSIONS
779 free(buf);
780#endif
781 }
Elliott Hughes82be86d2017-09-20 17:00:17 -0700782 return rc;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100783}