1 /***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 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 https://curl.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 * SPDX-License-Identifier: curl
22 *
23 ***************************************************************************/
24
25 #include "curl_setup.h"
26 #include "strtoofft.h"
27
28 #ifdef HAVE_NETINET_IN_H
29 #include <netinet/in.h>
30 #endif
31 #ifdef HAVE_NETDB_H
32 #include <netdb.h>
33 #endif
34 #ifdef HAVE_ARPA_INET_H
35 #include <arpa/inet.h>
36 #endif
37 #ifdef HAVE_NET_IF_H
38 #include <net/if.h>
39 #endif
40 #ifdef HAVE_SYS_IOCTL_H
41 #include <sys/ioctl.h>
42 #endif
43 #include <signal.h>
44
45 #ifdef HAVE_SYS_PARAM_H
46 #include <sys/param.h>
47 #endif
48
49 #ifdef HAVE_SYS_SELECT_H
50 #include <sys/select.h>
51 #elif defined(HAVE_UNISTD_H)
52 #include <unistd.h>
53 #endif
54
55 #ifndef HAVE_SOCKET
56 #error "We cannot compile without socket() support!"
57 #endif
58
59 #include "urldata.h"
60 #include <curl/curl.h>
61 #include "netrc.h"
62
63 #include "content_encoding.h"
64 #include "hostip.h"
65 #include "cfilters.h"
66 #include "cw-out.h"
67 #include "transfer.h"
68 #include "sendf.h"
69 #include "speedcheck.h"
70 #include "progress.h"
71 #include "http.h"
72 #include "url.h"
73 #include "getinfo.h"
74 #include "vtls/vtls.h"
75 #include "vtls/vtls_scache.h"
76 #include "vquic/vquic.h"
77 #include "select.h"
78 #include "multiif.h"
79 #include "connect.h"
80 #include "http2.h"
81 #include "mime.h"
82 #include "strcase.h"
83 #include "hsts.h"
84 #include "setopt.h"
85 #include "headers.h"
86
87 /* The last 3 #include files should be in this order */
88 #include "curl_printf.h"
89 #include "curl_memory.h"
90 #include "memdebug.h"
91
92 #if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_SMTP) || \
93 !defined(CURL_DISABLE_IMAP)
94 /*
95 * checkheaders() checks the linked list of custom headers for a
96 * particular header (prefix). Provide the prefix without colon!
97 *
98 * Returns a pointer to the first matching header or NULL if none matched.
99 */
Curl_checkheaders(const struct Curl_easy * data,const char * thisheader,const size_t thislen)100 char *Curl_checkheaders(const struct Curl_easy *data,
101 const char *thisheader,
102 const size_t thislen)
103 {
104 struct curl_slist *head;
105 DEBUGASSERT(thislen);
106 DEBUGASSERT(thisheader[thislen-1] != ':');
107
108 for(head = data->set.headers; head; head = head->next) {
109 if(strncasecompare(head->data, thisheader, thislen) &&
110 Curl_headersep(head->data[thislen]) )
111 return head->data;
112 }
113
114 return NULL;
115 }
116 #endif
117
data_pending(struct Curl_easy * data)118 static int data_pending(struct Curl_easy *data)
119 {
120 struct connectdata *conn = data->conn;
121
122 if(conn->handler->protocol&PROTO_FAMILY_FTP)
123 return Curl_conn_data_pending(data, SECONDARYSOCKET);
124
125 /* in the case of libssh2, we can never be really sure that we have emptied
126 its internal buffers so we MUST always try until we get EAGAIN back */
127 return conn->handler->protocol&(CURLPROTO_SCP|CURLPROTO_SFTP) ||
128 Curl_conn_data_pending(data, FIRSTSOCKET);
129 }
130
131 /*
132 * Check to see if CURLOPT_TIMECONDITION was met by comparing the time of the
133 * remote document with the time provided by CURLOPT_TIMEVAL
134 */
Curl_meets_timecondition(struct Curl_easy * data,time_t timeofdoc)135 bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc)
136 {
137 if((timeofdoc == 0) || (data->set.timevalue == 0))
138 return TRUE;
139
140 switch(data->set.timecondition) {
141 case CURL_TIMECOND_IFMODSINCE:
142 default:
143 if(timeofdoc <= data->set.timevalue) {
144 infof(data,
145 "The requested document is not new enough");
146 data->info.timecond = TRUE;
147 return FALSE;
148 }
149 break;
150 case CURL_TIMECOND_IFUNMODSINCE:
151 if(timeofdoc >= data->set.timevalue) {
152 infof(data,
153 "The requested document is not old enough");
154 data->info.timecond = TRUE;
155 return FALSE;
156 }
157 break;
158 }
159
160 return TRUE;
161 }
162
xfer_recv_shutdown(struct Curl_easy * data,bool * done)163 static CURLcode xfer_recv_shutdown(struct Curl_easy *data, bool *done)
164 {
165 int sockindex;
166
167 if(!data || !data->conn)
168 return CURLE_FAILED_INIT;
169 if(data->conn->sockfd == CURL_SOCKET_BAD)
170 return CURLE_FAILED_INIT;
171 sockindex = (data->conn->sockfd == data->conn->sock[SECONDARYSOCKET]);
172 return Curl_conn_shutdown(data, sockindex, done);
173 }
174
xfer_recv_shutdown_started(struct Curl_easy * data)175 static bool xfer_recv_shutdown_started(struct Curl_easy *data)
176 {
177 int sockindex;
178
179 if(!data || !data->conn)
180 return CURLE_FAILED_INIT;
181 if(data->conn->sockfd == CURL_SOCKET_BAD)
182 return CURLE_FAILED_INIT;
183 sockindex = (data->conn->sockfd == data->conn->sock[SECONDARYSOCKET]);
184 return Curl_shutdown_started(data, sockindex);
185 }
186
Curl_xfer_send_shutdown(struct Curl_easy * data,bool * done)187 CURLcode Curl_xfer_send_shutdown(struct Curl_easy *data, bool *done)
188 {
189 int sockindex;
190
191 if(!data || !data->conn)
192 return CURLE_FAILED_INIT;
193 if(data->conn->writesockfd == CURL_SOCKET_BAD)
194 return CURLE_FAILED_INIT;
195 sockindex = (data->conn->writesockfd == data->conn->sock[SECONDARYSOCKET]);
196 return Curl_conn_shutdown(data, sockindex, done);
197 }
198
199 /**
200 * Receive raw response data for the transfer.
201 * @param data the transfer
202 * @param buf buffer to keep response data received
203 * @param blen length of `buf`
204 * @param eos_reliable if EOS detection in underlying connection is reliable
205 * @param err error code in case of -1 return
206 * @return number of bytes read or -1 for error
207 */
xfer_recv_resp(struct Curl_easy * data,char * buf,size_t blen,bool eos_reliable,CURLcode * err)208 static ssize_t xfer_recv_resp(struct Curl_easy *data,
209 char *buf, size_t blen,
210 bool eos_reliable,
211 CURLcode *err)
212 {
213 ssize_t nread;
214
215 DEBUGASSERT(blen > 0);
216 /* If we are reading BODY data and the connection does NOT handle EOF
217 * and we know the size of the BODY data, limit the read amount */
218 if(!eos_reliable && !data->req.header && data->req.size != -1) {
219 curl_off_t totalleft = data->req.size - data->req.bytecount;
220 if(totalleft <= 0)
221 blen = 0;
222 else if(totalleft < (curl_off_t)blen)
223 blen = (size_t)totalleft;
224 }
225 else if(xfer_recv_shutdown_started(data)) {
226 /* we already received everything. Do not try more. */
227 blen = 0;
228 }
229
230 if(!blen) {
231 /* want nothing more */
232 *err = CURLE_OK;
233 nread = 0;
234 }
235 else {
236 *err = Curl_xfer_recv(data, buf, blen, &nread);
237 }
238
239 if(*err)
240 return -1;
241 if(nread == 0) {
242 if(data->req.shutdown) {
243 bool done;
244 *err = xfer_recv_shutdown(data, &done);
245 if(*err)
246 return -1;
247 if(!done) {
248 *err = CURLE_AGAIN;
249 return -1;
250 }
251 }
252 DEBUGF(infof(data, "sendrecv_dl: we are done"));
253 }
254 DEBUGASSERT(nread >= 0);
255 return nread;
256 }
257
258 /*
259 * Go ahead and do a read if we have a readable socket or if
260 * the stream was rewound (in which case we have data in a
261 * buffer)
262 */
sendrecv_dl(struct Curl_easy * data,struct SingleRequest * k,int * didwhat)263 static CURLcode sendrecv_dl(struct Curl_easy *data,
264 struct SingleRequest *k,
265 int *didwhat)
266 {
267 struct connectdata *conn = data->conn;
268 CURLcode result = CURLE_OK;
269 char *buf, *xfer_buf;
270 size_t blen, xfer_blen;
271 int maxloops = 10;
272 curl_off_t total_received = 0;
273 bool is_multiplex = FALSE;
274
275 result = Curl_multi_xfer_buf_borrow(data, &xfer_buf, &xfer_blen);
276 if(result)
277 goto out;
278
279 /* This is where we loop until we have read everything there is to
280 read or we get a CURLE_AGAIN */
281 do {
282 bool is_eos = FALSE;
283 size_t bytestoread;
284 ssize_t nread;
285
286 if(!is_multiplex) {
287 /* Multiplexed connection have inherent handling of EOF and we do not
288 * have to carefully restrict the amount we try to read.
289 * Multiplexed changes only in one direction. */
290 is_multiplex = Curl_conn_is_multiplex(conn, FIRSTSOCKET);
291 }
292
293 buf = xfer_buf;
294 bytestoread = xfer_blen;
295
296 if(bytestoread && data->set.max_recv_speed > 0) {
297 /* In case of speed limit on receiving: if this loop already got
298 * data, break out. If not, limit the amount of bytes to receive.
299 * The overall, timed, speed limiting is done in multi.c */
300 if(total_received)
301 break;
302 if(data->set.max_recv_speed < (curl_off_t)bytestoread)
303 bytestoread = (size_t)data->set.max_recv_speed;
304 }
305
306 nread = xfer_recv_resp(data, buf, bytestoread, is_multiplex, &result);
307 if(nread < 0) {
308 if(CURLE_AGAIN != result)
309 goto out; /* real error */
310 result = CURLE_OK;
311 if(data->req.download_done && data->req.no_body &&
312 !data->req.resp_trailer) {
313 DEBUGF(infof(data, "EAGAIN, download done, no trailer announced, "
314 "not waiting for EOS"));
315 nread = 0;
316 /* continue as if we read the EOS */
317 }
318 else
319 break; /* get out of loop */
320 }
321
322 /* We only get a 0-length read on EndOfStream */
323 blen = (size_t)nread;
324 is_eos = (blen == 0);
325 *didwhat |= KEEP_RECV;
326
327 if(!blen) {
328 /* if we receive 0 or less here, either the data transfer is done or the
329 server closed the connection and we bail out from this! */
330 if(is_multiplex)
331 DEBUGF(infof(data, "nread == 0, stream closed, bailing"));
332 else
333 DEBUGF(infof(data, "nread <= 0, server closed connection, bailing"));
334 result = Curl_req_stop_send_recv(data);
335 if(result)
336 goto out;
337 if(k->eos_written) /* already did write this to client, leave */
338 break;
339 }
340 total_received += blen;
341
342 result = Curl_xfer_write_resp(data, buf, blen, is_eos);
343 if(result || data->req.done)
344 goto out;
345
346 /* if we are done, we stop receiving. On multiplexed connections,
347 * we should read the EOS. Which may arrive as meta data after
348 * the bytes. Not taking it in might lead to RST of streams. */
349 if((!is_multiplex && data->req.download_done) || is_eos) {
350 data->req.keepon &= ~KEEP_RECV;
351 }
352 /* if we are PAUSEd or stopped receiving, leave the loop */
353 if((k->keepon & KEEP_RECV_PAUSE) || !(k->keepon & KEEP_RECV))
354 break;
355
356 } while(maxloops--);
357
358 if((maxloops <= 0) || data_pending(data)) {
359 /* did not read until EAGAIN or there is still pending data, mark as
360 read-again-please */
361 data->state.select_bits = CURL_CSELECT_IN;
362 if((k->keepon & KEEP_SENDBITS) == KEEP_SEND)
363 data->state.select_bits |= CURL_CSELECT_OUT;
364 }
365
366 if(((k->keepon & (KEEP_RECV|KEEP_SEND)) == KEEP_SEND) &&
367 (conn->bits.close || is_multiplex)) {
368 /* When we have read the entire thing and the close bit is set, the server
369 may now close the connection. If there is now any kind of sending going
370 on from our side, we need to stop that immediately. */
371 infof(data, "we are done reading and this is set to close, stop send");
372 Curl_req_abort_sending(data);
373 }
374
375 out:
376 Curl_multi_xfer_buf_release(data, xfer_buf);
377 if(result)
378 DEBUGF(infof(data, "sendrecv_dl() -> %d", result));
379 return result;
380 }
381
382 /*
383 * Send data to upload to the server, when the socket is writable.
384 */
sendrecv_ul(struct Curl_easy * data,int * didwhat)385 static CURLcode sendrecv_ul(struct Curl_easy *data, int *didwhat)
386 {
387 /* We should not get here when the sending is already done. It
388 * probably means that someone set `data-req.keepon |= KEEP_SEND`
389 * when it should not. */
390 DEBUGASSERT(!Curl_req_done_sending(data));
391
392 if(!Curl_req_done_sending(data)) {
393 *didwhat |= KEEP_SEND;
394 return Curl_req_send_more(data);
395 }
396 return CURLE_OK;
397 }
398
select_bits_paused(struct Curl_easy * data,int select_bits)399 static int select_bits_paused(struct Curl_easy *data, int select_bits)
400 {
401 /* See issue #11982: we really need to be careful not to progress
402 * a transfer direction when that direction is paused. Not all parts
403 * of our state machine are handling PAUSED transfers correctly. So, we
404 * do not want to go there.
405 * NOTE: we are only interested in PAUSE, not HOLD. */
406
407 /* if there is data in a direction not paused, return false */
408 if(((select_bits & CURL_CSELECT_IN) &&
409 !(data->req.keepon & KEEP_RECV_PAUSE)) ||
410 ((select_bits & CURL_CSELECT_OUT) &&
411 !(data->req.keepon & KEEP_SEND_PAUSE)))
412 return FALSE;
413
414 return (data->req.keepon & (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE));
415 }
416
417 /*
418 * Curl_sendrecv() is the low-level function to be called when data is to
419 * be read and written to/from the connection.
420 */
Curl_sendrecv(struct Curl_easy * data,struct curltime * nowp)421 CURLcode Curl_sendrecv(struct Curl_easy *data, struct curltime *nowp)
422 {
423 struct SingleRequest *k = &data->req;
424 CURLcode result = CURLE_OK;
425 int didwhat = 0;
426
427 DEBUGASSERT(nowp);
428 if(data->state.select_bits) {
429 if(select_bits_paused(data, data->state.select_bits)) {
430 /* leave the bits unchanged, so they'll tell us what to do when
431 * this transfer gets unpaused. */
432 result = CURLE_OK;
433 goto out;
434 }
435 data->state.select_bits = 0;
436 }
437
438 /* We go ahead and do a read if we have a readable socket or if the stream
439 was rewound (in which case we have data in a buffer) */
440 if(k->keepon & KEEP_RECV) {
441 result = sendrecv_dl(data, k, &didwhat);
442 if(result || data->req.done)
443 goto out;
444 }
445
446 /* If we still have writing to do, we check if we have a writable socket. */
447 if(Curl_req_want_send(data) || (data->req.keepon & KEEP_SEND_TIMED)) {
448 result = sendrecv_ul(data, &didwhat);
449 if(result)
450 goto out;
451 }
452
453 if(!didwhat) {
454 /* Transfer wanted to send/recv, but nothing was possible. */
455 result = Curl_conn_ev_data_idle(data);
456 if(result)
457 goto out;
458 }
459
460 if(Curl_pgrsUpdate(data))
461 result = CURLE_ABORTED_BY_CALLBACK;
462 else
463 result = Curl_speedcheck(data, *nowp);
464 if(result)
465 goto out;
466
467 if(k->keepon) {
468 if(0 > Curl_timeleft(data, nowp, FALSE)) {
469 if(k->size != -1) {
470 failf(data, "Operation timed out after %" FMT_TIMEDIFF_T
471 " milliseconds with %" FMT_OFF_T " out of %"
472 FMT_OFF_T " bytes received",
473 Curl_timediff(*nowp, data->progress.t_startsingle),
474 k->bytecount, k->size);
475 }
476 else {
477 failf(data, "Operation timed out after %" FMT_TIMEDIFF_T
478 " milliseconds with %" FMT_OFF_T " bytes received",
479 Curl_timediff(*nowp, data->progress.t_startsingle),
480 k->bytecount);
481 }
482 result = CURLE_OPERATION_TIMEDOUT;
483 goto out;
484 }
485 }
486 else {
487 /*
488 * The transfer has been performed. Just make some general checks before
489 * returning.
490 */
491 if(!(data->req.no_body) && (k->size != -1) &&
492 (k->bytecount != k->size) && !k->newurl) {
493 failf(data, "transfer closed with %" FMT_OFF_T
494 " bytes remaining to read", k->size - k->bytecount);
495 result = CURLE_PARTIAL_FILE;
496 goto out;
497 }
498 if(Curl_pgrsUpdate(data)) {
499 result = CURLE_ABORTED_BY_CALLBACK;
500 goto out;
501 }
502 }
503
504 /* If there is nothing more to send/recv, the request is done */
505 if(0 == (k->keepon&(KEEP_RECVBITS|KEEP_SENDBITS)))
506 data->req.done = TRUE;
507
508 out:
509 if(result)
510 DEBUGF(infof(data, "Curl_sendrecv() -> %d", result));
511 return result;
512 }
513
514 /* Curl_init_CONNECT() gets called each time the handle switches to CONNECT
515 which means this gets called once for each subsequent redirect etc */
Curl_init_CONNECT(struct Curl_easy * data)516 void Curl_init_CONNECT(struct Curl_easy *data)
517 {
518 data->state.fread_func = data->set.fread_func_set;
519 data->state.in = data->set.in_set;
520 data->state.upload = (data->state.httpreq == HTTPREQ_PUT);
521 }
522
523 /*
524 * Curl_pretransfer() is called immediately before a transfer starts, and only
525 * once for one transfer no matter if it has redirects or do multi-pass
526 * authentication etc.
527 */
Curl_pretransfer(struct Curl_easy * data)528 CURLcode Curl_pretransfer(struct Curl_easy *data)
529 {
530 CURLcode result = CURLE_OK;
531
532 if(!data->state.url && !data->set.uh) {
533 /* we cannot do anything without URL */
534 failf(data, "No URL set");
535 return CURLE_URL_MALFORMAT;
536 }
537
538 /* since the URL may have been redirected in a previous use of this handle */
539 if(data->state.url_alloc) {
540 /* the already set URL is allocated, free it first! */
541 Curl_safefree(data->state.url);
542 data->state.url_alloc = FALSE;
543 }
544
545 if(!data->state.url && data->set.uh) {
546 CURLUcode uc;
547 free(data->set.str[STRING_SET_URL]);
548 uc = curl_url_get(data->set.uh,
549 CURLUPART_URL, &data->set.str[STRING_SET_URL], 0);
550 if(uc) {
551 failf(data, "No URL set");
552 return CURLE_URL_MALFORMAT;
553 }
554 }
555
556 if(data->set.postfields && data->set.set_resume_from) {
557 /* we cannot */
558 failf(data, "cannot mix POSTFIELDS with RESUME_FROM");
559 return CURLE_BAD_FUNCTION_ARGUMENT;
560 }
561
562 data->state.prefer_ascii = data->set.prefer_ascii;
563 #ifdef CURL_LIST_ONLY_PROTOCOL
564 data->state.list_only = data->set.list_only;
565 #endif
566 data->state.httpreq = data->set.method;
567 data->state.url = data->set.str[STRING_SET_URL];
568
569 #ifdef USE_SSL
570 if(!data->state.ssl_scache) {
571 result = Curl_ssl_scache_create(data->set.general_ssl.max_ssl_sessions,
572 2, &data->state.ssl_scache);
573 if(result)
574 return result;
575 }
576 #endif
577
578 data->state.requests = 0;
579 data->state.followlocation = 0; /* reset the location-follow counter */
580 data->state.this_is_a_follow = FALSE; /* reset this */
581 data->state.errorbuf = FALSE; /* no error has occurred */
582 data->state.httpwant = data->set.httpwant;
583 data->state.httpversion = 0;
584 data->state.authproblem = FALSE;
585 data->state.authhost.want = data->set.httpauth;
586 data->state.authproxy.want = data->set.proxyauth;
587 Curl_safefree(data->info.wouldredirect);
588 Curl_data_priority_clear_state(data);
589
590 if(data->state.httpreq == HTTPREQ_PUT)
591 data->state.infilesize = data->set.filesize;
592 else if((data->state.httpreq != HTTPREQ_GET) &&
593 (data->state.httpreq != HTTPREQ_HEAD)) {
594 data->state.infilesize = data->set.postfieldsize;
595 if(data->set.postfields && (data->state.infilesize == -1))
596 data->state.infilesize = (curl_off_t)strlen(data->set.postfields);
597 }
598 else
599 data->state.infilesize = 0;
600
601 /* If there is a list of cookie files to read, do it now! */
602 Curl_cookie_loadfiles(data);
603
604 /* If there is a list of host pairs to deal with */
605 if(data->state.resolve)
606 result = Curl_loadhostpairs(data);
607
608 /* If there is a list of hsts files to read */
609 Curl_hsts_loadfiles(data);
610
611 if(!result) {
612 /* Allow data->set.use_port to set which port to use. This needs to be
613 * disabled for example when we follow Location: headers to URLs using
614 * different ports! */
615 data->state.allow_port = TRUE;
616
617 #if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(HAVE_MSG_NOSIGNAL)
618 /*************************************************************
619 * Tell signal handler to ignore SIGPIPE
620 *************************************************************/
621 if(!data->set.no_signal)
622 data->state.prev_signal = signal(SIGPIPE, SIG_IGN);
623 #endif
624
625 Curl_initinfo(data); /* reset session-specific information "variables" */
626 Curl_pgrsResetTransferSizes(data);
627 Curl_pgrsStartNow(data);
628
629 /* In case the handle is reused and an authentication method was picked
630 in the session we need to make sure we only use the one(s) we now
631 consider to be fine */
632 data->state.authhost.picked &= data->state.authhost.want;
633 data->state.authproxy.picked &= data->state.authproxy.want;
634
635 #ifndef CURL_DISABLE_FTP
636 data->state.wildcardmatch = data->set.wildcard_enabled;
637 if(data->state.wildcardmatch) {
638 struct WildcardData *wc;
639 if(!data->wildcard) {
640 data->wildcard = calloc(1, sizeof(struct WildcardData));
641 if(!data->wildcard)
642 return CURLE_OUT_OF_MEMORY;
643 }
644 wc = data->wildcard;
645 if(wc->state < CURLWC_INIT) {
646 if(wc->ftpwc)
647 wc->dtor(wc->ftpwc);
648 Curl_safefree(wc->pattern);
649 Curl_safefree(wc->path);
650 result = Curl_wildcard_init(wc); /* init wildcard structures */
651 if(result)
652 return CURLE_OUT_OF_MEMORY;
653 }
654 }
655 #endif
656 result = Curl_hsts_loadcb(data, data->hsts);
657 }
658
659 /*
660 * Set user-agent. Used for HTTP, but since we can attempt to tunnel
661 * basically anything through an HTTP proxy we cannot limit this based on
662 * protocol.
663 */
664 if(data->set.str[STRING_USERAGENT]) {
665 Curl_safefree(data->state.aptr.uagent);
666 data->state.aptr.uagent =
667 aprintf("User-Agent: %s\r\n", data->set.str[STRING_USERAGENT]);
668 if(!data->state.aptr.uagent)
669 return CURLE_OUT_OF_MEMORY;
670 }
671
672 if(data->set.str[STRING_USERNAME] ||
673 data->set.str[STRING_PASSWORD])
674 data->state.creds_from = CREDS_OPTION;
675 if(!result)
676 result = Curl_setstropt(&data->state.aptr.user,
677 data->set.str[STRING_USERNAME]);
678 if(!result)
679 result = Curl_setstropt(&data->state.aptr.passwd,
680 data->set.str[STRING_PASSWORD]);
681 #ifndef CURL_DISABLE_PROXY
682 if(!result)
683 result = Curl_setstropt(&data->state.aptr.proxyuser,
684 data->set.str[STRING_PROXYUSERNAME]);
685 if(!result)
686 result = Curl_setstropt(&data->state.aptr.proxypasswd,
687 data->set.str[STRING_PROXYPASSWORD]);
688 #endif
689
690 data->req.headerbytecount = 0;
691 Curl_headers_cleanup(data);
692 return result;
693 }
694
695 /* Returns CURLE_OK *and* sets '*url' if a request retry is wanted.
696
697 NOTE: that the *url is malloc()ed. */
Curl_retry_request(struct Curl_easy * data,char ** url)698 CURLcode Curl_retry_request(struct Curl_easy *data, char **url)
699 {
700 struct connectdata *conn = data->conn;
701 bool retry = FALSE;
702 *url = NULL;
703
704 /* if we are talking upload, we cannot do the checks below, unless the
705 protocol is HTTP as when uploading over HTTP we will still get a
706 response */
707 if(data->state.upload &&
708 !(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)))
709 return CURLE_OK;
710
711 if((data->req.bytecount + data->req.headerbytecount == 0) &&
712 conn->bits.reuse &&
713 (!data->req.no_body || (conn->handler->protocol & PROTO_FAMILY_HTTP))
714 #ifndef CURL_DISABLE_RTSP
715 && (data->set.rtspreq != RTSPREQ_RECEIVE)
716 #endif
717 )
718 /* We got no data, we attempted to reuse a connection. For HTTP this
719 can be a retry so we try again regardless if we expected a body.
720 For other protocols we only try again only if we expected a body.
721
722 This might happen if the connection was left alive when we were
723 done using it before, but that was closed when we wanted to read from
724 it again. Bad luck. Retry the same request on a fresh connect! */
725 retry = TRUE;
726 else if(data->state.refused_stream &&
727 (data->req.bytecount + data->req.headerbytecount == 0) ) {
728 /* This was sent on a refused stream, safe to rerun. A refused stream
729 error can typically only happen on HTTP/2 level if the stream is safe
730 to issue again, but the nghttp2 API can deliver the message to other
731 streams as well, which is why this adds the check the data counters
732 too. */
733 infof(data, "REFUSED_STREAM, retrying a fresh connect");
734 data->state.refused_stream = FALSE; /* clear again */
735 retry = TRUE;
736 }
737 if(retry) {
738 #define CONN_MAX_RETRIES 5
739 if(data->state.retrycount++ >= CONN_MAX_RETRIES) {
740 failf(data, "Connection died, tried %d times before giving up",
741 CONN_MAX_RETRIES);
742 data->state.retrycount = 0;
743 return CURLE_SEND_ERROR;
744 }
745 infof(data, "Connection died, retrying a fresh connect (retry count: %d)",
746 data->state.retrycount);
747 *url = strdup(data->state.url);
748 if(!*url)
749 return CURLE_OUT_OF_MEMORY;
750
751 connclose(conn, "retry"); /* close this connection */
752 conn->bits.retry = TRUE; /* mark this as a connection we are about
753 to retry. Marking it this way should
754 prevent i.e HTTP transfers to return
755 error just because nothing has been
756 transferred! */
757 Curl_creader_set_rewind(data, TRUE);
758 }
759 return CURLE_OK;
760 }
761
762 /*
763 * xfer_setup() is called to setup basic properties for the transfer.
764 */
xfer_setup(struct Curl_easy * data,int sockindex,curl_off_t size,bool getheader,int writesockindex,bool shutdown,bool shutdown_err_ignore)765 static void xfer_setup(
766 struct Curl_easy *data, /* transfer */
767 int sockindex, /* socket index to read from or -1 */
768 curl_off_t size, /* -1 if unknown at this point */
769 bool getheader, /* TRUE if header parsing is wanted */
770 int writesockindex, /* socket index to write to, it may be the same we
771 read from. -1 disables */
772 bool shutdown, /* shutdown connection at transfer end. Only
773 * supported when sending OR receiving. */
774 bool shutdown_err_ignore /* errors during shutdown do not fail the
775 * transfer */
776 )
777 {
778 struct SingleRequest *k = &data->req;
779 struct connectdata *conn = data->conn;
780 bool want_send = Curl_req_want_send(data);
781
782 DEBUGASSERT(conn != NULL);
783 DEBUGASSERT((sockindex <= 1) && (sockindex >= -1));
784 DEBUGASSERT((writesockindex <= 1) && (writesockindex >= -1));
785 DEBUGASSERT(!shutdown || (sockindex == -1) || (writesockindex == -1));
786
787 if(conn->bits.multiplex || conn->httpversion >= 20 || want_send) {
788 /* when multiplexing, the read/write sockets need to be the same! */
789 conn->sockfd = sockindex == -1 ?
790 ((writesockindex == -1 ? CURL_SOCKET_BAD : conn->sock[writesockindex])) :
791 conn->sock[sockindex];
792 conn->writesockfd = conn->sockfd;
793 if(want_send)
794 /* special and HTTP-specific */
795 writesockindex = FIRSTSOCKET;
796 }
797 else {
798 conn->sockfd = sockindex == -1 ?
799 CURL_SOCKET_BAD : conn->sock[sockindex];
800 conn->writesockfd = writesockindex == -1 ?
801 CURL_SOCKET_BAD : conn->sock[writesockindex];
802 }
803
804 k->getheader = getheader;
805 k->size = size;
806 k->shutdown = shutdown;
807 k->shutdown_err_ignore = shutdown_err_ignore;
808
809 /* The code sequence below is placed in this function just because all
810 necessary input is not always known in do_complete() as this function may
811 be called after that */
812
813 if(!k->getheader) {
814 k->header = FALSE;
815 if(size > 0)
816 Curl_pgrsSetDownloadSize(data, size);
817 }
818 /* we want header and/or body, if neither then do not do this! */
819 if(k->getheader || !data->req.no_body) {
820
821 if(sockindex != -1)
822 k->keepon |= KEEP_RECV;
823
824 if(writesockindex != -1)
825 k->keepon |= KEEP_SEND;
826 } /* if(k->getheader || !data->req.no_body) */
827
828 }
829
Curl_xfer_setup_nop(struct Curl_easy * data)830 void Curl_xfer_setup_nop(struct Curl_easy *data)
831 {
832 xfer_setup(data, -1, -1, FALSE, -1, FALSE, FALSE);
833 }
834
Curl_xfer_setup1(struct Curl_easy * data,int send_recv,curl_off_t recv_size,bool getheader)835 void Curl_xfer_setup1(struct Curl_easy *data,
836 int send_recv,
837 curl_off_t recv_size,
838 bool getheader)
839 {
840 int recv_index = (send_recv & CURL_XFER_RECV) ? FIRSTSOCKET : -1;
841 int send_index = (send_recv & CURL_XFER_SEND) ? FIRSTSOCKET : -1;
842 DEBUGASSERT((recv_index >= 0) || (recv_size == -1));
843 xfer_setup(data, recv_index, recv_size, getheader, send_index, FALSE, FALSE);
844 }
845
Curl_xfer_setup2(struct Curl_easy * data,int send_recv,curl_off_t recv_size,bool shutdown,bool shutdown_err_ignore)846 void Curl_xfer_setup2(struct Curl_easy *data,
847 int send_recv,
848 curl_off_t recv_size,
849 bool shutdown,
850 bool shutdown_err_ignore)
851 {
852 int recv_index = (send_recv & CURL_XFER_RECV) ? SECONDARYSOCKET : -1;
853 int send_index = (send_recv & CURL_XFER_SEND) ? SECONDARYSOCKET : -1;
854 DEBUGASSERT((recv_index >= 0) || (recv_size == -1));
855 xfer_setup(data, recv_index, recv_size, FALSE, send_index,
856 shutdown, shutdown_err_ignore);
857 }
858
Curl_xfer_write_resp(struct Curl_easy * data,const char * buf,size_t blen,bool is_eos)859 CURLcode Curl_xfer_write_resp(struct Curl_easy *data,
860 const char *buf, size_t blen,
861 bool is_eos)
862 {
863 CURLcode result = CURLE_OK;
864
865 if(data->conn->handler->write_resp) {
866 /* protocol handlers offering this function take full responsibility
867 * for writing all received download data to the client. */
868 result = data->conn->handler->write_resp(data, buf, blen, is_eos);
869 }
870 else {
871 /* No special handling by protocol handler, write all received data
872 * as BODY to the client. */
873 if(blen || is_eos) {
874 int cwtype = CLIENTWRITE_BODY;
875 if(is_eos)
876 cwtype |= CLIENTWRITE_EOS;
877 result = Curl_client_write(data, cwtype, buf, blen);
878 }
879 }
880
881 if(!result && is_eos) {
882 /* If we wrote the EOS, we are definitely done */
883 data->req.eos_written = TRUE;
884 data->req.download_done = TRUE;
885 }
886 CURL_TRC_WRITE(data, "xfer_write_resp(len=%zu, eos=%d) -> %d",
887 blen, is_eos, result);
888 return result;
889 }
890
Curl_xfer_write_resp_hd(struct Curl_easy * data,const char * hd0,size_t hdlen,bool is_eos)891 CURLcode Curl_xfer_write_resp_hd(struct Curl_easy *data,
892 const char *hd0, size_t hdlen, bool is_eos)
893 {
894 if(data->conn->handler->write_resp_hd) {
895 /* protocol handlers offering this function take full responsibility
896 * for writing all received download data to the client. */
897 return data->conn->handler->write_resp_hd(data, hd0, hdlen, is_eos);
898 }
899 /* No special handling by protocol handler, write as response bytes */
900 return Curl_xfer_write_resp(data, hd0, hdlen, is_eos);
901 }
902
Curl_xfer_write_done(struct Curl_easy * data,bool premature)903 CURLcode Curl_xfer_write_done(struct Curl_easy *data, bool premature)
904 {
905 (void)premature;
906 return Curl_cw_out_done(data);
907 }
908
Curl_xfer_needs_flush(struct Curl_easy * data)909 bool Curl_xfer_needs_flush(struct Curl_easy *data)
910 {
911 int sockindex;
912 sockindex = ((data->conn->writesockfd != CURL_SOCKET_BAD) &&
913 (data->conn->writesockfd == data->conn->sock[SECONDARYSOCKET]));
914 return Curl_conn_needs_flush(data, sockindex);
915 }
916
Curl_xfer_flush(struct Curl_easy * data)917 CURLcode Curl_xfer_flush(struct Curl_easy *data)
918 {
919 int sockindex;
920 sockindex = ((data->conn->writesockfd != CURL_SOCKET_BAD) &&
921 (data->conn->writesockfd == data->conn->sock[SECONDARYSOCKET]));
922 return Curl_conn_flush(data, sockindex);
923 }
924
Curl_xfer_send(struct Curl_easy * data,const void * buf,size_t blen,bool eos,size_t * pnwritten)925 CURLcode Curl_xfer_send(struct Curl_easy *data,
926 const void *buf, size_t blen, bool eos,
927 size_t *pnwritten)
928 {
929 CURLcode result;
930 int sockindex;
931
932 DEBUGASSERT(data);
933 DEBUGASSERT(data->conn);
934
935 sockindex = ((data->conn->writesockfd != CURL_SOCKET_BAD) &&
936 (data->conn->writesockfd == data->conn->sock[SECONDARYSOCKET]));
937 result = Curl_conn_send(data, sockindex, buf, blen, eos, pnwritten);
938 if(result == CURLE_AGAIN) {
939 result = CURLE_OK;
940 *pnwritten = 0;
941 }
942 else if(!result && *pnwritten)
943 data->info.request_size += *pnwritten;
944
945 DEBUGF(infof(data, "Curl_xfer_send(len=%zu, eos=%d) -> %d, %zu",
946 blen, eos, result, *pnwritten));
947 return result;
948 }
949
Curl_xfer_recv(struct Curl_easy * data,char * buf,size_t blen,ssize_t * pnrcvd)950 CURLcode Curl_xfer_recv(struct Curl_easy *data,
951 char *buf, size_t blen,
952 ssize_t *pnrcvd)
953 {
954 int sockindex;
955
956 DEBUGASSERT(data);
957 DEBUGASSERT(data->conn);
958 DEBUGASSERT(data->set.buffer_size > 0);
959
960 sockindex = ((data->conn->sockfd != CURL_SOCKET_BAD) &&
961 (data->conn->sockfd == data->conn->sock[SECONDARYSOCKET]));
962 if((size_t)data->set.buffer_size < blen)
963 blen = (size_t)data->set.buffer_size;
964 return Curl_conn_recv(data, sockindex, buf, blen, pnrcvd);
965 }
966
Curl_xfer_send_close(struct Curl_easy * data)967 CURLcode Curl_xfer_send_close(struct Curl_easy *data)
968 {
969 Curl_conn_ev_data_done_send(data);
970 return CURLE_OK;
971 }
972
Curl_xfer_is_blocked(struct Curl_easy * data)973 bool Curl_xfer_is_blocked(struct Curl_easy *data)
974 {
975 bool want_send = ((data)->req.keepon & KEEP_SEND);
976 bool want_recv = ((data)->req.keepon & KEEP_RECV);
977 if(!want_send)
978 return (want_recv && Curl_cwriter_is_paused(data));
979 else if(!want_recv)
980 return (want_send && Curl_creader_is_paused(data));
981 else
982 return Curl_creader_is_paused(data) && Curl_cwriter_is_paused(data);
983 }
984