• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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