1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2015, 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 http://curl.haxx.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  ***************************************************************************/
22 
23 #include "curl_setup.h"
24 
25 #include "strtoofft.h"
26 #include "strequal.h"
27 #include "rawstr.h"
28 
29 #ifdef HAVE_NETINET_IN_H
30 #include <netinet/in.h>
31 #endif
32 #ifdef HAVE_NETDB_H
33 #include <netdb.h>
34 #endif
35 #ifdef HAVE_ARPA_INET_H
36 #include <arpa/inet.h>
37 #endif
38 #ifdef HAVE_NET_IF_H
39 #include <net/if.h>
40 #endif
41 #ifdef HAVE_SYS_IOCTL_H
42 #include <sys/ioctl.h>
43 #endif
44 #ifdef HAVE_SIGNAL_H
45 #include <signal.h>
46 #endif
47 
48 #ifdef HAVE_SYS_PARAM_H
49 #include <sys/param.h>
50 #endif
51 
52 #ifdef HAVE_SYS_SELECT_H
53 #include <sys/select.h>
54 #endif
55 
56 #ifndef HAVE_SOCKET
57 #error "We can't compile without socket() support!"
58 #endif
59 
60 #include "urldata.h"
61 #include <curl/curl.h>
62 #include "netrc.h"
63 
64 #include "content_encoding.h"
65 #include "hostip.h"
66 #include "transfer.h"
67 #include "sendf.h"
68 #include "speedcheck.h"
69 #include "progress.h"
70 #include "http.h"
71 #include "url.h"
72 #include "getinfo.h"
73 #include "vtls/vtls.h"
74 #include "http_digest.h"
75 #include "curl_ntlm.h"
76 #include "http_negotiate.h"
77 #include "share.h"
78 #include "select.h"
79 #include "multiif.h"
80 #include "connect.h"
81 #include "non-ascii.h"
82 #include "curl_printf.h"
83 
84 /* The last #include files should be: */
85 #include "curl_memory.h"
86 #include "memdebug.h"
87 
88 /*
89  * This function will call the read callback to fill our buffer with data
90  * to upload.
91  */
Curl_fillreadbuffer(struct connectdata * conn,int bytes,int * nreadp)92 CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
93 {
94   struct SessionHandle *data = conn->data;
95   size_t buffersize = (size_t)bytes;
96   int nread;
97 #ifdef CURL_DOES_CONVERSIONS
98   bool sending_http_headers = FALSE;
99 
100   if(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)) {
101     const struct HTTP *http = data->req.protop;
102 
103     if(http->sending == HTTPSEND_REQUEST)
104       /* We're sending the HTTP request headers, not the data.
105          Remember that so we don't re-translate them into garbage. */
106       sending_http_headers = TRUE;
107   }
108 #endif
109 
110   if(data->req.upload_chunky) {
111     /* if chunked Transfer-Encoding */
112     buffersize -= (8 + 2 + 2);   /* 32bit hex + CRLF + CRLF */
113     data->req.upload_fromhere += (8 + 2); /* 32bit hex + CRLF */
114   }
115 
116   /* this function returns a size_t, so we typecast to int to prevent warnings
117      with picky compilers */
118   nread = (int)data->set.fread_func(data->req.upload_fromhere, 1,
119                                     buffersize, data->set.in);
120 
121   if(nread == CURL_READFUNC_ABORT) {
122     failf(data, "operation aborted by callback");
123     *nreadp = 0;
124     return CURLE_ABORTED_BY_CALLBACK;
125   }
126   else if(nread == CURL_READFUNC_PAUSE) {
127 
128     if(conn->handler->flags & PROTOPT_NONETWORK) {
129       /* protocols that work without network cannot be paused. This is
130          actually only FILE:// just now, and it can't pause since the transfer
131          isn't done using the "normal" procedure. */
132       failf(data, "Read callback asked for PAUSE when not supported!");
133       return CURLE_READ_ERROR;
134     }
135     else {
136       struct SingleRequest *k = &data->req;
137       /* CURL_READFUNC_PAUSE pauses read callbacks that feed socket writes */
138       k->keepon |= KEEP_SEND_PAUSE; /* mark socket send as paused */
139       if(data->req.upload_chunky) {
140         /* Back out the preallocation done above */
141         data->req.upload_fromhere -= (8 + 2);
142       }
143       *nreadp = 0;
144     }
145     return CURLE_OK; /* nothing was read */
146   }
147   else if((size_t)nread > buffersize) {
148     /* the read function returned a too large value */
149     *nreadp = 0;
150     failf(data, "read function returned funny value");
151     return CURLE_READ_ERROR;
152   }
153 
154   if(!data->req.forbidchunk && data->req.upload_chunky) {
155     /* if chunked Transfer-Encoding
156      *    build chunk:
157      *
158      *        <HEX SIZE> CRLF
159      *        <DATA> CRLF
160      */
161     /* On non-ASCII platforms the <DATA> may or may not be
162        translated based on set.prefer_ascii while the protocol
163        portion must always be translated to the network encoding.
164        To further complicate matters, line end conversion might be
165        done later on, so we need to prevent CRLFs from becoming
166        CRCRLFs if that's the case.  To do this we use bare LFs
167        here, knowing they'll become CRLFs later on.
168      */
169 
170     char hexbuffer[11];
171     const char *endofline_native;
172     const char *endofline_network;
173     int hexlen;
174 
175     if(
176 #ifdef CURL_DO_LINEEND_CONV
177        (data->set.prefer_ascii) ||
178 #endif
179        (data->set.crlf)) {
180       /* \n will become \r\n later on */
181       endofline_native  = "\n";
182       endofline_network = "\x0a";
183     }
184     else {
185       endofline_native  = "\r\n";
186       endofline_network = "\x0d\x0a";
187     }
188     hexlen = snprintf(hexbuffer, sizeof(hexbuffer),
189                       "%x%s", nread, endofline_native);
190 
191     /* move buffer pointer */
192     data->req.upload_fromhere -= hexlen;
193     nread += hexlen;
194 
195     /* copy the prefix to the buffer, leaving out the NUL */
196     memcpy(data->req.upload_fromhere, hexbuffer, hexlen);
197 
198     /* always append ASCII CRLF to the data */
199     memcpy(data->req.upload_fromhere + nread,
200            endofline_network,
201            strlen(endofline_network));
202 
203 #ifdef CURL_DOES_CONVERSIONS
204     CURLcode result;
205     int length;
206     if(data->set.prefer_ascii) {
207       /* translate the protocol and data */
208       length = nread;
209     }
210     else {
211       /* just translate the protocol portion */
212       length = strlen(hexbuffer);
213     }
214     result = Curl_convert_to_network(data, data->req.upload_fromhere, length);
215     /* Curl_convert_to_network calls failf if unsuccessful */
216     if(result)
217       return result;
218 #endif /* CURL_DOES_CONVERSIONS */
219 
220     if((nread - hexlen) == 0)
221       /* mark this as done once this chunk is transferred */
222       data->req.upload_done = TRUE;
223 
224     nread+=(int)strlen(endofline_native); /* for the added end of line */
225   }
226 #ifdef CURL_DOES_CONVERSIONS
227   else if((data->set.prefer_ascii) && (!sending_http_headers)) {
228     CURLcode result;
229     result = Curl_convert_to_network(data, data->req.upload_fromhere, nread);
230     /* Curl_convert_to_network calls failf if unsuccessful */
231     if(result)
232       return result;
233   }
234 #endif /* CURL_DOES_CONVERSIONS */
235 
236   *nreadp = nread;
237 
238   return CURLE_OK;
239 }
240 
241 
242 /*
243  * Curl_readrewind() rewinds the read stream. This is typically used for HTTP
244  * POST/PUT with multi-pass authentication when a sending was denied and a
245  * resend is necessary.
246  */
Curl_readrewind(struct connectdata * conn)247 CURLcode Curl_readrewind(struct connectdata *conn)
248 {
249   struct SessionHandle *data = conn->data;
250 
251   conn->bits.rewindaftersend = FALSE; /* we rewind now */
252 
253   /* explicitly switch off sending data on this connection now since we are
254      about to restart a new transfer and thus we want to avoid inadvertently
255      sending more data on the existing connection until the next transfer
256      starts */
257   data->req.keepon &= ~KEEP_SEND;
258 
259   /* We have sent away data. If not using CURLOPT_POSTFIELDS or
260      CURLOPT_HTTPPOST, call app to rewind
261   */
262   if(data->set.postfields ||
263      (data->set.httpreq == HTTPREQ_POST_FORM))
264     ; /* do nothing */
265   else {
266     if(data->set.seek_func) {
267       int err;
268 
269       err = (data->set.seek_func)(data->set.seek_client, 0, SEEK_SET);
270       if(err) {
271         failf(data, "seek callback returned error %d", (int)err);
272         return CURLE_SEND_FAIL_REWIND;
273       }
274     }
275     else if(data->set.ioctl_func) {
276       curlioerr err;
277 
278       err = (data->set.ioctl_func)(data, CURLIOCMD_RESTARTREAD,
279                                    data->set.ioctl_client);
280       infof(data, "the ioctl callback returned %d\n", (int)err);
281 
282       if(err) {
283         /* FIXME: convert to a human readable error message */
284         failf(data, "ioctl callback returned error %d", (int)err);
285         return CURLE_SEND_FAIL_REWIND;
286       }
287     }
288     else {
289       /* If no CURLOPT_READFUNCTION is used, we know that we operate on a
290          given FILE * stream and we can actually attempt to rewind that
291          ourselves with fseek() */
292       if(data->set.fread_func == (curl_read_callback)fread) {
293         if(-1 != fseek(data->set.in, 0, SEEK_SET))
294           /* successful rewind */
295           return CURLE_OK;
296       }
297 
298       /* no callback set or failure above, makes us fail at once */
299       failf(data, "necessary data rewind wasn't possible");
300       return CURLE_SEND_FAIL_REWIND;
301     }
302   }
303   return CURLE_OK;
304 }
305 
data_pending(const struct connectdata * conn)306 static int data_pending(const struct connectdata *conn)
307 {
308   /* in the case of libssh2, we can never be really sure that we have emptied
309      its internal buffers so we MUST always try until we get EAGAIN back */
310   return conn->handler->protocol&(CURLPROTO_SCP|CURLPROTO_SFTP) ||
311 #if defined(USE_NGHTTP2)
312     Curl_ssl_data_pending(conn, FIRSTSOCKET) ||
313     /* For HTTP/2, we may read up everything including responde body
314        with header fields in Curl_http_readwrite_headers. If no
315        content-length is provided, curl waits for the connection
316        close, which we emulate it using conn->proto.httpc.closed =
317        TRUE. The thing is if we read everything, then http2_recv won't
318        be called and we cannot signal the HTTP/2 stream has closed. As
319        a workaround, we return nonzero here to call http2_recv. */
320     ((conn->handler->protocol&PROTO_FAMILY_HTTP) && conn->httpversion == 20);
321 #else
322     Curl_ssl_data_pending(conn, FIRSTSOCKET);
323 #endif
324 }
325 
read_rewind(struct connectdata * conn,size_t thismuch)326 static void read_rewind(struct connectdata *conn,
327                         size_t thismuch)
328 {
329   DEBUGASSERT(conn->read_pos >= thismuch);
330 
331   conn->read_pos -= thismuch;
332   conn->bits.stream_was_rewound = TRUE;
333 
334 #ifdef DEBUGBUILD
335   {
336     char buf[512 + 1];
337     size_t show;
338 
339     show = CURLMIN(conn->buf_len - conn->read_pos, sizeof(buf)-1);
340     if(conn->master_buffer) {
341       memcpy(buf, conn->master_buffer + conn->read_pos, show);
342       buf[show] = '\0';
343     }
344     else {
345       buf[0] = '\0';
346     }
347 
348     DEBUGF(infof(conn->data,
349                  "Buffer after stream rewind (read_pos = %zu): [%s]\n",
350                  conn->read_pos, buf));
351   }
352 #endif
353 }
354 
355 /*
356  * Check to see if CURLOPT_TIMECONDITION was met by comparing the time of the
357  * remote document with the time provided by CURLOPT_TIMEVAL
358  */
Curl_meets_timecondition(struct SessionHandle * data,time_t timeofdoc)359 bool Curl_meets_timecondition(struct SessionHandle *data, time_t timeofdoc)
360 {
361   if((timeofdoc == 0) || (data->set.timevalue == 0))
362     return TRUE;
363 
364   switch(data->set.timecondition) {
365   case CURL_TIMECOND_IFMODSINCE:
366   default:
367     if(timeofdoc <= data->set.timevalue) {
368       infof(data,
369             "The requested document is not new enough\n");
370       data->info.timecond = TRUE;
371       return FALSE;
372     }
373     break;
374   case CURL_TIMECOND_IFUNMODSINCE:
375     if(timeofdoc >= data->set.timevalue) {
376       infof(data,
377             "The requested document is not old enough\n");
378       data->info.timecond = TRUE;
379       return FALSE;
380     }
381     break;
382   }
383 
384   return TRUE;
385 }
386 
387 /*
388  * Go ahead and do a read if we have a readable socket or if
389  * the stream was rewound (in which case we have data in a
390  * buffer)
391  */
readwrite_data(struct SessionHandle * data,struct connectdata * conn,struct SingleRequest * k,int * didwhat,bool * done)392 static CURLcode readwrite_data(struct SessionHandle *data,
393                                struct connectdata *conn,
394                                struct SingleRequest *k,
395                                int *didwhat, bool *done)
396 {
397   CURLcode result = CURLE_OK;
398   ssize_t nread; /* number of bytes read */
399   size_t excess = 0; /* excess bytes read */
400   bool is_empty_data = FALSE;
401   bool readmore = FALSE; /* used by RTP to signal for more data */
402 
403   *done = FALSE;
404 
405   /* This is where we loop until we have read everything there is to
406      read or we get a CURLE_AGAIN */
407   do {
408     size_t buffersize = data->set.buffer_size?
409       data->set.buffer_size : BUFSIZE;
410     size_t bytestoread = buffersize;
411 
412     if(k->size != -1 && !k->header) {
413       /* make sure we don't read "too much" if we can help it since we
414          might be pipelining and then someone else might want to read what
415          follows! */
416       curl_off_t totalleft = k->size - k->bytecount;
417       if(totalleft < (curl_off_t)bytestoread)
418         bytestoread = (size_t)totalleft;
419     }
420 
421     if(bytestoread) {
422       /* receive data from the network! */
423       result = Curl_read(conn, conn->sockfd, k->buf, bytestoread, &nread);
424 
425       /* read would've blocked */
426       if(CURLE_AGAIN == result)
427         break; /* get out of loop */
428 
429       if(result>0)
430         return result;
431     }
432     else {
433       /* read nothing but since we wanted nothing we consider this an OK
434          situation to proceed from */
435       DEBUGF(infof(data, "readwrite_data: we're done!\n"));
436       nread = 0;
437     }
438 
439     if((k->bytecount == 0) && (k->writebytecount == 0)) {
440       Curl_pgrsTime(data, TIMER_STARTTRANSFER);
441       if(k->exp100 > EXP100_SEND_DATA)
442         /* set time stamp to compare with when waiting for the 100 */
443         k->start100 = Curl_tvnow();
444     }
445 
446     *didwhat |= KEEP_RECV;
447     /* indicates data of zero size, i.e. empty file */
448     is_empty_data = ((nread == 0) && (k->bodywrites == 0)) ? TRUE : FALSE;
449 
450     /* NUL terminate, allowing string ops to be used */
451     if(0 < nread || is_empty_data) {
452       k->buf[nread] = 0;
453     }
454     else if(0 >= nread) {
455       /* if we receive 0 or less here, the server closed the connection
456          and we bail out from this! */
457       DEBUGF(infof(data, "nread <= 0, server closed connection, bailing\n"));
458       k->keepon &= ~KEEP_RECV;
459       break;
460     }
461 
462     /* Default buffer to use when we write the buffer, it may be changed
463        in the flow below before the actual storing is done. */
464     k->str = k->buf;
465 
466     if(conn->handler->readwrite) {
467       result = conn->handler->readwrite(data, conn, &nread, &readmore);
468       if(result)
469         return result;
470       if(readmore)
471         break;
472     }
473 
474 #ifndef CURL_DISABLE_HTTP
475     /* Since this is a two-state thing, we check if we are parsing
476        headers at the moment or not. */
477     if(k->header) {
478       /* we are in parse-the-header-mode */
479       bool stop_reading = FALSE;
480       result = Curl_http_readwrite_headers(data, conn, &nread, &stop_reading);
481       if(result)
482         return result;
483 
484       if(conn->handler->readwrite &&
485          (k->maxdownload <= 0 && nread > 0)) {
486         result = conn->handler->readwrite(data, conn, &nread, &readmore);
487         if(result)
488           return result;
489         if(readmore)
490           break;
491       }
492 
493       if(stop_reading) {
494         /* We've stopped dealing with input, get out of the do-while loop */
495 
496         if(nread > 0) {
497           if(Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1)) {
498             infof(data,
499                   "Rewinding stream by : %zd"
500                   " bytes on url %s (zero-length body)\n",
501                   nread, data->state.path);
502             read_rewind(conn, (size_t)nread);
503           }
504           else {
505             infof(data,
506                   "Excess found in a non pipelined read:"
507                   " excess = %zd"
508                   " url = %s (zero-length body)\n",
509                   nread, data->state.path);
510           }
511         }
512 
513         break;
514       }
515     }
516 #endif /* CURL_DISABLE_HTTP */
517 
518 
519     /* This is not an 'else if' since it may be a rest from the header
520        parsing, where the beginning of the buffer is headers and the end
521        is non-headers. */
522     if(k->str && !k->header && (nread > 0 || is_empty_data)) {
523 
524 #ifndef CURL_DISABLE_HTTP
525       if(0 == k->bodywrites && !is_empty_data) {
526         /* These checks are only made the first time we are about to
527            write a piece of the body */
528         if(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)) {
529           /* HTTP-only checks */
530 
531           if(data->req.newurl) {
532             if(conn->bits.close) {
533               /* Abort after the headers if "follow Location" is set
534                  and we're set to close anyway. */
535               k->keepon &= ~KEEP_RECV;
536               *done = TRUE;
537               return CURLE_OK;
538             }
539             /* We have a new url to load, but since we want to be able
540                to re-use this connection properly, we read the full
541                response in "ignore more" */
542             k->ignorebody = TRUE;
543             infof(data, "Ignoring the response-body\n");
544           }
545           if(data->state.resume_from && !k->content_range &&
546              (data->set.httpreq==HTTPREQ_GET) &&
547              !k->ignorebody) {
548 
549             if(k->size == data->state.resume_from) {
550               /* The resume point is at the end of file, consider this fine
551                  even if it doesn't allow resume from here. */
552               infof(data, "The entire document is already downloaded");
553               connclose(conn, "already downloaded");
554               /* Abort download */
555               k->keepon &= ~KEEP_RECV;
556               *done = TRUE;
557               return CURLE_OK;
558             }
559 
560             /* we wanted to resume a download, although the server doesn't
561              * seem to support this and we did this with a GET (if it
562              * wasn't a GET we did a POST or PUT resume) */
563             failf(data, "HTTP server doesn't seem to support "
564                   "byte ranges. Cannot resume.");
565             return CURLE_RANGE_ERROR;
566           }
567 
568           if(data->set.timecondition && !data->state.range) {
569             /* A time condition has been set AND no ranges have been
570                requested. This seems to be what chapter 13.3.4 of
571                RFC 2616 defines to be the correct action for a
572                HTTP/1.1 client */
573 
574             if(!Curl_meets_timecondition(data, k->timeofdoc)) {
575               *done = TRUE;
576               /* We're simulating a http 304 from server so we return
577                  what should have been returned from the server */
578               data->info.httpcode = 304;
579               infof(data, "Simulate a HTTP 304 response!\n");
580               /* we abort the transfer before it is completed == we ruin the
581                  re-use ability. Close the connection */
582               connclose(conn, "Simulated 304 handling");
583               return CURLE_OK;
584             }
585           } /* we have a time condition */
586 
587         } /* this is HTTP or RTSP */
588       } /* this is the first time we write a body part */
589 #endif /* CURL_DISABLE_HTTP */
590 
591       k->bodywrites++;
592 
593       /* pass data to the debug function before it gets "dechunked" */
594       if(data->set.verbose) {
595         if(k->badheader) {
596           Curl_debug(data, CURLINFO_DATA_IN, data->state.headerbuff,
597                      (size_t)k->hbuflen, conn);
598           if(k->badheader == HEADER_PARTHEADER)
599             Curl_debug(data, CURLINFO_DATA_IN,
600                        k->str, (size_t)nread, conn);
601         }
602         else
603           Curl_debug(data, CURLINFO_DATA_IN,
604                      k->str, (size_t)nread, conn);
605       }
606 
607 #ifndef CURL_DISABLE_HTTP
608       if(k->chunk) {
609         /*
610          * Here comes a chunked transfer flying and we need to decode this
611          * properly.  While the name says read, this function both reads
612          * and writes away the data. The returned 'nread' holds the number
613          * of actual data it wrote to the client.
614          */
615 
616         CHUNKcode res =
617           Curl_httpchunk_read(conn, k->str, nread, &nread);
618 
619         if(CHUNKE_OK < res) {
620           if(CHUNKE_WRITE_ERROR == res) {
621             failf(data, "Failed writing data");
622             return CURLE_WRITE_ERROR;
623           }
624           failf(data, "%s in chunked-encoding", Curl_chunked_strerror(res));
625           return CURLE_RECV_ERROR;
626         }
627         else if(CHUNKE_STOP == res) {
628           size_t dataleft;
629           /* we're done reading chunks! */
630           k->keepon &= ~KEEP_RECV; /* read no more */
631 
632           /* There are now possibly N number of bytes at the end of the
633              str buffer that weren't written to the client.
634 
635              We DO care about this data if we are pipelining.
636              Push it back to be read on the next pass. */
637 
638           dataleft = conn->chunk.dataleft;
639           if(dataleft != 0) {
640             infof(conn->data, "Leftovers after chunking: %zu bytes\n",
641                   dataleft);
642             if(Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1)) {
643               /* only attempt the rewind if we truly are pipelining */
644               infof(conn->data, "Rewinding %zu bytes\n",dataleft);
645               read_rewind(conn, dataleft);
646             }
647           }
648         }
649         /* If it returned OK, we just keep going */
650       }
651 #endif   /* CURL_DISABLE_HTTP */
652 
653       /* Account for body content stored in the header buffer */
654       if(k->badheader && !k->ignorebody) {
655         DEBUGF(infof(data, "Increasing bytecount by %zu from hbuflen\n",
656                      k->hbuflen));
657         k->bytecount += k->hbuflen;
658       }
659 
660       if((-1 != k->maxdownload) &&
661          (k->bytecount + nread >= k->maxdownload)) {
662 
663         excess = (size_t)(k->bytecount + nread - k->maxdownload);
664         if(excess > 0 && !k->ignorebody) {
665           if(Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1)) {
666             /* The 'excess' amount below can't be more than BUFSIZE which
667                always will fit in a size_t */
668             infof(data,
669                   "Rewinding stream by : %zu"
670                   " bytes on url %s (size = %" CURL_FORMAT_CURL_OFF_T
671                   ", maxdownload = %" CURL_FORMAT_CURL_OFF_T
672                   ", bytecount = %" CURL_FORMAT_CURL_OFF_T ", nread = %zd)\n",
673                   excess, data->state.path,
674                   k->size, k->maxdownload, k->bytecount, nread);
675             read_rewind(conn, excess);
676           }
677           else {
678             infof(data,
679                   "Excess found in a non pipelined read:"
680                   " excess = %zu"
681                   ", size = %" CURL_FORMAT_CURL_OFF_T
682                   ", maxdownload = %" CURL_FORMAT_CURL_OFF_T
683                   ", bytecount = %" CURL_FORMAT_CURL_OFF_T "\n",
684                   excess, k->size, k->maxdownload, k->bytecount);
685           }
686         }
687 
688         nread = (ssize_t) (k->maxdownload - k->bytecount);
689         if(nread < 0 ) /* this should be unusual */
690           nread = 0;
691 
692         k->keepon &= ~KEEP_RECV; /* we're done reading */
693       }
694 
695       k->bytecount += nread;
696 
697       Curl_pgrsSetDownloadCounter(data, k->bytecount);
698 
699       if(!k->chunk && (nread || k->badheader || is_empty_data)) {
700         /* If this is chunky transfer, it was already written */
701 
702         if(k->badheader && !k->ignorebody) {
703           /* we parsed a piece of data wrongly assuming it was a header
704              and now we output it as body instead */
705 
706           /* Don't let excess data pollute body writes */
707           if(k->maxdownload == -1 || (curl_off_t)k->hbuflen <= k->maxdownload)
708             result = Curl_client_write(conn, CLIENTWRITE_BODY,
709                                        data->state.headerbuff,
710                                        k->hbuflen);
711           else
712             result = Curl_client_write(conn, CLIENTWRITE_BODY,
713                                        data->state.headerbuff,
714                                        (size_t)k->maxdownload);
715 
716           if(result)
717             return result;
718         }
719         if(k->badheader < HEADER_ALLBAD) {
720           /* This switch handles various content encodings. If there's an
721              error here, be sure to check over the almost identical code
722              in http_chunks.c.
723              Make sure that ALL_CONTENT_ENCODINGS contains all the
724              encodings handled here. */
725 #ifdef HAVE_LIBZ
726           switch (conn->data->set.http_ce_skip ?
727                   IDENTITY : k->auto_decoding) {
728           case IDENTITY:
729 #endif
730             /* This is the default when the server sends no
731                Content-Encoding header. See Curl_readwrite_init; the
732                memset() call initializes k->auto_decoding to zero. */
733             if(!k->ignorebody) {
734 
735 #ifndef CURL_DISABLE_POP3
736               if(conn->handler->protocol&PROTO_FAMILY_POP3)
737                 result = Curl_pop3_write(conn, k->str, nread);
738               else
739 #endif /* CURL_DISABLE_POP3 */
740 
741                 result = Curl_client_write(conn, CLIENTWRITE_BODY, k->str,
742                                            nread);
743             }
744 #ifdef HAVE_LIBZ
745             break;
746 
747           case DEFLATE:
748             /* Assume CLIENTWRITE_BODY; headers are not encoded. */
749             if(!k->ignorebody)
750               result = Curl_unencode_deflate_write(conn, k, nread);
751             break;
752 
753           case GZIP:
754             /* Assume CLIENTWRITE_BODY; headers are not encoded. */
755             if(!k->ignorebody)
756               result = Curl_unencode_gzip_write(conn, k, nread);
757             break;
758 
759           case COMPRESS:
760           default:
761             failf (data, "Unrecognized content encoding type. "
762                    "libcurl understands `identity', `deflate' and `gzip' "
763                    "content encodings.");
764             result = CURLE_BAD_CONTENT_ENCODING;
765             break;
766           }
767 #endif
768         }
769         k->badheader = HEADER_NORMAL; /* taken care of now */
770 
771         if(result)
772           return result;
773       }
774 
775     } /* if(! header and data to read ) */
776 
777     if(conn->handler->readwrite &&
778        (excess > 0 && !conn->bits.stream_was_rewound)) {
779       /* Parse the excess data */
780       k->str += nread;
781       nread = (ssize_t)excess;
782 
783       result = conn->handler->readwrite(data, conn, &nread, &readmore);
784       if(result)
785         return result;
786 
787       if(readmore)
788         k->keepon |= KEEP_RECV; /* we're not done reading */
789       break;
790     }
791 
792     if(is_empty_data) {
793       /* if we received nothing, the server closed the connection and we
794          are done */
795       k->keepon &= ~KEEP_RECV;
796     }
797 
798   } while(data_pending(conn));
799 
800   if(((k->keepon & (KEEP_RECV|KEEP_SEND)) == KEEP_SEND) &&
801      conn->bits.close ) {
802     /* When we've read the entire thing and the close bit is set, the server
803        may now close the connection. If there's now any kind of sending going
804        on from our side, we need to stop that immediately. */
805     infof(data, "we are done reading and this is set to close, stop send\n");
806     k->keepon &= ~KEEP_SEND; /* no writing anymore either */
807   }
808 
809   return CURLE_OK;
810 }
811 
812 /*
813  * Send data to upload to the server, when the socket is writable.
814  */
readwrite_upload(struct SessionHandle * data,struct connectdata * conn,struct SingleRequest * k,int * didwhat)815 static CURLcode readwrite_upload(struct SessionHandle *data,
816                                  struct connectdata *conn,
817                                  struct SingleRequest *k,
818                                  int *didwhat)
819 {
820   ssize_t i, si;
821   ssize_t bytes_written;
822   CURLcode result;
823   ssize_t nread; /* number of bytes read */
824   bool sending_http_headers = FALSE;
825 
826   if((k->bytecount == 0) && (k->writebytecount == 0))
827     Curl_pgrsTime(data, TIMER_STARTTRANSFER);
828 
829   *didwhat |= KEEP_SEND;
830 
831   do {
832 
833     /* only read more data if there's no upload data already
834        present in the upload buffer */
835     if(0 == data->req.upload_present) {
836       /* init the "upload from here" pointer */
837       data->req.upload_fromhere = k->uploadbuf;
838 
839       if(!k->upload_done) {
840         /* HTTP pollution, this should be written nicer to become more
841            protocol agnostic. */
842         int fillcount;
843         struct HTTP *http = data->req.protop;
844 
845         if((k->exp100 == EXP100_SENDING_REQUEST) &&
846            (http->sending == HTTPSEND_BODY)) {
847           /* If this call is to send body data, we must take some action:
848              We have sent off the full HTTP 1.1 request, and we shall now
849              go into the Expect: 100 state and await such a header */
850           k->exp100 = EXP100_AWAITING_CONTINUE; /* wait for the header */
851           k->keepon &= ~KEEP_SEND;         /* disable writing */
852           k->start100 = Curl_tvnow();       /* timeout count starts now */
853           *didwhat &= ~KEEP_SEND;  /* we didn't write anything actually */
854 
855           /* set a timeout for the multi interface */
856           Curl_expire(data, data->set.expect_100_timeout);
857           break;
858         }
859 
860         if(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)) {
861           if(http->sending == HTTPSEND_REQUEST)
862             /* We're sending the HTTP request headers, not the data.
863                Remember that so we don't change the line endings. */
864             sending_http_headers = TRUE;
865           else
866             sending_http_headers = FALSE;
867         }
868 
869         result = Curl_fillreadbuffer(conn, BUFSIZE, &fillcount);
870         if(result)
871           return result;
872 
873         nread = (ssize_t)fillcount;
874       }
875       else
876         nread = 0; /* we're done uploading/reading */
877 
878       if(!nread && (k->keepon & KEEP_SEND_PAUSE)) {
879         /* this is a paused transfer */
880         break;
881       }
882       else if(nread<=0) {
883         /* done */
884         k->keepon &= ~KEEP_SEND; /* we're done writing */
885 
886         if(conn->bits.rewindaftersend) {
887           result = Curl_readrewind(conn);
888           if(result)
889             return result;
890         }
891         break;
892       }
893 
894       /* store number of bytes available for upload */
895       data->req.upload_present = nread;
896 
897       /* convert LF to CRLF if so asked */
898       if((!sending_http_headers) && (
899 #ifdef CURL_DO_LINEEND_CONV
900          /* always convert if we're FTPing in ASCII mode */
901          (data->set.prefer_ascii) ||
902 #endif
903          (data->set.crlf))) {
904         /* Do we need to allocate a scratch buffer? */
905         if(!data->state.scratch) {
906           data->state.scratch = malloc(2 * BUFSIZE);
907           if(!data->state.scratch) {
908             failf(data, "Failed to alloc scratch buffer!");
909 
910             return CURLE_OUT_OF_MEMORY;
911           }
912         }
913 
914         /*
915          * ASCII/EBCDIC Note: This is presumably a text (not binary)
916          * transfer so the data should already be in ASCII.
917          * That means the hex values for ASCII CR (0x0d) & LF (0x0a)
918          * must be used instead of the escape sequences \r & \n.
919          */
920         for(i = 0, si = 0; i < nread; i++, si++) {
921           if(data->req.upload_fromhere[i] == 0x0a) {
922             data->state.scratch[si++] = 0x0d;
923             data->state.scratch[si] = 0x0a;
924             if(!data->set.crlf) {
925               /* we're here only because FTP is in ASCII mode...
926                  bump infilesize for the LF we just added */
927               data->state.infilesize++;
928             }
929           }
930           else
931             data->state.scratch[si] = data->req.upload_fromhere[i];
932         }
933 
934         if(si != nread) {
935           /* only perform the special operation if we really did replace
936              anything */
937           nread = si;
938 
939           /* upload from the new (replaced) buffer instead */
940           data->req.upload_fromhere = data->state.scratch;
941 
942           /* set the new amount too */
943           data->req.upload_present = nread;
944         }
945       }
946 
947 #ifndef CURL_DISABLE_SMTP
948       if(conn->handler->protocol & PROTO_FAMILY_SMTP) {
949         result = Curl_smtp_escape_eob(conn, nread);
950         if(result)
951           return result;
952       }
953 #endif /* CURL_DISABLE_SMTP */
954     } /* if 0 == data->req.upload_present */
955     else {
956       /* We have a partial buffer left from a previous "round". Use
957          that instead of reading more data */
958     }
959 
960     /* write to socket (send away data) */
961     result = Curl_write(conn,
962                         conn->writesockfd,     /* socket to send to */
963                         data->req.upload_fromhere, /* buffer pointer */
964                         data->req.upload_present,  /* buffer size */
965                         &bytes_written);           /* actually sent */
966 
967     if(result)
968       return result;
969 
970     if(data->set.verbose)
971       /* show the data before we change the pointer upload_fromhere */
972       Curl_debug(data, CURLINFO_DATA_OUT, data->req.upload_fromhere,
973                  (size_t)bytes_written, conn);
974 
975     k->writebytecount += bytes_written;
976 
977     if(k->writebytecount == data->state.infilesize) {
978       /* we have sent all data we were supposed to */
979       k->upload_done = TRUE;
980       infof(data, "We are completely uploaded and fine\n");
981     }
982 
983     if(data->req.upload_present != bytes_written) {
984       /* we only wrote a part of the buffer (if anything), deal with it! */
985 
986       /* store the amount of bytes left in the buffer to write */
987       data->req.upload_present -= bytes_written;
988 
989       /* advance the pointer where to find the buffer when the next send
990          is to happen */
991       data->req.upload_fromhere += bytes_written;
992     }
993     else {
994       /* we've uploaded that buffer now */
995       data->req.upload_fromhere = k->uploadbuf;
996       data->req.upload_present = 0; /* no more bytes left */
997 
998       if(k->upload_done) {
999         /* switch off writing, we're done! */
1000         k->keepon &= ~KEEP_SEND; /* we're done writing */
1001       }
1002     }
1003 
1004     Curl_pgrsSetUploadCounter(data, k->writebytecount);
1005 
1006   } WHILE_FALSE; /* just to break out from! */
1007 
1008   return CURLE_OK;
1009 }
1010 
1011 /*
1012  * Curl_readwrite() is the low-level function to be called when data is to
1013  * be read and written to/from the connection.
1014  */
Curl_readwrite(struct connectdata * conn,struct SessionHandle * data,bool * done)1015 CURLcode Curl_readwrite(struct connectdata *conn,
1016                         struct SessionHandle *data,
1017                         bool *done)
1018 {
1019   struct SingleRequest *k = &data->req;
1020   CURLcode result;
1021   int didwhat=0;
1022 
1023   curl_socket_t fd_read;
1024   curl_socket_t fd_write;
1025   int select_res = conn->cselect_bits;
1026 
1027   conn->cselect_bits = 0;
1028 
1029   /* only use the proper socket if the *_HOLD bit is not set simultaneously as
1030      then we are in rate limiting state in that transfer direction */
1031 
1032   if((k->keepon & KEEP_RECVBITS) == KEEP_RECV)
1033     fd_read = conn->sockfd;
1034   else
1035     fd_read = CURL_SOCKET_BAD;
1036 
1037   if((k->keepon & KEEP_SENDBITS) == KEEP_SEND)
1038     fd_write = conn->writesockfd;
1039   else
1040     fd_write = CURL_SOCKET_BAD;
1041 
1042   if(conn->data->state.drain) {
1043     select_res |= CURL_CSELECT_IN;
1044     DEBUGF(infof(data, "Curl_readwrite: forcibly told to drain data\n"));
1045   }
1046 
1047   if(!select_res) /* Call for select()/poll() only, if read/write/error
1048                      status is not known. */
1049     select_res = Curl_socket_ready(fd_read, fd_write, 0);
1050 
1051   if(select_res == CURL_CSELECT_ERR) {
1052     failf(data, "select/poll returned error");
1053     return CURLE_SEND_ERROR;
1054   }
1055 
1056   /* We go ahead and do a read if we have a readable socket or if
1057      the stream was rewound (in which case we have data in a
1058      buffer) */
1059   if((k->keepon & KEEP_RECV) &&
1060      ((select_res & CURL_CSELECT_IN) || conn->bits.stream_was_rewound)) {
1061 
1062     result = readwrite_data(data, conn, k, &didwhat, done);
1063     if(result || *done)
1064       return result;
1065   }
1066 
1067   /* If we still have writing to do, we check if we have a writable socket. */
1068   if((k->keepon & KEEP_SEND) && (select_res & CURL_CSELECT_OUT)) {
1069     /* write */
1070 
1071     result = readwrite_upload(data, conn, k, &didwhat);
1072     if(result)
1073       return result;
1074   }
1075 
1076   k->now = Curl_tvnow();
1077   if(didwhat) {
1078     /* Update read/write counters */
1079     if(k->bytecountp)
1080       *k->bytecountp = k->bytecount; /* read count */
1081     if(k->writebytecountp)
1082       *k->writebytecountp = k->writebytecount; /* write count */
1083   }
1084   else {
1085     /* no read no write, this is a timeout? */
1086     if(k->exp100 == EXP100_AWAITING_CONTINUE) {
1087       /* This should allow some time for the header to arrive, but only a
1088          very short time as otherwise it'll be too much wasted time too
1089          often. */
1090 
1091       /* Quoting RFC2616, section "8.2.3 Use of the 100 (Continue) Status":
1092 
1093          Therefore, when a client sends this header field to an origin server
1094          (possibly via a proxy) from which it has never seen a 100 (Continue)
1095          status, the client SHOULD NOT wait for an indefinite period before
1096          sending the request body.
1097 
1098       */
1099 
1100       long ms = Curl_tvdiff(k->now, k->start100);
1101       if(ms >= data->set.expect_100_timeout) {
1102         /* we've waited long enough, continue anyway */
1103         k->exp100 = EXP100_SEND_DATA;
1104         k->keepon |= KEEP_SEND;
1105         infof(data, "Done waiting for 100-continue\n");
1106       }
1107     }
1108   }
1109 
1110   if(Curl_pgrsUpdate(conn))
1111     result = CURLE_ABORTED_BY_CALLBACK;
1112   else
1113     result = Curl_speedcheck(data, k->now);
1114   if(result)
1115     return result;
1116 
1117   if(k->keepon) {
1118     if(0 > Curl_timeleft(data, &k->now, FALSE)) {
1119       if(k->size != -1) {
1120         failf(data, "Operation timed out after %ld milliseconds with %"
1121               CURL_FORMAT_CURL_OFF_T " out of %"
1122               CURL_FORMAT_CURL_OFF_T " bytes received",
1123               Curl_tvdiff(k->now, data->progress.t_startsingle), k->bytecount,
1124               k->size);
1125       }
1126       else {
1127         failf(data, "Operation timed out after %ld milliseconds with %"
1128               CURL_FORMAT_CURL_OFF_T " bytes received",
1129               Curl_tvdiff(k->now, data->progress.t_startsingle), k->bytecount);
1130       }
1131       return CURLE_OPERATION_TIMEDOUT;
1132     }
1133   }
1134   else {
1135     /*
1136      * The transfer has been performed. Just make some general checks before
1137      * returning.
1138      */
1139 
1140     if(!(data->set.opt_no_body) && (k->size != -1) &&
1141        (k->bytecount != k->size) &&
1142 #ifdef CURL_DO_LINEEND_CONV
1143        /* Most FTP servers don't adjust their file SIZE response for CRLFs,
1144           so we'll check to see if the discrepancy can be explained
1145           by the number of CRLFs we've changed to LFs.
1146        */
1147        (k->bytecount != (k->size + data->state.crlf_conversions)) &&
1148 #endif /* CURL_DO_LINEEND_CONV */
1149        !data->req.newurl) {
1150       failf(data, "transfer closed with %" CURL_FORMAT_CURL_OFF_T
1151             " bytes remaining to read",
1152             k->size - k->bytecount);
1153       return CURLE_PARTIAL_FILE;
1154     }
1155     else if(!(data->set.opt_no_body) &&
1156             k->chunk &&
1157             (conn->chunk.state != CHUNK_STOP)) {
1158       /*
1159        * In chunked mode, return an error if the connection is closed prior to
1160        * the empty (terminating) chunk is read.
1161        *
1162        * The condition above used to check for
1163        * conn->proto.http->chunk.datasize != 0 which is true after reading
1164        * *any* chunk, not just the empty chunk.
1165        *
1166        */
1167       failf(data, "transfer closed with outstanding read data remaining");
1168       return CURLE_PARTIAL_FILE;
1169     }
1170     if(Curl_pgrsUpdate(conn))
1171       return CURLE_ABORTED_BY_CALLBACK;
1172   }
1173 
1174   /* Now update the "done" boolean we return */
1175   *done = (0 == (k->keepon&(KEEP_RECV|KEEP_SEND|
1176                             KEEP_RECV_PAUSE|KEEP_SEND_PAUSE))) ? TRUE : FALSE;
1177 
1178   return CURLE_OK;
1179 }
1180 
1181 /*
1182  * Curl_single_getsock() gets called by the multi interface code when the app
1183  * has requested to get the sockets for the current connection. This function
1184  * will then be called once for every connection that the multi interface
1185  * keeps track of. This function will only be called for connections that are
1186  * in the proper state to have this information available.
1187  */
Curl_single_getsock(const struct connectdata * conn,curl_socket_t * sock,int numsocks)1188 int Curl_single_getsock(const struct connectdata *conn,
1189                         curl_socket_t *sock, /* points to numsocks number
1190                                                 of sockets */
1191                         int numsocks)
1192 {
1193   const struct SessionHandle *data = conn->data;
1194   int bitmap = GETSOCK_BLANK;
1195   unsigned sockindex = 0;
1196 
1197   if(conn->handler->perform_getsock)
1198     return conn->handler->perform_getsock(conn, sock, numsocks);
1199 
1200   if(numsocks < 2)
1201     /* simple check but we might need two slots */
1202     return GETSOCK_BLANK;
1203 
1204   /* don't include HOLD and PAUSE connections */
1205   if((data->req.keepon & KEEP_RECVBITS) == KEEP_RECV) {
1206 
1207     DEBUGASSERT(conn->sockfd != CURL_SOCKET_BAD);
1208 
1209     bitmap |= GETSOCK_READSOCK(sockindex);
1210     sock[sockindex] = conn->sockfd;
1211   }
1212 
1213   /* don't include HOLD and PAUSE connections */
1214   if((data->req.keepon & KEEP_SENDBITS) == KEEP_SEND) {
1215 
1216     if((conn->sockfd != conn->writesockfd) ||
1217        bitmap == GETSOCK_BLANK) {
1218       /* only if they are not the same socket and we have a readable
1219          one, we increase index */
1220       if(bitmap != GETSOCK_BLANK)
1221         sockindex++; /* increase index if we need two entries */
1222 
1223       DEBUGASSERT(conn->writesockfd != CURL_SOCKET_BAD);
1224 
1225       sock[sockindex] = conn->writesockfd;
1226     }
1227 
1228     bitmap |= GETSOCK_WRITESOCK(sockindex);
1229   }
1230 
1231   return bitmap;
1232 }
1233 
1234 /*
1235  * Determine optimum sleep time based on configured rate, current rate,
1236  * and packet size.
1237  * Returns value in milliseconds.
1238  *
1239  * The basic idea is to adjust the desired rate up/down in this method
1240  * based on whether we are running too slow or too fast.  Then, calculate
1241  * how many milliseconds to wait for the next packet to achieve this new
1242  * rate.
1243  */
Curl_sleep_time(curl_off_t rate_bps,curl_off_t cur_rate_bps,int pkt_size)1244 long Curl_sleep_time(curl_off_t rate_bps, curl_off_t cur_rate_bps,
1245                              int pkt_size)
1246 {
1247   curl_off_t min_sleep = 0;
1248   curl_off_t rv = 0;
1249 
1250   if(rate_bps == 0)
1251     return 0;
1252 
1253   /* If running faster than about .1% of the desired speed, slow
1254    * us down a bit.  Use shift instead of division as the 0.1%
1255    * cutoff is arbitrary anyway.
1256    */
1257   if(cur_rate_bps > (rate_bps + (rate_bps >> 10))) {
1258     /* running too fast, decrease target rate by 1/64th of rate */
1259     rate_bps -= rate_bps >> 6;
1260     min_sleep = 1;
1261   }
1262   else if(cur_rate_bps < (rate_bps - (rate_bps >> 10))) {
1263     /* running too slow, increase target rate by 1/64th of rate */
1264     rate_bps += rate_bps >> 6;
1265   }
1266 
1267   /* Determine number of milliseconds to wait until we do
1268    * the next packet at the adjusted rate.  We should wait
1269    * longer when using larger packets, for instance.
1270    */
1271   rv = ((curl_off_t)(pkt_size * 1000) / rate_bps);
1272 
1273   /* Catch rounding errors and always slow down at least 1ms if
1274    * we are running too fast.
1275    */
1276   if(rv < min_sleep)
1277     rv = min_sleep;
1278 
1279   /* Bound value to fit in 'long' on 32-bit platform.  That's
1280    * plenty long enough anyway!
1281    */
1282   if(rv > 0x7fffffff)
1283     rv = 0x7fffffff;
1284 
1285   return (long)rv;
1286 }
1287 
1288 /*
1289  * Curl_pretransfer() is called immediately before a transfer starts.
1290  */
Curl_pretransfer(struct SessionHandle * data)1291 CURLcode Curl_pretransfer(struct SessionHandle *data)
1292 {
1293   CURLcode result;
1294   if(!data->change.url) {
1295     /* we can't do anything without URL */
1296     failf(data, "No URL set!");
1297     return CURLE_URL_MALFORMAT;
1298   }
1299 
1300   /* Init the SSL session ID cache here. We do it here since we want to do it
1301      after the *_setopt() calls (that could specify the size of the cache) but
1302      before any transfer takes place. */
1303   result = Curl_ssl_initsessions(data, data->set.ssl.max_ssl_sessions);
1304   if(result)
1305     return result;
1306 
1307   data->set.followlocation=0; /* reset the location-follow counter */
1308   data->state.this_is_a_follow = FALSE; /* reset this */
1309   data->state.errorbuf = FALSE; /* no error has occurred */
1310   data->state.httpversion = 0; /* don't assume any particular server version */
1311 
1312   data->state.authproblem = FALSE;
1313   data->state.authhost.want = data->set.httpauth;
1314   data->state.authproxy.want = data->set.proxyauth;
1315   Curl_safefree(data->info.wouldredirect);
1316   data->info.wouldredirect = NULL;
1317 
1318   /* If there is a list of cookie files to read, do it now! */
1319   if(data->change.cookielist)
1320     Curl_cookie_loadfiles(data);
1321 
1322   /* If there is a list of host pairs to deal with */
1323   if(data->change.resolve)
1324     result = Curl_loadhostpairs(data);
1325 
1326   if(!result) {
1327     /* Allow data->set.use_port to set which port to use. This needs to be
1328      * disabled for example when we follow Location: headers to URLs using
1329      * different ports! */
1330     data->state.allow_port = TRUE;
1331 
1332 #if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(HAVE_MSG_NOSIGNAL)
1333     /*************************************************************
1334      * Tell signal handler to ignore SIGPIPE
1335      *************************************************************/
1336     if(!data->set.no_signal)
1337       data->state.prev_signal = signal(SIGPIPE, SIG_IGN);
1338 #endif
1339 
1340     Curl_initinfo(data); /* reset session-specific information "variables" */
1341     Curl_pgrsResetTimesSizes(data);
1342     Curl_pgrsStartNow(data);
1343 
1344     if(data->set.timeout)
1345       Curl_expire(data, data->set.timeout);
1346 
1347     if(data->set.connecttimeout)
1348       Curl_expire(data, data->set.connecttimeout);
1349 
1350     /* In case the handle is re-used and an authentication method was picked
1351        in the session we need to make sure we only use the one(s) we now
1352        consider to be fine */
1353     data->state.authhost.picked &= data->state.authhost.want;
1354     data->state.authproxy.picked &= data->state.authproxy.want;
1355   }
1356 
1357   return result;
1358 }
1359 
1360 /*
1361  * Curl_posttransfer() is called immediately after a transfer ends
1362  */
Curl_posttransfer(struct SessionHandle * data)1363 CURLcode Curl_posttransfer(struct SessionHandle *data)
1364 {
1365 #if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(HAVE_MSG_NOSIGNAL)
1366   /* restore the signal handler for SIGPIPE before we get back */
1367   if(!data->set.no_signal)
1368     signal(SIGPIPE, data->state.prev_signal);
1369 #else
1370   (void)data; /* unused parameter */
1371 #endif
1372 
1373   return CURLE_OK;
1374 }
1375 
1376 #ifndef CURL_DISABLE_HTTP
1377 /*
1378  * strlen_url() returns the length of the given URL if the spaces within the
1379  * URL were properly URL encoded.
1380  */
strlen_url(const char * url)1381 static size_t strlen_url(const char *url)
1382 {
1383   const char *ptr;
1384   size_t newlen=0;
1385   bool left=TRUE; /* left side of the ? */
1386 
1387   for(ptr=url; *ptr; ptr++) {
1388     switch(*ptr) {
1389     case '?':
1390       left=FALSE;
1391       /* fall through */
1392     default:
1393       newlen++;
1394       break;
1395     case ' ':
1396       if(left)
1397         newlen+=3;
1398       else
1399         newlen++;
1400       break;
1401     }
1402   }
1403   return newlen;
1404 }
1405 
1406 /* strcpy_url() copies a url to a output buffer and URL-encodes the spaces in
1407  * the source URL accordingly.
1408  */
strcpy_url(char * output,const char * url)1409 static void strcpy_url(char *output, const char *url)
1410 {
1411   /* we must add this with whitespace-replacing */
1412   bool left=TRUE;
1413   const char *iptr;
1414   char *optr = output;
1415   for(iptr = url;    /* read from here */
1416       *iptr;         /* until zero byte */
1417       iptr++) {
1418     switch(*iptr) {
1419     case '?':
1420       left=FALSE;
1421       /* fall through */
1422     default:
1423       *optr++=*iptr;
1424       break;
1425     case ' ':
1426       if(left) {
1427         *optr++='%'; /* add a '%' */
1428         *optr++='2'; /* add a '2' */
1429         *optr++='0'; /* add a '0' */
1430       }
1431       else
1432         *optr++='+'; /* add a '+' here */
1433       break;
1434     }
1435   }
1436   *optr=0; /* zero terminate output buffer */
1437 
1438 }
1439 
1440 /*
1441  * Returns true if the given URL is absolute (as opposed to relative)
1442  */
is_absolute_url(const char * url)1443 static bool is_absolute_url(const char *url)
1444 {
1445   char prot[16]; /* URL protocol string storage */
1446   char letter;   /* used for a silly sscanf */
1447 
1448   return (2 == sscanf(url, "%15[^?&/:]://%c", prot, &letter)) ? TRUE : FALSE;
1449 }
1450 
1451 /*
1452  * Concatenate a relative URL to a base URL making it absolute.
1453  * URL-encodes any spaces.
1454  * The returned pointer must be freed by the caller unless NULL
1455  * (returns NULL on out of memory).
1456  */
concat_url(const char * base,const char * relurl)1457 static char *concat_url(const char *base, const char *relurl)
1458 {
1459   /***
1460    TRY to append this new path to the old URL
1461    to the right of the host part. Oh crap, this is doomed to cause
1462    problems in the future...
1463   */
1464   char *newest;
1465   char *protsep;
1466   char *pathsep;
1467   size_t newlen;
1468 
1469   const char *useurl = relurl;
1470   size_t urllen;
1471 
1472   /* we must make our own copy of the URL to play with, as it may
1473      point to read-only data */
1474   char *url_clone=strdup(base);
1475 
1476   if(!url_clone)
1477     return NULL; /* skip out of this NOW */
1478 
1479   /* protsep points to the start of the host name */
1480   protsep=strstr(url_clone, "//");
1481   if(!protsep)
1482     protsep=url_clone;
1483   else
1484     protsep+=2; /* pass the slashes */
1485 
1486   if('/' != relurl[0]) {
1487     int level=0;
1488 
1489     /* First we need to find out if there's a ?-letter in the URL,
1490        and cut it and the right-side of that off */
1491     pathsep = strchr(protsep, '?');
1492     if(pathsep)
1493       *pathsep=0;
1494 
1495     /* we have a relative path to append to the last slash if there's one
1496        available, or if the new URL is just a query string (starts with a
1497        '?')  we append the new one at the end of the entire currently worked
1498        out URL */
1499     if(useurl[0] != '?') {
1500       pathsep = strrchr(protsep, '/');
1501       if(pathsep)
1502         *pathsep=0;
1503     }
1504 
1505     /* Check if there's any slash after the host name, and if so, remember
1506        that position instead */
1507     pathsep = strchr(protsep, '/');
1508     if(pathsep)
1509       protsep = pathsep+1;
1510     else
1511       protsep = NULL;
1512 
1513     /* now deal with one "./" or any amount of "../" in the newurl
1514        and act accordingly */
1515 
1516     if((useurl[0] == '.') && (useurl[1] == '/'))
1517       useurl+=2; /* just skip the "./" */
1518 
1519     while((useurl[0] == '.') &&
1520           (useurl[1] == '.') &&
1521           (useurl[2] == '/')) {
1522       level++;
1523       useurl+=3; /* pass the "../" */
1524     }
1525 
1526     if(protsep) {
1527       while(level--) {
1528         /* cut off one more level from the right of the original URL */
1529         pathsep = strrchr(protsep, '/');
1530         if(pathsep)
1531           *pathsep=0;
1532         else {
1533           *protsep=0;
1534           break;
1535         }
1536       }
1537     }
1538   }
1539   else {
1540     /* We got a new absolute path for this server */
1541 
1542     if((relurl[0] == '/') && (relurl[1] == '/')) {
1543       /* the new URL starts with //, just keep the protocol part from the
1544          original one */
1545       *protsep=0;
1546       useurl = &relurl[2]; /* we keep the slashes from the original, so we
1547                               skip the new ones */
1548     }
1549     else {
1550       /* cut off the original URL from the first slash, or deal with URLs
1551          without slash */
1552       pathsep = strchr(protsep, '/');
1553       if(pathsep) {
1554         /* When people use badly formatted URLs, such as
1555            "http://www.url.com?dir=/home/daniel" we must not use the first
1556            slash, if there's a ?-letter before it! */
1557         char *sep = strchr(protsep, '?');
1558         if(sep && (sep < pathsep))
1559           pathsep = sep;
1560         *pathsep=0;
1561       }
1562       else {
1563         /* There was no slash. Now, since we might be operating on a badly
1564            formatted URL, such as "http://www.url.com?id=2380" which doesn't
1565            use a slash separator as it is supposed to, we need to check for a
1566            ?-letter as well! */
1567         pathsep = strchr(protsep, '?');
1568         if(pathsep)
1569           *pathsep=0;
1570       }
1571     }
1572   }
1573 
1574   /* If the new part contains a space, this is a mighty stupid redirect
1575      but we still make an effort to do "right". To the left of a '?'
1576      letter we replace each space with %20 while it is replaced with '+'
1577      on the right side of the '?' letter.
1578   */
1579   newlen = strlen_url(useurl);
1580 
1581   urllen = strlen(url_clone);
1582 
1583   newest = malloc(urllen + 1 + /* possible slash */
1584                   newlen + 1 /* zero byte */);
1585 
1586   if(!newest) {
1587     free(url_clone); /* don't leak this */
1588     return NULL;
1589   }
1590 
1591   /* copy over the root url part */
1592   memcpy(newest, url_clone, urllen);
1593 
1594   /* check if we need to append a slash */
1595   if(('/' == useurl[0]) || (protsep && !*protsep) || ('?' == useurl[0]))
1596     ;
1597   else
1598     newest[urllen++]='/';
1599 
1600   /* then append the new piece on the right side */
1601   strcpy_url(&newest[urllen], useurl);
1602 
1603   free(url_clone);
1604 
1605   return newest;
1606 }
1607 #endif /* CURL_DISABLE_HTTP */
1608 
1609 /*
1610  * Curl_follow() handles the URL redirect magic. Pass in the 'newurl' string
1611  * as given by the remote server and set up the new URL to request.
1612  */
Curl_follow(struct SessionHandle * data,char * newurl,followtype type)1613 CURLcode Curl_follow(struct SessionHandle *data,
1614                      char *newurl, /* this 'newurl' is the Location: string,
1615                                       and it must be malloc()ed before passed
1616                                       here */
1617                      followtype type) /* see transfer.h */
1618 {
1619 #ifdef CURL_DISABLE_HTTP
1620   (void)data;
1621   (void)newurl;
1622   (void)type;
1623   /* Location: following will not happen when HTTP is disabled */
1624   return CURLE_TOO_MANY_REDIRECTS;
1625 #else
1626 
1627   /* Location: redirect */
1628   bool disallowport = FALSE;
1629 
1630   if(type == FOLLOW_REDIR) {
1631     if((data->set.maxredirs != -1) &&
1632         (data->set.followlocation >= data->set.maxredirs)) {
1633       failf(data, "Maximum (%ld) redirects followed", data->set.maxredirs);
1634       return CURLE_TOO_MANY_REDIRECTS;
1635     }
1636 
1637     /* mark the next request as a followed location: */
1638     data->state.this_is_a_follow = TRUE;
1639 
1640     data->set.followlocation++; /* count location-followers */
1641 
1642     if(data->set.http_auto_referer) {
1643       /* We are asked to automatically set the previous URL as the referer
1644          when we get the next URL. We pick the ->url field, which may or may
1645          not be 100% correct */
1646 
1647       if(data->change.referer_alloc) {
1648         Curl_safefree(data->change.referer);
1649         data->change.referer_alloc = FALSE;
1650       }
1651 
1652       data->change.referer = strdup(data->change.url);
1653       if(!data->change.referer)
1654         return CURLE_OUT_OF_MEMORY;
1655       data->change.referer_alloc = TRUE; /* yes, free this later */
1656     }
1657   }
1658 
1659   if(!is_absolute_url(newurl))  {
1660     /***
1661      *DANG* this is an RFC 2068 violation. The URL is supposed
1662      to be absolute and this doesn't seem to be that!
1663      */
1664     char *absolute = concat_url(data->change.url, newurl);
1665     if(!absolute)
1666       return CURLE_OUT_OF_MEMORY;
1667     free(newurl);
1668     newurl = absolute;
1669   }
1670   else {
1671     /* This is an absolute URL, don't allow the custom port number */
1672     disallowport = TRUE;
1673 
1674     if(strchr(newurl, ' ')) {
1675       /* This new URL contains at least one space, this is a mighty stupid
1676          redirect but we still make an effort to do "right". */
1677       char *newest;
1678       size_t newlen = strlen_url(newurl);
1679 
1680       newest = malloc(newlen+1); /* get memory for this */
1681       if(!newest)
1682         return CURLE_OUT_OF_MEMORY;
1683       strcpy_url(newest, newurl); /* create a space-free URL */
1684 
1685       free(newurl); /* that was no good */
1686       newurl = newest; /* use this instead now */
1687     }
1688 
1689   }
1690 
1691   if(type == FOLLOW_FAKE) {
1692     /* we're only figuring out the new url if we would've followed locations
1693        but now we're done so we can get out! */
1694     data->info.wouldredirect = newurl;
1695     return CURLE_OK;
1696   }
1697 
1698   if(disallowport)
1699     data->state.allow_port = FALSE;
1700 
1701   if(data->change.url_alloc) {
1702     Curl_safefree(data->change.url);
1703     data->change.url_alloc = FALSE;
1704   }
1705 
1706   data->change.url = newurl;
1707   data->change.url_alloc = TRUE;
1708   newurl = NULL; /* don't free! */
1709 
1710   infof(data, "Issue another request to this URL: '%s'\n", data->change.url);
1711 
1712   /*
1713    * We get here when the HTTP code is 300-399 (and 401). We need to perform
1714    * differently based on exactly what return code there was.
1715    *
1716    * News from 7.10.6: we can also get here on a 401 or 407, in case we act on
1717    * a HTTP (proxy-) authentication scheme other than Basic.
1718    */
1719   switch(data->info.httpcode) {
1720     /* 401 - Act on a WWW-Authenticate, we keep on moving and do the
1721        Authorization: XXXX header in the HTTP request code snippet */
1722     /* 407 - Act on a Proxy-Authenticate, we keep on moving and do the
1723        Proxy-Authorization: XXXX header in the HTTP request code snippet */
1724     /* 300 - Multiple Choices */
1725     /* 306 - Not used */
1726     /* 307 - Temporary Redirect */
1727   default:  /* for all above (and the unknown ones) */
1728     /* Some codes are explicitly mentioned since I've checked RFC2616 and they
1729      * seem to be OK to POST to.
1730      */
1731     break;
1732   case 301: /* Moved Permanently */
1733     /* (quote from RFC7231, section 6.4.2)
1734      *
1735      * Note: For historical reasons, a user agent MAY change the request
1736      * method from POST to GET for the subsequent request.  If this
1737      * behavior is undesired, the 307 (Temporary Redirect) status code
1738      * can be used instead.
1739      *
1740      * ----
1741      *
1742      * Many webservers expect this, so these servers often answers to a POST
1743      * request with an error page. To be sure that libcurl gets the page that
1744      * most user agents would get, libcurl has to force GET.
1745      *
1746      * This behaviour is forbidden by RFC1945 and the obsolete RFC2616, and
1747      * can be overridden with CURLOPT_POSTREDIR.
1748      */
1749     if((data->set.httpreq == HTTPREQ_POST
1750         || data->set.httpreq == HTTPREQ_POST_FORM)
1751        && !(data->set.keep_post & CURL_REDIR_POST_301)) {
1752       infof(data, "Switch from POST to GET\n");
1753       data->set.httpreq = HTTPREQ_GET;
1754     }
1755     break;
1756   case 302: /* Found */
1757     /* (quote from RFC7231, section 6.4.3)
1758      *
1759      * Note: For historical reasons, a user agent MAY change the request
1760      * method from POST to GET for the subsequent request.  If this
1761      * behavior is undesired, the 307 (Temporary Redirect) status code
1762      * can be used instead.
1763      *
1764      * ----
1765      *
1766      * Many webservers expect this, so these servers often answers to a POST
1767      * request with an error page. To be sure that libcurl gets the page that
1768      * most user agents would get, libcurl has to force GET.
1769      *
1770      * This behaviour is forbidden by RFC1945 and the obsolete RFC2616, and
1771      * can be overridden with CURLOPT_POSTREDIR.
1772      */
1773     if((data->set.httpreq == HTTPREQ_POST
1774         || data->set.httpreq == HTTPREQ_POST_FORM)
1775        && !(data->set.keep_post & CURL_REDIR_POST_302)) {
1776       infof(data, "Switch from POST to GET\n");
1777       data->set.httpreq = HTTPREQ_GET;
1778     }
1779     break;
1780 
1781   case 303: /* See Other */
1782     /* Disable both types of POSTs, unless the user explicitely
1783        asks for POST after POST */
1784     if(data->set.httpreq != HTTPREQ_GET
1785       && !(data->set.keep_post & CURL_REDIR_POST_303)) {
1786       data->set.httpreq = HTTPREQ_GET; /* enforce GET request */
1787       infof(data, "Disables POST, goes with %s\n",
1788             data->set.opt_no_body?"HEAD":"GET");
1789     }
1790     break;
1791   case 304: /* Not Modified */
1792     /* 304 means we did a conditional request and it was "Not modified".
1793      * We shouldn't get any Location: header in this response!
1794      */
1795     break;
1796   case 305: /* Use Proxy */
1797     /* (quote from RFC2616, section 10.3.6):
1798      * "The requested resource MUST be accessed through the proxy given
1799      * by the Location field. The Location field gives the URI of the
1800      * proxy.  The recipient is expected to repeat this single request
1801      * via the proxy. 305 responses MUST only be generated by origin
1802      * servers."
1803      */
1804     break;
1805   }
1806   Curl_pgrsTime(data, TIMER_REDIRECT);
1807   Curl_pgrsResetTimesSizes(data);
1808 
1809   return CURLE_OK;
1810 #endif /* CURL_DISABLE_HTTP */
1811 }
1812 
1813 CURLcode
Curl_reconnect_request(struct connectdata ** connp)1814 Curl_reconnect_request(struct connectdata **connp)
1815 {
1816   CURLcode result = CURLE_OK;
1817   struct connectdata *conn = *connp;
1818   struct SessionHandle *data = conn->data;
1819 
1820   /* This was a re-use of a connection and we got a write error in the
1821    * DO-phase. Then we DISCONNECT this connection and have another attempt to
1822    * CONNECT and then DO again! The retry cannot possibly find another
1823    * connection to re-use, since we only keep one possible connection for
1824    * each.  */
1825 
1826   infof(data, "Re-used connection seems dead, get a new one\n");
1827 
1828   connclose(conn, "Reconnect dead connection"); /* enforce close */
1829   result = Curl_done(&conn, result, FALSE); /* we are so done with this */
1830 
1831   /* conn may no longer be a good pointer, clear it to avoid mistakes by
1832      parent functions */
1833   *connp = NULL;
1834 
1835   /*
1836    * According to bug report #1330310. We need to check for CURLE_SEND_ERROR
1837    * here as well. I figure this could happen when the request failed on a FTP
1838    * connection and thus Curl_done() itself tried to use the connection
1839    * (again). Slight Lack of feedback in the report, but I don't think this
1840    * extra check can do much harm.
1841    */
1842   if(!result || (CURLE_SEND_ERROR == result)) {
1843     bool async;
1844     bool protocol_done = TRUE;
1845 
1846     /* Now, redo the connect and get a new connection */
1847     result = Curl_connect(data, connp, &async, &protocol_done);
1848     if(!result) {
1849       /* We have connected or sent away a name resolve query fine */
1850 
1851       conn = *connp; /* setup conn to again point to something nice */
1852       if(async) {
1853         /* Now, if async is TRUE here, we need to wait for the name
1854            to resolve */
1855         result = Curl_resolver_wait_resolv(conn, NULL);
1856         if(result)
1857           return result;
1858 
1859         /* Resolved, continue with the connection */
1860         result = Curl_async_resolved(conn, &protocol_done);
1861         if(result)
1862           return result;
1863       }
1864     }
1865   }
1866 
1867   return result;
1868 }
1869 
1870 /* Returns CURLE_OK *and* sets '*url' if a request retry is wanted.
1871 
1872    NOTE: that the *url is malloc()ed. */
Curl_retry_request(struct connectdata * conn,char ** url)1873 CURLcode Curl_retry_request(struct connectdata *conn,
1874                             char **url)
1875 {
1876   struct SessionHandle *data = conn->data;
1877 
1878   *url = NULL;
1879 
1880   /* if we're talking upload, we can't do the checks below, unless the protocol
1881      is HTTP as when uploading over HTTP we will still get a response */
1882   if(data->set.upload &&
1883      !(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)))
1884     return CURLE_OK;
1885 
1886   if((data->req.bytecount + data->req.headerbytecount == 0) &&
1887       conn->bits.reuse &&
1888       !data->set.opt_no_body &&
1889       (data->set.rtspreq != RTSPREQ_RECEIVE)) {
1890     /* We got no data, we attempted to re-use a connection and yet we want a
1891        "body". This might happen if the connection was left alive when we were
1892        done using it before, but that was closed when we wanted to read from
1893        it again. Bad luck. Retry the same request on a fresh connect! */
1894     infof(conn->data, "Connection died, retrying a fresh connect\n");
1895     *url = strdup(conn->data->change.url);
1896     if(!*url)
1897       return CURLE_OUT_OF_MEMORY;
1898 
1899     connclose(conn, "retry"); /* close this connection */
1900     conn->bits.retry = TRUE; /* mark this as a connection we're about
1901                                 to retry. Marking it this way should
1902                                 prevent i.e HTTP transfers to return
1903                                 error just because nothing has been
1904                                 transferred! */
1905 
1906 
1907     if(conn->handler->protocol&PROTO_FAMILY_HTTP) {
1908       struct HTTP *http = data->req.protop;
1909       if(http->writebytecount)
1910         return Curl_readrewind(conn);
1911     }
1912   }
1913   return CURLE_OK;
1914 }
1915 
1916 /*
1917  * Curl_setup_transfer() is called to setup some basic properties for the
1918  * upcoming transfer.
1919  */
1920 void
Curl_setup_transfer(struct connectdata * conn,int sockindex,curl_off_t size,bool getheader,curl_off_t * bytecountp,int writesockindex,curl_off_t * writecountp)1921 Curl_setup_transfer(
1922   struct connectdata *conn, /* connection data */
1923   int sockindex,            /* socket index to read from or -1 */
1924   curl_off_t size,          /* -1 if unknown at this point */
1925   bool getheader,           /* TRUE if header parsing is wanted */
1926   curl_off_t *bytecountp,   /* return number of bytes read or NULL */
1927   int writesockindex,       /* socket index to write to, it may very well be
1928                                the same we read from. -1 disables */
1929   curl_off_t *writecountp   /* return number of bytes written or NULL */
1930   )
1931 {
1932   struct SessionHandle *data;
1933   struct SingleRequest *k;
1934 
1935   DEBUGASSERT(conn != NULL);
1936 
1937   data = conn->data;
1938   k = &data->req;
1939 
1940   DEBUGASSERT((sockindex <= 1) && (sockindex >= -1));
1941 
1942   /* now copy all input parameters */
1943   conn->sockfd = sockindex == -1 ?
1944       CURL_SOCKET_BAD : conn->sock[sockindex];
1945   conn->writesockfd = writesockindex == -1 ?
1946       CURL_SOCKET_BAD:conn->sock[writesockindex];
1947   k->getheader = getheader;
1948 
1949   k->size = size;
1950   k->bytecountp = bytecountp;
1951   k->writebytecountp = writecountp;
1952 
1953   /* The code sequence below is placed in this function just because all
1954      necessary input is not always known in do_complete() as this function may
1955      be called after that */
1956 
1957   if(!k->getheader) {
1958     k->header = FALSE;
1959     if(size > 0)
1960       Curl_pgrsSetDownloadSize(data, size);
1961   }
1962   /* we want header and/or body, if neither then don't do this! */
1963   if(k->getheader || !data->set.opt_no_body) {
1964 
1965     if(conn->sockfd != CURL_SOCKET_BAD)
1966       k->keepon |= KEEP_RECV;
1967 
1968     if(conn->writesockfd != CURL_SOCKET_BAD) {
1969       struct HTTP *http = data->req.protop;
1970       /* HTTP 1.1 magic:
1971 
1972          Even if we require a 100-return code before uploading data, we might
1973          need to write data before that since the REQUEST may not have been
1974          finished sent off just yet.
1975 
1976          Thus, we must check if the request has been sent before we set the
1977          state info where we wait for the 100-return code
1978       */
1979       if((data->state.expect100header) &&
1980          (conn->handler->protocol&PROTO_FAMILY_HTTP) &&
1981          (http->sending == HTTPSEND_BODY)) {
1982         /* wait with write until we either got 100-continue or a timeout */
1983         k->exp100 = EXP100_AWAITING_CONTINUE;
1984         k->start100 = Curl_tvnow();
1985 
1986         /* Set a timeout for the multi interface. Add the inaccuracy margin so
1987            that we don't fire slightly too early and get denied to run. */
1988         Curl_expire(data, data->set.expect_100_timeout);
1989       }
1990       else {
1991         if(data->state.expect100header)
1992           /* when we've sent off the rest of the headers, we must await a
1993              100-continue but first finish sending the request */
1994           k->exp100 = EXP100_SENDING_REQUEST;
1995 
1996         /* enable the write bit when we're not waiting for continue */
1997         k->keepon |= KEEP_SEND;
1998       }
1999     } /* if(conn->writesockfd != CURL_SOCKET_BAD) */
2000   } /* if(k->getheader || !data->set.opt_no_body) */
2001 
2002 }
2003