xref: /curl/lib/transfer.c (revision fc3e1cbc)
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