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