1 /***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
9 *
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at https://curl.se/docs/copyright.html.
13 *
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 * SPDX-License-Identifier: curl
22 *
23 ***************************************************************************/
24
25 #include "curl_setup.h"
26 #include "strtoofft.h"
27
28 #ifdef HAVE_NETINET_IN_H
29 #include <netinet/in.h>
30 #endif
31 #ifdef HAVE_NETDB_H
32 #include <netdb.h>
33 #endif
34 #ifdef HAVE_ARPA_INET_H
35 #include <arpa/inet.h>
36 #endif
37 #ifdef HAVE_NET_IF_H
38 #include <net/if.h>
39 #endif
40 #ifdef HAVE_SYS_IOCTL_H
41 #include <sys/ioctl.h>
42 #endif
43 #include <signal.h>
44
45 #ifdef HAVE_SYS_PARAM_H
46 #include <sys/param.h>
47 #endif
48
49 #ifdef HAVE_SYS_SELECT_H
50 #include <sys/select.h>
51 #elif defined(HAVE_UNISTD_H)
52 #include <unistd.h>
53 #endif
54
55 #ifndef HAVE_SOCKET
56 #error "We can't compile without socket() support!"
57 #endif
58
59 #include "urldata.h"
60 #include <curl/curl.h>
61 #include "netrc.h"
62
63 #include "content_encoding.h"
64 #include "hostip.h"
65 #include "cfilters.h"
66 #include "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 "vquic/vquic.h"
75 #include "select.h"
76 #include "multiif.h"
77 #include "connect.h"
78 #include "http2.h"
79 #include "mime.h"
80 #include "strcase.h"
81 #include "urlapi-int.h"
82 #include "hsts.h"
83 #include "setopt.h"
84 #include "headers.h"
85
86 /* The last 3 #include files should be in this order */
87 #include "curl_printf.h"
88 #include "curl_memory.h"
89 #include "memdebug.h"
90
91 #if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_SMTP) || \
92 !defined(CURL_DISABLE_IMAP)
93 /*
94 * checkheaders() checks the linked list of custom headers for a
95 * particular header (prefix). Provide the prefix without colon!
96 *
97 * Returns a pointer to the first matching header or NULL if none matched.
98 */
Curl_checkheaders(const struct Curl_easy * data,const char * thisheader,const size_t thislen)99 char *Curl_checkheaders(const struct Curl_easy *data,
100 const char *thisheader,
101 const size_t thislen)
102 {
103 struct curl_slist *head;
104 DEBUGASSERT(thislen);
105 DEBUGASSERT(thisheader[thislen-1] != ':');
106
107 for(head = data->set.headers; head; head = head->next) {
108 if(strncasecompare(head->data, thisheader, thislen) &&
109 Curl_headersep(head->data[thislen]) )
110 return head->data;
111 }
112
113 return NULL;
114 }
115 #endif
116
Curl_get_upload_buffer(struct Curl_easy * data)117 CURLcode Curl_get_upload_buffer(struct Curl_easy *data)
118 {
119 if(!data->state.ulbuf) {
120 data->state.ulbuf = malloc(data->set.upload_buffer_size);
121 if(!data->state.ulbuf)
122 return CURLE_OUT_OF_MEMORY;
123 }
124 return CURLE_OK;
125 }
126
127 #ifndef CURL_DISABLE_HTTP
128 /*
129 * This function will be called to loop through the trailers buffer
130 * until no more data is available for sending.
131 */
trailers_read(char * buffer,size_t size,size_t nitems,void * raw)132 static size_t trailers_read(char *buffer, size_t size, size_t nitems,
133 void *raw)
134 {
135 struct Curl_easy *data = (struct Curl_easy *)raw;
136 struct dynbuf *trailers_buf = &data->state.trailers_buf;
137 size_t bytes_left = Curl_dyn_len(trailers_buf) -
138 data->state.trailers_bytes_sent;
139 size_t to_copy = (size*nitems < bytes_left) ? size*nitems : bytes_left;
140 if(to_copy) {
141 memcpy(buffer,
142 Curl_dyn_ptr(trailers_buf) + data->state.trailers_bytes_sent,
143 to_copy);
144 data->state.trailers_bytes_sent += to_copy;
145 }
146 return to_copy;
147 }
148
trailers_left(void * raw)149 static size_t trailers_left(void *raw)
150 {
151 struct Curl_easy *data = (struct Curl_easy *)raw;
152 struct dynbuf *trailers_buf = &data->state.trailers_buf;
153 return Curl_dyn_len(trailers_buf) - data->state.trailers_bytes_sent;
154 }
155 #endif
156
157 /*
158 * This function will call the read callback to fill our buffer with data
159 * to upload.
160 */
Curl_fillreadbuffer(struct Curl_easy * data,size_t bytes,size_t * nreadp)161 CURLcode Curl_fillreadbuffer(struct Curl_easy *data, size_t bytes,
162 size_t *nreadp)
163 {
164 size_t buffersize = bytes;
165 size_t nread;
166 curl_read_callback readfunc = NULL;
167 void *extra_data = NULL;
168 int eof_index = 0;
169
170 #ifndef CURL_DISABLE_HTTP
171 if(data->state.trailers_state == TRAILERS_INITIALIZED) {
172 struct curl_slist *trailers = NULL;
173 CURLcode result;
174 int trailers_ret_code;
175
176 /* at this point we already verified that the callback exists
177 so we compile and store the trailers buffer, then proceed */
178 infof(data,
179 "Moving trailers state machine from initialized to sending.");
180 data->state.trailers_state = TRAILERS_SENDING;
181 Curl_dyn_init(&data->state.trailers_buf, DYN_TRAILERS);
182
183 data->state.trailers_bytes_sent = 0;
184 Curl_set_in_callback(data, true);
185 trailers_ret_code = data->set.trailer_callback(&trailers,
186 data->set.trailer_data);
187 Curl_set_in_callback(data, false);
188 if(trailers_ret_code == CURL_TRAILERFUNC_OK) {
189 result = Curl_http_compile_trailers(trailers, &data->state.trailers_buf,
190 data);
191 }
192 else {
193 failf(data, "operation aborted by trailing headers callback");
194 *nreadp = 0;
195 result = CURLE_ABORTED_BY_CALLBACK;
196 }
197 if(result) {
198 Curl_dyn_free(&data->state.trailers_buf);
199 curl_slist_free_all(trailers);
200 return result;
201 }
202 infof(data, "Successfully compiled trailers.");
203 curl_slist_free_all(trailers);
204 }
205 #endif
206
207 #ifndef CURL_DISABLE_HTTP
208 /* if we are transmitting trailing data, we don't need to write
209 a chunk size so we skip this */
210 if(data->req.upload_chunky &&
211 data->state.trailers_state == TRAILERS_NONE) {
212 /* if chunked Transfer-Encoding */
213 buffersize -= (8 + 2 + 2); /* 32bit hex + CRLF + CRLF */
214 data->req.upload_fromhere += (8 + 2); /* 32bit hex + CRLF */
215 }
216
217 if(data->state.trailers_state == TRAILERS_SENDING) {
218 /* if we're here then that means that we already sent the last empty chunk
219 but we didn't send a final CR LF, so we sent 0 CR LF. We then start
220 pulling trailing data until we have no more at which point we
221 simply return to the previous point in the state machine as if
222 nothing happened.
223 */
224 readfunc = trailers_read;
225 extra_data = (void *)data;
226 eof_index = 1;
227 }
228 else
229 #endif
230 {
231 readfunc = data->state.fread_func;
232 extra_data = data->state.in;
233 }
234
235 if(!data->req.fread_eof[eof_index]) {
236 Curl_set_in_callback(data, true);
237 nread = readfunc(data->req.upload_fromhere, 1, buffersize, extra_data);
238 Curl_set_in_callback(data, false);
239 /* make sure the callback is not called again after EOF */
240 data->req.fread_eof[eof_index] = !nread;
241 }
242 else
243 nread = 0;
244
245 if(nread == CURL_READFUNC_ABORT) {
246 failf(data, "operation aborted by callback");
247 *nreadp = 0;
248 return CURLE_ABORTED_BY_CALLBACK;
249 }
250 if(nread == CURL_READFUNC_PAUSE) {
251 struct SingleRequest *k = &data->req;
252
253 if(data->conn->handler->flags & PROTOPT_NONETWORK) {
254 /* protocols that work without network cannot be paused. This is
255 actually only FILE:// just now, and it can't pause since the transfer
256 isn't done using the "normal" procedure. */
257 failf(data, "Read callback asked for PAUSE when not supported");
258 return CURLE_READ_ERROR;
259 }
260
261 /* CURL_READFUNC_PAUSE pauses read callbacks that feed socket writes */
262 k->keepon |= KEEP_SEND_PAUSE; /* mark socket send as paused */
263 if(data->req.upload_chunky) {
264 /* Back out the preallocation done above */
265 data->req.upload_fromhere -= (8 + 2);
266 }
267 *nreadp = 0;
268
269 return CURLE_OK; /* nothing was read */
270 }
271 else if(nread > buffersize) {
272 /* the read function returned a too large value */
273 *nreadp = 0;
274 failf(data, "read function returned funny value");
275 return CURLE_READ_ERROR;
276 }
277
278 #ifndef CURL_DISABLE_HTTP
279 if(!data->req.forbidchunk && data->req.upload_chunky) {
280 /* if chunked Transfer-Encoding
281 * build chunk:
282 *
283 * <HEX SIZE> CRLF
284 * <DATA> CRLF
285 */
286 /* On non-ASCII platforms the <DATA> may or may not be
287 translated based on state.prefer_ascii while the protocol
288 portion must always be translated to the network encoding.
289 To further complicate matters, line end conversion might be
290 done later on, so we need to prevent CRLFs from becoming
291 CRCRLFs if that's the case. To do this we use bare LFs
292 here, knowing they'll become CRLFs later on.
293 */
294
295 bool added_crlf = FALSE;
296 int hexlen = 0;
297 const char *endofline_native;
298 const char *endofline_network;
299
300 if(
301 #ifdef CURL_DO_LINEEND_CONV
302 (data->state.prefer_ascii) ||
303 #endif
304 (data->set.crlf)) {
305 /* \n will become \r\n later on */
306 endofline_native = "\n";
307 endofline_network = "\x0a";
308 }
309 else {
310 endofline_native = "\r\n";
311 endofline_network = "\x0d\x0a";
312 }
313
314 /* if we're not handling trailing data, proceed as usual */
315 if(data->state.trailers_state != TRAILERS_SENDING) {
316 char hexbuffer[11] = "";
317 hexlen = msnprintf(hexbuffer, sizeof(hexbuffer),
318 "%zx%s", nread, endofline_native);
319
320 /* move buffer pointer */
321 data->req.upload_fromhere -= hexlen;
322 nread += hexlen;
323
324 /* copy the prefix to the buffer, leaving out the NUL */
325 memcpy(data->req.upload_fromhere, hexbuffer, hexlen);
326
327 /* always append ASCII CRLF to the data unless
328 we have a valid trailer callback */
329 if((nread-hexlen) == 0 &&
330 data->set.trailer_callback != NULL &&
331 data->state.trailers_state == TRAILERS_NONE) {
332 data->state.trailers_state = TRAILERS_INITIALIZED;
333 }
334 else {
335 memcpy(data->req.upload_fromhere + nread,
336 endofline_network,
337 strlen(endofline_network));
338 added_crlf = TRUE;
339 }
340 }
341
342 if(data->state.trailers_state == TRAILERS_SENDING &&
343 !trailers_left(data)) {
344 Curl_dyn_free(&data->state.trailers_buf);
345 data->state.trailers_state = TRAILERS_DONE;
346 data->set.trailer_data = NULL;
347 data->set.trailer_callback = NULL;
348 /* mark the transfer as done */
349 data->req.upload_done = TRUE;
350 infof(data, "Signaling end of chunked upload after trailers.");
351 }
352 else
353 if((nread - hexlen) == 0 &&
354 data->state.trailers_state != TRAILERS_INITIALIZED) {
355 /* mark this as done once this chunk is transferred */
356 data->req.upload_done = TRUE;
357 infof(data,
358 "Signaling end of chunked upload via terminating chunk.");
359 }
360
361 if(added_crlf)
362 nread += strlen(endofline_network); /* for the added end of line */
363 }
364 #endif
365
366 *nreadp = nread;
367
368 return CURLE_OK;
369 }
370
data_pending(struct Curl_easy * data)371 static int data_pending(struct Curl_easy *data)
372 {
373 struct connectdata *conn = data->conn;
374
375 if(conn->handler->protocol&PROTO_FAMILY_FTP)
376 return Curl_conn_data_pending(data, SECONDARYSOCKET);
377
378 /* in the case of libssh2, we can never be really sure that we have emptied
379 its internal buffers so we MUST always try until we get EAGAIN back */
380 return conn->handler->protocol&(CURLPROTO_SCP|CURLPROTO_SFTP) ||
381 Curl_conn_data_pending(data, FIRSTSOCKET);
382 }
383
384 /*
385 * Check to see if CURLOPT_TIMECONDITION was met by comparing the time of the
386 * remote document with the time provided by CURLOPT_TIMEVAL
387 */
Curl_meets_timecondition(struct Curl_easy * data,time_t timeofdoc)388 bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc)
389 {
390 if((timeofdoc == 0) || (data->set.timevalue == 0))
391 return TRUE;
392
393 switch(data->set.timecondition) {
394 case CURL_TIMECOND_IFMODSINCE:
395 default:
396 if(timeofdoc <= data->set.timevalue) {
397 infof(data,
398 "The requested document is not new enough");
399 data->info.timecond = TRUE;
400 return FALSE;
401 }
402 break;
403 case CURL_TIMECOND_IFUNMODSINCE:
404 if(timeofdoc >= data->set.timevalue) {
405 infof(data,
406 "The requested document is not old enough");
407 data->info.timecond = TRUE;
408 return FALSE;
409 }
410 break;
411 }
412
413 return TRUE;
414 }
415
416 /**
417 * Receive raw response data for the transfer.
418 * @param data the transfer
419 * @param buf buffer to keep response data received
420 * @param blen length of `buf`
421 * @param eos_reliable if EOS detection in underlying connection is reliable
422 * @param err error code in case of -1 return
423 * @return number of bytes read or -1 for error
424 */
Curl_xfer_recv_resp(struct Curl_easy * data,char * buf,size_t blen,bool eos_reliable,CURLcode * err)425 static ssize_t Curl_xfer_recv_resp(struct Curl_easy *data,
426 char *buf, size_t blen,
427 bool eos_reliable,
428 CURLcode *err)
429 {
430 ssize_t nread;
431
432 DEBUGASSERT(blen > 0);
433 /* If we are reading BODY data and the connection does NOT handle EOF
434 * and we know the size of the BODY data, limit the read amount */
435 if(!eos_reliable && !data->req.header && data->req.size != -1) {
436 curl_off_t totalleft = data->req.size - data->req.bytecount;
437 if(totalleft <= 0)
438 blen = 0;
439 else if(totalleft < (curl_off_t)blen)
440 blen = (size_t)totalleft;
441 }
442
443 if(!blen) {
444 /* want nothing - continue as if read nothing. */
445 DEBUGF(infof(data, "readwrite_data: we're done"));
446 *err = CURLE_OK;
447 return 0;
448 }
449
450 *err = Curl_read(data, data->conn->sockfd, buf, blen, &nread);
451 if(*err)
452 return -1;
453 DEBUGASSERT(nread >= 0);
454 *err = CURLE_OK;
455 return nread;
456 }
457
458 /*
459 * Go ahead and do a read if we have a readable socket or if
460 * the stream was rewound (in which case we have data in a
461 * buffer)
462 */
readwrite_data(struct Curl_easy * data,struct SingleRequest * k,int * didwhat,bool * done)463 static CURLcode readwrite_data(struct Curl_easy *data,
464 struct SingleRequest *k,
465 int *didwhat, bool *done)
466 {
467 struct connectdata *conn = data->conn;
468 CURLcode result = CURLE_OK;
469 char *buf;
470 size_t blen;
471 int maxloops = 10;
472 curl_off_t total_received = 0;
473 bool is_multiplex = FALSE;
474
475 DEBUGASSERT(data->state.buffer);
476 *done = FALSE;
477
478 /* This is where we loop until we have read everything there is to
479 read or we get a CURLE_AGAIN */
480 do {
481 bool is_eos = FALSE;
482 size_t bytestoread;
483 ssize_t nread;
484
485 if(!is_multiplex) {
486 /* Multiplexed connection have inherent handling of EOF and we do not
487 * have to carefully restrict the amount we try to read.
488 * Multiplexed changes only in one direction. */
489 is_multiplex = Curl_conn_is_multiplex(conn, FIRSTSOCKET);
490 }
491
492 buf = data->state.buffer;
493 bytestoread = data->set.buffer_size;
494
495 /* Observe any imposed speed limit */
496 if(bytestoread && data->set.max_recv_speed) {
497 curl_off_t net_limit = data->set.max_recv_speed - total_received;
498 if(net_limit <= 0)
499 break;
500 if((size_t)net_limit < bytestoread)
501 bytestoread = (size_t)net_limit;
502 }
503
504 nread = Curl_xfer_recv_resp(data, buf, bytestoread,
505 is_multiplex, &result);
506 if(nread < 0) {
507 if(CURLE_AGAIN == result) {
508 result = CURLE_OK;
509 break; /* get out of loop */
510 }
511 goto out; /* real error */
512 }
513
514 /* We only get a 0-length read on EndOfStream */
515 blen = (size_t)nread;
516 is_eos = (blen == 0);
517 *didwhat |= KEEP_RECV;
518
519 if(!blen) {
520 /* if we receive 0 or less here, either the data transfer is done or the
521 server closed the connection and we bail out from this! */
522 if(is_multiplex)
523 DEBUGF(infof(data, "nread == 0, stream closed, bailing"));
524 else
525 DEBUGF(infof(data, "nread <= 0, server closed connection, bailing"));
526 if(k->eos_written) { /* already did write this to client, leave */
527 k->keepon = 0; /* stop sending as well */
528 break;
529 }
530 }
531 total_received += blen;
532
533 result = Curl_xfer_write_resp(data, buf, blen, is_eos, done);
534 if(result || *done)
535 goto out;
536
537 /* if we are done, we stop receiving. On multiplexed connections,
538 * we should read the EOS. Which may arrive as meta data after
539 * the bytes. Not taking it in might lead to RST of streams. */
540 if((!is_multiplex && data->req.download_done) || is_eos) {
541 data->req.keepon &= ~KEEP_RECV;
542 }
543 /* if we are PAUSEd or stopped receiving, leave the loop */
544 if((k->keepon & KEEP_RECV_PAUSE) || !(k->keepon & KEEP_RECV))
545 break;
546
547 } while(maxloops-- && data_pending(data));
548
549 if(maxloops <= 0) {
550 /* did not read until EAGAIN, mark read-again-please */
551 data->state.select_bits = CURL_CSELECT_IN;
552 if((k->keepon & KEEP_SENDBITS) == KEEP_SEND)
553 data->state.select_bits |= CURL_CSELECT_OUT;
554 }
555
556 if(((k->keepon & (KEEP_RECV|KEEP_SEND)) == KEEP_SEND) &&
557 (conn->bits.close || is_multiplex)) {
558 /* When we've read the entire thing and the close bit is set, the server
559 may now close the connection. If there's now any kind of sending going
560 on from our side, we need to stop that immediately. */
561 infof(data, "we are done reading and this is set to close, stop send");
562 k->keepon &= ~KEEP_SEND; /* no writing anymore either */
563 k->keepon &= ~KEEP_SEND_PAUSE; /* no pausing anymore either */
564 }
565
566 out:
567 if(result)
568 DEBUGF(infof(data, "readwrite_data() -> %d", result));
569 return result;
570 }
571
Curl_done_sending(struct Curl_easy * data,struct SingleRequest * k)572 CURLcode Curl_done_sending(struct Curl_easy *data,
573 struct SingleRequest *k)
574 {
575 k->keepon &= ~KEEP_SEND; /* we're done writing */
576
577 /* These functions should be moved into the handler struct! */
578 Curl_conn_ev_data_done_send(data);
579
580 return CURLE_OK;
581 }
582
583 #if defined(_WIN32) && defined(USE_WINSOCK)
584 #ifndef SIO_IDEAL_SEND_BACKLOG_QUERY
585 #define SIO_IDEAL_SEND_BACKLOG_QUERY 0x4004747B
586 #endif
587
win_update_buffer_size(curl_socket_t sockfd)588 static void win_update_buffer_size(curl_socket_t sockfd)
589 {
590 int result;
591 ULONG ideal;
592 DWORD ideallen;
593 result = WSAIoctl(sockfd, SIO_IDEAL_SEND_BACKLOG_QUERY, 0, 0,
594 &ideal, sizeof(ideal), &ideallen, 0, 0);
595 if(result == 0) {
596 setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF,
597 (const char *)&ideal, sizeof(ideal));
598 }
599 }
600 #else
601 #define win_update_buffer_size(x)
602 #endif
603
604 #define curl_upload_refill_watermark(data) \
605 ((ssize_t)((data)->set.upload_buffer_size >> 5))
606
607 /*
608 * Send data to upload to the server, when the socket is writable.
609 */
readwrite_upload(struct Curl_easy * data,struct connectdata * conn,int * didwhat)610 static CURLcode readwrite_upload(struct Curl_easy *data,
611 struct connectdata *conn,
612 int *didwhat)
613 {
614 ssize_t i, si;
615 ssize_t bytes_written;
616 CURLcode result;
617 ssize_t nread; /* number of bytes read */
618 bool sending_http_headers = FALSE;
619 struct SingleRequest *k = &data->req;
620
621 *didwhat |= KEEP_SEND;
622
623 do {
624 curl_off_t nbody;
625 ssize_t offset = 0;
626
627 if(0 != k->upload_present &&
628 k->upload_present < curl_upload_refill_watermark(data) &&
629 !k->upload_chunky &&/*(variable sized chunked header; append not safe)*/
630 !k->upload_done && /*!(k->upload_done once k->upload_present sent)*/
631 !(k->writebytecount + k->upload_present - k->pendingheader ==
632 data->state.infilesize)) {
633 offset = k->upload_present;
634 }
635
636 /* only read more data if there's no upload data already
637 present in the upload buffer, or if appending to upload buffer */
638 if(0 == k->upload_present || offset) {
639 result = Curl_get_upload_buffer(data);
640 if(result)
641 return result;
642 if(offset && k->upload_fromhere != data->state.ulbuf)
643 memmove(data->state.ulbuf, k->upload_fromhere, offset);
644 /* init the "upload from here" pointer */
645 k->upload_fromhere = data->state.ulbuf;
646
647 if(!k->upload_done) {
648 /* HTTP pollution, this should be written nicer to become more
649 protocol agnostic. */
650 size_t fillcount;
651 struct HTTP *http = k->p.http;
652
653 if((k->exp100 == EXP100_SENDING_REQUEST) &&
654 (http->sending == HTTPSEND_BODY)) {
655 /* If this call is to send body data, we must take some action:
656 We have sent off the full HTTP 1.1 request, and we shall now
657 go into the Expect: 100 state and await such a header */
658 k->exp100 = EXP100_AWAITING_CONTINUE; /* wait for the header */
659 k->keepon &= ~KEEP_SEND; /* disable writing */
660 k->start100 = Curl_now(); /* timeout count starts now */
661 *didwhat &= ~KEEP_SEND; /* we didn't write anything actually */
662 /* set a timeout for the multi interface */
663 Curl_expire(data, data->set.expect_100_timeout, EXPIRE_100_TIMEOUT);
664 break;
665 }
666
667 if(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)) {
668 if(http->sending == HTTPSEND_REQUEST)
669 /* We're sending the HTTP request headers, not the data.
670 Remember that so we don't change the line endings. */
671 sending_http_headers = TRUE;
672 else
673 sending_http_headers = FALSE;
674 }
675
676 k->upload_fromhere += offset;
677 result = Curl_fillreadbuffer(data, data->set.upload_buffer_size-offset,
678 &fillcount);
679 k->upload_fromhere -= offset;
680 if(result)
681 return result;
682
683 nread = offset + fillcount;
684 }
685 else
686 nread = 0; /* we're done uploading/reading */
687
688 if(!nread && (k->keepon & KEEP_SEND_PAUSE)) {
689 /* this is a paused transfer */
690 break;
691 }
692 if(nread <= 0) {
693 result = Curl_done_sending(data, k);
694 if(result)
695 return result;
696 break;
697 }
698
699 /* store number of bytes available for upload */
700 k->upload_present = nread;
701
702 /* convert LF to CRLF if so asked */
703 if((!sending_http_headers) && (
704 #ifdef CURL_DO_LINEEND_CONV
705 /* always convert if we're FTPing in ASCII mode */
706 (data->state.prefer_ascii) ||
707 #endif
708 (data->set.crlf))) {
709 /* Do we need to allocate a scratch buffer? */
710 if(!data->state.scratch) {
711 data->state.scratch = malloc(2 * data->set.upload_buffer_size);
712 if(!data->state.scratch) {
713 failf(data, "Failed to alloc scratch buffer");
714
715 return CURLE_OUT_OF_MEMORY;
716 }
717 }
718
719 /*
720 * ASCII/EBCDIC Note: This is presumably a text (not binary)
721 * transfer so the data should already be in ASCII.
722 * That means the hex values for ASCII CR (0x0d) & LF (0x0a)
723 * must be used instead of the escape sequences \r & \n.
724 */
725 if(offset)
726 memcpy(data->state.scratch, k->upload_fromhere, offset);
727 for(i = offset, si = offset; i < nread; i++, si++) {
728 if(k->upload_fromhere[i] == 0x0a) {
729 data->state.scratch[si++] = 0x0d;
730 data->state.scratch[si] = 0x0a;
731 if(!data->set.crlf) {
732 /* we're here only because FTP is in ASCII mode...
733 bump infilesize for the LF we just added */
734 if(data->state.infilesize != -1)
735 data->state.infilesize++;
736 }
737 }
738 else
739 data->state.scratch[si] = k->upload_fromhere[i];
740 }
741
742 if(si != nread) {
743 /* only perform the special operation if we really did replace
744 anything */
745 nread = si;
746
747 /* upload from the new (replaced) buffer instead */
748 k->upload_fromhere = data->state.scratch;
749
750 /* set the new amount too */
751 k->upload_present = nread;
752 }
753 }
754
755 #ifndef CURL_DISABLE_SMTP
756 if(conn->handler->protocol & PROTO_FAMILY_SMTP) {
757 result = Curl_smtp_escape_eob(data, nread, offset);
758 if(result)
759 return result;
760 }
761 #endif /* CURL_DISABLE_SMTP */
762 } /* if 0 == k->upload_present or appended to upload buffer */
763 else {
764 /* We have a partial buffer left from a previous "round". Use
765 that instead of reading more data */
766 }
767
768 /* write to socket (send away data) */
769 result = Curl_write(data,
770 conn->writesockfd, /* socket to send to */
771 k->upload_fromhere, /* buffer pointer */
772 k->upload_present, /* buffer size */
773 &bytes_written); /* actually sent */
774 if(result)
775 return result;
776
777 #if defined(_WIN32) && defined(USE_WINSOCK)
778 {
779 struct curltime n = Curl_now();
780 if(Curl_timediff(n, k->last_sndbuf_update) > 1000) {
781 win_update_buffer_size(conn->writesockfd);
782 k->last_sndbuf_update = n;
783 }
784 }
785 #endif
786
787 if(k->pendingheader) {
788 /* parts of what was sent was header */
789 curl_off_t n = CURLMIN(k->pendingheader, bytes_written);
790 /* show the data before we change the pointer upload_fromhere */
791 Curl_debug(data, CURLINFO_HEADER_OUT, k->upload_fromhere, (size_t)n);
792 k->pendingheader -= n;
793 nbody = bytes_written - n; /* size of the written body part */
794 }
795 else
796 nbody = bytes_written;
797
798 if(nbody) {
799 /* show the data before we change the pointer upload_fromhere */
800 Curl_debug(data, CURLINFO_DATA_OUT,
801 &k->upload_fromhere[bytes_written - nbody],
802 (size_t)nbody);
803
804 k->writebytecount += nbody;
805 Curl_pgrsSetUploadCounter(data, k->writebytecount);
806 }
807
808 if((!k->upload_chunky || k->forbidchunk) &&
809 (k->writebytecount == data->state.infilesize)) {
810 /* we have sent all data we were supposed to */
811 k->upload_done = TRUE;
812 infof(data, "We are completely uploaded and fine");
813 }
814
815 if(k->upload_present != bytes_written) {
816 /* we only wrote a part of the buffer (if anything), deal with it! */
817
818 /* store the amount of bytes left in the buffer to write */
819 k->upload_present -= bytes_written;
820
821 /* advance the pointer where to find the buffer when the next send
822 is to happen */
823 k->upload_fromhere += bytes_written;
824 }
825 else {
826 /* we've uploaded that buffer now */
827 result = Curl_get_upload_buffer(data);
828 if(result)
829 return result;
830 k->upload_fromhere = data->state.ulbuf;
831 k->upload_present = 0; /* no more bytes left */
832
833 if(k->upload_done) {
834 result = Curl_done_sending(data, k);
835 if(result)
836 return result;
837 }
838 }
839
840
841 } while(0); /* just to break out from! */
842
843 return CURLE_OK;
844 }
845
select_bits_paused(struct Curl_easy * data,int select_bits)846 static int select_bits_paused(struct Curl_easy *data, int select_bits)
847 {
848 /* See issue #11982: we really need to be careful not to progress
849 * a transfer direction when that direction is paused. Not all parts
850 * of our state machine are handling PAUSED transfers correctly. So, we
851 * do not want to go there.
852 * NOTE: we are only interested in PAUSE, not HOLD. */
853
854 /* if there is data in a direction not paused, return false */
855 if(((select_bits & CURL_CSELECT_IN) &&
856 !(data->req.keepon & KEEP_RECV_PAUSE)) ||
857 ((select_bits & CURL_CSELECT_OUT) &&
858 !(data->req.keepon & KEEP_SEND_PAUSE)))
859 return FALSE;
860
861 return (data->req.keepon & (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE));
862 }
863
864 /*
865 * Curl_readwrite() is the low-level function to be called when data is to
866 * be read and written to/from the connection.
867 */
Curl_readwrite(struct Curl_easy * data,bool * done)868 CURLcode Curl_readwrite(struct Curl_easy *data,
869 bool *done)
870 {
871 struct connectdata *conn = data->conn;
872 struct SingleRequest *k = &data->req;
873 CURLcode result;
874 struct curltime now;
875 int didwhat = 0;
876 int select_bits;
877
878 if(data->state.select_bits) {
879 if(select_bits_paused(data, data->state.select_bits)) {
880 /* leave the bits unchanged, so they'll tell us what to do when
881 * this transfer gets unpaused. */
882 DEBUGF(infof(data, "readwrite, select_bits, early return on PAUSED"));
883 result = CURLE_OK;
884 goto out;
885 }
886 select_bits = data->state.select_bits;
887 data->state.select_bits = 0;
888 }
889 else {
890 curl_socket_t fd_read;
891 curl_socket_t fd_write;
892 /* only use the proper socket if the *_HOLD bit is not set simultaneously
893 as then we are in rate limiting state in that transfer direction */
894 if((k->keepon & KEEP_RECVBITS) == KEEP_RECV)
895 fd_read = conn->sockfd;
896 else
897 fd_read = CURL_SOCKET_BAD;
898
899 if((k->keepon & KEEP_SENDBITS) == KEEP_SEND)
900 fd_write = conn->writesockfd;
901 else
902 fd_write = CURL_SOCKET_BAD;
903
904 select_bits = Curl_socket_check(fd_read, CURL_SOCKET_BAD, fd_write, 0);
905 }
906
907 if(select_bits == CURL_CSELECT_ERR) {
908 failf(data, "select/poll returned error");
909 result = CURLE_SEND_ERROR;
910 goto out;
911 }
912
913 #ifdef USE_HYPER
914 if(conn->datastream) {
915 result = conn->datastream(data, conn, &didwhat, done, select_bits);
916 if(result || *done)
917 goto out;
918 }
919 else {
920 #endif
921 /* We go ahead and do a read if we have a readable socket or if
922 the stream was rewound (in which case we have data in a
923 buffer) */
924 if((k->keepon & KEEP_RECV) && (select_bits & CURL_CSELECT_IN)) {
925 result = readwrite_data(data, k, &didwhat, done);
926 if(result || *done)
927 goto out;
928 }
929
930 /* If we still have writing to do, we check if we have a writable socket. */
931 if((k->keepon & KEEP_SEND) && (select_bits & CURL_CSELECT_OUT)) {
932 /* write */
933
934 result = readwrite_upload(data, conn, &didwhat);
935 if(result)
936 goto out;
937 }
938 #ifdef USE_HYPER
939 }
940 #endif
941
942 now = Curl_now();
943 if(!didwhat) {
944 /* no read no write, this is a timeout? */
945 if(k->exp100 == EXP100_AWAITING_CONTINUE) {
946 /* This should allow some time for the header to arrive, but only a
947 very short time as otherwise it'll be too much wasted time too
948 often. */
949
950 /* Quoting RFC2616, section "8.2.3 Use of the 100 (Continue) Status":
951
952 Therefore, when a client sends this header field to an origin server
953 (possibly via a proxy) from which it has never seen a 100 (Continue)
954 status, the client SHOULD NOT wait for an indefinite period before
955 sending the request body.
956
957 */
958
959 timediff_t ms = Curl_timediff(now, k->start100);
960 if(ms >= data->set.expect_100_timeout) {
961 /* we've waited long enough, continue anyway */
962 k->exp100 = EXP100_SEND_DATA;
963 k->keepon |= KEEP_SEND;
964 Curl_expire_done(data, EXPIRE_100_TIMEOUT);
965 infof(data, "Done waiting for 100-continue");
966 }
967 }
968
969 result = Curl_conn_ev_data_idle(data);
970 if(result)
971 goto out;
972 }
973
974 if(Curl_pgrsUpdate(data))
975 result = CURLE_ABORTED_BY_CALLBACK;
976 else
977 result = Curl_speedcheck(data, now);
978 if(result)
979 goto out;
980
981 if(k->keepon) {
982 if(0 > Curl_timeleft(data, &now, FALSE)) {
983 if(k->size != -1) {
984 failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T
985 " milliseconds with %" CURL_FORMAT_CURL_OFF_T " out of %"
986 CURL_FORMAT_CURL_OFF_T " bytes received",
987 Curl_timediff(now, data->progress.t_startsingle),
988 k->bytecount, k->size);
989 }
990 else {
991 failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T
992 " milliseconds with %" CURL_FORMAT_CURL_OFF_T " bytes received",
993 Curl_timediff(now, data->progress.t_startsingle),
994 k->bytecount);
995 }
996 result = CURLE_OPERATION_TIMEDOUT;
997 goto out;
998 }
999 }
1000 else {
1001 /*
1002 * The transfer has been performed. Just make some general checks before
1003 * returning.
1004 */
1005
1006 if(!(data->req.no_body) && (k->size != -1) &&
1007 (k->bytecount != k->size) &&
1008 #ifdef CURL_DO_LINEEND_CONV
1009 /* Most FTP servers don't adjust their file SIZE response for CRLFs,
1010 so we'll check to see if the discrepancy can be explained
1011 by the number of CRLFs we've changed to LFs.
1012 */
1013 (k->bytecount != (k->size + data->state.crlf_conversions)) &&
1014 #endif /* CURL_DO_LINEEND_CONV */
1015 !k->newurl) {
1016 failf(data, "transfer closed with %" CURL_FORMAT_CURL_OFF_T
1017 " bytes remaining to read", k->size - k->bytecount);
1018 result = CURLE_PARTIAL_FILE;
1019 goto out;
1020 }
1021 if(Curl_pgrsUpdate(data)) {
1022 result = CURLE_ABORTED_BY_CALLBACK;
1023 goto out;
1024 }
1025 }
1026
1027 /* Now update the "done" boolean we return */
1028 *done = (0 == (k->keepon&(KEEP_RECVBITS|KEEP_SENDBITS))) ? TRUE : FALSE;
1029 out:
1030 if(result)
1031 DEBUGF(infof(data, "Curl_readwrite() -> %d", result));
1032 return result;
1033 }
1034
1035 /* Curl_init_CONNECT() gets called each time the handle switches to CONNECT
1036 which means this gets called once for each subsequent redirect etc */
Curl_init_CONNECT(struct Curl_easy * data)1037 void Curl_init_CONNECT(struct Curl_easy *data)
1038 {
1039 data->state.fread_func = data->set.fread_func_set;
1040 data->state.in = data->set.in_set;
1041 data->state.upload = (data->state.httpreq == HTTPREQ_PUT);
1042 }
1043
1044 /*
1045 * Curl_pretransfer() is called immediately before a transfer starts, and only
1046 * once for one transfer no matter if it has redirects or do multi-pass
1047 * authentication etc.
1048 */
Curl_pretransfer(struct Curl_easy * data)1049 CURLcode Curl_pretransfer(struct Curl_easy *data)
1050 {
1051 CURLcode result;
1052
1053 if(!data->state.url && !data->set.uh) {
1054 /* we can't do anything without URL */
1055 failf(data, "No URL set");
1056 return CURLE_URL_MALFORMAT;
1057 }
1058
1059 /* since the URL may have been redirected in a previous use of this handle */
1060 if(data->state.url_alloc) {
1061 /* the already set URL is allocated, free it first! */
1062 Curl_safefree(data->state.url);
1063 data->state.url_alloc = FALSE;
1064 }
1065
1066 if(!data->state.url && data->set.uh) {
1067 CURLUcode uc;
1068 free(data->set.str[STRING_SET_URL]);
1069 uc = curl_url_get(data->set.uh,
1070 CURLUPART_URL, &data->set.str[STRING_SET_URL], 0);
1071 if(uc) {
1072 failf(data, "No URL set");
1073 return CURLE_URL_MALFORMAT;
1074 }
1075 }
1076
1077 if(data->set.postfields && data->set.set_resume_from) {
1078 /* we can't */
1079 failf(data, "cannot mix POSTFIELDS with RESUME_FROM");
1080 return CURLE_BAD_FUNCTION_ARGUMENT;
1081 }
1082
1083 data->state.prefer_ascii = data->set.prefer_ascii;
1084 #ifdef CURL_LIST_ONLY_PROTOCOL
1085 data->state.list_only = data->set.list_only;
1086 #endif
1087 data->state.httpreq = data->set.method;
1088 data->state.url = data->set.str[STRING_SET_URL];
1089
1090 /* Init the SSL session ID cache here. We do it here since we want to do it
1091 after the *_setopt() calls (that could specify the size of the cache) but
1092 before any transfer takes place. */
1093 result = Curl_ssl_initsessions(data, data->set.general_ssl.max_ssl_sessions);
1094 if(result)
1095 return result;
1096
1097 data->state.requests = 0;
1098 data->state.followlocation = 0; /* reset the location-follow counter */
1099 data->state.this_is_a_follow = FALSE; /* reset this */
1100 data->state.errorbuf = FALSE; /* no error has occurred */
1101 data->state.httpwant = data->set.httpwant;
1102 data->state.httpversion = 0;
1103 data->state.authproblem = FALSE;
1104 data->state.authhost.want = data->set.httpauth;
1105 data->state.authproxy.want = data->set.proxyauth;
1106 Curl_safefree(data->info.wouldredirect);
1107 Curl_data_priority_clear_state(data);
1108
1109 if(data->state.httpreq == HTTPREQ_PUT)
1110 data->state.infilesize = data->set.filesize;
1111 else if((data->state.httpreq != HTTPREQ_GET) &&
1112 (data->state.httpreq != HTTPREQ_HEAD)) {
1113 data->state.infilesize = data->set.postfieldsize;
1114 if(data->set.postfields && (data->state.infilesize == -1))
1115 data->state.infilesize = (curl_off_t)strlen(data->set.postfields);
1116 }
1117 else
1118 data->state.infilesize = 0;
1119
1120 /* If there is a list of cookie files to read, do it now! */
1121 Curl_cookie_loadfiles(data);
1122
1123 /* If there is a list of host pairs to deal with */
1124 if(data->state.resolve)
1125 result = Curl_loadhostpairs(data);
1126
1127 /* If there is a list of hsts files to read */
1128 Curl_hsts_loadfiles(data);
1129
1130 if(!result) {
1131 /* Allow data->set.use_port to set which port to use. This needs to be
1132 * disabled for example when we follow Location: headers to URLs using
1133 * different ports! */
1134 data->state.allow_port = TRUE;
1135
1136 #if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(HAVE_MSG_NOSIGNAL)
1137 /*************************************************************
1138 * Tell signal handler to ignore SIGPIPE
1139 *************************************************************/
1140 if(!data->set.no_signal)
1141 data->state.prev_signal = signal(SIGPIPE, SIG_IGN);
1142 #endif
1143
1144 Curl_initinfo(data); /* reset session-specific information "variables" */
1145 Curl_pgrsResetTransferSizes(data);
1146 Curl_pgrsStartNow(data);
1147
1148 /* In case the handle is reused and an authentication method was picked
1149 in the session we need to make sure we only use the one(s) we now
1150 consider to be fine */
1151 data->state.authhost.picked &= data->state.authhost.want;
1152 data->state.authproxy.picked &= data->state.authproxy.want;
1153
1154 #ifndef CURL_DISABLE_FTP
1155 data->state.wildcardmatch = data->set.wildcard_enabled;
1156 if(data->state.wildcardmatch) {
1157 struct WildcardData *wc;
1158 if(!data->wildcard) {
1159 data->wildcard = calloc(1, sizeof(struct WildcardData));
1160 if(!data->wildcard)
1161 return CURLE_OUT_OF_MEMORY;
1162 }
1163 wc = data->wildcard;
1164 if(wc->state < CURLWC_INIT) {
1165 if(wc->ftpwc)
1166 wc->dtor(wc->ftpwc);
1167 Curl_safefree(wc->pattern);
1168 Curl_safefree(wc->path);
1169 result = Curl_wildcard_init(wc); /* init wildcard structures */
1170 if(result)
1171 return CURLE_OUT_OF_MEMORY;
1172 }
1173 }
1174 #endif
1175 result = Curl_hsts_loadcb(data, data->hsts);
1176 }
1177
1178 /*
1179 * Set user-agent. Used for HTTP, but since we can attempt to tunnel
1180 * basically anything through an HTTP proxy we can't limit this based on
1181 * protocol.
1182 */
1183 if(data->set.str[STRING_USERAGENT]) {
1184 Curl_safefree(data->state.aptr.uagent);
1185 data->state.aptr.uagent =
1186 aprintf("User-Agent: %s\r\n", data->set.str[STRING_USERAGENT]);
1187 if(!data->state.aptr.uagent)
1188 return CURLE_OUT_OF_MEMORY;
1189 }
1190
1191 if(!result)
1192 result = Curl_setstropt(&data->state.aptr.user,
1193 data->set.str[STRING_USERNAME]);
1194 if(!result)
1195 result = Curl_setstropt(&data->state.aptr.passwd,
1196 data->set.str[STRING_PASSWORD]);
1197 if(!result)
1198 result = Curl_setstropt(&data->state.aptr.proxyuser,
1199 data->set.str[STRING_PROXYUSERNAME]);
1200 if(!result)
1201 result = Curl_setstropt(&data->state.aptr.proxypasswd,
1202 data->set.str[STRING_PROXYPASSWORD]);
1203
1204 data->req.headerbytecount = 0;
1205 Curl_headers_cleanup(data);
1206 return result;
1207 }
1208
1209 /*
1210 * Curl_posttransfer() is called immediately after a transfer ends
1211 */
Curl_posttransfer(struct Curl_easy * data)1212 CURLcode Curl_posttransfer(struct Curl_easy *data)
1213 {
1214 #if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(HAVE_MSG_NOSIGNAL)
1215 /* restore the signal handler for SIGPIPE before we get back */
1216 if(!data->set.no_signal)
1217 signal(SIGPIPE, data->state.prev_signal);
1218 #else
1219 (void)data; /* unused parameter */
1220 #endif
1221
1222 return CURLE_OK;
1223 }
1224
1225 /*
1226 * Curl_follow() handles the URL redirect magic. Pass in the 'newurl' string
1227 * as given by the remote server and set up the new URL to request.
1228 *
1229 * This function DOES NOT FREE the given url.
1230 */
Curl_follow(struct Curl_easy * data,char * newurl,followtype type)1231 CURLcode Curl_follow(struct Curl_easy *data,
1232 char *newurl, /* the Location: string */
1233 followtype type) /* see transfer.h */
1234 {
1235 #ifdef CURL_DISABLE_HTTP
1236 (void)data;
1237 (void)newurl;
1238 (void)type;
1239 /* Location: following will not happen when HTTP is disabled */
1240 return CURLE_TOO_MANY_REDIRECTS;
1241 #else
1242
1243 /* Location: redirect */
1244 bool disallowport = FALSE;
1245 bool reachedmax = FALSE;
1246 CURLUcode uc;
1247
1248 DEBUGASSERT(type != FOLLOW_NONE);
1249
1250 if(type != FOLLOW_FAKE)
1251 data->state.requests++; /* count all real follows */
1252 if(type == FOLLOW_REDIR) {
1253 if((data->set.maxredirs != -1) &&
1254 (data->state.followlocation >= data->set.maxredirs)) {
1255 reachedmax = TRUE;
1256 type = FOLLOW_FAKE; /* switch to fake to store the would-be-redirected
1257 to URL */
1258 }
1259 else {
1260 data->state.followlocation++; /* count redirect-followings, including
1261 auth reloads */
1262
1263 if(data->set.http_auto_referer) {
1264 CURLU *u;
1265 char *referer = NULL;
1266
1267 /* We are asked to automatically set the previous URL as the referer
1268 when we get the next URL. We pick the ->url field, which may or may
1269 not be 100% correct */
1270
1271 if(data->state.referer_alloc) {
1272 Curl_safefree(data->state.referer);
1273 data->state.referer_alloc = FALSE;
1274 }
1275
1276 /* Make a copy of the URL without credentials and fragment */
1277 u = curl_url();
1278 if(!u)
1279 return CURLE_OUT_OF_MEMORY;
1280
1281 uc = curl_url_set(u, CURLUPART_URL, data->state.url, 0);
1282 if(!uc)
1283 uc = curl_url_set(u, CURLUPART_FRAGMENT, NULL, 0);
1284 if(!uc)
1285 uc = curl_url_set(u, CURLUPART_USER, NULL, 0);
1286 if(!uc)
1287 uc = curl_url_set(u, CURLUPART_PASSWORD, NULL, 0);
1288 if(!uc)
1289 uc = curl_url_get(u, CURLUPART_URL, &referer, 0);
1290
1291 curl_url_cleanup(u);
1292
1293 if(uc || !referer)
1294 return CURLE_OUT_OF_MEMORY;
1295
1296 data->state.referer = referer;
1297 data->state.referer_alloc = TRUE; /* yes, free this later */
1298 }
1299 }
1300 }
1301
1302 if((type != FOLLOW_RETRY) &&
1303 (data->req.httpcode != 401) && (data->req.httpcode != 407) &&
1304 Curl_is_absolute_url(newurl, NULL, 0, FALSE)) {
1305 /* If this is not redirect due to a 401 or 407 response and an absolute
1306 URL: don't allow a custom port number */
1307 disallowport = TRUE;
1308 }
1309
1310 DEBUGASSERT(data->state.uh);
1311 uc = curl_url_set(data->state.uh, CURLUPART_URL, newurl,
1312 (type == FOLLOW_FAKE) ? CURLU_NON_SUPPORT_SCHEME :
1313 ((type == FOLLOW_REDIR) ? CURLU_URLENCODE : 0) |
1314 CURLU_ALLOW_SPACE |
1315 (data->set.path_as_is ? CURLU_PATH_AS_IS : 0));
1316 if(uc) {
1317 if(type != FOLLOW_FAKE) {
1318 failf(data, "The redirect target URL could not be parsed: %s",
1319 curl_url_strerror(uc));
1320 return Curl_uc_to_curlcode(uc);
1321 }
1322
1323 /* the URL could not be parsed for some reason, but since this is FAKE
1324 mode, just duplicate the field as-is */
1325 newurl = strdup(newurl);
1326 if(!newurl)
1327 return CURLE_OUT_OF_MEMORY;
1328 }
1329 else {
1330 uc = curl_url_get(data->state.uh, CURLUPART_URL, &newurl, 0);
1331 if(uc)
1332 return Curl_uc_to_curlcode(uc);
1333
1334 /* Clear auth if this redirects to a different port number or protocol,
1335 unless permitted */
1336 if(!data->set.allow_auth_to_other_hosts && (type != FOLLOW_FAKE)) {
1337 char *portnum;
1338 int port;
1339 bool clear = FALSE;
1340
1341 if(data->set.use_port && data->state.allow_port)
1342 /* a custom port is used */
1343 port = (int)data->set.use_port;
1344 else {
1345 uc = curl_url_get(data->state.uh, CURLUPART_PORT, &portnum,
1346 CURLU_DEFAULT_PORT);
1347 if(uc) {
1348 free(newurl);
1349 return Curl_uc_to_curlcode(uc);
1350 }
1351 port = atoi(portnum);
1352 free(portnum);
1353 }
1354 if(port != data->info.conn_remote_port) {
1355 infof(data, "Clear auth, redirects to port from %u to %u",
1356 data->info.conn_remote_port, port);
1357 clear = TRUE;
1358 }
1359 else {
1360 char *scheme;
1361 const struct Curl_handler *p;
1362 uc = curl_url_get(data->state.uh, CURLUPART_SCHEME, &scheme, 0);
1363 if(uc) {
1364 free(newurl);
1365 return Curl_uc_to_curlcode(uc);
1366 }
1367
1368 p = Curl_get_scheme_handler(scheme);
1369 if(p && (p->protocol != data->info.conn_protocol)) {
1370 infof(data, "Clear auth, redirects scheme from %s to %s",
1371 data->info.conn_scheme, scheme);
1372 clear = TRUE;
1373 }
1374 free(scheme);
1375 }
1376 if(clear) {
1377 Curl_safefree(data->state.aptr.user);
1378 Curl_safefree(data->state.aptr.passwd);
1379 }
1380 }
1381 }
1382
1383 if(type == FOLLOW_FAKE) {
1384 /* we're only figuring out the new url if we would've followed locations
1385 but now we're done so we can get out! */
1386 data->info.wouldredirect = newurl;
1387
1388 if(reachedmax) {
1389 failf(data, "Maximum (%ld) redirects followed", data->set.maxredirs);
1390 return CURLE_TOO_MANY_REDIRECTS;
1391 }
1392 return CURLE_OK;
1393 }
1394
1395 if(disallowport)
1396 data->state.allow_port = FALSE;
1397
1398 if(data->state.url_alloc)
1399 Curl_safefree(data->state.url);
1400
1401 data->state.url = newurl;
1402 data->state.url_alloc = TRUE;
1403
1404 infof(data, "Issue another request to this URL: '%s'", data->state.url);
1405
1406 /*
1407 * We get here when the HTTP code is 300-399 (and 401). We need to perform
1408 * differently based on exactly what return code there was.
1409 *
1410 * News from 7.10.6: we can also get here on a 401 or 407, in case we act on
1411 * an HTTP (proxy-) authentication scheme other than Basic.
1412 */
1413 switch(data->info.httpcode) {
1414 /* 401 - Act on a WWW-Authenticate, we keep on moving and do the
1415 Authorization: XXXX header in the HTTP request code snippet */
1416 /* 407 - Act on a Proxy-Authenticate, we keep on moving and do the
1417 Proxy-Authorization: XXXX header in the HTTP request code snippet */
1418 /* 300 - Multiple Choices */
1419 /* 306 - Not used */
1420 /* 307 - Temporary Redirect */
1421 default: /* for all above (and the unknown ones) */
1422 /* Some codes are explicitly mentioned since I've checked RFC2616 and they
1423 * seem to be OK to POST to.
1424 */
1425 break;
1426 case 301: /* Moved Permanently */
1427 /* (quote from RFC7231, section 6.4.2)
1428 *
1429 * Note: For historical reasons, a user agent MAY change the request
1430 * method from POST to GET for the subsequent request. If this
1431 * behavior is undesired, the 307 (Temporary Redirect) status code
1432 * can be used instead.
1433 *
1434 * ----
1435 *
1436 * Many webservers expect this, so these servers often answers to a POST
1437 * request with an error page. To be sure that libcurl gets the page that
1438 * most user agents would get, libcurl has to force GET.
1439 *
1440 * This behavior is forbidden by RFC1945 and the obsolete RFC2616, and
1441 * can be overridden with CURLOPT_POSTREDIR.
1442 */
1443 if((data->state.httpreq == HTTPREQ_POST
1444 || data->state.httpreq == HTTPREQ_POST_FORM
1445 || data->state.httpreq == HTTPREQ_POST_MIME)
1446 && !(data->set.keep_post & CURL_REDIR_POST_301)) {
1447 infof(data, "Switch from POST to GET");
1448 data->state.httpreq = HTTPREQ_GET;
1449 }
1450 break;
1451 case 302: /* Found */
1452 /* (quote from RFC7231, section 6.4.3)
1453 *
1454 * Note: For historical reasons, a user agent MAY change the request
1455 * method from POST to GET for the subsequent request. If this
1456 * behavior is undesired, the 307 (Temporary Redirect) status code
1457 * can be used instead.
1458 *
1459 * ----
1460 *
1461 * Many webservers expect this, so these servers often answers to a POST
1462 * request with an error page. To be sure that libcurl gets the page that
1463 * most user agents would get, libcurl has to force GET.
1464 *
1465 * This behavior is forbidden by RFC1945 and the obsolete RFC2616, and
1466 * can be overridden with CURLOPT_POSTREDIR.
1467 */
1468 if((data->state.httpreq == HTTPREQ_POST
1469 || data->state.httpreq == HTTPREQ_POST_FORM
1470 || data->state.httpreq == HTTPREQ_POST_MIME)
1471 && !(data->set.keep_post & CURL_REDIR_POST_302)) {
1472 infof(data, "Switch from POST to GET");
1473 data->state.httpreq = HTTPREQ_GET;
1474 }
1475 break;
1476
1477 case 303: /* See Other */
1478 /* 'See Other' location is not the resource but a substitute for the
1479 * resource. In this case we switch the method to GET/HEAD, unless the
1480 * method is POST and the user specified to keep it as POST.
1481 * https://github.com/curl/curl/issues/5237#issuecomment-614641049
1482 */
1483 if(data->state.httpreq != HTTPREQ_GET &&
1484 ((data->state.httpreq != HTTPREQ_POST &&
1485 data->state.httpreq != HTTPREQ_POST_FORM &&
1486 data->state.httpreq != HTTPREQ_POST_MIME) ||
1487 !(data->set.keep_post & CURL_REDIR_POST_303))) {
1488 data->state.httpreq = HTTPREQ_GET;
1489 infof(data, "Switch to %s",
1490 data->req.no_body?"HEAD":"GET");
1491 }
1492 break;
1493 case 304: /* Not Modified */
1494 /* 304 means we did a conditional request and it was "Not modified".
1495 * We shouldn't get any Location: header in this response!
1496 */
1497 break;
1498 case 305: /* Use Proxy */
1499 /* (quote from RFC2616, section 10.3.6):
1500 * "The requested resource MUST be accessed through the proxy given
1501 * by the Location field. The Location field gives the URI of the
1502 * proxy. The recipient is expected to repeat this single request
1503 * via the proxy. 305 responses MUST only be generated by origin
1504 * servers."
1505 */
1506 break;
1507 }
1508 Curl_pgrsTime(data, TIMER_REDIRECT);
1509 Curl_pgrsResetTransferSizes(data);
1510
1511 return CURLE_OK;
1512 #endif /* CURL_DISABLE_HTTP */
1513 }
1514
1515 /* Returns CURLE_OK *and* sets '*url' if a request retry is wanted.
1516
1517 NOTE: that the *url is malloc()ed. */
Curl_retry_request(struct Curl_easy * data,char ** url)1518 CURLcode Curl_retry_request(struct Curl_easy *data, char **url)
1519 {
1520 struct connectdata *conn = data->conn;
1521 bool retry = FALSE;
1522 *url = NULL;
1523
1524 /* if we're talking upload, we can't do the checks below, unless the protocol
1525 is HTTP as when uploading over HTTP we will still get a response */
1526 if(data->state.upload &&
1527 !(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)))
1528 return CURLE_OK;
1529
1530 if((data->req.bytecount + data->req.headerbytecount == 0) &&
1531 conn->bits.reuse &&
1532 (!data->req.no_body || (conn->handler->protocol & PROTO_FAMILY_HTTP))
1533 #ifndef CURL_DISABLE_RTSP
1534 && (data->set.rtspreq != RTSPREQ_RECEIVE)
1535 #endif
1536 )
1537 /* We got no data, we attempted to reuse a connection. For HTTP this
1538 can be a retry so we try again regardless if we expected a body.
1539 For other protocols we only try again only if we expected a body.
1540
1541 This might happen if the connection was left alive when we were
1542 done using it before, but that was closed when we wanted to read from
1543 it again. Bad luck. Retry the same request on a fresh connect! */
1544 retry = TRUE;
1545 else if(data->state.refused_stream &&
1546 (data->req.bytecount + data->req.headerbytecount == 0) ) {
1547 /* This was sent on a refused stream, safe to rerun. A refused stream
1548 error can typically only happen on HTTP/2 level if the stream is safe
1549 to issue again, but the nghttp2 API can deliver the message to other
1550 streams as well, which is why this adds the check the data counters
1551 too. */
1552 infof(data, "REFUSED_STREAM, retrying a fresh connect");
1553 data->state.refused_stream = FALSE; /* clear again */
1554 retry = TRUE;
1555 }
1556 if(retry) {
1557 #define CONN_MAX_RETRIES 5
1558 if(data->state.retrycount++ >= CONN_MAX_RETRIES) {
1559 failf(data, "Connection died, tried %d times before giving up",
1560 CONN_MAX_RETRIES);
1561 data->state.retrycount = 0;
1562 return CURLE_SEND_ERROR;
1563 }
1564 infof(data, "Connection died, retrying a fresh connect (retry count: %d)",
1565 data->state.retrycount);
1566 *url = strdup(data->state.url);
1567 if(!*url)
1568 return CURLE_OUT_OF_MEMORY;
1569
1570 connclose(conn, "retry"); /* close this connection */
1571 conn->bits.retry = TRUE; /* mark this as a connection we're about
1572 to retry. Marking it this way should
1573 prevent i.e HTTP transfers to return
1574 error just because nothing has been
1575 transferred! */
1576
1577
1578 if((conn->handler->protocol&PROTO_FAMILY_HTTP) &&
1579 data->req.writebytecount) {
1580 data->state.rewindbeforesend = TRUE;
1581 infof(data, "state.rewindbeforesend = TRUE");
1582 }
1583 }
1584 return CURLE_OK;
1585 }
1586
1587 /*
1588 * Curl_setup_transfer() is called to setup some basic properties for the
1589 * upcoming transfer.
1590 */
1591 void
Curl_setup_transfer(struct Curl_easy * data,int sockindex,curl_off_t size,bool getheader,int writesockindex)1592 Curl_setup_transfer(
1593 struct Curl_easy *data, /* transfer */
1594 int sockindex, /* socket index to read from or -1 */
1595 curl_off_t size, /* -1 if unknown at this point */
1596 bool getheader, /* TRUE if header parsing is wanted */
1597 int writesockindex /* socket index to write to, it may very well be
1598 the same we read from. -1 disables */
1599 )
1600 {
1601 struct SingleRequest *k = &data->req;
1602 struct connectdata *conn = data->conn;
1603 struct HTTP *http = data->req.p.http;
1604 bool httpsending;
1605
1606 DEBUGASSERT(conn != NULL);
1607 DEBUGASSERT((sockindex <= 1) && (sockindex >= -1));
1608
1609 httpsending = ((conn->handler->protocol&PROTO_FAMILY_HTTP) &&
1610 (http->sending == HTTPSEND_REQUEST));
1611
1612 if(conn->bits.multiplex || conn->httpversion >= 20 || httpsending) {
1613 /* when multiplexing, the read/write sockets need to be the same! */
1614 conn->sockfd = sockindex == -1 ?
1615 ((writesockindex == -1 ? CURL_SOCKET_BAD : conn->sock[writesockindex])) :
1616 conn->sock[sockindex];
1617 conn->writesockfd = conn->sockfd;
1618 if(httpsending)
1619 /* special and very HTTP-specific */
1620 writesockindex = FIRSTSOCKET;
1621 }
1622 else {
1623 conn->sockfd = sockindex == -1 ?
1624 CURL_SOCKET_BAD : conn->sock[sockindex];
1625 conn->writesockfd = writesockindex == -1 ?
1626 CURL_SOCKET_BAD:conn->sock[writesockindex];
1627 }
1628 k->getheader = getheader;
1629
1630 k->size = size;
1631
1632 /* The code sequence below is placed in this function just because all
1633 necessary input is not always known in do_complete() as this function may
1634 be called after that */
1635
1636 if(!k->getheader) {
1637 k->header = FALSE;
1638 if(size > 0)
1639 Curl_pgrsSetDownloadSize(data, size);
1640 }
1641 /* we want header and/or body, if neither then don't do this! */
1642 if(k->getheader || !data->req.no_body) {
1643
1644 if(sockindex != -1)
1645 k->keepon |= KEEP_RECV;
1646
1647 if(writesockindex != -1) {
1648 /* HTTP 1.1 magic:
1649
1650 Even if we require a 100-return code before uploading data, we might
1651 need to write data before that since the REQUEST may not have been
1652 finished sent off just yet.
1653
1654 Thus, we must check if the request has been sent before we set the
1655 state info where we wait for the 100-return code
1656 */
1657 if((data->state.expect100header) &&
1658 (conn->handler->protocol&PROTO_FAMILY_HTTP) &&
1659 (http->sending == HTTPSEND_BODY)) {
1660 /* wait with write until we either got 100-continue or a timeout */
1661 k->exp100 = EXP100_AWAITING_CONTINUE;
1662 k->start100 = Curl_now();
1663
1664 /* Set a timeout for the multi interface. Add the inaccuracy margin so
1665 that we don't fire slightly too early and get denied to run. */
1666 Curl_expire(data, data->set.expect_100_timeout, EXPIRE_100_TIMEOUT);
1667 }
1668 else {
1669 if(data->state.expect100header)
1670 /* when we've sent off the rest of the headers, we must await a
1671 100-continue but first finish sending the request */
1672 k->exp100 = EXP100_SENDING_REQUEST;
1673
1674 /* enable the write bit when we're not waiting for continue */
1675 k->keepon |= KEEP_SEND;
1676 }
1677 } /* if(writesockindex != -1) */
1678 } /* if(k->getheader || !data->req.no_body) */
1679
1680 }
1681
Curl_xfer_write_resp(struct Curl_easy * data,char * buf,size_t blen,bool is_eos,bool * done)1682 CURLcode Curl_xfer_write_resp(struct Curl_easy *data,
1683 char *buf, size_t blen,
1684 bool is_eos, bool *done)
1685 {
1686 CURLcode result = CURLE_OK;
1687
1688 if(data->conn->handler->write_resp) {
1689 /* protocol handlers offering this function take full responsibility
1690 * for writing all received download data to the client. */
1691 result = data->conn->handler->write_resp(data, buf, blen, is_eos, done);
1692 }
1693 else {
1694 /* No special handling by protocol handler, write all received data
1695 * as BODY to the client. */
1696 if(blen || is_eos) {
1697 int cwtype = CLIENTWRITE_BODY;
1698 if(is_eos)
1699 cwtype |= CLIENTWRITE_EOS;
1700
1701 #ifndef CURL_DISABLE_POP3
1702 if(blen && data->conn->handler->protocol & PROTO_FAMILY_POP3) {
1703 result = data->req.ignorebody? CURLE_OK :
1704 Curl_pop3_write(data, buf, blen);
1705 }
1706 else
1707 #endif /* CURL_DISABLE_POP3 */
1708 result = Curl_client_write(data, cwtype, buf, blen);
1709 }
1710 }
1711
1712 if(!result && is_eos) {
1713 /* If we wrote the EOS, we are definitely done */
1714 data->req.eos_written = TRUE;
1715 data->req.download_done = TRUE;
1716 }
1717 return result;
1718 }
1719