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