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 #ifdef HAVE_NETINET_IN_H
26 #include <netinet/in.h>
27 #endif
28 #ifdef HAVE_NETDB_H
29 #include <netdb.h>
30 #endif
31 #ifdef HAVE_ARPA_INET_H
32 #include <arpa/inet.h>
33 #endif
34 #ifdef HAVE_NET_IF_H
35 #include <net/if.h>
36 #endif
37 #ifdef HAVE_SYS_IOCTL_H
38 #include <sys/ioctl.h>
39 #endif
40
41 #ifdef HAVE_SYS_PARAM_H
42 #include <sys/param.h>
43 #endif
44
45 #ifdef __VMS
46 #include <in.h>
47 #include <inet.h>
48 #endif
49
50 #ifdef HAVE_SYS_UN_H
51 #include <sys/un.h>
52 #endif
53
54 #ifndef HAVE_SOCKET
55 #error "We can't compile without socket() support!"
56 #endif
57
58 #ifdef HAVE_LIMITS_H
59 #include <limits.h>
60 #endif
61
62 #ifdef USE_LIBIDN
63 #include <idna.h>
64 #include <tld.h>
65 #include <stringprep.h>
66 #ifdef HAVE_IDN_FREE_H
67 #include <idn-free.h>
68 #else
69 /* prototype from idn-free.h, not provided by libidn 0.4.5's make install! */
70 void idn_free (void *ptr);
71 #endif
72 #ifndef HAVE_IDN_FREE
73 /* if idn_free() was not found in this version of libidn use free() instead */
74 #define idn_free(x) (free)(x)
75 #endif
76 #elif defined(USE_WIN32_IDN)
77 /* prototype for curl_win32_idn_to_ascii() */
78 int curl_win32_idn_to_ascii(const char *in, char **out);
79 #endif /* USE_LIBIDN */
80
81 #include "urldata.h"
82 #include "netrc.h"
83
84 #include "formdata.h"
85 #include "vtls/vtls.h"
86 #include "hostip.h"
87 #include "transfer.h"
88 #include "sendf.h"
89 #include "progress.h"
90 #include "cookie.h"
91 #include "strequal.h"
92 #include "strerror.h"
93 #include "escape.h"
94 #include "strtok.h"
95 #include "share.h"
96 #include "content_encoding.h"
97 #include "http_digest.h"
98 #include "http_negotiate.h"
99 #include "select.h"
100 #include "multiif.h"
101 #include "easyif.h"
102 #include "speedcheck.h"
103 #include "rawstr.h"
104 #include "warnless.h"
105 #include "non-ascii.h"
106 #include "inet_pton.h"
107
108 /* And now for the protocols */
109 #include "ftp.h"
110 #include "dict.h"
111 #include "telnet.h"
112 #include "tftp.h"
113 #include "http.h"
114 #include "file.h"
115 #include "curl_ldap.h"
116 #include "ssh.h"
117 #include "imap.h"
118 #include "url.h"
119 #include "connect.h"
120 #include "inet_ntop.h"
121 #include "curl_ntlm.h"
122 #include "curl_ntlm_wb.h"
123 #include "socks.h"
124 #include "curl_rtmp.h"
125 #include "gopher.h"
126 #include "http_proxy.h"
127 #include "conncache.h"
128 #include "multihandle.h"
129 #include "pipeline.h"
130 #include "dotdot.h"
131 #include "strdup.h"
132 #include "curl_printf.h"
133 #include "curl_memory.h"
134 /* The last #include file should be: */
135 #include "memdebug.h"
136
137 /* Local static prototypes */
138 static struct connectdata *
139 find_oldest_idle_connection(struct SessionHandle *data);
140 static struct connectdata *
141 find_oldest_idle_connection_in_bundle(struct SessionHandle *data,
142 struct connectbundle *bundle);
143 static void conn_free(struct connectdata *conn);
144 static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke);
145 static CURLcode do_init(struct connectdata *conn);
146 static CURLcode parse_url_login(struct SessionHandle *data,
147 struct connectdata *conn,
148 char **userptr, char **passwdptr,
149 char **optionsptr);
150 static CURLcode parse_login_details(const char *login, const size_t len,
151 char **userptr, char **passwdptr,
152 char **optionsptr);
153 /*
154 * Protocol table.
155 */
156
157 static const struct Curl_handler * const protocols[] = {
158
159 #ifndef CURL_DISABLE_HTTP
160 &Curl_handler_http,
161 #endif
162
163 #if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)
164 &Curl_handler_https,
165 #endif
166
167 #ifndef CURL_DISABLE_FTP
168 &Curl_handler_ftp,
169 #endif
170
171 #if defined(USE_SSL) && !defined(CURL_DISABLE_FTP)
172 &Curl_handler_ftps,
173 #endif
174
175 #ifndef CURL_DISABLE_TELNET
176 &Curl_handler_telnet,
177 #endif
178
179 #ifndef CURL_DISABLE_DICT
180 &Curl_handler_dict,
181 #endif
182
183 #ifndef CURL_DISABLE_LDAP
184 &Curl_handler_ldap,
185 #if !defined(CURL_DISABLE_LDAPS) && \
186 ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \
187 (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)))
188 &Curl_handler_ldaps,
189 #endif
190 #endif
191
192 #ifndef CURL_DISABLE_FILE
193 &Curl_handler_file,
194 #endif
195
196 #ifndef CURL_DISABLE_TFTP
197 &Curl_handler_tftp,
198 #endif
199
200 #ifdef USE_LIBSSH2
201 &Curl_handler_scp,
202 &Curl_handler_sftp,
203 #endif
204
205 #ifndef CURL_DISABLE_IMAP
206 &Curl_handler_imap,
207 #ifdef USE_SSL
208 &Curl_handler_imaps,
209 #endif
210 #endif
211
212 #ifndef CURL_DISABLE_POP3
213 &Curl_handler_pop3,
214 #ifdef USE_SSL
215 &Curl_handler_pop3s,
216 #endif
217 #endif
218
219 #if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
220 (CURL_SIZEOF_CURL_OFF_T > 4) && \
221 (!defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO))
222 &Curl_handler_smb,
223 #ifdef USE_SSL
224 &Curl_handler_smbs,
225 #endif
226 #endif
227
228 #ifndef CURL_DISABLE_SMTP
229 &Curl_handler_smtp,
230 #ifdef USE_SSL
231 &Curl_handler_smtps,
232 #endif
233 #endif
234
235 #ifndef CURL_DISABLE_RTSP
236 &Curl_handler_rtsp,
237 #endif
238
239 #ifndef CURL_DISABLE_GOPHER
240 &Curl_handler_gopher,
241 #endif
242
243 #ifdef USE_LIBRTMP
244 &Curl_handler_rtmp,
245 &Curl_handler_rtmpt,
246 &Curl_handler_rtmpe,
247 &Curl_handler_rtmpte,
248 &Curl_handler_rtmps,
249 &Curl_handler_rtmpts,
250 #endif
251
252 (struct Curl_handler *) NULL
253 };
254
255 /*
256 * Dummy handler for undefined protocol schemes.
257 */
258
259 static const struct Curl_handler Curl_handler_dummy = {
260 "<no protocol>", /* scheme */
261 ZERO_NULL, /* setup_connection */
262 ZERO_NULL, /* do_it */
263 ZERO_NULL, /* done */
264 ZERO_NULL, /* do_more */
265 ZERO_NULL, /* connect_it */
266 ZERO_NULL, /* connecting */
267 ZERO_NULL, /* doing */
268 ZERO_NULL, /* proto_getsock */
269 ZERO_NULL, /* doing_getsock */
270 ZERO_NULL, /* domore_getsock */
271 ZERO_NULL, /* perform_getsock */
272 ZERO_NULL, /* disconnect */
273 ZERO_NULL, /* readwrite */
274 0, /* defport */
275 0, /* protocol */
276 PROTOPT_NONE /* flags */
277 };
278
Curl_freeset(struct SessionHandle * data)279 void Curl_freeset(struct SessionHandle *data)
280 {
281 /* Free all dynamic strings stored in the data->set substructure. */
282 enum dupstring i;
283 for(i=(enum dupstring)0; i < STRING_LAST; i++) {
284 Curl_safefree(data->set.str[i]);
285 }
286
287 if(data->change.referer_alloc) {
288 Curl_safefree(data->change.referer);
289 data->change.referer_alloc = FALSE;
290 }
291 data->change.referer = NULL;
292 if(data->change.url_alloc) {
293 Curl_safefree(data->change.url);
294 data->change.url_alloc = FALSE;
295 }
296 data->change.url = NULL;
297 }
298
setstropt(char ** charp,char * s)299 static CURLcode setstropt(char **charp, char *s)
300 {
301 /* Release the previous storage at `charp' and replace by a dynamic storage
302 copy of `s'. Return CURLE_OK or CURLE_OUT_OF_MEMORY. */
303
304 Curl_safefree(*charp);
305
306 if(s) {
307 s = strdup(s);
308
309 if(!s)
310 return CURLE_OUT_OF_MEMORY;
311
312 *charp = s;
313 }
314
315 return CURLE_OK;
316 }
317
setstropt_userpwd(char * option,char ** userp,char ** passwdp)318 static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp)
319 {
320 CURLcode result = CURLE_OK;
321 char *user = NULL;
322 char *passwd = NULL;
323
324 /* Parse the login details if specified. It not then we treat NULL as a hint
325 to clear the existing data */
326 if(option) {
327 result = parse_login_details(option, strlen(option),
328 (userp ? &user : NULL),
329 (passwdp ? &passwd : NULL),
330 NULL);
331 }
332
333 if(!result) {
334 /* Store the username part of option if required */
335 if(userp) {
336 if(!user && option && option[0] == ':') {
337 /* Allocate an empty string instead of returning NULL as user name */
338 user = strdup("");
339 if(!user)
340 result = CURLE_OUT_OF_MEMORY;
341 }
342
343 Curl_safefree(*userp);
344 *userp = user;
345 }
346
347 /* Store the password part of option if required */
348 if(passwdp) {
349 Curl_safefree(*passwdp);
350 *passwdp = passwd;
351 }
352 }
353
354 return result;
355 }
356
Curl_dupset(struct SessionHandle * dst,struct SessionHandle * src)357 CURLcode Curl_dupset(struct SessionHandle *dst, struct SessionHandle *src)
358 {
359 CURLcode result = CURLE_OK;
360 enum dupstring i;
361
362 /* Copy src->set into dst->set first, then deal with the strings
363 afterwards */
364 dst->set = src->set;
365
366 /* clear all string pointers first */
367 memset(dst->set.str, 0, STRING_LAST * sizeof(char *));
368
369 /* duplicate all strings */
370 for(i=(enum dupstring)0; i< STRING_LASTZEROTERMINATED; i++) {
371 result = setstropt(&dst->set.str[i], src->set.str[i]);
372 if(result)
373 return result;
374 }
375
376 /* duplicate memory areas pointed to */
377 i = STRING_COPYPOSTFIELDS;
378 if(src->set.postfieldsize && src->set.str[i]) {
379 /* postfieldsize is curl_off_t, Curl_memdup() takes a size_t ... */
380 dst->set.str[i] = Curl_memdup(src->set.str[i],
381 curlx_sotouz(src->set.postfieldsize));
382 if(!dst->set.str[i])
383 return CURLE_OUT_OF_MEMORY;
384 /* point to the new copy */
385 dst->set.postfields = dst->set.str[i];
386 }
387
388 return CURLE_OK;
389 }
390
391 /*
392 * This is the internal function curl_easy_cleanup() calls. This should
393 * cleanup and free all resources associated with this sessionhandle.
394 *
395 * NOTE: if we ever add something that attempts to write to a socket or
396 * similar here, we must ignore SIGPIPE first. It is currently only done
397 * when curl_easy_perform() is invoked.
398 */
399
Curl_close(struct SessionHandle * data)400 CURLcode Curl_close(struct SessionHandle *data)
401 {
402 struct Curl_multi *m;
403
404 if(!data)
405 return CURLE_OK;
406
407 Curl_expire(data, 0); /* shut off timers */
408
409 m = data->multi;
410
411 if(m)
412 /* This handle is still part of a multi handle, take care of this first
413 and detach this handle from there. */
414 curl_multi_remove_handle(data->multi, data);
415
416 if(data->multi_easy)
417 /* when curl_easy_perform() is used, it creates its own multi handle to
418 use and this is the one */
419 curl_multi_cleanup(data->multi_easy);
420
421 /* Destroy the timeout list that is held in the easy handle. It is
422 /normally/ done by curl_multi_remove_handle() but this is "just in
423 case" */
424 if(data->state.timeoutlist) {
425 Curl_llist_destroy(data->state.timeoutlist, NULL);
426 data->state.timeoutlist = NULL;
427 }
428
429 data->magic = 0; /* force a clear AFTER the possibly enforced removal from
430 the multi handle, since that function uses the magic
431 field! */
432
433 if(data->state.rangestringalloc)
434 free(data->state.range);
435
436 /* Free the pathbuffer */
437 Curl_safefree(data->state.pathbuffer);
438 data->state.path = NULL;
439
440 /* freed here just in case DONE wasn't called */
441 Curl_free_request_state(data);
442
443 /* Close down all open SSL info and sessions */
444 Curl_ssl_close_all(data);
445 Curl_safefree(data->state.first_host);
446 Curl_safefree(data->state.scratch);
447 Curl_ssl_free_certinfo(data);
448
449 /* Cleanup possible redirect junk */
450 free(data->req.newurl);
451 data->req.newurl = NULL;
452
453 if(data->change.referer_alloc) {
454 Curl_safefree(data->change.referer);
455 data->change.referer_alloc = FALSE;
456 }
457 data->change.referer = NULL;
458
459 if(data->change.url_alloc) {
460 Curl_safefree(data->change.url);
461 data->change.url_alloc = FALSE;
462 }
463 data->change.url = NULL;
464
465 Curl_safefree(data->state.headerbuff);
466
467 Curl_flush_cookies(data, 1);
468
469 Curl_digest_cleanup(data);
470
471 Curl_safefree(data->info.contenttype);
472 Curl_safefree(data->info.wouldredirect);
473
474 /* this destroys the channel and we cannot use it anymore after this */
475 Curl_resolver_cleanup(data->state.resolver);
476
477 Curl_convert_close(data);
478
479 /* No longer a dirty share, if it exists */
480 if(data->share) {
481 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
482 data->share->dirty--;
483 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
484 }
485
486 Curl_freeset(data);
487 free(data);
488 return CURLE_OK;
489 }
490
491 /*
492 * Initialize the UserDefined fields within a SessionHandle.
493 * This may be safely called on a new or existing SessionHandle.
494 */
Curl_init_userdefined(struct UserDefined * set)495 CURLcode Curl_init_userdefined(struct UserDefined *set)
496 {
497 CURLcode result = CURLE_OK;
498
499 set->out = stdout; /* default output to stdout */
500 set->in = stdin; /* default input from stdin */
501 set->err = stderr; /* default stderr to stderr */
502
503 /* use fwrite as default function to store output */
504 set->fwrite_func = (curl_write_callback)fwrite;
505
506 /* use fread as default function to read input */
507 set->fread_func = (curl_read_callback)fread;
508 set->is_fread_set = 0;
509 set->is_fwrite_set = 0;
510
511 set->seek_func = ZERO_NULL;
512 set->seek_client = ZERO_NULL;
513
514 /* conversion callbacks for non-ASCII hosts */
515 set->convfromnetwork = ZERO_NULL;
516 set->convtonetwork = ZERO_NULL;
517 set->convfromutf8 = ZERO_NULL;
518
519 set->filesize = -1; /* we don't know the size */
520 set->postfieldsize = -1; /* unknown size */
521 set->maxredirs = -1; /* allow any amount by default */
522
523 set->httpreq = HTTPREQ_GET; /* Default HTTP request */
524 set->rtspreq = RTSPREQ_OPTIONS; /* Default RTSP request */
525 set->ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */
526 set->ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */
527 set->ftp_use_pret = FALSE; /* mainly useful for drftpd servers */
528 set->ftp_filemethod = FTPFILE_MULTICWD;
529
530 set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
531
532 /* Set the default size of the SSL session ID cache */
533 set->ssl.max_ssl_sessions = 5;
534
535 set->proxyport = CURL_DEFAULT_PROXY_PORT; /* from url.h */
536 set->proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
537 set->httpauth = CURLAUTH_BASIC; /* defaults to basic */
538 set->proxyauth = CURLAUTH_BASIC; /* defaults to basic */
539
540 /* make libcurl quiet by default: */
541 set->hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */
542
543 /*
544 * libcurl 7.10 introduced SSL verification *by default*! This needs to be
545 * switched off unless wanted.
546 */
547 set->ssl.verifypeer = TRUE;
548 set->ssl.verifyhost = TRUE;
549 #ifdef USE_TLS_SRP
550 set->ssl.authtype = CURL_TLSAUTH_NONE;
551 #endif
552 set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
553 type */
554 set->ssl.sessionid = TRUE; /* session ID caching enabled by default */
555
556 set->new_file_perms = 0644; /* Default permissions */
557 set->new_directory_perms = 0755; /* Default permissions */
558
559 /* for the *protocols fields we don't use the CURLPROTO_ALL convenience
560 define since we internally only use the lower 16 bits for the passed
561 in bitmask to not conflict with the private bits */
562 set->allowed_protocols = CURLPROTO_ALL;
563 set->redir_protocols = CURLPROTO_ALL & /* All except FILE, SCP and SMB */
564 ~(CURLPROTO_FILE | CURLPROTO_SCP | CURLPROTO_SMB |
565 CURLPROTO_SMBS);
566
567 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
568 /*
569 * disallow unprotected protection negotiation NEC reference implementation
570 * seem not to follow rfc1961 section 4.3/4.4
571 */
572 set->socks5_gssapi_nec = FALSE;
573 /* set default GSS-API service name */
574 result = setstropt(&set->str[STRING_SOCKS5_GSSAPI_SERVICE],
575 (char *) CURL_DEFAULT_SOCKS5_GSSAPI_SERVICE);
576 if(result)
577 return result;
578
579 /* set default negotiate proxy service name */
580 result = setstropt(&set->str[STRING_PROXY_SERVICE_NAME],
581 (char *) CURL_DEFAULT_PROXY_SERVICE_NAME);
582 if(result)
583 return result;
584
585 /* set default negotiate service name */
586 result = setstropt(&set->str[STRING_SERVICE_NAME],
587 (char *) CURL_DEFAULT_SERVICE_NAME);
588 if(result)
589 return result;
590 #endif
591
592 /* This is our preferred CA cert bundle/path since install time */
593 #if defined(CURL_CA_BUNDLE)
594 result = setstropt(&set->str[STRING_SSL_CAFILE], (char *) CURL_CA_BUNDLE);
595 if(result)
596 return result;
597 #endif
598 #if defined(CURL_CA_PATH)
599 result = setstropt(&set->str[STRING_SSL_CAPATH], (char *) CURL_CA_PATH);
600 if(result)
601 return result;
602 #endif
603
604 set->wildcardmatch = FALSE;
605 set->chunk_bgn = ZERO_NULL;
606 set->chunk_end = ZERO_NULL;
607
608 /* tcp keepalives are disabled by default, but provide reasonable values for
609 * the interval and idle times.
610 */
611 set->tcp_keepalive = FALSE;
612 set->tcp_keepintvl = 60;
613 set->tcp_keepidle = 60;
614
615 set->ssl_enable_npn = TRUE;
616 set->ssl_enable_alpn = TRUE;
617
618 set->expect_100_timeout = 1000L; /* Wait for a second by default. */
619 set->sep_headers = TRUE; /* separated header lists by default */
620 return result;
621 }
622
623 /**
624 * Curl_open()
625 *
626 * @param curl is a pointer to a sessionhandle pointer that gets set by this
627 * function.
628 * @return CURLcode
629 */
630
Curl_open(struct SessionHandle ** curl)631 CURLcode Curl_open(struct SessionHandle **curl)
632 {
633 CURLcode result;
634 struct SessionHandle *data;
635
636 /* Very simple start-up: alloc the struct, init it with zeroes and return */
637 data = calloc(1, sizeof(struct SessionHandle));
638 if(!data) {
639 /* this is a very serious error */
640 DEBUGF(fprintf(stderr, "Error: calloc of SessionHandle failed\n"));
641 return CURLE_OUT_OF_MEMORY;
642 }
643
644 data->magic = CURLEASY_MAGIC_NUMBER;
645
646 result = Curl_resolver_init(&data->state.resolver);
647 if(result) {
648 DEBUGF(fprintf(stderr, "Error: resolver_init failed\n"));
649 free(data);
650 return result;
651 }
652
653 /* We do some initial setup here, all those fields that can't be just 0 */
654
655 data->state.headerbuff = malloc(HEADERSIZE);
656 if(!data->state.headerbuff) {
657 DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n"));
658 result = CURLE_OUT_OF_MEMORY;
659 }
660 else {
661 result = Curl_init_userdefined(&data->set);
662
663 data->state.headersize=HEADERSIZE;
664
665 Curl_convert_init(data);
666
667 /* most recent connection is not yet defined */
668 data->state.lastconnect = NULL;
669
670 data->progress.flags |= PGRS_HIDE;
671 data->state.current_speed = -1; /* init to negative == impossible */
672
673 data->wildcard.state = CURLWC_INIT;
674 data->wildcard.filelist = NULL;
675 data->set.fnmatch = ZERO_NULL;
676 data->set.maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */
677 }
678
679 if(result) {
680 Curl_resolver_cleanup(data->state.resolver);
681 free(data->state.headerbuff);
682 Curl_freeset(data);
683 free(data);
684 data = NULL;
685 }
686 else
687 *curl = data;
688
689 return result;
690 }
691
Curl_setopt(struct SessionHandle * data,CURLoption option,va_list param)692 CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
693 va_list param)
694 {
695 char *argptr;
696 CURLcode result = CURLE_OK;
697 long arg;
698 #ifndef CURL_DISABLE_HTTP
699 curl_off_t bigsize;
700 #endif
701
702 switch(option) {
703 case CURLOPT_DNS_CACHE_TIMEOUT:
704 data->set.dns_cache_timeout = va_arg(param, long);
705 break;
706 case CURLOPT_DNS_USE_GLOBAL_CACHE:
707 /* remember we want this enabled */
708 arg = va_arg(param, long);
709 data->set.global_dns_cache = (0 != arg)?TRUE:FALSE;
710 break;
711 case CURLOPT_SSL_CIPHER_LIST:
712 /* set a list of cipher we want to use in the SSL connection */
713 result = setstropt(&data->set.str[STRING_SSL_CIPHER_LIST],
714 va_arg(param, char *));
715 break;
716
717 case CURLOPT_RANDOM_FILE:
718 /*
719 * This is the path name to a file that contains random data to seed
720 * the random SSL stuff with. The file is only used for reading.
721 */
722 result = setstropt(&data->set.str[STRING_SSL_RANDOM_FILE],
723 va_arg(param, char *));
724 break;
725 case CURLOPT_EGDSOCKET:
726 /*
727 * The Entropy Gathering Daemon socket pathname
728 */
729 result = setstropt(&data->set.str[STRING_SSL_EGDSOCKET],
730 va_arg(param, char *));
731 break;
732 case CURLOPT_MAXCONNECTS:
733 /*
734 * Set the absolute number of maximum simultaneous alive connection that
735 * libcurl is allowed to have.
736 */
737 data->set.maxconnects = va_arg(param, long);
738 break;
739 case CURLOPT_FORBID_REUSE:
740 /*
741 * When this transfer is done, it must not be left to be reused by a
742 * subsequent transfer but shall be closed immediately.
743 */
744 data->set.reuse_forbid = (0 != va_arg(param, long))?TRUE:FALSE;
745 break;
746 case CURLOPT_FRESH_CONNECT:
747 /*
748 * This transfer shall not use a previously cached connection but
749 * should be made with a fresh new connect!
750 */
751 data->set.reuse_fresh = (0 != va_arg(param, long))?TRUE:FALSE;
752 break;
753 case CURLOPT_VERBOSE:
754 /*
755 * Verbose means infof() calls that give a lot of information about
756 * the connection and transfer procedures as well as internal choices.
757 */
758 data->set.verbose = (0 != va_arg(param, long))?TRUE:FALSE;
759 break;
760 case CURLOPT_HEADER:
761 /*
762 * Set to include the header in the general data output stream.
763 */
764 data->set.include_header = (0 != va_arg(param, long))?TRUE:FALSE;
765 break;
766 case CURLOPT_NOPROGRESS:
767 /*
768 * Shut off the internal supported progress meter
769 */
770 data->set.hide_progress = (0 != va_arg(param, long))?TRUE:FALSE;
771 if(data->set.hide_progress)
772 data->progress.flags |= PGRS_HIDE;
773 else
774 data->progress.flags &= ~PGRS_HIDE;
775 break;
776 case CURLOPT_NOBODY:
777 /*
778 * Do not include the body part in the output data stream.
779 */
780 data->set.opt_no_body = (0 != va_arg(param, long))?TRUE:FALSE;
781 break;
782 case CURLOPT_FAILONERROR:
783 /*
784 * Don't output the >=400 error code HTML-page, but instead only
785 * return error.
786 */
787 data->set.http_fail_on_error = (0 != va_arg(param, long))?TRUE:FALSE;
788 break;
789 case CURLOPT_UPLOAD:
790 case CURLOPT_PUT:
791 /*
792 * We want to sent data to the remote host. If this is HTTP, that equals
793 * using the PUT request.
794 */
795 data->set.upload = (0 != va_arg(param, long))?TRUE:FALSE;
796 if(data->set.upload) {
797 /* If this is HTTP, PUT is what's needed to "upload" */
798 data->set.httpreq = HTTPREQ_PUT;
799 data->set.opt_no_body = FALSE; /* this is implied */
800 }
801 else
802 /* In HTTP, the opposite of upload is GET (unless NOBODY is true as
803 then this can be changed to HEAD later on) */
804 data->set.httpreq = HTTPREQ_GET;
805 break;
806 case CURLOPT_FILETIME:
807 /*
808 * Try to get the file time of the remote document. The time will
809 * later (possibly) become available using curl_easy_getinfo().
810 */
811 data->set.get_filetime = (0 != va_arg(param, long))?TRUE:FALSE;
812 break;
813 case CURLOPT_FTP_CREATE_MISSING_DIRS:
814 /*
815 * An FTP option that modifies an upload to create missing directories on
816 * the server.
817 */
818 switch(va_arg(param, long)) {
819 case 0:
820 data->set.ftp_create_missing_dirs = 0;
821 break;
822 case 1:
823 data->set.ftp_create_missing_dirs = 1;
824 break;
825 case 2:
826 data->set.ftp_create_missing_dirs = 2;
827 break;
828 default:
829 /* reserve other values for future use */
830 result = CURLE_UNKNOWN_OPTION;
831 break;
832 }
833 break;
834 case CURLOPT_SERVER_RESPONSE_TIMEOUT:
835 /*
836 * Option that specifies how quickly an server response must be obtained
837 * before it is considered failure. For pingpong protocols.
838 */
839 data->set.server_response_timeout = va_arg( param , long ) * 1000;
840 break;
841 case CURLOPT_TFTP_BLKSIZE:
842 /*
843 * TFTP option that specifies the block size to use for data transmission
844 */
845 data->set.tftp_blksize = va_arg(param, long);
846 break;
847 case CURLOPT_DIRLISTONLY:
848 /*
849 * An option that changes the command to one that asks for a list
850 * only, no file info details.
851 */
852 data->set.ftp_list_only = (0 != va_arg(param, long))?TRUE:FALSE;
853 break;
854 case CURLOPT_APPEND:
855 /*
856 * We want to upload and append to an existing file.
857 */
858 data->set.ftp_append = (0 != va_arg(param, long))?TRUE:FALSE;
859 break;
860 case CURLOPT_FTP_FILEMETHOD:
861 /*
862 * How do access files over FTP.
863 */
864 data->set.ftp_filemethod = (curl_ftpfile)va_arg(param, long);
865 break;
866 case CURLOPT_NETRC:
867 /*
868 * Parse the $HOME/.netrc file
869 */
870 data->set.use_netrc = (enum CURL_NETRC_OPTION)va_arg(param, long);
871 break;
872 case CURLOPT_NETRC_FILE:
873 /*
874 * Use this file instead of the $HOME/.netrc file
875 */
876 result = setstropt(&data->set.str[STRING_NETRC_FILE],
877 va_arg(param, char *));
878 break;
879 case CURLOPT_TRANSFERTEXT:
880 /*
881 * This option was previously named 'FTPASCII'. Renamed to work with
882 * more protocols than merely FTP.
883 *
884 * Transfer using ASCII (instead of BINARY).
885 */
886 data->set.prefer_ascii = (0 != va_arg(param, long))?TRUE:FALSE;
887 break;
888 case CURLOPT_TIMECONDITION:
889 /*
890 * Set HTTP time condition. This must be one of the defines in the
891 * curl/curl.h header file.
892 */
893 data->set.timecondition = (curl_TimeCond)va_arg(param, long);
894 break;
895 case CURLOPT_TIMEVALUE:
896 /*
897 * This is the value to compare with the remote document with the
898 * method set with CURLOPT_TIMECONDITION
899 */
900 data->set.timevalue = (time_t)va_arg(param, long);
901 break;
902 case CURLOPT_SSLVERSION:
903 /*
904 * Set explicit SSL version to try to connect with, as some SSL
905 * implementations are lame.
906 */
907 #ifdef USE_SSL
908 data->set.ssl.version = va_arg(param, long);
909 #else
910 result = CURLE_UNKNOWN_OPTION;
911 #endif
912 break;
913
914 #ifndef CURL_DISABLE_HTTP
915 case CURLOPT_AUTOREFERER:
916 /*
917 * Switch on automatic referer that gets set if curl follows locations.
918 */
919 data->set.http_auto_referer = (0 != va_arg(param, long))?TRUE:FALSE;
920 break;
921
922 case CURLOPT_ACCEPT_ENCODING:
923 /*
924 * String to use at the value of Accept-Encoding header.
925 *
926 * If the encoding is set to "" we use an Accept-Encoding header that
927 * encompasses all the encodings we support.
928 * If the encoding is set to NULL we don't send an Accept-Encoding header
929 * and ignore an received Content-Encoding header.
930 *
931 */
932 argptr = va_arg(param, char *);
933 result = setstropt(&data->set.str[STRING_ENCODING],
934 (argptr && !*argptr)?
935 (char *) ALL_CONTENT_ENCODINGS: argptr);
936 break;
937
938 case CURLOPT_TRANSFER_ENCODING:
939 data->set.http_transfer_encoding = (0 != va_arg(param, long))?TRUE:FALSE;
940 break;
941
942 case CURLOPT_FOLLOWLOCATION:
943 /*
944 * Follow Location: header hints on a HTTP-server.
945 */
946 data->set.http_follow_location = (0 != va_arg(param, long))?TRUE:FALSE;
947 break;
948
949 case CURLOPT_UNRESTRICTED_AUTH:
950 /*
951 * Send authentication (user+password) when following locations, even when
952 * hostname changed.
953 */
954 data->set.http_disable_hostname_check_before_authentication =
955 (0 != va_arg(param, long))?TRUE:FALSE;
956 break;
957
958 case CURLOPT_MAXREDIRS:
959 /*
960 * The maximum amount of hops you allow curl to follow Location:
961 * headers. This should mostly be used to detect never-ending loops.
962 */
963 data->set.maxredirs = va_arg(param, long);
964 break;
965
966 case CURLOPT_POSTREDIR:
967 {
968 /*
969 * Set the behaviour of POST when redirecting
970 * CURL_REDIR_GET_ALL - POST is changed to GET after 301 and 302
971 * CURL_REDIR_POST_301 - POST is kept as POST after 301
972 * CURL_REDIR_POST_302 - POST is kept as POST after 302
973 * CURL_REDIR_POST_303 - POST is kept as POST after 303
974 * CURL_REDIR_POST_ALL - POST is kept as POST after 301, 302 and 303
975 * other - POST is kept as POST after 301 and 302
976 */
977 int postRedir = curlx_sltosi(va_arg(param, long));
978 data->set.keep_post = postRedir & CURL_REDIR_POST_ALL;
979 }
980 break;
981
982 case CURLOPT_POST:
983 /* Does this option serve a purpose anymore? Yes it does, when
984 CURLOPT_POSTFIELDS isn't used and the POST data is read off the
985 callback! */
986 if(va_arg(param, long)) {
987 data->set.httpreq = HTTPREQ_POST;
988 data->set.opt_no_body = FALSE; /* this is implied */
989 }
990 else
991 data->set.httpreq = HTTPREQ_GET;
992 break;
993
994 case CURLOPT_COPYPOSTFIELDS:
995 /*
996 * A string with POST data. Makes curl HTTP POST. Even if it is NULL.
997 * If needed, CURLOPT_POSTFIELDSIZE must have been set prior to
998 * CURLOPT_COPYPOSTFIELDS and not altered later.
999 */
1000 argptr = va_arg(param, char *);
1001
1002 if(!argptr || data->set.postfieldsize == -1)
1003 result = setstropt(&data->set.str[STRING_COPYPOSTFIELDS], argptr);
1004 else {
1005 /*
1006 * Check that requested length does not overflow the size_t type.
1007 */
1008
1009 if((data->set.postfieldsize < 0) ||
1010 ((sizeof(curl_off_t) != sizeof(size_t)) &&
1011 (data->set.postfieldsize > (curl_off_t)((size_t)-1))))
1012 result = CURLE_OUT_OF_MEMORY;
1013 else {
1014 char * p;
1015
1016 (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1017
1018 /* Allocate even when size == 0. This satisfies the need of possible
1019 later address compare to detect the COPYPOSTFIELDS mode, and
1020 to mark that postfields is used rather than read function or
1021 form data.
1022 */
1023 p = malloc((size_t)(data->set.postfieldsize?
1024 data->set.postfieldsize:1));
1025
1026 if(!p)
1027 result = CURLE_OUT_OF_MEMORY;
1028 else {
1029 if(data->set.postfieldsize)
1030 memcpy(p, argptr, (size_t)data->set.postfieldsize);
1031
1032 data->set.str[STRING_COPYPOSTFIELDS] = p;
1033 }
1034 }
1035 }
1036
1037 data->set.postfields = data->set.str[STRING_COPYPOSTFIELDS];
1038 data->set.httpreq = HTTPREQ_POST;
1039 break;
1040
1041 case CURLOPT_POSTFIELDS:
1042 /*
1043 * Like above, but use static data instead of copying it.
1044 */
1045 data->set.postfields = va_arg(param, void *);
1046 /* Release old copied data. */
1047 (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1048 data->set.httpreq = HTTPREQ_POST;
1049 break;
1050
1051 case CURLOPT_POSTFIELDSIZE:
1052 /*
1053 * The size of the POSTFIELD data to prevent libcurl to do strlen() to
1054 * figure it out. Enables binary posts.
1055 */
1056 bigsize = va_arg(param, long);
1057
1058 if(data->set.postfieldsize < bigsize &&
1059 data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
1060 /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */
1061 (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1062 data->set.postfields = NULL;
1063 }
1064
1065 data->set.postfieldsize = bigsize;
1066 break;
1067
1068 case CURLOPT_POSTFIELDSIZE_LARGE:
1069 /*
1070 * The size of the POSTFIELD data to prevent libcurl to do strlen() to
1071 * figure it out. Enables binary posts.
1072 */
1073 bigsize = va_arg(param, curl_off_t);
1074
1075 if(data->set.postfieldsize < bigsize &&
1076 data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
1077 /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */
1078 (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1079 data->set.postfields = NULL;
1080 }
1081
1082 data->set.postfieldsize = bigsize;
1083 break;
1084
1085 case CURLOPT_HTTPPOST:
1086 /*
1087 * Set to make us do HTTP POST
1088 */
1089 data->set.httppost = va_arg(param, struct curl_httppost *);
1090 data->set.httpreq = HTTPREQ_POST_FORM;
1091 data->set.opt_no_body = FALSE; /* this is implied */
1092 break;
1093
1094 case CURLOPT_REFERER:
1095 /*
1096 * String to set in the HTTP Referer: field.
1097 */
1098 if(data->change.referer_alloc) {
1099 Curl_safefree(data->change.referer);
1100 data->change.referer_alloc = FALSE;
1101 }
1102 result = setstropt(&data->set.str[STRING_SET_REFERER],
1103 va_arg(param, char *));
1104 data->change.referer = data->set.str[STRING_SET_REFERER];
1105 break;
1106
1107 case CURLOPT_USERAGENT:
1108 /*
1109 * String to use in the HTTP User-Agent field
1110 */
1111 result = setstropt(&data->set.str[STRING_USERAGENT],
1112 va_arg(param, char *));
1113 break;
1114
1115 case CURLOPT_HTTPHEADER:
1116 /*
1117 * Set a list with HTTP headers to use (or replace internals with)
1118 */
1119 data->set.headers = va_arg(param, struct curl_slist *);
1120 break;
1121
1122 case CURLOPT_PROXYHEADER:
1123 /*
1124 * Set a list with proxy headers to use (or replace internals with)
1125 *
1126 * Since CURLOPT_HTTPHEADER was the only way to set HTTP headers for a
1127 * long time we remain doing it this way until CURLOPT_PROXYHEADER is
1128 * used. As soon as this option has been used, if set to anything but
1129 * NULL, custom headers for proxies are only picked from this list.
1130 *
1131 * Set this option to NULL to restore the previous behavior.
1132 */
1133 data->set.proxyheaders = va_arg(param, struct curl_slist *);
1134 break;
1135
1136 case CURLOPT_HEADEROPT:
1137 /*
1138 * Set header option.
1139 */
1140 arg = va_arg(param, long);
1141 data->set.sep_headers = (arg & CURLHEADER_SEPARATE)? TRUE: FALSE;
1142 break;
1143
1144 case CURLOPT_HTTP200ALIASES:
1145 /*
1146 * Set a list of aliases for HTTP 200 in response header
1147 */
1148 data->set.http200aliases = va_arg(param, struct curl_slist *);
1149 break;
1150
1151 #if !defined(CURL_DISABLE_COOKIES)
1152 case CURLOPT_COOKIE:
1153 /*
1154 * Cookie string to send to the remote server in the request.
1155 */
1156 result = setstropt(&data->set.str[STRING_COOKIE],
1157 va_arg(param, char *));
1158 break;
1159
1160 case CURLOPT_COOKIEFILE:
1161 /*
1162 * Set cookie file to read and parse. Can be used multiple times.
1163 */
1164 argptr = (char *)va_arg(param, void *);
1165 if(argptr) {
1166 struct curl_slist *cl;
1167 /* append the cookie file name to the list of file names, and deal with
1168 them later */
1169 cl = curl_slist_append(data->change.cookielist, argptr);
1170 if(!cl) {
1171 curl_slist_free_all(data->change.cookielist);
1172 data->change.cookielist = NULL;
1173 return CURLE_OUT_OF_MEMORY;
1174 }
1175 data->change.cookielist = cl; /* store the list for later use */
1176 }
1177 break;
1178
1179 case CURLOPT_COOKIEJAR:
1180 /*
1181 * Set cookie file name to dump all cookies to when we're done.
1182 */
1183 {
1184 struct CookieInfo *newcookies;
1185 result = setstropt(&data->set.str[STRING_COOKIEJAR],
1186 va_arg(param, char *));
1187
1188 /*
1189 * Activate the cookie parser. This may or may not already
1190 * have been made.
1191 */
1192 newcookies = Curl_cookie_init(data, NULL, data->cookies,
1193 data->set.cookiesession);
1194 if(!newcookies)
1195 result = CURLE_OUT_OF_MEMORY;
1196 data->cookies = newcookies;
1197 }
1198 break;
1199
1200 case CURLOPT_COOKIESESSION:
1201 /*
1202 * Set this option to TRUE to start a new "cookie session". It will
1203 * prevent the forthcoming read-cookies-from-file actions to accept
1204 * cookies that are marked as being session cookies, as they belong to a
1205 * previous session.
1206 *
1207 * In the original Netscape cookie spec, "session cookies" are cookies
1208 * with no expire date set. RFC2109 describes the same action if no
1209 * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds
1210 * a 'Discard' action that can enforce the discard even for cookies that
1211 * have a Max-Age.
1212 *
1213 * We run mostly with the original cookie spec, as hardly anyone implements
1214 * anything else.
1215 */
1216 data->set.cookiesession = (0 != va_arg(param, long))?TRUE:FALSE;
1217 break;
1218
1219 case CURLOPT_COOKIELIST:
1220 argptr = va_arg(param, char *);
1221
1222 if(argptr == NULL)
1223 break;
1224
1225 if(Curl_raw_equal(argptr, "ALL")) {
1226 /* clear all cookies */
1227 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
1228 Curl_cookie_clearall(data->cookies);
1229 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
1230 }
1231 else if(Curl_raw_equal(argptr, "SESS")) {
1232 /* clear session cookies */
1233 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
1234 Curl_cookie_clearsess(data->cookies);
1235 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
1236 }
1237 else if(Curl_raw_equal(argptr, "FLUSH")) {
1238 /* flush cookies to file, takes care of the locking */
1239 Curl_flush_cookies(data, 0);
1240 }
1241 else if(Curl_raw_equal(argptr, "RELOAD")) {
1242 /* reload cookies from file */
1243 Curl_cookie_loadfiles(data);
1244 break;
1245 }
1246 else {
1247 if(!data->cookies)
1248 /* if cookie engine was not running, activate it */
1249 data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE);
1250
1251 argptr = strdup(argptr);
1252 if(!argptr || !data->cookies) {
1253 result = CURLE_OUT_OF_MEMORY;
1254 free(argptr);
1255 }
1256 else {
1257 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
1258
1259 if(checkprefix("Set-Cookie:", argptr))
1260 /* HTTP Header format line */
1261 Curl_cookie_add(data, data->cookies, TRUE, argptr + 11, NULL, NULL);
1262
1263 else
1264 /* Netscape format line */
1265 Curl_cookie_add(data, data->cookies, FALSE, argptr, NULL, NULL);
1266
1267 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
1268 free(argptr);
1269 }
1270 }
1271
1272 break;
1273 #endif /* CURL_DISABLE_COOKIES */
1274
1275 case CURLOPT_HTTPGET:
1276 /*
1277 * Set to force us do HTTP GET
1278 */
1279 if(va_arg(param, long)) {
1280 data->set.httpreq = HTTPREQ_GET;
1281 data->set.upload = FALSE; /* switch off upload */
1282 data->set.opt_no_body = FALSE; /* this is implied */
1283 }
1284 break;
1285
1286 case CURLOPT_HTTP_VERSION:
1287 /*
1288 * This sets a requested HTTP version to be used. The value is one of
1289 * the listed enums in curl/curl.h.
1290 */
1291 arg = va_arg(param, long);
1292 #ifndef USE_NGHTTP2
1293 if(arg == CURL_HTTP_VERSION_2_0)
1294 return CURLE_UNSUPPORTED_PROTOCOL;
1295 #endif
1296 data->set.httpversion = arg;
1297 break;
1298
1299 case CURLOPT_HTTPAUTH:
1300 /*
1301 * Set HTTP Authentication type BITMASK.
1302 */
1303 {
1304 int bitcheck;
1305 bool authbits;
1306 unsigned long auth = va_arg(param, unsigned long);
1307
1308 if(auth == CURLAUTH_NONE) {
1309 data->set.httpauth = auth;
1310 break;
1311 }
1312
1313 /* the DIGEST_IE bit is only used to set a special marker, for all the
1314 rest we need to handle it as normal DIGEST */
1315 data->state.authhost.iestyle = (auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE;
1316
1317 if(auth & CURLAUTH_DIGEST_IE) {
1318 auth |= CURLAUTH_DIGEST; /* set standard digest bit */
1319 auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */
1320 }
1321
1322 /* switch off bits we can't support */
1323 #ifndef USE_NTLM
1324 auth &= ~CURLAUTH_NTLM; /* no NTLM support */
1325 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
1326 #elif !defined(NTLM_WB_ENABLED)
1327 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
1328 #endif
1329 #ifndef USE_SPNEGO
1330 auth &= ~CURLAUTH_NEGOTIATE; /* no Negotiate (SPNEGO) auth without
1331 GSS-API or SSPI */
1332 #endif
1333
1334 /* check if any auth bit lower than CURLAUTH_ONLY is still set */
1335 bitcheck = 0;
1336 authbits = FALSE;
1337 while(bitcheck < 31) {
1338 if(auth & (1UL << bitcheck++)) {
1339 authbits = TRUE;
1340 break;
1341 }
1342 }
1343 if(!authbits)
1344 return CURLE_NOT_BUILT_IN; /* no supported types left! */
1345
1346 data->set.httpauth = auth;
1347 }
1348 break;
1349
1350 case CURLOPT_EXPECT_100_TIMEOUT_MS:
1351 /*
1352 * Time to wait for a response to a HTTP request containing an
1353 * Expect: 100-continue header before sending the data anyway.
1354 */
1355 data->set.expect_100_timeout = va_arg(param, long);
1356 break;
1357
1358 #endif /* CURL_DISABLE_HTTP */
1359
1360 case CURLOPT_CUSTOMREQUEST:
1361 /*
1362 * Set a custom string to use as request
1363 */
1364 result = setstropt(&data->set.str[STRING_CUSTOMREQUEST],
1365 va_arg(param, char *));
1366
1367 /* we don't set
1368 data->set.httpreq = HTTPREQ_CUSTOM;
1369 here, we continue as if we were using the already set type
1370 and this just changes the actual request keyword */
1371 break;
1372
1373 #ifndef CURL_DISABLE_PROXY
1374 case CURLOPT_HTTPPROXYTUNNEL:
1375 /*
1376 * Tunnel operations through the proxy instead of normal proxy use
1377 */
1378 data->set.tunnel_thru_httpproxy = (0 != va_arg(param, long))?TRUE:FALSE;
1379 break;
1380
1381 case CURLOPT_PROXYPORT:
1382 /*
1383 * Explicitly set HTTP proxy port number.
1384 */
1385 data->set.proxyport = va_arg(param, long);
1386 break;
1387
1388 case CURLOPT_PROXYAUTH:
1389 /*
1390 * Set HTTP Authentication type BITMASK.
1391 */
1392 {
1393 int bitcheck;
1394 bool authbits;
1395 unsigned long auth = va_arg(param, unsigned long);
1396
1397 if(auth == CURLAUTH_NONE) {
1398 data->set.proxyauth = auth;
1399 break;
1400 }
1401
1402 /* the DIGEST_IE bit is only used to set a special marker, for all the
1403 rest we need to handle it as normal DIGEST */
1404 data->state.authproxy.iestyle = (auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE;
1405
1406 if(auth & CURLAUTH_DIGEST_IE) {
1407 auth |= CURLAUTH_DIGEST; /* set standard digest bit */
1408 auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */
1409 }
1410 /* switch off bits we can't support */
1411 #ifndef USE_NTLM
1412 auth &= ~CURLAUTH_NTLM; /* no NTLM support */
1413 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
1414 #elif !defined(NTLM_WB_ENABLED)
1415 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
1416 #endif
1417 #ifndef USE_SPNEGO
1418 auth &= ~CURLAUTH_NEGOTIATE; /* no Negotiate (SPNEGO) auth without
1419 GSS-API or SSPI */
1420 #endif
1421
1422 /* check if any auth bit lower than CURLAUTH_ONLY is still set */
1423 bitcheck = 0;
1424 authbits = FALSE;
1425 while(bitcheck < 31) {
1426 if(auth & (1UL << bitcheck++)) {
1427 authbits = TRUE;
1428 break;
1429 }
1430 }
1431 if(!authbits)
1432 return CURLE_NOT_BUILT_IN; /* no supported types left! */
1433
1434 data->set.proxyauth = auth;
1435 }
1436 break;
1437
1438 case CURLOPT_PROXY:
1439 /*
1440 * Set proxy server:port to use as HTTP proxy.
1441 *
1442 * If the proxy is set to "" we explicitly say that we don't want to use a
1443 * proxy (even though there might be environment variables saying so).
1444 *
1445 * Setting it to NULL, means no proxy but allows the environment variables
1446 * to decide for us.
1447 */
1448 result = setstropt(&data->set.str[STRING_PROXY],
1449 va_arg(param, char *));
1450 break;
1451
1452 case CURLOPT_PROXYTYPE:
1453 /*
1454 * Set proxy type. HTTP/HTTP_1_0/SOCKS4/SOCKS4a/SOCKS5/SOCKS5_HOSTNAME
1455 */
1456 data->set.proxytype = (curl_proxytype)va_arg(param, long);
1457 break;
1458
1459 case CURLOPT_PROXY_TRANSFER_MODE:
1460 /*
1461 * set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy
1462 */
1463 switch (va_arg(param, long)) {
1464 case 0:
1465 data->set.proxy_transfer_mode = FALSE;
1466 break;
1467 case 1:
1468 data->set.proxy_transfer_mode = TRUE;
1469 break;
1470 default:
1471 /* reserve other values for future use */
1472 result = CURLE_UNKNOWN_OPTION;
1473 break;
1474 }
1475 break;
1476 #endif /* CURL_DISABLE_PROXY */
1477
1478 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
1479 case CURLOPT_SOCKS5_GSSAPI_SERVICE:
1480 /*
1481 * Set GSS-API service name
1482 */
1483 result = setstropt(&data->set.str[STRING_SOCKS5_GSSAPI_SERVICE],
1484 va_arg(param, char *));
1485 break;
1486
1487 case CURLOPT_PROXY_SERVICE_NAME:
1488 /*
1489 * Set negotiate proxy service name
1490 */
1491 result = setstropt(&data->set.str[STRING_PROXY_SERVICE_NAME],
1492 va_arg(param, char *));
1493 break;
1494
1495 case CURLOPT_SOCKS5_GSSAPI_NEC:
1496 /*
1497 * set flag for nec socks5 support
1498 */
1499 data->set.socks5_gssapi_nec = (0 != va_arg(param, long))?TRUE:FALSE;
1500 break;
1501
1502 case CURLOPT_SERVICE_NAME:
1503 /*
1504 * Set negotiate service identity
1505 */
1506 result = setstropt(&data->set.str[STRING_SERVICE_NAME],
1507 va_arg(param, char *));
1508 break;
1509
1510 #endif
1511
1512 case CURLOPT_HEADERDATA:
1513 /*
1514 * Custom pointer to pass the header write callback function
1515 */
1516 data->set.writeheader = (void *)va_arg(param, void *);
1517 break;
1518 case CURLOPT_ERRORBUFFER:
1519 /*
1520 * Error buffer provided by the caller to get the human readable
1521 * error string in.
1522 */
1523 data->set.errorbuffer = va_arg(param, char *);
1524 break;
1525 case CURLOPT_WRITEDATA:
1526 /*
1527 * FILE pointer to write to. Or possibly
1528 * used as argument to the write callback.
1529 */
1530 data->set.out = va_arg(param, void *);
1531 break;
1532 case CURLOPT_FTPPORT:
1533 /*
1534 * Use FTP PORT, this also specifies which IP address to use
1535 */
1536 result = setstropt(&data->set.str[STRING_FTPPORT],
1537 va_arg(param, char *));
1538 data->set.ftp_use_port = (NULL != data->set.str[STRING_FTPPORT]) ?
1539 TRUE:FALSE;
1540 break;
1541
1542 case CURLOPT_FTP_USE_EPRT:
1543 data->set.ftp_use_eprt = (0 != va_arg(param, long))?TRUE:FALSE;
1544 break;
1545
1546 case CURLOPT_FTP_USE_EPSV:
1547 data->set.ftp_use_epsv = (0 != va_arg(param, long))?TRUE:FALSE;
1548 break;
1549
1550 case CURLOPT_FTP_USE_PRET:
1551 data->set.ftp_use_pret = (0 != va_arg(param, long))?TRUE:FALSE;
1552 break;
1553
1554 case CURLOPT_FTP_SSL_CCC:
1555 data->set.ftp_ccc = (curl_ftpccc)va_arg(param, long);
1556 break;
1557
1558 case CURLOPT_FTP_SKIP_PASV_IP:
1559 /*
1560 * Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the
1561 * bypass of the IP address in PASV responses.
1562 */
1563 data->set.ftp_skip_ip = (0 != va_arg(param, long))?TRUE:FALSE;
1564 break;
1565
1566 case CURLOPT_READDATA:
1567 /*
1568 * FILE pointer to read the file to be uploaded from. Or possibly
1569 * used as argument to the read callback.
1570 */
1571 data->set.in = va_arg(param, void *);
1572 break;
1573 case CURLOPT_INFILESIZE:
1574 /*
1575 * If known, this should inform curl about the file size of the
1576 * to-be-uploaded file.
1577 */
1578 data->set.filesize = va_arg(param, long);
1579 break;
1580 case CURLOPT_INFILESIZE_LARGE:
1581 /*
1582 * If known, this should inform curl about the file size of the
1583 * to-be-uploaded file.
1584 */
1585 data->set.filesize = va_arg(param, curl_off_t);
1586 break;
1587 case CURLOPT_LOW_SPEED_LIMIT:
1588 /*
1589 * The low speed limit that if transfers are below this for
1590 * CURLOPT_LOW_SPEED_TIME, the transfer is aborted.
1591 */
1592 data->set.low_speed_limit=va_arg(param, long);
1593 break;
1594 case CURLOPT_MAX_SEND_SPEED_LARGE:
1595 /*
1596 * When transfer uploads are faster then CURLOPT_MAX_SEND_SPEED_LARGE
1597 * bytes per second the transfer is throttled..
1598 */
1599 data->set.max_send_speed=va_arg(param, curl_off_t);
1600 break;
1601 case CURLOPT_MAX_RECV_SPEED_LARGE:
1602 /*
1603 * When receiving data faster than CURLOPT_MAX_RECV_SPEED_LARGE bytes per
1604 * second the transfer is throttled..
1605 */
1606 data->set.max_recv_speed=va_arg(param, curl_off_t);
1607 break;
1608 case CURLOPT_LOW_SPEED_TIME:
1609 /*
1610 * The low speed time that if transfers are below the set
1611 * CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted.
1612 */
1613 data->set.low_speed_time=va_arg(param, long);
1614 break;
1615 case CURLOPT_URL:
1616 /*
1617 * The URL to fetch.
1618 */
1619 if(data->change.url_alloc) {
1620 /* the already set URL is allocated, free it first! */
1621 Curl_safefree(data->change.url);
1622 data->change.url_alloc = FALSE;
1623 }
1624 result = setstropt(&data->set.str[STRING_SET_URL],
1625 va_arg(param, char *));
1626 data->change.url = data->set.str[STRING_SET_URL];
1627 break;
1628 case CURLOPT_PORT:
1629 /*
1630 * The port number to use when getting the URL
1631 */
1632 data->set.use_port = va_arg(param, long);
1633 break;
1634 case CURLOPT_TIMEOUT:
1635 /*
1636 * The maximum time you allow curl to use for a single transfer
1637 * operation.
1638 */
1639 data->set.timeout = va_arg(param, long) * 1000L;
1640 break;
1641
1642 case CURLOPT_TIMEOUT_MS:
1643 data->set.timeout = va_arg(param, long);
1644 break;
1645
1646 case CURLOPT_CONNECTTIMEOUT:
1647 /*
1648 * The maximum time you allow curl to use to connect.
1649 */
1650 data->set.connecttimeout = va_arg(param, long) * 1000L;
1651 break;
1652
1653 case CURLOPT_CONNECTTIMEOUT_MS:
1654 data->set.connecttimeout = va_arg(param, long);
1655 break;
1656
1657 case CURLOPT_ACCEPTTIMEOUT_MS:
1658 /*
1659 * The maximum time you allow curl to wait for server connect
1660 */
1661 data->set.accepttimeout = va_arg(param, long);
1662 break;
1663
1664 case CURLOPT_USERPWD:
1665 /*
1666 * user:password to use in the operation
1667 */
1668 result = setstropt_userpwd(va_arg(param, char *),
1669 &data->set.str[STRING_USERNAME],
1670 &data->set.str[STRING_PASSWORD]);
1671 break;
1672
1673 case CURLOPT_USERNAME:
1674 /*
1675 * authentication user name to use in the operation
1676 */
1677 result = setstropt(&data->set.str[STRING_USERNAME],
1678 va_arg(param, char *));
1679 break;
1680
1681 case CURLOPT_PASSWORD:
1682 /*
1683 * authentication password to use in the operation
1684 */
1685 result = setstropt(&data->set.str[STRING_PASSWORD],
1686 va_arg(param, char *));
1687 break;
1688
1689 case CURLOPT_LOGIN_OPTIONS:
1690 /*
1691 * authentication options to use in the operation
1692 */
1693 result = setstropt(&data->set.str[STRING_OPTIONS],
1694 va_arg(param, char *));
1695 break;
1696
1697 case CURLOPT_XOAUTH2_BEARER:
1698 /*
1699 * XOAUTH2 bearer token to use in the operation
1700 */
1701 result = setstropt(&data->set.str[STRING_BEARER],
1702 va_arg(param, char *));
1703 break;
1704
1705 case CURLOPT_POSTQUOTE:
1706 /*
1707 * List of RAW FTP commands to use after a transfer
1708 */
1709 data->set.postquote = va_arg(param, struct curl_slist *);
1710 break;
1711 case CURLOPT_PREQUOTE:
1712 /*
1713 * List of RAW FTP commands to use prior to RETR (Wesley Laxton)
1714 */
1715 data->set.prequote = va_arg(param, struct curl_slist *);
1716 break;
1717 case CURLOPT_QUOTE:
1718 /*
1719 * List of RAW FTP commands to use before a transfer
1720 */
1721 data->set.quote = va_arg(param, struct curl_slist *);
1722 break;
1723 case CURLOPT_RESOLVE:
1724 /*
1725 * List of NAME:[address] names to populate the DNS cache with
1726 * Prefix the NAME with dash (-) to _remove_ the name from the cache.
1727 *
1728 * Names added with this API will remain in the cache until explicitly
1729 * removed or the handle is cleaned up.
1730 *
1731 * This API can remove any name from the DNS cache, but only entries
1732 * that aren't actually in use right now will be pruned immediately.
1733 */
1734 data->set.resolve = va_arg(param, struct curl_slist *);
1735 data->change.resolve = data->set.resolve;
1736 break;
1737 case CURLOPT_PROGRESSFUNCTION:
1738 /*
1739 * Progress callback function
1740 */
1741 data->set.fprogress = va_arg(param, curl_progress_callback);
1742 if(data->set.fprogress)
1743 data->progress.callback = TRUE; /* no longer internal */
1744 else
1745 data->progress.callback = FALSE; /* NULL enforces internal */
1746 break;
1747
1748 case CURLOPT_XFERINFOFUNCTION:
1749 /*
1750 * Transfer info callback function
1751 */
1752 data->set.fxferinfo = va_arg(param, curl_xferinfo_callback);
1753 if(data->set.fxferinfo)
1754 data->progress.callback = TRUE; /* no longer internal */
1755 else
1756 data->progress.callback = FALSE; /* NULL enforces internal */
1757
1758 break;
1759
1760 case CURLOPT_PROGRESSDATA:
1761 /*
1762 * Custom client data to pass to the progress callback
1763 */
1764 data->set.progress_client = va_arg(param, void *);
1765 break;
1766
1767 #ifndef CURL_DISABLE_PROXY
1768 case CURLOPT_PROXYUSERPWD:
1769 /*
1770 * user:password needed to use the proxy
1771 */
1772 result = setstropt_userpwd(va_arg(param, char *),
1773 &data->set.str[STRING_PROXYUSERNAME],
1774 &data->set.str[STRING_PROXYPASSWORD]);
1775 break;
1776 case CURLOPT_PROXYUSERNAME:
1777 /*
1778 * authentication user name to use in the operation
1779 */
1780 result = setstropt(&data->set.str[STRING_PROXYUSERNAME],
1781 va_arg(param, char *));
1782 break;
1783 case CURLOPT_PROXYPASSWORD:
1784 /*
1785 * authentication password to use in the operation
1786 */
1787 result = setstropt(&data->set.str[STRING_PROXYPASSWORD],
1788 va_arg(param, char *));
1789 break;
1790 case CURLOPT_NOPROXY:
1791 /*
1792 * proxy exception list
1793 */
1794 result = setstropt(&data->set.str[STRING_NOPROXY],
1795 va_arg(param, char *));
1796 break;
1797 #endif
1798
1799 case CURLOPT_RANGE:
1800 /*
1801 * What range of the file you want to transfer
1802 */
1803 result = setstropt(&data->set.str[STRING_SET_RANGE],
1804 va_arg(param, char *));
1805 break;
1806 case CURLOPT_RESUME_FROM:
1807 /*
1808 * Resume transfer at the give file position
1809 */
1810 data->set.set_resume_from = va_arg(param, long);
1811 break;
1812 case CURLOPT_RESUME_FROM_LARGE:
1813 /*
1814 * Resume transfer at the give file position
1815 */
1816 data->set.set_resume_from = va_arg(param, curl_off_t);
1817 break;
1818 case CURLOPT_DEBUGFUNCTION:
1819 /*
1820 * stderr write callback.
1821 */
1822 data->set.fdebug = va_arg(param, curl_debug_callback);
1823 /*
1824 * if the callback provided is NULL, it'll use the default callback
1825 */
1826 break;
1827 case CURLOPT_DEBUGDATA:
1828 /*
1829 * Set to a void * that should receive all error writes. This
1830 * defaults to CURLOPT_STDERR for normal operations.
1831 */
1832 data->set.debugdata = va_arg(param, void *);
1833 break;
1834 case CURLOPT_STDERR:
1835 /*
1836 * Set to a FILE * that should receive all error writes. This
1837 * defaults to stderr for normal operations.
1838 */
1839 data->set.err = va_arg(param, FILE *);
1840 if(!data->set.err)
1841 data->set.err = stderr;
1842 break;
1843 case CURLOPT_HEADERFUNCTION:
1844 /*
1845 * Set header write callback
1846 */
1847 data->set.fwrite_header = va_arg(param, curl_write_callback);
1848 break;
1849 case CURLOPT_WRITEFUNCTION:
1850 /*
1851 * Set data write callback
1852 */
1853 data->set.fwrite_func = va_arg(param, curl_write_callback);
1854 if(!data->set.fwrite_func) {
1855 data->set.is_fwrite_set = 0;
1856 /* When set to NULL, reset to our internal default function */
1857 data->set.fwrite_func = (curl_write_callback)fwrite;
1858 }
1859 else
1860 data->set.is_fwrite_set = 1;
1861 break;
1862 case CURLOPT_READFUNCTION:
1863 /*
1864 * Read data callback
1865 */
1866 data->set.fread_func = va_arg(param, curl_read_callback);
1867 if(!data->set.fread_func) {
1868 data->set.is_fread_set = 0;
1869 /* When set to NULL, reset to our internal default function */
1870 data->set.fread_func = (curl_read_callback)fread;
1871 }
1872 else
1873 data->set.is_fread_set = 1;
1874 break;
1875 case CURLOPT_SEEKFUNCTION:
1876 /*
1877 * Seek callback. Might be NULL.
1878 */
1879 data->set.seek_func = va_arg(param, curl_seek_callback);
1880 break;
1881 case CURLOPT_SEEKDATA:
1882 /*
1883 * Seek control callback. Might be NULL.
1884 */
1885 data->set.seek_client = va_arg(param, void *);
1886 break;
1887 case CURLOPT_CONV_FROM_NETWORK_FUNCTION:
1888 /*
1889 * "Convert from network encoding" callback
1890 */
1891 data->set.convfromnetwork = va_arg(param, curl_conv_callback);
1892 break;
1893 case CURLOPT_CONV_TO_NETWORK_FUNCTION:
1894 /*
1895 * "Convert to network encoding" callback
1896 */
1897 data->set.convtonetwork = va_arg(param, curl_conv_callback);
1898 break;
1899 case CURLOPT_CONV_FROM_UTF8_FUNCTION:
1900 /*
1901 * "Convert from UTF-8 encoding" callback
1902 */
1903 data->set.convfromutf8 = va_arg(param, curl_conv_callback);
1904 break;
1905 case CURLOPT_IOCTLFUNCTION:
1906 /*
1907 * I/O control callback. Might be NULL.
1908 */
1909 data->set.ioctl_func = va_arg(param, curl_ioctl_callback);
1910 break;
1911 case CURLOPT_IOCTLDATA:
1912 /*
1913 * I/O control data pointer. Might be NULL.
1914 */
1915 data->set.ioctl_client = va_arg(param, void *);
1916 break;
1917 case CURLOPT_SSLCERT:
1918 /*
1919 * String that holds file name of the SSL certificate to use
1920 */
1921 result = setstropt(&data->set.str[STRING_CERT],
1922 va_arg(param, char *));
1923 break;
1924 case CURLOPT_SSLCERTTYPE:
1925 /*
1926 * String that holds file type of the SSL certificate to use
1927 */
1928 result = setstropt(&data->set.str[STRING_CERT_TYPE],
1929 va_arg(param, char *));
1930 break;
1931 case CURLOPT_SSLKEY:
1932 /*
1933 * String that holds file name of the SSL key to use
1934 */
1935 result = setstropt(&data->set.str[STRING_KEY],
1936 va_arg(param, char *));
1937 break;
1938 case CURLOPT_SSLKEYTYPE:
1939 /*
1940 * String that holds file type of the SSL key to use
1941 */
1942 result = setstropt(&data->set.str[STRING_KEY_TYPE],
1943 va_arg(param, char *));
1944 break;
1945 case CURLOPT_KEYPASSWD:
1946 /*
1947 * String that holds the SSL or SSH private key password.
1948 */
1949 result = setstropt(&data->set.str[STRING_KEY_PASSWD],
1950 va_arg(param, char *));
1951 break;
1952 case CURLOPT_SSLENGINE:
1953 /*
1954 * String that holds the SSL crypto engine.
1955 */
1956 argptr = va_arg(param, char *);
1957 if(argptr && argptr[0])
1958 result = Curl_ssl_set_engine(data, argptr);
1959 break;
1960
1961 case CURLOPT_SSLENGINE_DEFAULT:
1962 /*
1963 * flag to set engine as default.
1964 */
1965 result = Curl_ssl_set_engine_default(data);
1966 break;
1967 case CURLOPT_CRLF:
1968 /*
1969 * Kludgy option to enable CRLF conversions. Subject for removal.
1970 */
1971 data->set.crlf = (0 != va_arg(param, long))?TRUE:FALSE;
1972 break;
1973
1974 case CURLOPT_INTERFACE:
1975 /*
1976 * Set what interface or address/hostname to bind the socket to when
1977 * performing an operation and thus what from-IP your connection will use.
1978 */
1979 result = setstropt(&data->set.str[STRING_DEVICE],
1980 va_arg(param, char *));
1981 break;
1982 case CURLOPT_LOCALPORT:
1983 /*
1984 * Set what local port to bind the socket to when performing an operation.
1985 */
1986 data->set.localport = curlx_sltous(va_arg(param, long));
1987 break;
1988 case CURLOPT_LOCALPORTRANGE:
1989 /*
1990 * Set number of local ports to try, starting with CURLOPT_LOCALPORT.
1991 */
1992 data->set.localportrange = curlx_sltosi(va_arg(param, long));
1993 break;
1994 case CURLOPT_KRBLEVEL:
1995 /*
1996 * A string that defines the kerberos security level.
1997 */
1998 result = setstropt(&data->set.str[STRING_KRB_LEVEL],
1999 va_arg(param, char *));
2000 data->set.krb = (NULL != data->set.str[STRING_KRB_LEVEL])?TRUE:FALSE;
2001 break;
2002 case CURLOPT_GSSAPI_DELEGATION:
2003 /*
2004 * GSS-API credential delegation
2005 */
2006 data->set.gssapi_delegation = va_arg(param, long);
2007 break;
2008 case CURLOPT_SSL_VERIFYPEER:
2009 /*
2010 * Enable peer SSL verifying.
2011 */
2012 data->set.ssl.verifypeer = (0 != va_arg(param, long))?TRUE:FALSE;
2013 break;
2014 case CURLOPT_SSL_VERIFYHOST:
2015 /*
2016 * Enable verification of the host name in the peer certificate
2017 */
2018 arg = va_arg(param, long);
2019
2020 /* Obviously people are not reading documentation and too many thought
2021 this argument took a boolean when it wasn't and misused it. We thus ban
2022 1 as a sensible input and we warn about its use. Then we only have the
2023 2 action internally stored as TRUE. */
2024
2025 if(1 == arg) {
2026 failf(data, "CURLOPT_SSL_VERIFYHOST no longer supports 1 as value!");
2027 return CURLE_BAD_FUNCTION_ARGUMENT;
2028 }
2029
2030 data->set.ssl.verifyhost = (0 != arg)?TRUE:FALSE;
2031 break;
2032 case CURLOPT_SSL_VERIFYSTATUS:
2033 /*
2034 * Enable certificate status verifying.
2035 */
2036 if(!Curl_ssl_cert_status_request()) {
2037 result = CURLE_NOT_BUILT_IN;
2038 break;
2039 }
2040
2041 data->set.ssl.verifystatus = (0 != va_arg(param, long))?TRUE:FALSE;
2042 break;
2043 case CURLOPT_SSL_CTX_FUNCTION:
2044 #ifdef have_curlssl_ssl_ctx
2045 /*
2046 * Set a SSL_CTX callback
2047 */
2048 data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback);
2049 #else
2050 result = CURLE_NOT_BUILT_IN;
2051 #endif
2052 break;
2053 case CURLOPT_SSL_CTX_DATA:
2054 #ifdef have_curlssl_ssl_ctx
2055 /*
2056 * Set a SSL_CTX callback parameter pointer
2057 */
2058 data->set.ssl.fsslctxp = va_arg(param, void *);
2059 #else
2060 result = CURLE_NOT_BUILT_IN;
2061 #endif
2062 break;
2063 case CURLOPT_SSL_FALSESTART:
2064 /*
2065 * Enable TLS false start.
2066 */
2067 if(!Curl_ssl_false_start()) {
2068 result = CURLE_NOT_BUILT_IN;
2069 break;
2070 }
2071
2072 data->set.ssl.falsestart = (0 != va_arg(param, long))?TRUE:FALSE;
2073 break;
2074 case CURLOPT_CERTINFO:
2075 #ifdef have_curlssl_certinfo
2076 data->set.ssl.certinfo = (0 != va_arg(param, long))?TRUE:FALSE;
2077 #else
2078 result = CURLE_NOT_BUILT_IN;
2079 #endif
2080 break;
2081 case CURLOPT_PINNEDPUBLICKEY:
2082 /*
2083 * Set pinned public key for SSL connection.
2084 * Specify file name of the public key in DER format.
2085 */
2086 result = setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY],
2087 va_arg(param, char *));
2088 break;
2089 case CURLOPT_CAINFO:
2090 /*
2091 * Set CA info for SSL connection. Specify file name of the CA certificate
2092 */
2093 result = setstropt(&data->set.str[STRING_SSL_CAFILE],
2094 va_arg(param, char *));
2095 break;
2096 case CURLOPT_CAPATH:
2097 #ifdef have_curlssl_ca_path /* not supported by all backends */
2098 /*
2099 * Set CA path info for SSL connection. Specify directory name of the CA
2100 * certificates which have been prepared using openssl c_rehash utility.
2101 */
2102 /* This does not work on windows. */
2103 result = setstropt(&data->set.str[STRING_SSL_CAPATH],
2104 va_arg(param, char *));
2105 #else
2106 result = CURLE_NOT_BUILT_IN;
2107 #endif
2108 break;
2109 case CURLOPT_CRLFILE:
2110 /*
2111 * Set CRL file info for SSL connection. Specify file name of the CRL
2112 * to check certificates revocation
2113 */
2114 result = setstropt(&data->set.str[STRING_SSL_CRLFILE],
2115 va_arg(param, char *));
2116 break;
2117 case CURLOPT_ISSUERCERT:
2118 /*
2119 * Set Issuer certificate file
2120 * to check certificates issuer
2121 */
2122 result = setstropt(&data->set.str[STRING_SSL_ISSUERCERT],
2123 va_arg(param, char *));
2124 break;
2125 case CURLOPT_TELNETOPTIONS:
2126 /*
2127 * Set a linked list of telnet options
2128 */
2129 data->set.telnet_options = va_arg(param, struct curl_slist *);
2130 break;
2131
2132 case CURLOPT_BUFFERSIZE:
2133 /*
2134 * The application kindly asks for a differently sized receive buffer.
2135 * If it seems reasonable, we'll use it.
2136 */
2137 data->set.buffer_size = va_arg(param, long);
2138
2139 if((data->set.buffer_size> (BUFSIZE -1 )) ||
2140 (data->set.buffer_size < 1))
2141 data->set.buffer_size = 0; /* huge internal default */
2142
2143 break;
2144
2145 case CURLOPT_NOSIGNAL:
2146 /*
2147 * The application asks not to set any signal() or alarm() handlers,
2148 * even when using a timeout.
2149 */
2150 data->set.no_signal = (0 != va_arg(param, long))?TRUE:FALSE;
2151 break;
2152
2153 case CURLOPT_SHARE:
2154 {
2155 struct Curl_share *set;
2156 set = va_arg(param, struct Curl_share *);
2157
2158 /* disconnect from old share, if any */
2159 if(data->share) {
2160 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
2161
2162 if(data->dns.hostcachetype == HCACHE_SHARED) {
2163 data->dns.hostcache = NULL;
2164 data->dns.hostcachetype = HCACHE_NONE;
2165 }
2166
2167 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
2168 if(data->share->cookies == data->cookies)
2169 data->cookies = NULL;
2170 #endif
2171
2172 if(data->share->sslsession == data->state.session)
2173 data->state.session = NULL;
2174
2175 data->share->dirty--;
2176
2177 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
2178 data->share = NULL;
2179 }
2180
2181 /* use new share if it set */
2182 data->share = set;
2183 if(data->share) {
2184
2185 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
2186
2187 data->share->dirty++;
2188
2189 if(data->share->specifier & (1<< CURL_LOCK_DATA_DNS)) {
2190 /* use shared host cache */
2191 data->dns.hostcache = &data->share->hostcache;
2192 data->dns.hostcachetype = HCACHE_SHARED;
2193 }
2194 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
2195 if(data->share->cookies) {
2196 /* use shared cookie list, first free own one if any */
2197 Curl_cookie_cleanup(data->cookies);
2198 /* enable cookies since we now use a share that uses cookies! */
2199 data->cookies = data->share->cookies;
2200 }
2201 #endif /* CURL_DISABLE_HTTP */
2202 if(data->share->sslsession) {
2203 data->set.ssl.max_ssl_sessions = data->share->max_ssl_sessions;
2204 data->state.session = data->share->sslsession;
2205 }
2206 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
2207
2208 }
2209 /* check for host cache not needed,
2210 * it will be done by curl_easy_perform */
2211 }
2212 break;
2213
2214 case CURLOPT_PRIVATE:
2215 /*
2216 * Set private data pointer.
2217 */
2218 data->set.private_data = va_arg(param, void *);
2219 break;
2220
2221 case CURLOPT_MAXFILESIZE:
2222 /*
2223 * Set the maximum size of a file to download.
2224 */
2225 data->set.max_filesize = va_arg(param, long);
2226 break;
2227
2228 #ifdef USE_SSL
2229 case CURLOPT_USE_SSL:
2230 /*
2231 * Make transfers attempt to use SSL/TLS.
2232 */
2233 data->set.use_ssl = (curl_usessl)va_arg(param, long);
2234 break;
2235
2236 case CURLOPT_SSL_OPTIONS:
2237 arg = va_arg(param, long);
2238 data->set.ssl_enable_beast = arg&CURLSSLOPT_ALLOW_BEAST?TRUE:FALSE;
2239 break;
2240
2241 #endif
2242 case CURLOPT_FTPSSLAUTH:
2243 /*
2244 * Set a specific auth for FTP-SSL transfers.
2245 */
2246 data->set.ftpsslauth = (curl_ftpauth)va_arg(param, long);
2247 break;
2248
2249 case CURLOPT_IPRESOLVE:
2250 data->set.ipver = va_arg(param, long);
2251 break;
2252
2253 case CURLOPT_MAXFILESIZE_LARGE:
2254 /*
2255 * Set the maximum size of a file to download.
2256 */
2257 data->set.max_filesize = va_arg(param, curl_off_t);
2258 break;
2259
2260 case CURLOPT_TCP_NODELAY:
2261 /*
2262 * Enable or disable TCP_NODELAY, which will disable/enable the Nagle
2263 * algorithm
2264 */
2265 data->set.tcp_nodelay = (0 != va_arg(param, long))?TRUE:FALSE;
2266 break;
2267
2268 case CURLOPT_FTP_ACCOUNT:
2269 result = setstropt(&data->set.str[STRING_FTP_ACCOUNT],
2270 va_arg(param, char *));
2271 break;
2272
2273 case CURLOPT_IGNORE_CONTENT_LENGTH:
2274 data->set.ignorecl = (0 != va_arg(param, long))?TRUE:FALSE;
2275 break;
2276
2277 case CURLOPT_CONNECT_ONLY:
2278 /*
2279 * No data transfer, set up connection and let application use the socket
2280 */
2281 data->set.connect_only = (0 != va_arg(param, long))?TRUE:FALSE;
2282 break;
2283
2284 case CURLOPT_FTP_ALTERNATIVE_TO_USER:
2285 result = setstropt(&data->set.str[STRING_FTP_ALTERNATIVE_TO_USER],
2286 va_arg(param, char *));
2287 break;
2288
2289 case CURLOPT_SOCKOPTFUNCTION:
2290 /*
2291 * socket callback function: called after socket() but before connect()
2292 */
2293 data->set.fsockopt = va_arg(param, curl_sockopt_callback);
2294 break;
2295
2296 case CURLOPT_SOCKOPTDATA:
2297 /*
2298 * socket callback data pointer. Might be NULL.
2299 */
2300 data->set.sockopt_client = va_arg(param, void *);
2301 break;
2302
2303 case CURLOPT_OPENSOCKETFUNCTION:
2304 /*
2305 * open/create socket callback function: called instead of socket(),
2306 * before connect()
2307 */
2308 data->set.fopensocket = va_arg(param, curl_opensocket_callback);
2309 break;
2310
2311 case CURLOPT_OPENSOCKETDATA:
2312 /*
2313 * socket callback data pointer. Might be NULL.
2314 */
2315 data->set.opensocket_client = va_arg(param, void *);
2316 break;
2317
2318 case CURLOPT_CLOSESOCKETFUNCTION:
2319 /*
2320 * close socket callback function: called instead of close()
2321 * when shutting down a connection
2322 */
2323 data->set.fclosesocket = va_arg(param, curl_closesocket_callback);
2324 break;
2325
2326 case CURLOPT_CLOSESOCKETDATA:
2327 /*
2328 * socket callback data pointer. Might be NULL.
2329 */
2330 data->set.closesocket_client = va_arg(param, void *);
2331 break;
2332
2333 case CURLOPT_SSL_SESSIONID_CACHE:
2334 data->set.ssl.sessionid = (0 != va_arg(param, long))?TRUE:FALSE;
2335 break;
2336
2337 #ifdef USE_LIBSSH2
2338 /* we only include SSH options if explicitly built to support SSH */
2339 case CURLOPT_SSH_AUTH_TYPES:
2340 data->set.ssh_auth_types = va_arg(param, long);
2341 break;
2342
2343 case CURLOPT_SSH_PUBLIC_KEYFILE:
2344 /*
2345 * Use this file instead of the $HOME/.ssh/id_dsa.pub file
2346 */
2347 result = setstropt(&data->set.str[STRING_SSH_PUBLIC_KEY],
2348 va_arg(param, char *));
2349 break;
2350
2351 case CURLOPT_SSH_PRIVATE_KEYFILE:
2352 /*
2353 * Use this file instead of the $HOME/.ssh/id_dsa file
2354 */
2355 result = setstropt(&data->set.str[STRING_SSH_PRIVATE_KEY],
2356 va_arg(param, char *));
2357 break;
2358 case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5:
2359 /*
2360 * Option to allow for the MD5 of the host public key to be checked
2361 * for validation purposes.
2362 */
2363 result = setstropt(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5],
2364 va_arg(param, char *));
2365 break;
2366 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2367 case CURLOPT_SSH_KNOWNHOSTS:
2368 /*
2369 * Store the file name to read known hosts from.
2370 */
2371 result = setstropt(&data->set.str[STRING_SSH_KNOWNHOSTS],
2372 va_arg(param, char *));
2373 break;
2374
2375 case CURLOPT_SSH_KEYFUNCTION:
2376 /* setting to NULL is fine since the ssh.c functions themselves will
2377 then rever to use the internal default */
2378 data->set.ssh_keyfunc = va_arg(param, curl_sshkeycallback);
2379 break;
2380
2381 case CURLOPT_SSH_KEYDATA:
2382 /*
2383 * Custom client data to pass to the SSH keyfunc callback
2384 */
2385 data->set.ssh_keyfunc_userp = va_arg(param, void *);
2386 break;
2387 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2388
2389 #endif /* USE_LIBSSH2 */
2390
2391 case CURLOPT_HTTP_TRANSFER_DECODING:
2392 /*
2393 * disable libcurl transfer encoding is used
2394 */
2395 data->set.http_te_skip = (0 == va_arg(param, long))?TRUE:FALSE;
2396 break;
2397
2398 case CURLOPT_HTTP_CONTENT_DECODING:
2399 /*
2400 * raw data passed to the application when content encoding is used
2401 */
2402 data->set.http_ce_skip = (0 == va_arg(param, long))?TRUE:FALSE;
2403 break;
2404
2405 case CURLOPT_NEW_FILE_PERMS:
2406 /*
2407 * Uses these permissions instead of 0644
2408 */
2409 data->set.new_file_perms = va_arg(param, long);
2410 break;
2411
2412 case CURLOPT_NEW_DIRECTORY_PERMS:
2413 /*
2414 * Uses these permissions instead of 0755
2415 */
2416 data->set.new_directory_perms = va_arg(param, long);
2417 break;
2418
2419 case CURLOPT_ADDRESS_SCOPE:
2420 /*
2421 * We always get longs when passed plain numericals, but for this value we
2422 * know that an unsigned int will always hold the value so we blindly
2423 * typecast to this type
2424 */
2425 data->set.scope_id = curlx_sltoui(va_arg(param, long));
2426 break;
2427
2428 case CURLOPT_PROTOCOLS:
2429 /* set the bitmask for the protocols that are allowed to be used for the
2430 transfer, which thus helps the app which takes URLs from users or other
2431 external inputs and want to restrict what protocol(s) to deal
2432 with. Defaults to CURLPROTO_ALL. */
2433 data->set.allowed_protocols = va_arg(param, long);
2434 break;
2435
2436 case CURLOPT_REDIR_PROTOCOLS:
2437 /* set the bitmask for the protocols that libcurl is allowed to follow to,
2438 as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
2439 to be set in both bitmasks to be allowed to get redirected to. Defaults
2440 to all protocols except FILE and SCP. */
2441 data->set.redir_protocols = va_arg(param, long);
2442 break;
2443
2444 case CURLOPT_MAIL_FROM:
2445 /* Set the SMTP mail originator */
2446 result = setstropt(&data->set.str[STRING_MAIL_FROM],
2447 va_arg(param, char *));
2448 break;
2449
2450 case CURLOPT_MAIL_AUTH:
2451 /* Set the SMTP auth originator */
2452 result = setstropt(&data->set.str[STRING_MAIL_AUTH],
2453 va_arg(param, char *));
2454 break;
2455
2456 case CURLOPT_MAIL_RCPT:
2457 /* Set the list of mail recipients */
2458 data->set.mail_rcpt = va_arg(param, struct curl_slist *);
2459 break;
2460
2461 case CURLOPT_SASL_IR:
2462 /* Enable/disable SASL initial response */
2463 data->set.sasl_ir = (0 != va_arg(param, long)) ? TRUE : FALSE;
2464 break;
2465
2466 case CURLOPT_RTSP_REQUEST:
2467 {
2468 /*
2469 * Set the RTSP request method (OPTIONS, SETUP, PLAY, etc...)
2470 * Would this be better if the RTSPREQ_* were just moved into here?
2471 */
2472 long curl_rtspreq = va_arg(param, long);
2473 Curl_RtspReq rtspreq = RTSPREQ_NONE;
2474 switch(curl_rtspreq) {
2475 case CURL_RTSPREQ_OPTIONS:
2476 rtspreq = RTSPREQ_OPTIONS;
2477 break;
2478
2479 case CURL_RTSPREQ_DESCRIBE:
2480 rtspreq = RTSPREQ_DESCRIBE;
2481 break;
2482
2483 case CURL_RTSPREQ_ANNOUNCE:
2484 rtspreq = RTSPREQ_ANNOUNCE;
2485 break;
2486
2487 case CURL_RTSPREQ_SETUP:
2488 rtspreq = RTSPREQ_SETUP;
2489 break;
2490
2491 case CURL_RTSPREQ_PLAY:
2492 rtspreq = RTSPREQ_PLAY;
2493 break;
2494
2495 case CURL_RTSPREQ_PAUSE:
2496 rtspreq = RTSPREQ_PAUSE;
2497 break;
2498
2499 case CURL_RTSPREQ_TEARDOWN:
2500 rtspreq = RTSPREQ_TEARDOWN;
2501 break;
2502
2503 case CURL_RTSPREQ_GET_PARAMETER:
2504 rtspreq = RTSPREQ_GET_PARAMETER;
2505 break;
2506
2507 case CURL_RTSPREQ_SET_PARAMETER:
2508 rtspreq = RTSPREQ_SET_PARAMETER;
2509 break;
2510
2511 case CURL_RTSPREQ_RECORD:
2512 rtspreq = RTSPREQ_RECORD;
2513 break;
2514
2515 case CURL_RTSPREQ_RECEIVE:
2516 rtspreq = RTSPREQ_RECEIVE;
2517 break;
2518 default:
2519 rtspreq = RTSPREQ_NONE;
2520 }
2521
2522 data->set.rtspreq = rtspreq;
2523 break;
2524 }
2525
2526
2527 case CURLOPT_RTSP_SESSION_ID:
2528 /*
2529 * Set the RTSP Session ID manually. Useful if the application is
2530 * resuming a previously established RTSP session
2531 */
2532 result = setstropt(&data->set.str[STRING_RTSP_SESSION_ID],
2533 va_arg(param, char *));
2534 break;
2535
2536 case CURLOPT_RTSP_STREAM_URI:
2537 /*
2538 * Set the Stream URI for the RTSP request. Unless the request is
2539 * for generic server options, the application will need to set this.
2540 */
2541 result = setstropt(&data->set.str[STRING_RTSP_STREAM_URI],
2542 va_arg(param, char *));
2543 break;
2544
2545 case CURLOPT_RTSP_TRANSPORT:
2546 /*
2547 * The content of the Transport: header for the RTSP request
2548 */
2549 result = setstropt(&data->set.str[STRING_RTSP_TRANSPORT],
2550 va_arg(param, char *));
2551 break;
2552
2553 case CURLOPT_RTSP_CLIENT_CSEQ:
2554 /*
2555 * Set the CSEQ number to issue for the next RTSP request. Useful if the
2556 * application is resuming a previously broken connection. The CSEQ
2557 * will increment from this new number henceforth.
2558 */
2559 data->state.rtsp_next_client_CSeq = va_arg(param, long);
2560 break;
2561
2562 case CURLOPT_RTSP_SERVER_CSEQ:
2563 /* Same as the above, but for server-initiated requests */
2564 data->state.rtsp_next_client_CSeq = va_arg(param, long);
2565 break;
2566
2567 case CURLOPT_INTERLEAVEDATA:
2568 data->set.rtp_out = va_arg(param, void *);
2569 break;
2570 case CURLOPT_INTERLEAVEFUNCTION:
2571 /* Set the user defined RTP write function */
2572 data->set.fwrite_rtp = va_arg(param, curl_write_callback);
2573 break;
2574
2575 case CURLOPT_WILDCARDMATCH:
2576 data->set.wildcardmatch = (0 != va_arg(param, long))?TRUE:FALSE;
2577 break;
2578 case CURLOPT_CHUNK_BGN_FUNCTION:
2579 data->set.chunk_bgn = va_arg(param, curl_chunk_bgn_callback);
2580 break;
2581 case CURLOPT_CHUNK_END_FUNCTION:
2582 data->set.chunk_end = va_arg(param, curl_chunk_end_callback);
2583 break;
2584 case CURLOPT_FNMATCH_FUNCTION:
2585 data->set.fnmatch = va_arg(param, curl_fnmatch_callback);
2586 break;
2587 case CURLOPT_CHUNK_DATA:
2588 data->wildcard.customptr = va_arg(param, void *);
2589 break;
2590 case CURLOPT_FNMATCH_DATA:
2591 data->set.fnmatch_data = va_arg(param, void *);
2592 break;
2593 #ifdef USE_TLS_SRP
2594 case CURLOPT_TLSAUTH_USERNAME:
2595 result = setstropt(&data->set.str[STRING_TLSAUTH_USERNAME],
2596 va_arg(param, char *));
2597 if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype)
2598 data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
2599 break;
2600 case CURLOPT_TLSAUTH_PASSWORD:
2601 result = setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD],
2602 va_arg(param, char *));
2603 if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype)
2604 data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
2605 break;
2606 case CURLOPT_TLSAUTH_TYPE:
2607 if(strnequal((char *)va_arg(param, char *), "SRP", strlen("SRP")))
2608 data->set.ssl.authtype = CURL_TLSAUTH_SRP;
2609 else
2610 data->set.ssl.authtype = CURL_TLSAUTH_NONE;
2611 break;
2612 #endif
2613 case CURLOPT_DNS_SERVERS:
2614 result = Curl_set_dns_servers(data, va_arg(param, char *));
2615 break;
2616 case CURLOPT_DNS_INTERFACE:
2617 result = Curl_set_dns_interface(data, va_arg(param, char *));
2618 break;
2619 case CURLOPT_DNS_LOCAL_IP4:
2620 result = Curl_set_dns_local_ip4(data, va_arg(param, char *));
2621 break;
2622 case CURLOPT_DNS_LOCAL_IP6:
2623 result = Curl_set_dns_local_ip6(data, va_arg(param, char *));
2624 break;
2625
2626 case CURLOPT_TCP_KEEPALIVE:
2627 data->set.tcp_keepalive = (0 != va_arg(param, long))?TRUE:FALSE;
2628 break;
2629 case CURLOPT_TCP_KEEPIDLE:
2630 data->set.tcp_keepidle = va_arg(param, long);
2631 break;
2632 case CURLOPT_TCP_KEEPINTVL:
2633 data->set.tcp_keepintvl = va_arg(param, long);
2634 break;
2635 case CURLOPT_SSL_ENABLE_NPN:
2636 data->set.ssl_enable_npn = (0 != va_arg(param, long))?TRUE:FALSE;
2637 break;
2638 case CURLOPT_SSL_ENABLE_ALPN:
2639 data->set.ssl_enable_alpn = (0 != va_arg(param, long))?TRUE:FALSE;
2640 break;
2641
2642 #ifdef USE_UNIX_SOCKETS
2643 case CURLOPT_UNIX_SOCKET_PATH:
2644 result = setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH],
2645 va_arg(param, char *));
2646 break;
2647 #endif
2648
2649 case CURLOPT_PATH_AS_IS:
2650 data->set.path_as_is = (0 != va_arg(param, long))?TRUE:FALSE;
2651 break;
2652 case CURLOPT_PIPEWAIT:
2653 data->set.pipewait = (0 != va_arg(param, long))?TRUE:FALSE;
2654 break;
2655 default:
2656 /* unknown tag and its companion, just ignore: */
2657 result = CURLE_UNKNOWN_OPTION;
2658 break;
2659 }
2660
2661 return result;
2662 }
2663
conn_free(struct connectdata * conn)2664 static void conn_free(struct connectdata *conn)
2665 {
2666 if(!conn)
2667 return;
2668
2669 /* possible left-overs from the async name resolvers */
2670 Curl_resolver_cancel(conn);
2671
2672 /* close the SSL stuff before we close any sockets since they will/may
2673 write to the sockets */
2674 Curl_ssl_close(conn, FIRSTSOCKET);
2675 Curl_ssl_close(conn, SECONDARYSOCKET);
2676
2677 /* close possibly still open sockets */
2678 if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
2679 Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
2680 if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET])
2681 Curl_closesocket(conn, conn->sock[FIRSTSOCKET]);
2682 if(CURL_SOCKET_BAD != conn->tempsock[0])
2683 Curl_closesocket(conn, conn->tempsock[0]);
2684 if(CURL_SOCKET_BAD != conn->tempsock[1])
2685 Curl_closesocket(conn, conn->tempsock[1]);
2686
2687 #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
2688 defined(NTLM_WB_ENABLED)
2689 Curl_ntlm_wb_cleanup(conn);
2690 #endif
2691
2692 Curl_safefree(conn->user);
2693 Curl_safefree(conn->passwd);
2694 Curl_safefree(conn->xoauth2_bearer);
2695 Curl_safefree(conn->options);
2696 Curl_safefree(conn->proxyuser);
2697 Curl_safefree(conn->proxypasswd);
2698 Curl_safefree(conn->allocptr.proxyuserpwd);
2699 Curl_safefree(conn->allocptr.uagent);
2700 Curl_safefree(conn->allocptr.userpwd);
2701 Curl_safefree(conn->allocptr.accept_encoding);
2702 Curl_safefree(conn->allocptr.te);
2703 Curl_safefree(conn->allocptr.rangeline);
2704 Curl_safefree(conn->allocptr.ref);
2705 Curl_safefree(conn->allocptr.host);
2706 Curl_safefree(conn->allocptr.cookiehost);
2707 Curl_safefree(conn->allocptr.rtsp_transport);
2708 Curl_safefree(conn->trailer);
2709 Curl_safefree(conn->host.rawalloc); /* host name buffer */
2710 Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */
2711 Curl_safefree(conn->master_buffer);
2712
2713 Curl_llist_destroy(conn->send_pipe, NULL);
2714 Curl_llist_destroy(conn->recv_pipe, NULL);
2715
2716 conn->send_pipe = NULL;
2717 conn->recv_pipe = NULL;
2718
2719 Curl_safefree(conn->localdev);
2720 Curl_free_ssl_config(&conn->ssl_config);
2721
2722 free(conn); /* free all the connection oriented data */
2723 }
2724
2725 /*
2726 * Disconnects the given connection. Note the connection may not be the
2727 * primary connection, like when freeing room in the connection cache or
2728 * killing of a dead old connection.
2729 *
2730 * This function MUST NOT reset state in the SessionHandle struct if that
2731 * isn't strictly bound to the life-time of *this* particular connection.
2732 *
2733 */
2734
Curl_disconnect(struct connectdata * conn,bool dead_connection)2735 CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
2736 {
2737 struct SessionHandle *data;
2738 if(!conn)
2739 return CURLE_OK; /* this is closed and fine already */
2740 data = conn->data;
2741
2742 if(!data) {
2743 DEBUGF(fprintf(stderr, "DISCONNECT without easy handle, ignoring\n"));
2744 return CURLE_OK;
2745 }
2746
2747 if(conn->dns_entry != NULL) {
2748 Curl_resolv_unlock(data, conn->dns_entry);
2749 conn->dns_entry = NULL;
2750 }
2751
2752 Curl_hostcache_prune(data); /* kill old DNS cache entries */
2753
2754 #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM)
2755 /* Cleanup NTLM connection-related data */
2756 Curl_http_ntlm_cleanup(conn);
2757 #endif
2758
2759 if(conn->handler->disconnect)
2760 /* This is set if protocol-specific cleanups should be made */
2761 conn->handler->disconnect(conn, dead_connection);
2762
2763 /* unlink ourselves! */
2764 infof(data, "Closing connection %ld\n", conn->connection_id);
2765 Curl_conncache_remove_conn(data->state.conn_cache, conn);
2766
2767 #if defined(USE_LIBIDN)
2768 if(conn->host.encalloc)
2769 idn_free(conn->host.encalloc); /* encoded host name buffer, must be freed
2770 with idn_free() since this was allocated
2771 by libidn */
2772 if(conn->proxy.encalloc)
2773 idn_free(conn->proxy.encalloc); /* encoded proxy name buffer, must be
2774 freed with idn_free() since this was
2775 allocated by libidn */
2776 #elif defined(USE_WIN32_IDN)
2777 free(conn->host.encalloc); /* encoded host name buffer, must be freed with
2778 idn_free() since this was allocated by
2779 curl_win32_idn_to_ascii */
2780 free(conn->proxy.encalloc); /* encoded proxy name buffer, must be freed
2781 with idn_free() since this was allocated by
2782 curl_win32_idn_to_ascii */
2783 #endif
2784
2785 Curl_ssl_close(conn, FIRSTSOCKET);
2786
2787 /* Indicate to all handles on the pipe that we're dead */
2788 if(Curl_pipeline_wanted(data->multi, CURLPIPE_ANY)) {
2789 signalPipeClose(conn->send_pipe, TRUE);
2790 signalPipeClose(conn->recv_pipe, TRUE);
2791 }
2792
2793 conn_free(conn);
2794
2795 return CURLE_OK;
2796 }
2797
2798 /*
2799 * This function should return TRUE if the socket is to be assumed to
2800 * be dead. Most commonly this happens when the server has closed the
2801 * connection due to inactivity.
2802 */
SocketIsDead(curl_socket_t sock)2803 static bool SocketIsDead(curl_socket_t sock)
2804 {
2805 int sval;
2806 bool ret_val = TRUE;
2807
2808 sval = Curl_socket_ready(sock, CURL_SOCKET_BAD, 0);
2809 if(sval == 0)
2810 /* timeout */
2811 ret_val = FALSE;
2812
2813 return ret_val;
2814 }
2815
2816 /*
2817 * IsPipeliningPossible() returns TRUE if the options set would allow
2818 * pipelining/multiplexing and the connection is using a HTTP protocol.
2819 */
IsPipeliningPossible(const struct SessionHandle * handle,const struct connectdata * conn)2820 static bool IsPipeliningPossible(const struct SessionHandle *handle,
2821 const struct connectdata *conn)
2822 {
2823 /* If a HTTP protocol and pipelining is enabled */
2824 if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
2825
2826 if(Curl_pipeline_wanted(handle->multi, CURLPIPE_HTTP1) &&
2827 (handle->set.httpversion != CURL_HTTP_VERSION_1_0) &&
2828 (handle->set.httpreq == HTTPREQ_GET ||
2829 handle->set.httpreq == HTTPREQ_HEAD))
2830 /* didn't ask for HTTP/1.0 and a GET or HEAD */
2831 return TRUE;
2832
2833 if(Curl_pipeline_wanted(handle->multi, CURLPIPE_MULTIPLEX) &&
2834 (handle->set.httpversion == CURL_HTTP_VERSION_2_0))
2835 /* allows HTTP/2 */
2836 return TRUE;
2837 }
2838 return FALSE;
2839 }
2840
Curl_removeHandleFromPipeline(struct SessionHandle * handle,struct curl_llist * pipeline)2841 int Curl_removeHandleFromPipeline(struct SessionHandle *handle,
2842 struct curl_llist *pipeline)
2843 {
2844 struct curl_llist_element *curr;
2845
2846 curr = pipeline->head;
2847 while(curr) {
2848 if(curr->ptr == handle) {
2849 Curl_llist_remove(pipeline, curr, NULL);
2850 return 1; /* we removed a handle */
2851 }
2852 curr = curr->next;
2853 }
2854
2855 return 0;
2856 }
2857
2858 #if 0 /* this code is saved here as it is useful for debugging purposes */
2859 static void Curl_printPipeline(struct curl_llist *pipeline)
2860 {
2861 struct curl_llist_element *curr;
2862
2863 curr = pipeline->head;
2864 while(curr) {
2865 struct SessionHandle *data = (struct SessionHandle *) curr->ptr;
2866 infof(data, "Handle in pipeline: %s\n", data->state.path);
2867 curr = curr->next;
2868 }
2869 }
2870 #endif
2871
gethandleathead(struct curl_llist * pipeline)2872 static struct SessionHandle* gethandleathead(struct curl_llist *pipeline)
2873 {
2874 struct curl_llist_element *curr = pipeline->head;
2875 if(curr) {
2876 return (struct SessionHandle *) curr->ptr;
2877 }
2878
2879 return NULL;
2880 }
2881
2882 /* remove the specified connection from all (possible) pipelines and related
2883 queues */
Curl_getoff_all_pipelines(struct SessionHandle * data,struct connectdata * conn)2884 void Curl_getoff_all_pipelines(struct SessionHandle *data,
2885 struct connectdata *conn)
2886 {
2887 bool recv_head = (conn->readchannel_inuse &&
2888 Curl_recvpipe_head(data, conn));
2889 bool send_head = (conn->writechannel_inuse &&
2890 Curl_sendpipe_head(data, conn));
2891
2892 if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) && recv_head)
2893 Curl_pipeline_leave_read(conn);
2894 if(Curl_removeHandleFromPipeline(data, conn->send_pipe) && send_head)
2895 Curl_pipeline_leave_write(conn);
2896 }
2897
signalPipeClose(struct curl_llist * pipeline,bool pipe_broke)2898 static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke)
2899 {
2900 struct curl_llist_element *curr;
2901
2902 if(!pipeline)
2903 return;
2904
2905 curr = pipeline->head;
2906 while(curr) {
2907 struct curl_llist_element *next = curr->next;
2908 struct SessionHandle *data = (struct SessionHandle *) curr->ptr;
2909
2910 #ifdef DEBUGBUILD /* debug-only code */
2911 if(data->magic != CURLEASY_MAGIC_NUMBER) {
2912 /* MAJOR BADNESS */
2913 infof(data, "signalPipeClose() found BAAD easy handle\n");
2914 }
2915 #endif
2916
2917 if(pipe_broke)
2918 data->state.pipe_broke = TRUE;
2919 Curl_multi_handlePipeBreak(data);
2920 Curl_llist_remove(pipeline, curr, NULL);
2921 curr = next;
2922 }
2923 }
2924
2925 /*
2926 * This function finds the connection in the connection
2927 * cache that has been unused for the longest time.
2928 *
2929 * Returns the pointer to the oldest idle connection, or NULL if none was
2930 * found.
2931 */
2932 static struct connectdata *
find_oldest_idle_connection(struct SessionHandle * data)2933 find_oldest_idle_connection(struct SessionHandle *data)
2934 {
2935 struct conncache *bc = data->state.conn_cache;
2936 struct curl_hash_iterator iter;
2937 struct curl_llist_element *curr;
2938 struct curl_hash_element *he;
2939 long highscore=-1;
2940 long score;
2941 struct timeval now;
2942 struct connectdata *conn_candidate = NULL;
2943 struct connectbundle *bundle;
2944
2945 now = Curl_tvnow();
2946
2947 Curl_hash_start_iterate(&bc->hash, &iter);
2948
2949 he = Curl_hash_next_element(&iter);
2950 while(he) {
2951 struct connectdata *conn;
2952
2953 bundle = he->ptr;
2954
2955 curr = bundle->conn_list->head;
2956 while(curr) {
2957 conn = curr->ptr;
2958
2959 if(!conn->inuse) {
2960 /* Set higher score for the age passed since the connection was used */
2961 score = Curl_tvdiff(now, conn->now);
2962
2963 if(score > highscore) {
2964 highscore = score;
2965 conn_candidate = conn;
2966 }
2967 }
2968 curr = curr->next;
2969 }
2970
2971 he = Curl_hash_next_element(&iter);
2972 }
2973
2974 return conn_candidate;
2975 }
2976
2977 /*
2978 * This function finds the connection in the connection
2979 * bundle that has been unused for the longest time.
2980 *
2981 * Returns the pointer to the oldest idle connection, or NULL if none was
2982 * found.
2983 */
2984 static struct connectdata *
find_oldest_idle_connection_in_bundle(struct SessionHandle * data,struct connectbundle * bundle)2985 find_oldest_idle_connection_in_bundle(struct SessionHandle *data,
2986 struct connectbundle *bundle)
2987 {
2988 struct curl_llist_element *curr;
2989 long highscore=-1;
2990 long score;
2991 struct timeval now;
2992 struct connectdata *conn_candidate = NULL;
2993 struct connectdata *conn;
2994
2995 (void)data;
2996
2997 now = Curl_tvnow();
2998
2999 curr = bundle->conn_list->head;
3000 while(curr) {
3001 conn = curr->ptr;
3002
3003 if(!conn->inuse) {
3004 /* Set higher score for the age passed since the connection was used */
3005 score = Curl_tvdiff(now, conn->now);
3006
3007 if(score > highscore) {
3008 highscore = score;
3009 conn_candidate = conn;
3010 }
3011 }
3012 curr = curr->next;
3013 }
3014
3015 return conn_candidate;
3016 }
3017
3018 /*
3019 * This function checks if given connection is dead and disconnects if so.
3020 * (That also removes it from the connection cache.)
3021 *
3022 * Returns TRUE if the connection actually was dead and disconnected.
3023 */
disconnect_if_dead(struct connectdata * conn,struct SessionHandle * data)3024 static bool disconnect_if_dead(struct connectdata *conn,
3025 struct SessionHandle *data)
3026 {
3027 size_t pipeLen = conn->send_pipe->size + conn->recv_pipe->size;
3028 if(!pipeLen && !conn->inuse) {
3029 /* The check for a dead socket makes sense only if there are no
3030 handles in pipeline and the connection isn't already marked in
3031 use */
3032 bool dead;
3033 if(conn->handler->protocol & CURLPROTO_RTSP)
3034 /* RTSP is a special case due to RTP interleaving */
3035 dead = Curl_rtsp_connisdead(conn);
3036 else
3037 dead = SocketIsDead(conn->sock[FIRSTSOCKET]);
3038
3039 if(dead) {
3040 conn->data = data;
3041 infof(data, "Connection %ld seems to be dead!\n", conn->connection_id);
3042
3043 /* disconnect resources */
3044 Curl_disconnect(conn, /* dead_connection */TRUE);
3045 return TRUE;
3046 }
3047 }
3048 return FALSE;
3049 }
3050
3051 /*
3052 * Wrapper to use disconnect_if_dead() function in Curl_conncache_foreach()
3053 *
3054 * Returns always 0.
3055 */
call_disconnect_if_dead(struct connectdata * conn,void * param)3056 static int call_disconnect_if_dead(struct connectdata *conn,
3057 void *param)
3058 {
3059 struct SessionHandle* data = (struct SessionHandle*)param;
3060 disconnect_if_dead(conn, data);
3061 return 0; /* continue iteration */
3062 }
3063
3064 /*
3065 * This function scans the connection cache for half-open/dead connections,
3066 * closes and removes them.
3067 * The cleanup is done at most once per second.
3068 */
prune_dead_connections(struct SessionHandle * data)3069 static void prune_dead_connections(struct SessionHandle *data)
3070 {
3071 struct timeval now = Curl_tvnow();
3072 long elapsed = Curl_tvdiff(now, data->state.conn_cache->last_cleanup);
3073
3074 if(elapsed >= 1000L) {
3075 Curl_conncache_foreach(data->state.conn_cache, data,
3076 call_disconnect_if_dead);
3077 data->state.conn_cache->last_cleanup = now;
3078 }
3079 }
3080
3081
max_pipeline_length(struct Curl_multi * multi)3082 static size_t max_pipeline_length(struct Curl_multi *multi)
3083 {
3084 return multi ? multi->max_pipeline_length : 0;
3085 }
3086
3087
3088 /*
3089 * Given one filled in connection struct (named needle), this function should
3090 * detect if there already is one that has all the significant details
3091 * exactly the same and thus should be used instead.
3092 *
3093 * If there is a match, this function returns TRUE - and has marked the
3094 * connection as 'in-use'. It must later be called with ConnectionDone() to
3095 * return back to 'idle' (unused) state.
3096 *
3097 * The force_reuse flag is set if the connection must be used, even if
3098 * the pipelining strategy wants to open a new connection instead of reusing.
3099 */
3100 static bool
ConnectionExists(struct SessionHandle * data,struct connectdata * needle,struct connectdata ** usethis,bool * force_reuse,bool * waitpipe)3101 ConnectionExists(struct SessionHandle *data,
3102 struct connectdata *needle,
3103 struct connectdata **usethis,
3104 bool *force_reuse,
3105 bool *waitpipe)
3106 {
3107 struct connectdata *check;
3108 struct connectdata *chosen = 0;
3109 bool canPipeline = IsPipeliningPossible(data, needle);
3110 #ifdef USE_NTLM
3111 bool wantNTLMhttp = ((data->state.authhost.want & CURLAUTH_NTLM) ||
3112 (data->state.authhost.want & CURLAUTH_NTLM_WB)) &&
3113 (needle->handler->protocol & PROTO_FAMILY_HTTP) ? TRUE : FALSE;
3114 #endif
3115 struct connectbundle *bundle;
3116
3117 *force_reuse = FALSE;
3118 *waitpipe = FALSE;
3119
3120 /* We can't pipe if the site is blacklisted */
3121 if(canPipeline && Curl_pipeline_site_blacklisted(data, needle)) {
3122 canPipeline = FALSE;
3123 }
3124
3125 /* Look up the bundle with all the connections to this
3126 particular host */
3127 bundle = Curl_conncache_find_bundle(needle, data->state.conn_cache);
3128 if(bundle) {
3129 /* Max pipe length is zero (unlimited) for multiplexed connections */
3130 size_t max_pipe_len = (bundle->multiuse != BUNDLE_MULTIPLEX)?
3131 max_pipeline_length(data->multi):0;
3132 size_t best_pipe_len = max_pipe_len;
3133 struct curl_llist_element *curr;
3134
3135 infof(data, "Found bundle for host %s: %p\n",
3136 needle->host.name, (void *)bundle);
3137
3138 /* We can't pipe if we don't know anything about the server */
3139 if(canPipeline) {
3140 if(bundle->multiuse <= BUNDLE_UNKNOWN) {
3141 if((bundle->multiuse == BUNDLE_UNKNOWN) && data->set.pipewait) {
3142 infof(data, "Server doesn't support multi-use yet, wait\n");
3143 *waitpipe = TRUE;
3144 return FALSE; /* no re-use */
3145 }
3146
3147 infof(data, "Server doesn't support multi-use (yet)\n");
3148 canPipeline = FALSE;
3149 }
3150 }
3151
3152 curr = bundle->conn_list->head;
3153 while(curr) {
3154 bool match = FALSE;
3155 #if defined(USE_NTLM)
3156 bool credentialsMatch = FALSE;
3157 #endif
3158 size_t pipeLen;
3159
3160 /*
3161 * Note that if we use a HTTP proxy, we check connections to that
3162 * proxy and not to the actual remote server.
3163 */
3164 check = curr->ptr;
3165 curr = curr->next;
3166
3167 if(disconnect_if_dead(check, data))
3168 continue;
3169
3170 pipeLen = check->send_pipe->size + check->recv_pipe->size;
3171
3172 if(canPipeline) {
3173
3174 if(!check->bits.multiplex) {
3175 /* If not multiplexing, make sure the pipe has only GET requests */
3176 struct SessionHandle* sh = gethandleathead(check->send_pipe);
3177 struct SessionHandle* rh = gethandleathead(check->recv_pipe);
3178 if(sh) {
3179 if(!IsPipeliningPossible(sh, check))
3180 continue;
3181 }
3182 else if(rh) {
3183 if(!IsPipeliningPossible(rh, check))
3184 continue;
3185 }
3186 }
3187 }
3188 else {
3189 if(pipeLen > 0) {
3190 /* can only happen within multi handles, and means that another easy
3191 handle is using this connection */
3192 continue;
3193 }
3194
3195 if(Curl_resolver_asynch()) {
3196 /* ip_addr_str[0] is NUL only if the resolving of the name hasn't
3197 completed yet and until then we don't re-use this connection */
3198 if(!check->ip_addr_str[0]) {
3199 infof(data,
3200 "Connection #%ld is still name resolving, can't reuse\n",
3201 check->connection_id);
3202 continue;
3203 }
3204 }
3205
3206 if((check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) ||
3207 check->bits.close) {
3208 /* Don't pick a connection that hasn't connected yet or that is going
3209 to get closed. */
3210 infof(data, "Connection #%ld isn't open enough, can't reuse\n",
3211 check->connection_id);
3212 #ifdef DEBUGBUILD
3213 if(check->recv_pipe->size > 0) {
3214 infof(data,
3215 "BAD! Unconnected #%ld has a non-empty recv pipeline!\n",
3216 check->connection_id);
3217 }
3218 #endif
3219 continue;
3220 }
3221 }
3222
3223 if((needle->handler->flags&PROTOPT_SSL) !=
3224 (check->handler->flags&PROTOPT_SSL))
3225 /* don't do mixed SSL and non-SSL connections */
3226 if(!(needle->handler->protocol & check->handler->protocol))
3227 /* except protocols that have been upgraded via TLS */
3228 continue;
3229
3230 if(needle->handler->flags&PROTOPT_SSL) {
3231 if((data->set.ssl.verifypeer != check->verifypeer) ||
3232 (data->set.ssl.verifyhost != check->verifyhost))
3233 continue;
3234 }
3235
3236 if(needle->bits.proxy != check->bits.proxy)
3237 /* don't do mixed proxy and non-proxy connections */
3238 continue;
3239
3240 if(!canPipeline && check->inuse)
3241 /* this request can't be pipelined but the checked connection is
3242 already in use so we skip it */
3243 continue;
3244
3245 if(needle->localdev || needle->localport) {
3246 /* If we are bound to a specific local end (IP+port), we must not
3247 re-use a random other one, although if we didn't ask for a
3248 particular one we can reuse one that was bound.
3249
3250 This comparison is a bit rough and too strict. Since the input
3251 parameters can be specified in numerous ways and still end up the
3252 same it would take a lot of processing to make it really accurate.
3253 Instead, this matching will assume that re-uses of bound connections
3254 will most likely also re-use the exact same binding parameters and
3255 missing out a few edge cases shouldn't hurt anyone very much.
3256 */
3257 if((check->localport != needle->localport) ||
3258 (check->localportrange != needle->localportrange) ||
3259 !check->localdev ||
3260 !needle->localdev ||
3261 strcmp(check->localdev, needle->localdev))
3262 continue;
3263 }
3264
3265 if((!(needle->handler->flags & PROTOPT_CREDSPERREQUEST))
3266 #ifdef USE_NTLM
3267 || (wantNTLMhttp || check->ntlm.state != NTLMSTATE_NONE)
3268 #endif
3269 ) {
3270 /* This protocol requires credentials per connection or is HTTP+NTLM,
3271 so verify that we're using the same name and password as well */
3272 if(!strequal(needle->user, check->user) ||
3273 !strequal(needle->passwd, check->passwd)) {
3274 /* one of them was different */
3275 continue;
3276 }
3277 #if defined(USE_NTLM)
3278 credentialsMatch = TRUE;
3279 #endif
3280 }
3281
3282 if(!needle->bits.httpproxy || needle->handler->flags&PROTOPT_SSL ||
3283 (needle->bits.httpproxy && check->bits.httpproxy &&
3284 needle->bits.tunnel_proxy && check->bits.tunnel_proxy &&
3285 Curl_raw_equal(needle->proxy.name, check->proxy.name) &&
3286 (needle->port == check->port))) {
3287 /* The requested connection does not use a HTTP proxy or it uses SSL or
3288 it is a non-SSL protocol tunneled over the same http proxy name and
3289 port number or it is a non-SSL protocol which is allowed to be
3290 upgraded via TLS */
3291
3292 if((Curl_raw_equal(needle->handler->scheme, check->handler->scheme) ||
3293 needle->handler->protocol & check->handler->protocol) &&
3294 Curl_raw_equal(needle->host.name, check->host.name) &&
3295 needle->remote_port == check->remote_port) {
3296 if(needle->handler->flags & PROTOPT_SSL) {
3297 /* This is a SSL connection so verify that we're using the same
3298 SSL options as well */
3299 if(!Curl_ssl_config_matches(&needle->ssl_config,
3300 &check->ssl_config)) {
3301 DEBUGF(infof(data,
3302 "Connection #%ld has different SSL parameters, "
3303 "can't reuse\n",
3304 check->connection_id));
3305 continue;
3306 }
3307 else if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete) {
3308 DEBUGF(infof(data,
3309 "Connection #%ld has not started SSL connect, "
3310 "can't reuse\n",
3311 check->connection_id));
3312 continue;
3313 }
3314 }
3315 match = TRUE;
3316 }
3317 }
3318 else { /* The requested needle connection is using a proxy,
3319 is the checked one using the same host, port and type? */
3320 if(check->bits.proxy &&
3321 (needle->proxytype == check->proxytype) &&
3322 (needle->bits.tunnel_proxy == check->bits.tunnel_proxy) &&
3323 Curl_raw_equal(needle->proxy.name, check->proxy.name) &&
3324 needle->port == check->port) {
3325 /* This is the same proxy connection, use it! */
3326 match = TRUE;
3327 }
3328 }
3329
3330 if(match) {
3331 #if defined(USE_NTLM)
3332 /* If we are looking for an HTTP+NTLM connection, check if this is
3333 already authenticating with the right credentials. If not, keep
3334 looking so that we can reuse NTLM connections if
3335 possible. (Especially we must not reuse the same connection if
3336 partway through a handshake!) */
3337 if(wantNTLMhttp) {
3338 if(credentialsMatch && check->ntlm.state != NTLMSTATE_NONE) {
3339 chosen = check;
3340
3341 /* We must use this connection, no other */
3342 *force_reuse = TRUE;
3343 break;
3344 }
3345 else if(credentialsMatch)
3346 /* this is a backup choice */
3347 chosen = check;
3348 continue;
3349 }
3350 #endif
3351
3352 if(canPipeline) {
3353 /* We can pipeline if we want to. Let's continue looking for
3354 the optimal connection to use, i.e the shortest pipe that is not
3355 blacklisted. */
3356
3357 if(pipeLen == 0) {
3358 /* We have the optimal connection. Let's stop looking. */
3359 chosen = check;
3360 break;
3361 }
3362
3363 /* We can't use the connection if the pipe is full */
3364 if(max_pipe_len && (pipeLen >= max_pipe_len)) {
3365 infof(data, "Pipe is full, skip (%zu)\n", pipeLen);
3366 continue;
3367 }
3368 #ifdef USE_NGHTTP2
3369 /* If multiplexed, make sure we don't go over concurrency limit */
3370 if(check->bits.multiplex) {
3371 /* Multiplexed connections can only be HTTP/2 for now */
3372 struct http_conn *httpc = &check->proto.httpc;
3373 if(pipeLen >= httpc->settings.max_concurrent_streams) {
3374 infof(data, "MAX_CONCURRENT_STREAMS reached, skip (%zu)\n",
3375 pipeLen);
3376 continue;
3377 }
3378 }
3379 #endif
3380 /* We can't use the connection if the pipe is penalized */
3381 if(Curl_pipeline_penalized(data, check)) {
3382 infof(data, "Penalized, skip\n");
3383 continue;
3384 }
3385
3386 if(max_pipe_len) {
3387 if(pipeLen < best_pipe_len) {
3388 /* This connection has a shorter pipe so far. We'll pick this
3389 and continue searching */
3390 chosen = check;
3391 best_pipe_len = pipeLen;
3392 continue;
3393 }
3394 }
3395 else {
3396 /* When not pipelining (== multiplexed), we have a match here! */
3397 chosen = check;
3398 infof(data, "Multiplexed connection found!\n");
3399 break;
3400 }
3401 }
3402 else {
3403 /* We have found a connection. Let's stop searching. */
3404 chosen = check;
3405 break;
3406 }
3407 }
3408 }
3409 }
3410
3411 if(chosen) {
3412 *usethis = chosen;
3413 return TRUE; /* yes, we found one to use! */
3414 }
3415
3416 return FALSE; /* no matching connecting exists */
3417 }
3418
3419 /* Mark the connection as 'idle', or close it if the cache is full.
3420 Returns TRUE if the connection is kept, or FALSE if it was closed. */
3421 static bool
ConnectionDone(struct SessionHandle * data,struct connectdata * conn)3422 ConnectionDone(struct SessionHandle *data, struct connectdata *conn)
3423 {
3424 /* data->multi->maxconnects can be negative, deal with it. */
3425 size_t maxconnects =
3426 (data->multi->maxconnects < 0) ? data->multi->num_easy * 4:
3427 data->multi->maxconnects;
3428 struct connectdata *conn_candidate = NULL;
3429
3430 /* Mark the current connection as 'unused' */
3431 conn->inuse = FALSE;
3432
3433 if(maxconnects > 0 &&
3434 data->state.conn_cache->num_connections > maxconnects) {
3435 infof(data, "Connection cache is full, closing the oldest one.\n");
3436
3437 conn_candidate = find_oldest_idle_connection(data);
3438
3439 if(conn_candidate) {
3440 /* Set the connection's owner correctly */
3441 conn_candidate->data = data;
3442
3443 /* the winner gets the honour of being disconnected */
3444 (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
3445 }
3446 }
3447
3448 return (conn_candidate == conn) ? FALSE : TRUE;
3449 }
3450
3451 /* after a TCP connection to the proxy has been verified, this function does
3452 the next magic step.
3453
3454 Note: this function's sub-functions call failf()
3455
3456 */
Curl_connected_proxy(struct connectdata * conn,int sockindex)3457 CURLcode Curl_connected_proxy(struct connectdata *conn,
3458 int sockindex)
3459 {
3460 if(!conn->bits.proxy || sockindex)
3461 /* this magic only works for the primary socket as the secondary is used
3462 for FTP only and it has FTP specific magic in ftp.c */
3463 return CURLE_OK;
3464
3465 switch(conn->proxytype) {
3466 #ifndef CURL_DISABLE_PROXY
3467 case CURLPROXY_SOCKS5:
3468 case CURLPROXY_SOCKS5_HOSTNAME:
3469 return Curl_SOCKS5(conn->proxyuser, conn->proxypasswd,
3470 conn->host.name, conn->remote_port,
3471 FIRSTSOCKET, conn);
3472
3473 case CURLPROXY_SOCKS4:
3474 return Curl_SOCKS4(conn->proxyuser, conn->host.name,
3475 conn->remote_port, FIRSTSOCKET, conn, FALSE);
3476
3477 case CURLPROXY_SOCKS4A:
3478 return Curl_SOCKS4(conn->proxyuser, conn->host.name,
3479 conn->remote_port, FIRSTSOCKET, conn, TRUE);
3480
3481 #endif /* CURL_DISABLE_PROXY */
3482 case CURLPROXY_HTTP:
3483 case CURLPROXY_HTTP_1_0:
3484 /* do nothing here. handled later. */
3485 break;
3486 default:
3487 break;
3488 } /* switch proxytype */
3489
3490 return CURLE_OK;
3491 }
3492
3493 /*
3494 * verboseconnect() displays verbose information after a connect
3495 */
3496 #ifndef CURL_DISABLE_VERBOSE_STRINGS
Curl_verboseconnect(struct connectdata * conn)3497 void Curl_verboseconnect(struct connectdata *conn)
3498 {
3499 if(conn->data->set.verbose)
3500 infof(conn->data, "Connected to %s (%s) port %ld (#%ld)\n",
3501 conn->bits.proxy ? conn->proxy.dispname : conn->host.dispname,
3502 conn->ip_addr_str, conn->port, conn->connection_id);
3503 }
3504 #endif
3505
Curl_protocol_getsock(struct connectdata * conn,curl_socket_t * socks,int numsocks)3506 int Curl_protocol_getsock(struct connectdata *conn,
3507 curl_socket_t *socks,
3508 int numsocks)
3509 {
3510 if(conn->handler->proto_getsock)
3511 return conn->handler->proto_getsock(conn, socks, numsocks);
3512 return GETSOCK_BLANK;
3513 }
3514
Curl_doing_getsock(struct connectdata * conn,curl_socket_t * socks,int numsocks)3515 int Curl_doing_getsock(struct connectdata *conn,
3516 curl_socket_t *socks,
3517 int numsocks)
3518 {
3519 if(conn && conn->handler->doing_getsock)
3520 return conn->handler->doing_getsock(conn, socks, numsocks);
3521 return GETSOCK_BLANK;
3522 }
3523
3524 /*
3525 * We are doing protocol-specific connecting and this is being called over and
3526 * over from the multi interface until the connection phase is done on
3527 * protocol layer.
3528 */
3529
Curl_protocol_connecting(struct connectdata * conn,bool * done)3530 CURLcode Curl_protocol_connecting(struct connectdata *conn,
3531 bool *done)
3532 {
3533 CURLcode result=CURLE_OK;
3534
3535 if(conn && conn->handler->connecting) {
3536 *done = FALSE;
3537 result = conn->handler->connecting(conn, done);
3538 }
3539 else
3540 *done = TRUE;
3541
3542 return result;
3543 }
3544
3545 /*
3546 * We are DOING this is being called over and over from the multi interface
3547 * until the DOING phase is done on protocol layer.
3548 */
3549
Curl_protocol_doing(struct connectdata * conn,bool * done)3550 CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done)
3551 {
3552 CURLcode result=CURLE_OK;
3553
3554 if(conn && conn->handler->doing) {
3555 *done = FALSE;
3556 result = conn->handler->doing(conn, done);
3557 }
3558 else
3559 *done = TRUE;
3560
3561 return result;
3562 }
3563
3564 /*
3565 * We have discovered that the TCP connection has been successful, we can now
3566 * proceed with some action.
3567 *
3568 */
Curl_protocol_connect(struct connectdata * conn,bool * protocol_done)3569 CURLcode Curl_protocol_connect(struct connectdata *conn,
3570 bool *protocol_done)
3571 {
3572 CURLcode result=CURLE_OK;
3573
3574 *protocol_done = FALSE;
3575
3576 if(conn->bits.tcpconnect[FIRSTSOCKET] && conn->bits.protoconnstart) {
3577 /* We already are connected, get back. This may happen when the connect
3578 worked fine in the first call, like when we connect to a local server
3579 or proxy. Note that we don't know if the protocol is actually done.
3580
3581 Unless this protocol doesn't have any protocol-connect callback, as
3582 then we know we're done. */
3583 if(!conn->handler->connecting)
3584 *protocol_done = TRUE;
3585
3586 return CURLE_OK;
3587 }
3588
3589 if(!conn->bits.protoconnstart) {
3590
3591 result = Curl_proxy_connect(conn);
3592 if(result)
3593 return result;
3594
3595 if(conn->bits.tunnel_proxy && conn->bits.httpproxy &&
3596 (conn->tunnel_state[FIRSTSOCKET] != TUNNEL_COMPLETE))
3597 /* when using an HTTP tunnel proxy, await complete tunnel establishment
3598 before proceeding further. Return CURLE_OK so we'll be called again */
3599 return CURLE_OK;
3600
3601 if(conn->handler->connect_it) {
3602 /* is there a protocol-specific connect() procedure? */
3603
3604 /* Call the protocol-specific connect function */
3605 result = conn->handler->connect_it(conn, protocol_done);
3606 }
3607 else
3608 *protocol_done = TRUE;
3609
3610 /* it has started, possibly even completed but that knowledge isn't stored
3611 in this bit! */
3612 if(!result)
3613 conn->bits.protoconnstart = TRUE;
3614 }
3615
3616 return result; /* pass back status */
3617 }
3618
3619 /*
3620 * Helpers for IDNA convertions.
3621 */
is_ASCII_name(const char * hostname)3622 static bool is_ASCII_name(const char *hostname)
3623 {
3624 const unsigned char *ch = (const unsigned char*)hostname;
3625
3626 while(*ch) {
3627 if(*ch++ & 0x80)
3628 return FALSE;
3629 }
3630 return TRUE;
3631 }
3632
3633 #ifdef USE_LIBIDN
3634 /*
3635 * Check if characters in hostname is allowed in Top Level Domain.
3636 */
tld_check_name(struct SessionHandle * data,const char * ace_hostname)3637 static bool tld_check_name(struct SessionHandle *data,
3638 const char *ace_hostname)
3639 {
3640 size_t err_pos;
3641 char *uc_name = NULL;
3642 int rc;
3643 #ifndef CURL_DISABLE_VERBOSE_STRINGS
3644 const char *tld_errmsg = "<no msg>";
3645 #else
3646 (void)data;
3647 #endif
3648
3649 /* Convert (and downcase) ACE-name back into locale's character set */
3650 rc = idna_to_unicode_lzlz(ace_hostname, &uc_name, 0);
3651 if(rc != IDNA_SUCCESS)
3652 return FALSE;
3653
3654 rc = tld_check_lz(uc_name, &err_pos, NULL);
3655 #ifndef CURL_DISABLE_VERBOSE_STRINGS
3656 #ifdef HAVE_TLD_STRERROR
3657 if(rc != TLD_SUCCESS)
3658 tld_errmsg = tld_strerror((Tld_rc)rc);
3659 #endif
3660 if(rc == TLD_INVALID)
3661 infof(data, "WARNING: %s; pos %u = `%c'/0x%02X\n",
3662 tld_errmsg, err_pos, uc_name[err_pos],
3663 uc_name[err_pos] & 255);
3664 else if(rc != TLD_SUCCESS)
3665 infof(data, "WARNING: TLD check for %s failed; %s\n",
3666 uc_name, tld_errmsg);
3667 #endif /* CURL_DISABLE_VERBOSE_STRINGS */
3668 if(uc_name)
3669 idn_free(uc_name);
3670 if(rc != TLD_SUCCESS)
3671 return FALSE;
3672
3673 return TRUE;
3674 }
3675 #endif
3676
3677 /*
3678 * Perform any necessary IDN conversion of hostname
3679 */
fix_hostname(struct SessionHandle * data,struct connectdata * conn,struct hostname * host)3680 static void fix_hostname(struct SessionHandle *data,
3681 struct connectdata *conn, struct hostname *host)
3682 {
3683 size_t len;
3684
3685 #ifndef USE_LIBIDN
3686 (void)data;
3687 (void)conn;
3688 #elif defined(CURL_DISABLE_VERBOSE_STRINGS)
3689 (void)conn;
3690 #endif
3691
3692 /* set the name we use to display the host name */
3693 host->dispname = host->name;
3694
3695 len = strlen(host->name);
3696 if(len && (host->name[len-1] == '.'))
3697 /* strip off a single trailing dot if present, primarily for SNI but
3698 there's no use for it */
3699 host->name[len-1]=0;
3700
3701 if(!is_ASCII_name(host->name)) {
3702 #ifdef USE_LIBIDN
3703 /*************************************************************
3704 * Check name for non-ASCII and convert hostname to ACE form.
3705 *************************************************************/
3706 if(stringprep_check_version(LIBIDN_REQUIRED_VERSION)) {
3707 char *ace_hostname = NULL;
3708 int rc = idna_to_ascii_lz(host->name, &ace_hostname, 0);
3709 infof (data, "Input domain encoded as `%s'\n",
3710 stringprep_locale_charset ());
3711 if(rc != IDNA_SUCCESS)
3712 infof(data, "Failed to convert %s to ACE; %s\n",
3713 host->name, Curl_idn_strerror(conn, rc));
3714 else {
3715 /* tld_check_name() displays a warning if the host name contains
3716 "illegal" characters for this TLD */
3717 (void)tld_check_name(data, ace_hostname);
3718
3719 host->encalloc = ace_hostname;
3720 /* change the name pointer to point to the encoded hostname */
3721 host->name = host->encalloc;
3722 }
3723 }
3724 #elif defined(USE_WIN32_IDN)
3725 /*************************************************************
3726 * Check name for non-ASCII and convert hostname to ACE form.
3727 *************************************************************/
3728 char *ace_hostname = NULL;
3729 int rc = curl_win32_idn_to_ascii(host->name, &ace_hostname);
3730 if(rc == 0)
3731 infof(data, "Failed to convert %s to ACE;\n",
3732 host->name);
3733 else {
3734 host->encalloc = ace_hostname;
3735 /* change the name pointer to point to the encoded hostname */
3736 host->name = host->encalloc;
3737 }
3738 #else
3739 infof(data, "IDN support not present, can't parse Unicode domains\n");
3740 #endif
3741 }
3742 }
3743
llist_dtor(void * user,void * element)3744 static void llist_dtor(void *user, void *element)
3745 {
3746 (void)user;
3747 (void)element;
3748 /* Do nothing */
3749 }
3750
3751 /*
3752 * Allocate and initialize a new connectdata object.
3753 */
allocate_conn(struct SessionHandle * data)3754 static struct connectdata *allocate_conn(struct SessionHandle *data)
3755 {
3756 struct connectdata *conn = calloc(1, sizeof(struct connectdata));
3757 if(!conn)
3758 return NULL;
3759
3760 conn->handler = &Curl_handler_dummy; /* Be sure we have a handler defined
3761 already from start to avoid NULL
3762 situations and checks */
3763
3764 /* and we setup a few fields in case we end up actually using this struct */
3765
3766 conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
3767 conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
3768 conn->tempsock[0] = CURL_SOCKET_BAD; /* no file descriptor */
3769 conn->tempsock[1] = CURL_SOCKET_BAD; /* no file descriptor */
3770 conn->connection_id = -1; /* no ID */
3771 conn->port = -1; /* unknown at this point */
3772 conn->remote_port = -1; /* unknown */
3773
3774 /* Default protocol-independent behavior doesn't support persistent
3775 connections, so we set this to force-close. Protocols that support
3776 this need to set this to FALSE in their "curl_do" functions. */
3777 connclose(conn, "Default to force-close");
3778
3779 /* Store creation time to help future close decision making */
3780 conn->created = Curl_tvnow();
3781
3782 conn->data = data; /* Setup the association between this connection
3783 and the SessionHandle */
3784
3785 conn->proxytype = data->set.proxytype; /* type */
3786
3787 #ifdef CURL_DISABLE_PROXY
3788
3789 conn->bits.proxy = FALSE;
3790 conn->bits.httpproxy = FALSE;
3791 conn->bits.proxy_user_passwd = FALSE;
3792 conn->bits.tunnel_proxy = FALSE;
3793
3794 #else /* CURL_DISABLE_PROXY */
3795
3796 /* note that these two proxy bits are now just on what looks to be
3797 requested, they may be altered down the road */
3798 conn->bits.proxy = (data->set.str[STRING_PROXY] &&
3799 *data->set.str[STRING_PROXY])?TRUE:FALSE;
3800 conn->bits.httpproxy = (conn->bits.proxy &&
3801 (conn->proxytype == CURLPROXY_HTTP ||
3802 conn->proxytype == CURLPROXY_HTTP_1_0))?TRUE:FALSE;
3803 conn->bits.proxy_user_passwd =
3804 (NULL != data->set.str[STRING_PROXYUSERNAME])?TRUE:FALSE;
3805 conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy;
3806
3807 #endif /* CURL_DISABLE_PROXY */
3808
3809 conn->bits.user_passwd = (NULL != data->set.str[STRING_USERNAME])?TRUE:FALSE;
3810 conn->bits.ftp_use_epsv = data->set.ftp_use_epsv;
3811 conn->bits.ftp_use_eprt = data->set.ftp_use_eprt;
3812
3813 conn->verifypeer = data->set.ssl.verifypeer;
3814 conn->verifyhost = data->set.ssl.verifyhost;
3815
3816 conn->ip_version = data->set.ipver;
3817
3818 #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
3819 defined(NTLM_WB_ENABLED)
3820 conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
3821 conn->ntlm_auth_hlpr_pid = 0;
3822 conn->challenge_header = NULL;
3823 conn->response_header = NULL;
3824 #endif
3825
3826 if(Curl_pipeline_wanted(data->multi, CURLPIPE_HTTP1) &&
3827 !conn->master_buffer) {
3828 /* Allocate master_buffer to be used for HTTP/1 pipelining */
3829 conn->master_buffer = calloc(BUFSIZE, sizeof (char));
3830 if(!conn->master_buffer)
3831 goto error;
3832 }
3833
3834 /* Initialize the pipeline lists */
3835 conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
3836 conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
3837 if(!conn->send_pipe || !conn->recv_pipe)
3838 goto error;
3839
3840 #ifdef HAVE_GSSAPI
3841 conn->data_prot = PROT_CLEAR;
3842 #endif
3843
3844 /* Store the local bind parameters that will be used for this connection */
3845 if(data->set.str[STRING_DEVICE]) {
3846 conn->localdev = strdup(data->set.str[STRING_DEVICE]);
3847 if(!conn->localdev)
3848 goto error;
3849 }
3850 conn->localportrange = data->set.localportrange;
3851 conn->localport = data->set.localport;
3852
3853 /* the close socket stuff needs to be copied to the connection struct as
3854 it may live on without (this specific) SessionHandle */
3855 conn->fclosesocket = data->set.fclosesocket;
3856 conn->closesocket_client = data->set.closesocket_client;
3857
3858 return conn;
3859 error:
3860
3861 Curl_llist_destroy(conn->send_pipe, NULL);
3862 Curl_llist_destroy(conn->recv_pipe, NULL);
3863
3864 conn->send_pipe = NULL;
3865 conn->recv_pipe = NULL;
3866
3867 free(conn->master_buffer);
3868 free(conn->localdev);
3869 free(conn);
3870 return NULL;
3871 }
3872
findprotocol(struct SessionHandle * data,struct connectdata * conn,const char * protostr)3873 static CURLcode findprotocol(struct SessionHandle *data,
3874 struct connectdata *conn,
3875 const char *protostr)
3876 {
3877 const struct Curl_handler * const *pp;
3878 const struct Curl_handler *p;
3879
3880 /* Scan protocol handler table and match against 'protostr' to set a few
3881 variables based on the URL. Now that the handler may be changed later
3882 when the protocol specific setup function is called. */
3883 for(pp = protocols; (p = *pp) != NULL; pp++) {
3884 if(Curl_raw_equal(p->scheme, protostr)) {
3885 /* Protocol found in table. Check if allowed */
3886 if(!(data->set.allowed_protocols & p->protocol))
3887 /* nope, get out */
3888 break;
3889
3890 /* it is allowed for "normal" request, now do an extra check if this is
3891 the result of a redirect */
3892 if(data->state.this_is_a_follow &&
3893 !(data->set.redir_protocols & p->protocol))
3894 /* nope, get out */
3895 break;
3896
3897 /* Perform setup complement if some. */
3898 conn->handler = conn->given = p;
3899
3900 /* 'port' and 'remote_port' are set in setup_connection_internals() */
3901 return CURLE_OK;
3902 }
3903 }
3904
3905
3906 /* The protocol was not found in the table, but we don't have to assign it
3907 to anything since it is already assigned to a dummy-struct in the
3908 create_conn() function when the connectdata struct is allocated. */
3909 failf(data, "Protocol \"%s\" not supported or disabled in " LIBCURL_NAME,
3910 protostr);
3911
3912 return CURLE_UNSUPPORTED_PROTOCOL;
3913 }
3914
3915 /*
3916 * Parse URL and fill in the relevant members of the connection struct.
3917 */
parseurlandfillconn(struct SessionHandle * data,struct connectdata * conn,bool * prot_missing,char ** userp,char ** passwdp,char ** optionsp)3918 static CURLcode parseurlandfillconn(struct SessionHandle *data,
3919 struct connectdata *conn,
3920 bool *prot_missing,
3921 char **userp, char **passwdp,
3922 char **optionsp)
3923 {
3924 char *at;
3925 char *fragment;
3926 char *path = data->state.path;
3927 char *query;
3928 int rc;
3929 char protobuf[16] = "";
3930 const char *protop = "";
3931 CURLcode result;
3932 bool rebuild_url = FALSE;
3933
3934 *prot_missing = FALSE;
3935
3936 /* We might pass the entire URL into the request so we need to make sure
3937 * there are no bad characters in there.*/
3938 if(strpbrk(data->change.url, "\r\n")) {
3939 failf(data, "Illegal characters found in URL");
3940 return CURLE_URL_MALFORMAT;
3941 }
3942
3943 /*************************************************************
3944 * Parse the URL.
3945 *
3946 * We need to parse the url even when using the proxy, because we will need
3947 * the hostname and port in case we are trying to SSL connect through the
3948 * proxy -- and we don't know if we will need to use SSL until we parse the
3949 * url ...
3950 ************************************************************/
3951 if((2 == sscanf(data->change.url, "%15[^:]:%[^\n]",
3952 protobuf, path)) &&
3953 Curl_raw_equal(protobuf, "file")) {
3954 if(path[0] == '/' && path[1] == '/') {
3955 /* Allow omitted hostname (e.g. file:/<path>). This is not strictly
3956 * speaking a valid file: URL by RFC 1738, but treating file:/<path> as
3957 * file://localhost/<path> is similar to how other schemes treat missing
3958 * hostnames. See RFC 1808. */
3959
3960 /* This cannot be done with strcpy() in a portable manner, since the
3961 memory areas overlap! */
3962 memmove(path, path + 2, strlen(path + 2)+1);
3963 }
3964 /*
3965 * we deal with file://<host>/<path> differently since it supports no
3966 * hostname other than "localhost" and "127.0.0.1", which is unique among
3967 * the URL protocols specified in RFC 1738
3968 */
3969 if(path[0] != '/') {
3970 /* the URL included a host name, we ignore host names in file:// URLs
3971 as the standards don't define what to do with them */
3972 char *ptr=strchr(path, '/');
3973 if(ptr) {
3974 /* there was a slash present
3975
3976 RFC1738 (section 3.1, page 5) says:
3977
3978 The rest of the locator consists of data specific to the scheme,
3979 and is known as the "url-path". It supplies the details of how the
3980 specified resource can be accessed. Note that the "/" between the
3981 host (or port) and the url-path is NOT part of the url-path.
3982
3983 As most agents use file://localhost/foo to get '/foo' although the
3984 slash preceding foo is a separator and not a slash for the path,
3985 a URL as file://localhost//foo must be valid as well, to refer to
3986 the same file with an absolute path.
3987 */
3988
3989 if(ptr[1] && ('/' == ptr[1]))
3990 /* if there was two slashes, we skip the first one as that is then
3991 used truly as a separator */
3992 ptr++;
3993
3994 /* This cannot be made with strcpy, as the memory chunks overlap! */
3995 memmove(path, ptr, strlen(ptr)+1);
3996 }
3997 }
3998
3999 protop = "file"; /* protocol string */
4000 }
4001 else {
4002 /* clear path */
4003 path[0]=0;
4004
4005 if(2 > sscanf(data->change.url,
4006 "%15[^\n:]://%[^\n/?]%[^\n]",
4007 protobuf,
4008 conn->host.name, path)) {
4009
4010 /*
4011 * The URL was badly formatted, let's try the browser-style _without_
4012 * protocol specified like 'http://'.
4013 */
4014 rc = sscanf(data->change.url, "%[^\n/?]%[^\n]", conn->host.name, path);
4015 if(1 > rc) {
4016 /*
4017 * We couldn't even get this format.
4018 * djgpp 2.04 has a sscanf() bug where 'conn->host.name' is
4019 * assigned, but the return value is EOF!
4020 */
4021 #if defined(__DJGPP__) && (DJGPP_MINOR == 4)
4022 if(!(rc == -1 && *conn->host.name))
4023 #endif
4024 {
4025 failf(data, "<url> malformed");
4026 return CURLE_URL_MALFORMAT;
4027 }
4028 }
4029
4030 /*
4031 * Since there was no protocol part specified, we guess what protocol it
4032 * is based on the first letters of the server name.
4033 */
4034
4035 /* Note: if you add a new protocol, please update the list in
4036 * lib/version.c too! */
4037
4038 if(checkprefix("FTP.", conn->host.name))
4039 protop = "ftp";
4040 else if(checkprefix("DICT.", conn->host.name))
4041 protop = "DICT";
4042 else if(checkprefix("LDAP.", conn->host.name))
4043 protop = "LDAP";
4044 else if(checkprefix("IMAP.", conn->host.name))
4045 protop = "IMAP";
4046 else if(checkprefix("SMTP.", conn->host.name))
4047 protop = "smtp";
4048 else if(checkprefix("POP3.", conn->host.name))
4049 protop = "pop3";
4050 else {
4051 protop = "http";
4052 }
4053
4054 *prot_missing = TRUE; /* not given in URL */
4055 }
4056 else
4057 protop = protobuf;
4058 }
4059
4060 /* We search for '?' in the host name (but only on the right side of a
4061 * @-letter to allow ?-letters in username and password) to handle things
4062 * like http://example.com?param= (notice the missing '/').
4063 */
4064 at = strchr(conn->host.name, '@');
4065 if(at)
4066 query = strchr(at+1, '?');
4067 else
4068 query = strchr(conn->host.name, '?');
4069
4070 if(query) {
4071 /* We must insert a slash before the '?'-letter in the URL. If the URL had
4072 a slash after the '?', that is where the path currently begins and the
4073 '?string' is still part of the host name.
4074
4075 We must move the trailing part from the host name and put it first in
4076 the path. And have it all prefixed with a slash.
4077 */
4078
4079 size_t hostlen = strlen(query);
4080 size_t pathlen = strlen(path);
4081
4082 /* move the existing path plus the zero byte forward, to make room for
4083 the host-name part */
4084 memmove(path+hostlen+1, path, pathlen+1);
4085
4086 /* now copy the trailing host part in front of the existing path */
4087 memcpy(path+1, query, hostlen);
4088
4089 path[0]='/'; /* prepend the missing slash */
4090 rebuild_url = TRUE;
4091
4092 *query=0; /* now cut off the hostname at the ? */
4093 }
4094 else if(!path[0]) {
4095 /* if there's no path set, use a single slash */
4096 strcpy(path, "/");
4097 rebuild_url = TRUE;
4098 }
4099
4100 /* If the URL is malformatted (missing a '/' after hostname before path) we
4101 * insert a slash here. The only letter except '/' we accept to start a path
4102 * is '?'.
4103 */
4104 if(path[0] == '?') {
4105 /* We need this function to deal with overlapping memory areas. We know
4106 that the memory area 'path' points to is 'urllen' bytes big and that
4107 is bigger than the path. Use +1 to move the zero byte too. */
4108 memmove(&path[1], path, strlen(path)+1);
4109 path[0] = '/';
4110 rebuild_url = TRUE;
4111 }
4112 else if(!data->set.path_as_is) {
4113 /* sanitise paths and remove ../ and ./ sequences according to RFC3986 */
4114 char *newp = Curl_dedotdotify(path);
4115 if(!newp)
4116 return CURLE_OUT_OF_MEMORY;
4117
4118 if(strcmp(newp, path)) {
4119 rebuild_url = TRUE;
4120 free(data->state.pathbuffer);
4121 data->state.pathbuffer = newp;
4122 data->state.path = newp;
4123 path = newp;
4124 }
4125 else
4126 free(newp);
4127 }
4128
4129 /*
4130 * "rebuild_url" means that one or more URL components have been modified so
4131 * we need to generate an updated full version. We need the corrected URL
4132 * when communicating over HTTP proxy and we don't know at this point if
4133 * we're using a proxy or not.
4134 */
4135 if(rebuild_url) {
4136 char *reurl;
4137
4138 size_t plen = strlen(path); /* new path, should be 1 byte longer than
4139 the original */
4140 size_t urllen = strlen(data->change.url); /* original URL length */
4141
4142 size_t prefixlen = strlen(conn->host.name);
4143
4144 if(!*prot_missing)
4145 prefixlen += strlen(protop) + strlen("://");
4146
4147 reurl = malloc(urllen + 2); /* 2 for zerobyte + slash */
4148 if(!reurl)
4149 return CURLE_OUT_OF_MEMORY;
4150
4151 /* copy the prefix */
4152 memcpy(reurl, data->change.url, prefixlen);
4153
4154 /* append the trailing piece + zerobyte */
4155 memcpy(&reurl[prefixlen], path, plen + 1);
4156
4157 /* possible free the old one */
4158 if(data->change.url_alloc) {
4159 Curl_safefree(data->change.url);
4160 data->change.url_alloc = FALSE;
4161 }
4162
4163 infof(data, "Rebuilt URL to: %s\n", reurl);
4164
4165 data->change.url = reurl;
4166 data->change.url_alloc = TRUE; /* free this later */
4167 }
4168
4169 /*
4170 * Parse the login details from the URL and strip them out of
4171 * the host name
4172 */
4173 result = parse_url_login(data, conn, userp, passwdp, optionsp);
4174 if(result)
4175 return result;
4176
4177 if(conn->host.name[0] == '[') {
4178 /* This looks like an IPv6 address literal. See if there is an address
4179 scope if there is no location header */
4180 char *percent = strchr(conn->host.name, '%');
4181 if(percent) {
4182 unsigned int identifier_offset = 3;
4183 char *endp;
4184 unsigned long scope;
4185 if(strncmp("%25", percent, 3) != 0) {
4186 infof(data,
4187 "Please URL encode %% as %%25, see RFC 6874.\n");
4188 identifier_offset = 1;
4189 }
4190 scope = strtoul(percent + identifier_offset, &endp, 10);
4191 if(*endp == ']') {
4192 /* The address scope was well formed. Knock it out of the
4193 hostname. */
4194 memmove(percent, endp, strlen(endp)+1);
4195 conn->scope_id = (unsigned int)scope;
4196 }
4197 else {
4198 /* Zone identifier is not numeric */
4199 #if defined(HAVE_NET_IF_H) && defined(IFNAMSIZ) && defined(HAVE_IF_NAMETOINDEX)
4200 char ifname[IFNAMSIZ + 2];
4201 char *square_bracket;
4202 unsigned int scopeidx = 0;
4203 strncpy(ifname, percent + identifier_offset, IFNAMSIZ + 2);
4204 /* Ensure nullbyte termination */
4205 ifname[IFNAMSIZ + 1] = '\0';
4206 square_bracket = strchr(ifname, ']');
4207 if(square_bracket) {
4208 /* Remove ']' */
4209 *square_bracket = '\0';
4210 scopeidx = if_nametoindex(ifname);
4211 if(scopeidx == 0) {
4212 infof(data, "Invalid network interface: %s; %s\n", ifname,
4213 strerror(errno));
4214 }
4215 }
4216 if(scopeidx > 0) {
4217 char *p = percent + identifier_offset + strlen(ifname);
4218
4219 /* Remove zone identifier from hostname */
4220 memmove(percent, p, strlen(p) + 1);
4221 conn->scope_id = scopeidx;
4222 }
4223 else
4224 #endif /* HAVE_NET_IF_H && IFNAMSIZ */
4225 infof(data, "Invalid IPv6 address format\n");
4226 }
4227 }
4228 }
4229
4230 if(data->set.scope_id)
4231 /* Override any scope that was set above. */
4232 conn->scope_id = data->set.scope_id;
4233
4234 /* Remove the fragment part of the path. Per RFC 2396, this is always the
4235 last part of the URI. We are looking for the first '#' so that we deal
4236 gracefully with non conformant URI such as http://example.com#foo#bar. */
4237 fragment = strchr(path, '#');
4238 if(fragment) {
4239 *fragment = 0;
4240
4241 /* we know the path part ended with a fragment, so we know the full URL
4242 string does too and we need to cut it off from there so it isn't used
4243 over proxy */
4244 fragment = strchr(data->change.url, '#');
4245 if(fragment)
4246 *fragment = 0;
4247 }
4248
4249 /*
4250 * So if the URL was A://B/C#D,
4251 * protop is A
4252 * conn->host.name is B
4253 * data->state.path is /C
4254 */
4255
4256 return findprotocol(data, conn, protop);
4257 }
4258
4259 /*
4260 * If we're doing a resumed transfer, we need to setup our stuff
4261 * properly.
4262 */
setup_range(struct SessionHandle * data)4263 static CURLcode setup_range(struct SessionHandle *data)
4264 {
4265 struct UrlState *s = &data->state;
4266 s->resume_from = data->set.set_resume_from;
4267 if(s->resume_from || data->set.str[STRING_SET_RANGE]) {
4268 if(s->rangestringalloc)
4269 free(s->range);
4270
4271 if(s->resume_from)
4272 s->range = aprintf("%" CURL_FORMAT_CURL_OFF_TU "-", s->resume_from);
4273 else
4274 s->range = strdup(data->set.str[STRING_SET_RANGE]);
4275
4276 s->rangestringalloc = (s->range)?TRUE:FALSE;
4277
4278 if(!s->range)
4279 return CURLE_OUT_OF_MEMORY;
4280
4281 /* tell ourselves to fetch this range */
4282 s->use_range = TRUE; /* enable range download */
4283 }
4284 else
4285 s->use_range = FALSE; /* disable range download */
4286
4287 return CURLE_OK;
4288 }
4289
4290
4291 /*
4292 * setup_connection_internals() -
4293 *
4294 * Setup connection internals specific to the requested protocol in the
4295 * SessionHandle. This is inited and setup before the connection is made but
4296 * is about the particular protocol that is to be used.
4297 *
4298 * This MUST get called after proxy magic has been figured out.
4299 */
setup_connection_internals(struct connectdata * conn)4300 static CURLcode setup_connection_internals(struct connectdata *conn)
4301 {
4302 const struct Curl_handler * p;
4303 CURLcode result;
4304 struct SessionHandle *data = conn->data;
4305
4306 /* in some case in the multi state-machine, we go back to the CONNECT state
4307 and then a second (or third or...) call to this function will be made
4308 without doing a DISCONNECT or DONE in between (since the connection is
4309 yet in place) and therefore this function needs to first make sure
4310 there's no lingering previous data allocated. */
4311 Curl_free_request_state(data);
4312
4313 memset(&data->req, 0, sizeof(struct SingleRequest));
4314 data->req.maxdownload = -1;
4315
4316 conn->socktype = SOCK_STREAM; /* most of them are TCP streams */
4317
4318 /* Perform setup complement if some. */
4319 p = conn->handler;
4320
4321 if(p->setup_connection) {
4322 result = (*p->setup_connection)(conn);
4323
4324 if(result)
4325 return result;
4326
4327 p = conn->handler; /* May have changed. */
4328 }
4329
4330 if(conn->port < 0)
4331 /* we check for -1 here since if proxy was detected already, this
4332 was very likely already set to the proxy port */
4333 conn->port = p->defport;
4334
4335 /* only if remote_port was not already parsed off the URL we use the
4336 default port number */
4337 if(conn->remote_port < 0)
4338 conn->remote_port = (unsigned short)conn->given->defport;
4339
4340 return CURLE_OK;
4341 }
4342
4343 /*
4344 * Curl_free_request_state() should free temp data that was allocated in the
4345 * SessionHandle for this single request.
4346 */
4347
Curl_free_request_state(struct SessionHandle * data)4348 void Curl_free_request_state(struct SessionHandle *data)
4349 {
4350 Curl_safefree(data->req.protop);
4351 Curl_safefree(data->req.newurl);
4352 }
4353
4354
4355 #ifndef CURL_DISABLE_PROXY
4356 /****************************************************************
4357 * Checks if the host is in the noproxy list. returns true if it matches
4358 * and therefore the proxy should NOT be used.
4359 ****************************************************************/
check_noproxy(const char * name,const char * no_proxy)4360 static bool check_noproxy(const char* name, const char* no_proxy)
4361 {
4362 /* no_proxy=domain1.dom,host.domain2.dom
4363 * (a comma-separated list of hosts which should
4364 * not be proxied, or an asterisk to override
4365 * all proxy variables)
4366 */
4367 size_t tok_start;
4368 size_t tok_end;
4369 const char* separator = ", ";
4370 size_t no_proxy_len;
4371 size_t namelen;
4372 char *endptr;
4373
4374 if(no_proxy && no_proxy[0]) {
4375 if(Curl_raw_equal("*", no_proxy)) {
4376 return TRUE;
4377 }
4378
4379 /* NO_PROXY was specified and it wasn't just an asterisk */
4380
4381 no_proxy_len = strlen(no_proxy);
4382 endptr = strchr(name, ':');
4383 if(endptr)
4384 namelen = endptr - name;
4385 else
4386 namelen = strlen(name);
4387
4388 for(tok_start = 0; tok_start < no_proxy_len; tok_start = tok_end + 1) {
4389 while(tok_start < no_proxy_len &&
4390 strchr(separator, no_proxy[tok_start]) != NULL) {
4391 /* Look for the beginning of the token. */
4392 ++tok_start;
4393 }
4394
4395 if(tok_start == no_proxy_len)
4396 break; /* It was all trailing separator chars, no more tokens. */
4397
4398 for(tok_end = tok_start; tok_end < no_proxy_len &&
4399 strchr(separator, no_proxy[tok_end]) == NULL; ++tok_end)
4400 /* Look for the end of the token. */
4401 ;
4402
4403 /* To match previous behaviour, where it was necessary to specify
4404 * ".local.com" to prevent matching "notlocal.com", we will leave
4405 * the '.' off.
4406 */
4407 if(no_proxy[tok_start] == '.')
4408 ++tok_start;
4409
4410 if((tok_end - tok_start) <= namelen) {
4411 /* Match the last part of the name to the domain we are checking. */
4412 const char *checkn = name + namelen - (tok_end - tok_start);
4413 if(Curl_raw_nequal(no_proxy + tok_start, checkn,
4414 tok_end - tok_start)) {
4415 if((tok_end - tok_start) == namelen || *(checkn - 1) == '.') {
4416 /* We either have an exact match, or the previous character is a .
4417 * so it is within the same domain, so no proxy for this host.
4418 */
4419 return TRUE;
4420 }
4421 }
4422 } /* if((tok_end - tok_start) <= namelen) */
4423 } /* for(tok_start = 0; tok_start < no_proxy_len;
4424 tok_start = tok_end + 1) */
4425 } /* NO_PROXY was specified and it wasn't just an asterisk */
4426
4427 return FALSE;
4428 }
4429
4430 /****************************************************************
4431 * Detect what (if any) proxy to use. Remember that this selects a host
4432 * name and is not limited to HTTP proxies only.
4433 * The returned pointer must be freed by the caller (unless NULL)
4434 ****************************************************************/
detect_proxy(struct connectdata * conn)4435 static char *detect_proxy(struct connectdata *conn)
4436 {
4437 char *proxy = NULL;
4438
4439 #ifndef CURL_DISABLE_HTTP
4440 /* If proxy was not specified, we check for default proxy environment
4441 * variables, to enable i.e Lynx compliance:
4442 *
4443 * http_proxy=http://some.server.dom:port/
4444 * https_proxy=http://some.server.dom:port/
4445 * ftp_proxy=http://some.server.dom:port/
4446 * no_proxy=domain1.dom,host.domain2.dom
4447 * (a comma-separated list of hosts which should
4448 * not be proxied, or an asterisk to override
4449 * all proxy variables)
4450 * all_proxy=http://some.server.dom:port/
4451 * (seems to exist for the CERN www lib. Probably
4452 * the first to check for.)
4453 *
4454 * For compatibility, the all-uppercase versions of these variables are
4455 * checked if the lowercase versions don't exist.
4456 */
4457 char *no_proxy=NULL;
4458 char proxy_env[128];
4459
4460 no_proxy=curl_getenv("no_proxy");
4461 if(!no_proxy)
4462 no_proxy=curl_getenv("NO_PROXY");
4463
4464 if(!check_noproxy(conn->host.name, no_proxy)) {
4465 /* It was not listed as without proxy */
4466 const char *protop = conn->handler->scheme;
4467 char *envp = proxy_env;
4468 char *prox;
4469
4470 /* Now, build <protocol>_proxy and check for such a one to use */
4471 while(*protop)
4472 *envp++ = (char)tolower((int)*protop++);
4473
4474 /* append _proxy */
4475 strcpy(envp, "_proxy");
4476
4477 /* read the protocol proxy: */
4478 prox=curl_getenv(proxy_env);
4479
4480 /*
4481 * We don't try the uppercase version of HTTP_PROXY because of
4482 * security reasons:
4483 *
4484 * When curl is used in a webserver application
4485 * environment (cgi or php), this environment variable can
4486 * be controlled by the web server user by setting the
4487 * http header 'Proxy:' to some value.
4488 *
4489 * This can cause 'internal' http/ftp requests to be
4490 * arbitrarily redirected by any external attacker.
4491 */
4492 if(!prox && !Curl_raw_equal("http_proxy", proxy_env)) {
4493 /* There was no lowercase variable, try the uppercase version: */
4494 Curl_strntoupper(proxy_env, proxy_env, sizeof(proxy_env));
4495 prox=curl_getenv(proxy_env);
4496 }
4497
4498 if(prox)
4499 proxy = prox; /* use this */
4500 else {
4501 proxy = curl_getenv("all_proxy"); /* default proxy to use */
4502 if(!proxy)
4503 proxy=curl_getenv("ALL_PROXY");
4504 }
4505 } /* if(!check_noproxy(conn->host.name, no_proxy)) - it wasn't specified
4506 non-proxy */
4507 free(no_proxy);
4508
4509 #else /* !CURL_DISABLE_HTTP */
4510
4511 (void)conn;
4512 #endif /* CURL_DISABLE_HTTP */
4513
4514 return proxy;
4515 }
4516
4517 /*
4518 * If this is supposed to use a proxy, we need to figure out the proxy
4519 * host name, so that we can re-use an existing connection
4520 * that may exist registered to the same proxy host.
4521 */
parse_proxy(struct SessionHandle * data,struct connectdata * conn,char * proxy)4522 static CURLcode parse_proxy(struct SessionHandle *data,
4523 struct connectdata *conn, char *proxy)
4524 {
4525 char *prox_portno;
4526 char *endofprot;
4527
4528 /* We use 'proxyptr' to point to the proxy name from now on... */
4529 char *proxyptr;
4530 char *portptr;
4531 char *atsign;
4532
4533 /* We do the proxy host string parsing here. We want the host name and the
4534 * port name. Accept a protocol:// prefix
4535 */
4536
4537 /* Parse the protocol part if present */
4538 endofprot = strstr(proxy, "://");
4539 if(endofprot) {
4540 proxyptr = endofprot+3;
4541 if(checkprefix("socks5h", proxy))
4542 conn->proxytype = CURLPROXY_SOCKS5_HOSTNAME;
4543 else if(checkprefix("socks5", proxy))
4544 conn->proxytype = CURLPROXY_SOCKS5;
4545 else if(checkprefix("socks4a", proxy))
4546 conn->proxytype = CURLPROXY_SOCKS4A;
4547 else if(checkprefix("socks4", proxy) || checkprefix("socks", proxy))
4548 conn->proxytype = CURLPROXY_SOCKS4;
4549 /* Any other xxx:// : change to http proxy */
4550 }
4551 else
4552 proxyptr = proxy; /* No xxx:// head: It's a HTTP proxy */
4553
4554 /* Is there a username and password given in this proxy url? */
4555 atsign = strchr(proxyptr, '@');
4556 if(atsign) {
4557 char *proxyuser = NULL;
4558 char *proxypasswd = NULL;
4559 CURLcode result =
4560 parse_login_details(proxyptr, atsign - proxyptr,
4561 &proxyuser, &proxypasswd, NULL);
4562 if(!result) {
4563 /* found user and password, rip them out. note that we are
4564 unescaping them, as there is otherwise no way to have a
4565 username or password with reserved characters like ':' in
4566 them. */
4567 Curl_safefree(conn->proxyuser);
4568 if(proxyuser && strlen(proxyuser) < MAX_CURL_USER_LENGTH)
4569 conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
4570 else
4571 conn->proxyuser = strdup("");
4572
4573 if(!conn->proxyuser)
4574 result = CURLE_OUT_OF_MEMORY;
4575 else {
4576 Curl_safefree(conn->proxypasswd);
4577 if(proxypasswd && strlen(proxypasswd) < MAX_CURL_PASSWORD_LENGTH)
4578 conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL);
4579 else
4580 conn->proxypasswd = strdup("");
4581
4582 if(!conn->proxypasswd)
4583 result = CURLE_OUT_OF_MEMORY;
4584 }
4585
4586 if(!result) {
4587 conn->bits.proxy_user_passwd = TRUE; /* enable it */
4588 atsign++; /* the right side of the @-letter */
4589
4590 proxyptr = atsign; /* now use this instead */
4591 }
4592 }
4593
4594 free(proxyuser);
4595 free(proxypasswd);
4596
4597 if(result)
4598 return result;
4599 }
4600
4601 /* start scanning for port number at this point */
4602 portptr = proxyptr;
4603
4604 /* detect and extract RFC6874-style IPv6-addresses */
4605 if(*proxyptr == '[') {
4606 char *ptr = ++proxyptr; /* advance beyond the initial bracket */
4607 while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '.')))
4608 ptr++;
4609 if(*ptr == '%') {
4610 /* There might be a zone identifier */
4611 if(strncmp("%25", ptr, 3))
4612 infof(data, "Please URL encode %% as %%25, see RFC 6874.\n");
4613 ptr++;
4614 /* Allow unresered characters as defined in RFC 3986 */
4615 while(*ptr && (ISALPHA(*ptr) || ISXDIGIT(*ptr) || (*ptr == '-') ||
4616 (*ptr == '.') || (*ptr == '_') || (*ptr == '~')))
4617 ptr++;
4618 }
4619 if(*ptr == ']')
4620 /* yeps, it ended nicely with a bracket as well */
4621 *ptr++ = 0;
4622 else
4623 infof(data, "Invalid IPv6 address format\n");
4624 portptr = ptr;
4625 /* Note that if this didn't end with a bracket, we still advanced the
4626 * proxyptr first, but I can't see anything wrong with that as no host
4627 * name nor a numeric can legally start with a bracket.
4628 */
4629 }
4630
4631 /* Get port number off proxy.server.com:1080 */
4632 prox_portno = strchr(portptr, ':');
4633 if(prox_portno) {
4634 *prox_portno = 0x0; /* cut off number from host name */
4635 prox_portno ++;
4636 /* now set the local port number */
4637 conn->port = strtol(prox_portno, NULL, 10);
4638 }
4639 else {
4640 if(proxyptr[0]=='/')
4641 /* If the first character in the proxy string is a slash, fail
4642 immediately. The following code will otherwise clear the string which
4643 will lead to code running as if no proxy was set! */
4644 return CURLE_COULDNT_RESOLVE_PROXY;
4645
4646 /* without a port number after the host name, some people seem to use
4647 a slash so we strip everything from the first slash */
4648 atsign = strchr(proxyptr, '/');
4649 if(atsign)
4650 *atsign = 0x0; /* cut off path part from host name */
4651
4652 if(data->set.proxyport)
4653 /* None given in the proxy string, then get the default one if it is
4654 given */
4655 conn->port = data->set.proxyport;
4656 }
4657
4658 /* now, clone the cleaned proxy host name */
4659 conn->proxy.rawalloc = strdup(proxyptr);
4660 conn->proxy.name = conn->proxy.rawalloc;
4661
4662 if(!conn->proxy.rawalloc)
4663 return CURLE_OUT_OF_MEMORY;
4664
4665 return CURLE_OK;
4666 }
4667
4668 /*
4669 * Extract the user and password from the authentication string
4670 */
parse_proxy_auth(struct SessionHandle * data,struct connectdata * conn)4671 static CURLcode parse_proxy_auth(struct SessionHandle *data,
4672 struct connectdata *conn)
4673 {
4674 char proxyuser[MAX_CURL_USER_LENGTH]="";
4675 char proxypasswd[MAX_CURL_PASSWORD_LENGTH]="";
4676
4677 if(data->set.str[STRING_PROXYUSERNAME] != NULL) {
4678 strncpy(proxyuser, data->set.str[STRING_PROXYUSERNAME],
4679 MAX_CURL_USER_LENGTH);
4680 proxyuser[MAX_CURL_USER_LENGTH-1] = '\0'; /*To be on safe side*/
4681 }
4682 if(data->set.str[STRING_PROXYPASSWORD] != NULL) {
4683 strncpy(proxypasswd, data->set.str[STRING_PROXYPASSWORD],
4684 MAX_CURL_PASSWORD_LENGTH);
4685 proxypasswd[MAX_CURL_PASSWORD_LENGTH-1] = '\0'; /*To be on safe side*/
4686 }
4687
4688 conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
4689 if(!conn->proxyuser)
4690 return CURLE_OUT_OF_MEMORY;
4691
4692 conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL);
4693 if(!conn->proxypasswd)
4694 return CURLE_OUT_OF_MEMORY;
4695
4696 return CURLE_OK;
4697 }
4698 #endif /* CURL_DISABLE_PROXY */
4699
4700 /*
4701 * parse_url_login()
4702 *
4703 * Parse the login details (user name, password and options) from the URL and
4704 * strip them out of the host name
4705 *
4706 * Inputs: data->set.use_netrc (CURLOPT_NETRC)
4707 * conn->host.name
4708 *
4709 * Outputs: (almost :- all currently undefined)
4710 * conn->bits.user_passwd - non-zero if non-default passwords exist
4711 * user - non-zero length if defined
4712 * passwd - non-zero length if defined
4713 * options - non-zero length if defined
4714 * conn->host.name - remove user name and password
4715 */
parse_url_login(struct SessionHandle * data,struct connectdata * conn,char ** user,char ** passwd,char ** options)4716 static CURLcode parse_url_login(struct SessionHandle *data,
4717 struct connectdata *conn,
4718 char **user, char **passwd, char **options)
4719 {
4720 CURLcode result = CURLE_OK;
4721 char *userp = NULL;
4722 char *passwdp = NULL;
4723 char *optionsp = NULL;
4724
4725 /* At this point, we're hoping all the other special cases have
4726 * been taken care of, so conn->host.name is at most
4727 * [user[:password][;options]]@]hostname
4728 *
4729 * We need somewhere to put the embedded details, so do that first.
4730 */
4731
4732 char *ptr = strchr(conn->host.name, '@');
4733 char *login = conn->host.name;
4734
4735 DEBUGASSERT(!**user);
4736 DEBUGASSERT(!**passwd);
4737 DEBUGASSERT(!**options);
4738
4739 if(!ptr)
4740 goto out;
4741
4742 /* We will now try to extract the
4743 * possible login information in a string like:
4744 * ftp://user:password@ftp.my.site:8021/README */
4745 conn->host.name = ++ptr;
4746
4747 /* So the hostname is sane. Only bother interpreting the
4748 * results if we could care. It could still be wasted
4749 * work because it might be overtaken by the programmatically
4750 * set user/passwd, but doing that first adds more cases here :-(
4751 */
4752
4753 if(data->set.use_netrc == CURL_NETRC_REQUIRED)
4754 goto out;
4755
4756 /* We could use the login information in the URL so extract it */
4757 result = parse_login_details(login, ptr - login - 1,
4758 &userp, &passwdp, &optionsp);
4759 if(result)
4760 goto out;
4761
4762 if(userp) {
4763 char *newname;
4764
4765 /* We have a user in the URL */
4766 conn->bits.userpwd_in_url = TRUE;
4767 conn->bits.user_passwd = TRUE; /* enable user+password */
4768
4769 /* Decode the user */
4770 newname = curl_easy_unescape(data, userp, 0, NULL);
4771 if(!newname) {
4772 result = CURLE_OUT_OF_MEMORY;
4773 goto out;
4774 }
4775
4776 free(*user);
4777 *user = newname;
4778 }
4779
4780 if(passwdp) {
4781 /* We have a password in the URL so decode it */
4782 char *newpasswd = curl_easy_unescape(data, passwdp, 0, NULL);
4783 if(!newpasswd) {
4784 result = CURLE_OUT_OF_MEMORY;
4785 goto out;
4786 }
4787
4788 free(*passwd);
4789 *passwd = newpasswd;
4790 }
4791
4792 if(optionsp) {
4793 /* We have an options list in the URL so decode it */
4794 char *newoptions = curl_easy_unescape(data, optionsp, 0, NULL);
4795 if(!newoptions) {
4796 result = CURLE_OUT_OF_MEMORY;
4797 goto out;
4798 }
4799
4800 free(*options);
4801 *options = newoptions;
4802 }
4803
4804
4805 out:
4806
4807 free(userp);
4808 free(passwdp);
4809 free(optionsp);
4810
4811 return result;
4812 }
4813
4814 /*
4815 * parse_login_details()
4816 *
4817 * This is used to parse a login string for user name, password and options in
4818 * the following formats:
4819 *
4820 * user
4821 * user:password
4822 * user:password;options
4823 * user;options
4824 * user;options:password
4825 * :password
4826 * :password;options
4827 * ;options
4828 * ;options:password
4829 *
4830 * Parameters:
4831 *
4832 * login [in] - The login string.
4833 * len [in] - The length of the login string.
4834 * userp [in/out] - The address where a pointer to newly allocated memory
4835 * holding the user will be stored upon completion.
4836 * passdwp [in/out] - The address where a pointer to newly allocated memory
4837 * holding the password will be stored upon completion.
4838 * optionsp [in/out] - The address where a pointer to newly allocated memory
4839 * holding the options will be stored upon completion.
4840 *
4841 * Returns CURLE_OK on success.
4842 */
parse_login_details(const char * login,const size_t len,char ** userp,char ** passwdp,char ** optionsp)4843 static CURLcode parse_login_details(const char *login, const size_t len,
4844 char **userp, char **passwdp,
4845 char **optionsp)
4846 {
4847 CURLcode result = CURLE_OK;
4848 char *ubuf = NULL;
4849 char *pbuf = NULL;
4850 char *obuf = NULL;
4851 const char *psep = NULL;
4852 const char *osep = NULL;
4853 size_t ulen;
4854 size_t plen;
4855 size_t olen;
4856
4857 /* Attempt to find the password separator */
4858 if(passwdp) {
4859 psep = strchr(login, ':');
4860
4861 /* Within the constraint of the login string */
4862 if(psep >= login + len)
4863 psep = NULL;
4864 }
4865
4866 /* Attempt to find the options separator */
4867 if(optionsp) {
4868 osep = strchr(login, ';');
4869
4870 /* Within the constraint of the login string */
4871 if(osep >= login + len)
4872 osep = NULL;
4873 }
4874
4875 /* Calculate the portion lengths */
4876 ulen = (psep ?
4877 (size_t)(osep && psep > osep ? osep - login : psep - login) :
4878 (osep ? (size_t)(osep - login) : len));
4879 plen = (psep ?
4880 (osep && osep > psep ? (size_t)(osep - psep) :
4881 (size_t)(login + len - psep)) - 1 : 0);
4882 olen = (osep ?
4883 (psep && psep > osep ? (size_t)(psep - osep) :
4884 (size_t)(login + len - osep)) - 1 : 0);
4885
4886 /* Allocate the user portion buffer */
4887 if(userp && ulen) {
4888 ubuf = malloc(ulen + 1);
4889 if(!ubuf)
4890 result = CURLE_OUT_OF_MEMORY;
4891 }
4892
4893 /* Allocate the password portion buffer */
4894 if(!result && passwdp && plen) {
4895 pbuf = malloc(plen + 1);
4896 if(!pbuf) {
4897 free(ubuf);
4898 result = CURLE_OUT_OF_MEMORY;
4899 }
4900 }
4901
4902 /* Allocate the options portion buffer */
4903 if(!result && optionsp && olen) {
4904 obuf = malloc(olen + 1);
4905 if(!obuf) {
4906 free(pbuf);
4907 free(ubuf);
4908 result = CURLE_OUT_OF_MEMORY;
4909 }
4910 }
4911
4912 if(!result) {
4913 /* Store the user portion if necessary */
4914 if(ubuf) {
4915 memcpy(ubuf, login, ulen);
4916 ubuf[ulen] = '\0';
4917 Curl_safefree(*userp);
4918 *userp = ubuf;
4919 }
4920
4921 /* Store the password portion if necessary */
4922 if(pbuf) {
4923 memcpy(pbuf, psep + 1, plen);
4924 pbuf[plen] = '\0';
4925 Curl_safefree(*passwdp);
4926 *passwdp = pbuf;
4927 }
4928
4929 /* Store the options portion if necessary */
4930 if(obuf) {
4931 memcpy(obuf, osep + 1, olen);
4932 obuf[olen] = '\0';
4933 Curl_safefree(*optionsp);
4934 *optionsp = obuf;
4935 }
4936 }
4937
4938 return result;
4939 }
4940
4941 /*************************************************************
4942 * Figure out the remote port number and fix it in the URL
4943 *
4944 * No matter if we use a proxy or not, we have to figure out the remote
4945 * port number of various reasons.
4946 *
4947 * To be able to detect port number flawlessly, we must not confuse them
4948 * IPv6-specified addresses in the [0::1] style. (RFC2732)
4949 *
4950 * The conn->host.name is currently [user:passwd@]host[:port] where host
4951 * could be a hostname, IPv4 address or IPv6 address.
4952 *
4953 * The port number embedded in the URL is replaced, if necessary.
4954 *************************************************************/
parse_remote_port(struct SessionHandle * data,struct connectdata * conn)4955 static CURLcode parse_remote_port(struct SessionHandle *data,
4956 struct connectdata *conn)
4957 {
4958 char *portptr;
4959 char endbracket;
4960
4961 /* Note that at this point, the IPv6 address cannot contain any scope
4962 suffix as that has already been removed in the parseurlandfillconn()
4963 function */
4964 if((1 == sscanf(conn->host.name, "[%*45[0123456789abcdefABCDEF:.]%c",
4965 &endbracket)) &&
4966 (']' == endbracket)) {
4967 /* this is a RFC2732-style specified IP-address */
4968 conn->bits.ipv6_ip = TRUE;
4969
4970 conn->host.name++; /* skip over the starting bracket */
4971 portptr = strchr(conn->host.name, ']');
4972 if(portptr) {
4973 *portptr++ = '\0'; /* zero terminate, killing the bracket */
4974 if(':' != *portptr)
4975 portptr = NULL; /* no port number available */
4976 }
4977 }
4978 else {
4979 #ifdef ENABLE_IPV6
4980 struct in6_addr in6;
4981 if(Curl_inet_pton(AF_INET6, conn->host.name, &in6) > 0) {
4982 /* This is a numerical IPv6 address, meaning this is a wrongly formatted
4983 URL */
4984 failf(data, "IPv6 numerical address used in URL without brackets");
4985 return CURLE_URL_MALFORMAT;
4986 }
4987 #endif
4988
4989 portptr = strrchr(conn->host.name, ':');
4990 }
4991
4992 if(data->set.use_port && data->state.allow_port) {
4993 /* if set, we use this and ignore the port possibly given in the URL */
4994 conn->remote_port = (unsigned short)data->set.use_port;
4995 if(portptr)
4996 *portptr = '\0'; /* cut off the name there anyway - if there was a port
4997 number - since the port number is to be ignored! */
4998 if(conn->bits.httpproxy) {
4999 /* we need to create new URL with the new port number */
5000 char *url;
5001 char type[12]="";
5002
5003 if(conn->bits.type_set)
5004 snprintf(type, sizeof(type), ";type=%c",
5005 data->set.prefer_ascii?'A':
5006 (data->set.ftp_list_only?'D':'I'));
5007
5008 /*
5009 * This synthesized URL isn't always right--suffixes like ;type=A are
5010 * stripped off. It would be better to work directly from the original
5011 * URL and simply replace the port part of it.
5012 */
5013 url = aprintf("%s://%s%s%s:%hu%s%s%s", conn->given->scheme,
5014 conn->bits.ipv6_ip?"[":"", conn->host.name,
5015 conn->bits.ipv6_ip?"]":"", conn->remote_port,
5016 data->state.slash_removed?"/":"", data->state.path,
5017 type);
5018 if(!url)
5019 return CURLE_OUT_OF_MEMORY;
5020
5021 if(data->change.url_alloc) {
5022 Curl_safefree(data->change.url);
5023 data->change.url_alloc = FALSE;
5024 }
5025
5026 data->change.url = url;
5027 data->change.url_alloc = TRUE;
5028 }
5029 }
5030 else if(portptr) {
5031 /* no CURLOPT_PORT given, extract the one from the URL */
5032
5033 char *rest;
5034 long port;
5035
5036 port=strtol(portptr+1, &rest, 10); /* Port number must be decimal */
5037
5038 if((port < 0) || (port > 0xffff)) {
5039 /* Single unix standard says port numbers are 16 bits long */
5040 failf(data, "Port number out of range");
5041 return CURLE_URL_MALFORMAT;
5042 }
5043
5044 else if(rest != &portptr[1]) {
5045 *portptr = '\0'; /* cut off the name there */
5046 conn->remote_port = curlx_ultous(port);
5047 }
5048 else
5049 /* Browser behavior adaptation. If there's a colon with no digits after,
5050 just cut off the name there which makes us ignore the colon and just
5051 use the default port. Firefox and Chrome both do that. */
5052 *portptr = '\0';
5053 }
5054 return CURLE_OK;
5055 }
5056
5057 /*
5058 * Override the login details from the URL with that in the CURLOPT_USERPWD
5059 * option or a .netrc file, if applicable.
5060 */
override_login(struct SessionHandle * data,struct connectdata * conn,char ** userp,char ** passwdp,char ** optionsp)5061 static CURLcode override_login(struct SessionHandle *data,
5062 struct connectdata *conn,
5063 char **userp, char **passwdp, char **optionsp)
5064 {
5065 if(data->set.str[STRING_USERNAME]) {
5066 free(*userp);
5067 *userp = strdup(data->set.str[STRING_USERNAME]);
5068 if(!*userp)
5069 return CURLE_OUT_OF_MEMORY;
5070 }
5071
5072 if(data->set.str[STRING_PASSWORD]) {
5073 free(*passwdp);
5074 *passwdp = strdup(data->set.str[STRING_PASSWORD]);
5075 if(!*passwdp)
5076 return CURLE_OUT_OF_MEMORY;
5077 }
5078
5079 if(data->set.str[STRING_OPTIONS]) {
5080 free(*optionsp);
5081 *optionsp = strdup(data->set.str[STRING_OPTIONS]);
5082 if(!*optionsp)
5083 return CURLE_OUT_OF_MEMORY;
5084 }
5085
5086 conn->bits.netrc = FALSE;
5087 if(data->set.use_netrc != CURL_NETRC_IGNORED) {
5088 int ret = Curl_parsenetrc(conn->host.name,
5089 userp, passwdp,
5090 data->set.str[STRING_NETRC_FILE]);
5091 if(ret > 0) {
5092 infof(data, "Couldn't find host %s in the "
5093 DOT_CHAR "netrc file; using defaults\n",
5094 conn->host.name);
5095 }
5096 else if(ret < 0 ) {
5097 return CURLE_OUT_OF_MEMORY;
5098 }
5099 else {
5100 /* set bits.netrc TRUE to remember that we got the name from a .netrc
5101 file, so that it is safe to use even if we followed a Location: to a
5102 different host or similar. */
5103 conn->bits.netrc = TRUE;
5104
5105 conn->bits.user_passwd = TRUE; /* enable user+password */
5106 }
5107 }
5108
5109 return CURLE_OK;
5110 }
5111
5112 /*
5113 * Set the login details so they're available in the connection
5114 */
set_login(struct connectdata * conn,const char * user,const char * passwd,const char * options)5115 static CURLcode set_login(struct connectdata *conn,
5116 const char *user, const char *passwd,
5117 const char *options)
5118 {
5119 CURLcode result = CURLE_OK;
5120
5121 /* If our protocol needs a password and we have none, use the defaults */
5122 if((conn->handler->flags & PROTOPT_NEEDSPWD) && !conn->bits.user_passwd) {
5123 /* Store the default user */
5124 conn->user = strdup(CURL_DEFAULT_USER);
5125
5126 /* Store the default password */
5127 if(conn->user)
5128 conn->passwd = strdup(CURL_DEFAULT_PASSWORD);
5129 else
5130 conn->passwd = NULL;
5131
5132 /* This is the default password, so DON'T set conn->bits.user_passwd */
5133 }
5134 else {
5135 /* Store the user, zero-length if not set */
5136 conn->user = strdup(user);
5137
5138 /* Store the password (only if user is present), zero-length if not set */
5139 if(conn->user)
5140 conn->passwd = strdup(passwd);
5141 else
5142 conn->passwd = NULL;
5143 }
5144
5145 if(!conn->user || !conn->passwd)
5146 result = CURLE_OUT_OF_MEMORY;
5147
5148 /* Store the options, null if not set */
5149 if(!result && options[0]) {
5150 conn->options = strdup(options);
5151
5152 if(!conn->options)
5153 result = CURLE_OUT_OF_MEMORY;
5154 }
5155
5156 return result;
5157 }
5158
5159 /*************************************************************
5160 * Resolve the address of the server or proxy
5161 *************************************************************/
resolve_server(struct SessionHandle * data,struct connectdata * conn,bool * async)5162 static CURLcode resolve_server(struct SessionHandle *data,
5163 struct connectdata *conn,
5164 bool *async)
5165 {
5166 CURLcode result=CURLE_OK;
5167 long timeout_ms = Curl_timeleft(data, NULL, TRUE);
5168
5169 /*************************************************************
5170 * Resolve the name of the server or proxy
5171 *************************************************************/
5172 if(conn->bits.reuse)
5173 /* We're reusing the connection - no need to resolve anything, and
5174 fix_hostname() was called already in create_conn() for the re-use
5175 case. */
5176 *async = FALSE;
5177
5178 else {
5179 /* this is a fresh connect */
5180 int rc;
5181 struct Curl_dns_entry *hostaddr;
5182
5183 /* set a pointer to the hostname we display */
5184 fix_hostname(data, conn, &conn->host);
5185
5186 #ifdef USE_UNIX_SOCKETS
5187 if(data->set.str[STRING_UNIX_SOCKET_PATH]) {
5188 /* Unix domain sockets are local. The host gets ignored, just use the
5189 * specified domain socket address. Do not cache "DNS entries". There is
5190 * no DNS involved and we already have the filesystem path available */
5191 const char *path = data->set.str[STRING_UNIX_SOCKET_PATH];
5192
5193 hostaddr = calloc(1, sizeof(struct Curl_dns_entry));
5194 if(!hostaddr)
5195 result = CURLE_OUT_OF_MEMORY;
5196 else if((hostaddr->addr = Curl_unix2addr(path)) != NULL)
5197 hostaddr->inuse++;
5198 else {
5199 /* Long paths are not supported for now */
5200 if(strlen(path) >= sizeof(((struct sockaddr_un *)0)->sun_path)) {
5201 failf(data, "Unix socket path too long: '%s'", path);
5202 result = CURLE_COULDNT_RESOLVE_HOST;
5203 }
5204 else
5205 result = CURLE_OUT_OF_MEMORY;
5206 free(hostaddr);
5207 hostaddr = NULL;
5208 }
5209 }
5210 else
5211 #endif
5212 if(!conn->proxy.name || !*conn->proxy.name) {
5213 /* If not connecting via a proxy, extract the port from the URL, if it is
5214 * there, thus overriding any defaults that might have been set above. */
5215 conn->port = conn->remote_port; /* it is the same port */
5216
5217 /* Resolve target host right on */
5218 rc = Curl_resolv_timeout(conn, conn->host.name, (int)conn->port,
5219 &hostaddr, timeout_ms);
5220 if(rc == CURLRESOLV_PENDING)
5221 *async = TRUE;
5222
5223 else if(rc == CURLRESOLV_TIMEDOUT)
5224 result = CURLE_OPERATION_TIMEDOUT;
5225
5226 else if(!hostaddr) {
5227 failf(data, "Couldn't resolve host '%s'", conn->host.dispname);
5228 result = CURLE_COULDNT_RESOLVE_HOST;
5229 /* don't return yet, we need to clean up the timeout first */
5230 }
5231 }
5232 else {
5233 /* This is a proxy that hasn't been resolved yet. */
5234
5235 /* IDN-fix the proxy name */
5236 fix_hostname(data, conn, &conn->proxy);
5237
5238 /* resolve proxy */
5239 rc = Curl_resolv_timeout(conn, conn->proxy.name, (int)conn->port,
5240 &hostaddr, timeout_ms);
5241
5242 if(rc == CURLRESOLV_PENDING)
5243 *async = TRUE;
5244
5245 else if(rc == CURLRESOLV_TIMEDOUT)
5246 result = CURLE_OPERATION_TIMEDOUT;
5247
5248 else if(!hostaddr) {
5249 failf(data, "Couldn't resolve proxy '%s'", conn->proxy.dispname);
5250 result = CURLE_COULDNT_RESOLVE_PROXY;
5251 /* don't return yet, we need to clean up the timeout first */
5252 }
5253 }
5254 DEBUGASSERT(conn->dns_entry == NULL);
5255 conn->dns_entry = hostaddr;
5256 }
5257
5258 return result;
5259 }
5260
5261 /*
5262 * Cleanup the connection just allocated before we can move along and use the
5263 * previously existing one. All relevant data is copied over and old_conn is
5264 * ready for freeing once this function returns.
5265 */
reuse_conn(struct connectdata * old_conn,struct connectdata * conn)5266 static void reuse_conn(struct connectdata *old_conn,
5267 struct connectdata *conn)
5268 {
5269 free(old_conn->proxy.rawalloc);
5270
5271 /* free the SSL config struct from this connection struct as this was
5272 allocated in vain and is targeted for destruction */
5273 Curl_free_ssl_config(&old_conn->ssl_config);
5274
5275 conn->data = old_conn->data;
5276
5277 /* get the user+password information from the old_conn struct since it may
5278 * be new for this request even when we re-use an existing connection */
5279 conn->bits.user_passwd = old_conn->bits.user_passwd;
5280 if(conn->bits.user_passwd) {
5281 /* use the new user name and password though */
5282 Curl_safefree(conn->user);
5283 Curl_safefree(conn->passwd);
5284 conn->user = old_conn->user;
5285 conn->passwd = old_conn->passwd;
5286 old_conn->user = NULL;
5287 old_conn->passwd = NULL;
5288 }
5289
5290 conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd;
5291 if(conn->bits.proxy_user_passwd) {
5292 /* use the new proxy user name and proxy password though */
5293 Curl_safefree(conn->proxyuser);
5294 Curl_safefree(conn->proxypasswd);
5295 conn->proxyuser = old_conn->proxyuser;
5296 conn->proxypasswd = old_conn->proxypasswd;
5297 old_conn->proxyuser = NULL;
5298 old_conn->proxypasswd = NULL;
5299 }
5300
5301 /* host can change, when doing keepalive with a proxy or if the case is
5302 different this time etc */
5303 Curl_safefree(conn->host.rawalloc);
5304 conn->host=old_conn->host;
5305
5306 /* persist connection info in session handle */
5307 Curl_persistconninfo(conn);
5308
5309 /* re-use init */
5310 conn->bits.reuse = TRUE; /* yes, we're re-using here */
5311
5312 Curl_safefree(old_conn->user);
5313 Curl_safefree(old_conn->passwd);
5314 Curl_safefree(old_conn->proxyuser);
5315 Curl_safefree(old_conn->proxypasswd);
5316 Curl_safefree(old_conn->localdev);
5317
5318 Curl_llist_destroy(old_conn->send_pipe, NULL);
5319 Curl_llist_destroy(old_conn->recv_pipe, NULL);
5320
5321 old_conn->send_pipe = NULL;
5322 old_conn->recv_pipe = NULL;
5323
5324 Curl_safefree(old_conn->master_buffer);
5325 }
5326
5327 /**
5328 * create_conn() sets up a new connectdata struct, or re-uses an already
5329 * existing one, and resolves host name.
5330 *
5331 * if this function returns CURLE_OK and *async is set to TRUE, the resolve
5332 * response will be coming asynchronously. If *async is FALSE, the name is
5333 * already resolved.
5334 *
5335 * @param data The sessionhandle pointer
5336 * @param in_connect is set to the next connection data pointer
5337 * @param async is set TRUE when an async DNS resolution is pending
5338 * @see Curl_setup_conn()
5339 *
5340 * *NOTE* this function assigns the conn->data pointer!
5341 */
5342
create_conn(struct SessionHandle * data,struct connectdata ** in_connect,bool * async)5343 static CURLcode create_conn(struct SessionHandle *data,
5344 struct connectdata **in_connect,
5345 bool *async)
5346 {
5347 CURLcode result = CURLE_OK;
5348 struct connectdata *conn;
5349 struct connectdata *conn_temp = NULL;
5350 size_t urllen;
5351 char *user = NULL;
5352 char *passwd = NULL;
5353 char *options = NULL;
5354 bool reuse;
5355 char *proxy = NULL;
5356 bool prot_missing = FALSE;
5357 bool connections_available = TRUE;
5358 bool force_reuse = FALSE;
5359 bool waitpipe = FALSE;
5360 size_t max_host_connections = Curl_multi_max_host_connections(data->multi);
5361 size_t max_total_connections = Curl_multi_max_total_connections(data->multi);
5362
5363 *async = FALSE;
5364
5365 /*************************************************************
5366 * Check input data
5367 *************************************************************/
5368
5369 if(!data->change.url) {
5370 result = CURLE_URL_MALFORMAT;
5371 goto out;
5372 }
5373
5374 /* First, split up the current URL in parts so that we can use the
5375 parts for checking against the already present connections. In order
5376 to not have to modify everything at once, we allocate a temporary
5377 connection data struct and fill in for comparison purposes. */
5378 conn = allocate_conn(data);
5379
5380 if(!conn) {
5381 result = CURLE_OUT_OF_MEMORY;
5382 goto out;
5383 }
5384
5385 /* We must set the return variable as soon as possible, so that our
5386 parent can cleanup any possible allocs we may have done before
5387 any failure */
5388 *in_connect = conn;
5389
5390 /* This initing continues below, see the comment "Continue connectdata
5391 * initialization here" */
5392
5393 /***********************************************************
5394 * We need to allocate memory to store the path in. We get the size of the
5395 * full URL to be sure, and we need to make it at least 256 bytes since
5396 * other parts of the code will rely on this fact
5397 ***********************************************************/
5398 #define LEAST_PATH_ALLOC 256
5399 urllen=strlen(data->change.url);
5400 if(urllen < LEAST_PATH_ALLOC)
5401 urllen=LEAST_PATH_ALLOC;
5402
5403 /*
5404 * We malloc() the buffers below urllen+2 to make room for 2 possibilities:
5405 * 1 - an extra terminating zero
5406 * 2 - an extra slash (in case a syntax like "www.host.com?moo" is used)
5407 */
5408
5409 Curl_safefree(data->state.pathbuffer);
5410 data->state.path = NULL;
5411
5412 data->state.pathbuffer = malloc(urllen+2);
5413 if(NULL == data->state.pathbuffer) {
5414 result = CURLE_OUT_OF_MEMORY; /* really bad error */
5415 goto out;
5416 }
5417 data->state.path = data->state.pathbuffer;
5418
5419 conn->host.rawalloc = malloc(urllen+2);
5420 if(NULL == conn->host.rawalloc) {
5421 Curl_safefree(data->state.pathbuffer);
5422 data->state.path = NULL;
5423 result = CURLE_OUT_OF_MEMORY;
5424 goto out;
5425 }
5426
5427 conn->host.name = conn->host.rawalloc;
5428 conn->host.name[0] = 0;
5429
5430 user = strdup("");
5431 passwd = strdup("");
5432 options = strdup("");
5433 if(!user || !passwd || !options) {
5434 result = CURLE_OUT_OF_MEMORY;
5435 goto out;
5436 }
5437
5438 result = parseurlandfillconn(data, conn, &prot_missing, &user, &passwd,
5439 &options);
5440 if(result)
5441 goto out;
5442
5443 /*************************************************************
5444 * No protocol part in URL was used, add it!
5445 *************************************************************/
5446 if(prot_missing) {
5447 /* We're guessing prefixes here and if we're told to use a proxy or if
5448 we're gonna follow a Location: later or... then we need the protocol
5449 part added so that we have a valid URL. */
5450 char *reurl;
5451
5452 reurl = aprintf("%s://%s", conn->handler->scheme, data->change.url);
5453
5454 if(!reurl) {
5455 result = CURLE_OUT_OF_MEMORY;
5456 goto out;
5457 }
5458
5459 if(data->change.url_alloc) {
5460 Curl_safefree(data->change.url);
5461 data->change.url_alloc = FALSE;
5462 }
5463
5464 data->change.url = reurl;
5465 data->change.url_alloc = TRUE; /* free this later */
5466 }
5467
5468 /*************************************************************
5469 * If the protocol can't handle url query strings, then cut
5470 * off the unhandable part
5471 *************************************************************/
5472 if((conn->given->flags&PROTOPT_NOURLQUERY)) {
5473 char *path_q_sep = strchr(conn->data->state.path, '?');
5474 if(path_q_sep) {
5475 /* according to rfc3986, allow the query (?foo=bar)
5476 also on protocols that can't handle it.
5477
5478 cut the string-part after '?'
5479 */
5480
5481 /* terminate the string */
5482 path_q_sep[0] = 0;
5483 }
5484 }
5485
5486 if(data->set.str[STRING_BEARER]) {
5487 conn->xoauth2_bearer = strdup(data->set.str[STRING_BEARER]);
5488 if(!conn->xoauth2_bearer) {
5489 result = CURLE_OUT_OF_MEMORY;
5490 goto out;
5491 }
5492 }
5493
5494 #ifndef CURL_DISABLE_PROXY
5495 /*************************************************************
5496 * Extract the user and password from the authentication string
5497 *************************************************************/
5498 if(conn->bits.proxy_user_passwd) {
5499 result = parse_proxy_auth(data, conn);
5500 if(result)
5501 goto out;
5502 }
5503
5504 /*************************************************************
5505 * Detect what (if any) proxy to use
5506 *************************************************************/
5507 if(data->set.str[STRING_PROXY]) {
5508 proxy = strdup(data->set.str[STRING_PROXY]);
5509 /* if global proxy is set, this is it */
5510 if(NULL == proxy) {
5511 failf(data, "memory shortage");
5512 result = CURLE_OUT_OF_MEMORY;
5513 goto out;
5514 }
5515 }
5516
5517 if(data->set.str[STRING_NOPROXY] &&
5518 check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY])) {
5519 free(proxy); /* proxy is in exception list */
5520 proxy = NULL;
5521 }
5522 else if(!proxy)
5523 proxy = detect_proxy(conn);
5524
5525 #ifdef USE_UNIX_SOCKETS
5526 if(proxy && data->set.str[STRING_UNIX_SOCKET_PATH]) {
5527 free(proxy); /* Unix domain sockets cannot be proxied, so disable it */
5528 proxy = NULL;
5529 }
5530 #endif
5531
5532 if(proxy && (!*proxy || (conn->handler->flags & PROTOPT_NONETWORK))) {
5533 free(proxy); /* Don't bother with an empty proxy string or if the
5534 protocol doesn't work with network */
5535 proxy = NULL;
5536 }
5537
5538 /***********************************************************************
5539 * If this is supposed to use a proxy, we need to figure out the proxy host
5540 * name, proxy type and port number, so that we can re-use an existing
5541 * connection that may exist registered to the same proxy host.
5542 ***********************************************************************/
5543 if(proxy) {
5544 result = parse_proxy(data, conn, proxy);
5545
5546 free(proxy); /* parse_proxy copies the proxy string */
5547 proxy = NULL;
5548
5549 if(result)
5550 goto out;
5551
5552 if((conn->proxytype == CURLPROXY_HTTP) ||
5553 (conn->proxytype == CURLPROXY_HTTP_1_0)) {
5554 #ifdef CURL_DISABLE_HTTP
5555 /* asking for a HTTP proxy is a bit funny when HTTP is disabled... */
5556 result = CURLE_UNSUPPORTED_PROTOCOL;
5557 goto out;
5558 #else
5559 /* force this connection's protocol to become HTTP if not already
5560 compatible - if it isn't tunneling through */
5561 if(!(conn->handler->protocol & PROTO_FAMILY_HTTP) &&
5562 !conn->bits.tunnel_proxy)
5563 conn->handler = &Curl_handler_http;
5564
5565 conn->bits.httpproxy = TRUE;
5566 #endif
5567 }
5568 else {
5569 conn->bits.httpproxy = FALSE; /* not a HTTP proxy */
5570 conn->bits.tunnel_proxy = FALSE; /* no tunneling if not HTTP */
5571 }
5572 conn->bits.proxy = TRUE;
5573 }
5574 else {
5575 /* we aren't using the proxy after all... */
5576 conn->bits.proxy = FALSE;
5577 conn->bits.httpproxy = FALSE;
5578 conn->bits.proxy_user_passwd = FALSE;
5579 conn->bits.tunnel_proxy = FALSE;
5580 }
5581
5582 #endif /* CURL_DISABLE_PROXY */
5583
5584 /*************************************************************
5585 * If the protocol is using SSL and HTTP proxy is used, we set
5586 * the tunnel_proxy bit.
5587 *************************************************************/
5588 if((conn->given->flags&PROTOPT_SSL) && conn->bits.httpproxy)
5589 conn->bits.tunnel_proxy = TRUE;
5590
5591 /*************************************************************
5592 * Figure out the remote port number and fix it in the URL
5593 *************************************************************/
5594 result = parse_remote_port(data, conn);
5595 if(result)
5596 goto out;
5597
5598 /* Check for overridden login details and set them accordingly so they
5599 they are known when protocol->setup_connection is called! */
5600 result = override_login(data, conn, &user, &passwd, &options);
5601 if(result)
5602 goto out;
5603 result = set_login(conn, user, passwd, options);
5604 if(result)
5605 goto out;
5606
5607 /*************************************************************
5608 * Setup internals depending on protocol. Needs to be done after
5609 * we figured out what/if proxy to use.
5610 *************************************************************/
5611 result = setup_connection_internals(conn);
5612 if(result)
5613 goto out;
5614
5615 conn->recv[FIRSTSOCKET] = Curl_recv_plain;
5616 conn->send[FIRSTSOCKET] = Curl_send_plain;
5617 conn->recv[SECONDARYSOCKET] = Curl_recv_plain;
5618 conn->send[SECONDARYSOCKET] = Curl_send_plain;
5619
5620 /***********************************************************************
5621 * file: is a special case in that it doesn't need a network connection
5622 ***********************************************************************/
5623 #ifndef CURL_DISABLE_FILE
5624 if(conn->handler->flags & PROTOPT_NONETWORK) {
5625 bool done;
5626 /* this is supposed to be the connect function so we better at least check
5627 that the file is present here! */
5628 DEBUGASSERT(conn->handler->connect_it);
5629 result = conn->handler->connect_it(conn, &done);
5630
5631 /* Setup a "faked" transfer that'll do nothing */
5632 if(!result) {
5633 conn->data = data;
5634 conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; /* we are "connected */
5635
5636 Curl_conncache_add_conn(data->state.conn_cache, conn);
5637
5638 /*
5639 * Setup whatever necessary for a resumed transfer
5640 */
5641 result = setup_range(data);
5642 if(result) {
5643 DEBUGASSERT(conn->handler->done);
5644 /* we ignore the return code for the protocol-specific DONE */
5645 (void)conn->handler->done(conn, result, FALSE);
5646 goto out;
5647 }
5648
5649 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */
5650 -1, NULL); /* no upload */
5651 }
5652
5653 /* since we skip do_init() */
5654 do_init(conn);
5655
5656 goto out;
5657 }
5658 #endif
5659
5660 /* Get a cloned copy of the SSL config situation stored in the
5661 connection struct. But to get this going nicely, we must first make
5662 sure that the strings in the master copy are pointing to the correct
5663 strings in the session handle strings array!
5664
5665 Keep in mind that the pointers in the master copy are pointing to strings
5666 that will be freed as part of the SessionHandle struct, but all cloned
5667 copies will be separately allocated.
5668 */
5669 data->set.ssl.CApath = data->set.str[STRING_SSL_CAPATH];
5670 data->set.ssl.CAfile = data->set.str[STRING_SSL_CAFILE];
5671 data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE];
5672 data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT];
5673 data->set.ssl.random_file = data->set.str[STRING_SSL_RANDOM_FILE];
5674 data->set.ssl.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
5675 data->set.ssl.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST];
5676 #ifdef USE_TLS_SRP
5677 data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME];
5678 data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD];
5679 #endif
5680
5681 if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config)) {
5682 result = CURLE_OUT_OF_MEMORY;
5683 goto out;
5684 }
5685
5686 prune_dead_connections(data);
5687
5688 /*************************************************************
5689 * Check the current list of connections to see if we can
5690 * re-use an already existing one or if we have to create a
5691 * new one.
5692 *************************************************************/
5693
5694 /* reuse_fresh is TRUE if we are told to use a new connection by force, but
5695 we only acknowledge this option if this is not a re-used connection
5696 already (which happens due to follow-location or during a HTTP
5697 authentication phase). */
5698 if(data->set.reuse_fresh && !data->state.this_is_a_follow)
5699 reuse = FALSE;
5700 else
5701 reuse = ConnectionExists(data, conn, &conn_temp, &force_reuse, &waitpipe);
5702
5703 /* If we found a reusable connection, we may still want to
5704 open a new connection if we are pipelining. */
5705 if(reuse && !force_reuse && IsPipeliningPossible(data, conn_temp)) {
5706 size_t pipelen = conn_temp->send_pipe->size + conn_temp->recv_pipe->size;
5707 if(pipelen > 0) {
5708 infof(data, "Found connection %ld, with requests in the pipe (%zu)\n",
5709 conn_temp->connection_id, pipelen);
5710
5711 if(conn_temp->bundle->num_connections < max_host_connections &&
5712 data->state.conn_cache->num_connections < max_total_connections) {
5713 /* We want a new connection anyway */
5714 reuse = FALSE;
5715
5716 infof(data, "We can reuse, but we want a new connection anyway\n");
5717 }
5718 }
5719 }
5720
5721 if(reuse) {
5722 /*
5723 * We already have a connection for this, we got the former connection
5724 * in the conn_temp variable and thus we need to cleanup the one we
5725 * just allocated before we can move along and use the previously
5726 * existing one.
5727 */
5728 conn_temp->inuse = TRUE; /* mark this as being in use so that no other
5729 handle in a multi stack may nick it */
5730 reuse_conn(conn, conn_temp);
5731 free(conn); /* we don't need this anymore */
5732 conn = conn_temp;
5733 *in_connect = conn;
5734
5735 /* set a pointer to the hostname we display */
5736 fix_hostname(data, conn, &conn->host);
5737
5738 infof(data, "Re-using existing connection! (#%ld) with %s %s\n",
5739 conn->connection_id,
5740 conn->bits.proxy?"proxy":"host",
5741 conn->proxy.name?conn->proxy.dispname:conn->host.dispname);
5742 }
5743 else {
5744 /* We have decided that we want a new connection. However, we may not
5745 be able to do that if we have reached the limit of how many
5746 connections we are allowed to open. */
5747 struct connectbundle *bundle = NULL;
5748
5749 if(waitpipe)
5750 /* There is a connection that *might* become usable for pipelining
5751 "soon", and we wait for that */
5752 connections_available = FALSE;
5753 else
5754 bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache);
5755
5756 if(max_host_connections > 0 && bundle &&
5757 (bundle->num_connections >= max_host_connections)) {
5758 struct connectdata *conn_candidate;
5759
5760 /* The bundle is full. Let's see if we can kill a connection. */
5761 conn_candidate = find_oldest_idle_connection_in_bundle(data, bundle);
5762
5763 if(conn_candidate) {
5764 /* Set the connection's owner correctly, then kill it */
5765 conn_candidate->data = data;
5766 (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
5767 }
5768 else {
5769 infof(data, "No more connections allowed to host: %d\n",
5770 max_host_connections);
5771 connections_available = FALSE;
5772 }
5773 }
5774
5775 if(connections_available &&
5776 (max_total_connections > 0) &&
5777 (data->state.conn_cache->num_connections >= max_total_connections)) {
5778 struct connectdata *conn_candidate;
5779
5780 /* The cache is full. Let's see if we can kill a connection. */
5781 conn_candidate = find_oldest_idle_connection(data);
5782
5783 if(conn_candidate) {
5784 /* Set the connection's owner correctly, then kill it */
5785 conn_candidate->data = data;
5786 (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
5787 }
5788 else {
5789 infof(data, "No connections available in cache\n");
5790 connections_available = FALSE;
5791 }
5792 }
5793
5794 if(!connections_available) {
5795 infof(data, "No connections available.\n");
5796
5797 conn_free(conn);
5798 *in_connect = NULL;
5799
5800 result = CURLE_NO_CONNECTION_AVAILABLE;
5801 goto out;
5802 }
5803 else {
5804 /*
5805 * This is a brand new connection, so let's store it in the connection
5806 * cache of ours!
5807 */
5808 Curl_conncache_add_conn(data->state.conn_cache, conn);
5809 }
5810
5811 #if defined(USE_NTLM)
5812 /* If NTLM is requested in a part of this connection, make sure we don't
5813 assume the state is fine as this is a fresh connection and NTLM is
5814 connection based. */
5815 if((data->state.authhost.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
5816 data->state.authhost.done) {
5817 infof(data, "NTLM picked AND auth done set, clear picked!\n");
5818 data->state.authhost.picked = CURLAUTH_NONE;
5819 }
5820
5821 if((data->state.authproxy.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
5822 data->state.authproxy.done) {
5823 infof(data, "NTLM-proxy picked AND auth done set, clear picked!\n");
5824 data->state.authproxy.picked = CURLAUTH_NONE;
5825 }
5826 #endif
5827 }
5828
5829 /* Mark the connection as used */
5830 conn->inuse = TRUE;
5831
5832 /* Setup and init stuff before DO starts, in preparing for the transfer. */
5833 do_init(conn);
5834
5835 /*
5836 * Setup whatever necessary for a resumed transfer
5837 */
5838 result = setup_range(data);
5839 if(result)
5840 goto out;
5841
5842 /* Continue connectdata initialization here. */
5843
5844 /*
5845 * Inherit the proper values from the urldata struct AFTER we have arranged
5846 * the persistent connection stuff
5847 */
5848 conn->seek_func = data->set.seek_func;
5849 conn->seek_client = data->set.seek_client;
5850
5851 /*************************************************************
5852 * Resolve the address of the server or proxy
5853 *************************************************************/
5854 result = resolve_server(data, conn, async);
5855
5856 out:
5857
5858 free(options);
5859 free(passwd);
5860 free(user);
5861 free(proxy);
5862 return result;
5863 }
5864
5865 /* Curl_setup_conn() is called after the name resolve initiated in
5866 * create_conn() is all done.
5867 *
5868 * Curl_setup_conn() also handles reused connections
5869 *
5870 * conn->data MUST already have been setup fine (in create_conn)
5871 */
5872
Curl_setup_conn(struct connectdata * conn,bool * protocol_done)5873 CURLcode Curl_setup_conn(struct connectdata *conn,
5874 bool *protocol_done)
5875 {
5876 CURLcode result = CURLE_OK;
5877 struct SessionHandle *data = conn->data;
5878
5879 Curl_pgrsTime(data, TIMER_NAMELOOKUP);
5880
5881 if(conn->handler->flags & PROTOPT_NONETWORK) {
5882 /* nothing to setup when not using a network */
5883 *protocol_done = TRUE;
5884 return result;
5885 }
5886 *protocol_done = FALSE; /* default to not done */
5887
5888 /* set proxy_connect_closed to false unconditionally already here since it
5889 is used strictly to provide extra information to a parent function in the
5890 case of proxy CONNECT failures and we must make sure we don't have it
5891 lingering set from a previous invoke */
5892 conn->bits.proxy_connect_closed = FALSE;
5893
5894 /*
5895 * Set user-agent. Used for HTTP, but since we can attempt to tunnel
5896 * basically anything through a http proxy we can't limit this based on
5897 * protocol.
5898 */
5899 if(data->set.str[STRING_USERAGENT]) {
5900 Curl_safefree(conn->allocptr.uagent);
5901 conn->allocptr.uagent =
5902 aprintf("User-Agent: %s\r\n", data->set.str[STRING_USERAGENT]);
5903 if(!conn->allocptr.uagent)
5904 return CURLE_OUT_OF_MEMORY;
5905 }
5906
5907 data->req.headerbytecount = 0;
5908
5909 #ifdef CURL_DO_LINEEND_CONV
5910 data->state.crlf_conversions = 0; /* reset CRLF conversion counter */
5911 #endif /* CURL_DO_LINEEND_CONV */
5912
5913 /* set start time here for timeout purposes in the connect procedure, it
5914 is later set again for the progress meter purpose */
5915 conn->now = Curl_tvnow();
5916
5917 if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
5918 conn->bits.tcpconnect[FIRSTSOCKET] = FALSE;
5919 result = Curl_connecthost(conn, conn->dns_entry);
5920 if(result)
5921 return result;
5922 }
5923 else {
5924 Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */
5925 Curl_pgrsTime(data, TIMER_APPCONNECT); /* we're connected already */
5926 conn->bits.tcpconnect[FIRSTSOCKET] = TRUE;
5927 *protocol_done = TRUE;
5928 Curl_updateconninfo(conn, conn->sock[FIRSTSOCKET]);
5929 Curl_verboseconnect(conn);
5930 }
5931
5932 conn->now = Curl_tvnow(); /* time this *after* the connect is done, we
5933 set this here perhaps a second time */
5934
5935 #ifdef __EMX__
5936 /*
5937 * This check is quite a hack. We're calling _fsetmode to fix the problem
5938 * with fwrite converting newline characters (you get mangled text files,
5939 * and corrupted binary files when you download to stdout and redirect it to
5940 * a file).
5941 */
5942
5943 if((data->set.out)->_handle == NULL) {
5944 _fsetmode(stdout, "b");
5945 }
5946 #endif
5947
5948 return result;
5949 }
5950
Curl_connect(struct SessionHandle * data,struct connectdata ** in_connect,bool * asyncp,bool * protocol_done)5951 CURLcode Curl_connect(struct SessionHandle *data,
5952 struct connectdata **in_connect,
5953 bool *asyncp,
5954 bool *protocol_done)
5955 {
5956 CURLcode result;
5957
5958 *asyncp = FALSE; /* assume synchronous resolves by default */
5959
5960 /* call the stuff that needs to be called */
5961 result = create_conn(data, in_connect, asyncp);
5962
5963 if(!result) {
5964 /* no error */
5965 if((*in_connect)->send_pipe->size || (*in_connect)->recv_pipe->size)
5966 /* pipelining */
5967 *protocol_done = TRUE;
5968 else if(!*asyncp) {
5969 /* DNS resolution is done: that's either because this is a reused
5970 connection, in which case DNS was unnecessary, or because DNS
5971 really did finish already (synch resolver/fast async resolve) */
5972 result = Curl_setup_conn(*in_connect, protocol_done);
5973 }
5974 }
5975
5976 if(result == CURLE_NO_CONNECTION_AVAILABLE) {
5977 *in_connect = NULL;
5978 return result;
5979 }
5980
5981 if(result && *in_connect) {
5982 /* We're not allowed to return failure with memory left allocated
5983 in the connectdata struct, free those here */
5984 Curl_disconnect(*in_connect, FALSE); /* close the connection */
5985 *in_connect = NULL; /* return a NULL */
5986 }
5987
5988 return result;
5989 }
5990
Curl_done(struct connectdata ** connp,CURLcode status,bool premature)5991 CURLcode Curl_done(struct connectdata **connp,
5992 CURLcode status, /* an error if this is called after an
5993 error was detected */
5994 bool premature)
5995 {
5996 CURLcode result;
5997 struct connectdata *conn;
5998 struct SessionHandle *data;
5999
6000 DEBUGASSERT(*connp);
6001
6002 conn = *connp;
6003 data = conn->data;
6004
6005 DEBUGF(infof(data, "Curl_done\n"));
6006
6007 if(data->state.done)
6008 /* Stop if Curl_done() has already been called */
6009 return CURLE_OK;
6010
6011 Curl_getoff_all_pipelines(data, conn);
6012
6013 /* Cleanup possible redirect junk */
6014 free(data->req.newurl);
6015 data->req.newurl = NULL;
6016 free(data->req.location);
6017 data->req.location = NULL;
6018
6019 switch(status) {
6020 case CURLE_ABORTED_BY_CALLBACK:
6021 case CURLE_READ_ERROR:
6022 case CURLE_WRITE_ERROR:
6023 /* When we're aborted due to a callback return code it basically have to
6024 be counted as premature as there is trouble ahead if we don't. We have
6025 many callbacks and protocols work differently, we could potentially do
6026 this more fine-grained in the future. */
6027 premature = TRUE;
6028 default:
6029 break;
6030 }
6031
6032 /* this calls the protocol-specific function pointer previously set */
6033 if(conn->handler->done)
6034 result = conn->handler->done(conn, status, premature);
6035 else
6036 result = status;
6037
6038 if(!result && Curl_pgrsDone(conn))
6039 result = CURLE_ABORTED_BY_CALLBACK;
6040
6041 if((conn->send_pipe->size + conn->recv_pipe->size != 0 &&
6042 !data->set.reuse_forbid &&
6043 !conn->bits.close)) {
6044 /* Stop if pipeline is not empty and we do not have to close
6045 connection. */
6046 DEBUGF(infof(data, "Connection still in use, no more Curl_done now!\n"));
6047 return CURLE_OK;
6048 }
6049
6050 data->state.done = TRUE; /* called just now! */
6051 Curl_resolver_cancel(conn);
6052
6053 if(conn->dns_entry) {
6054 Curl_resolv_unlock(data, conn->dns_entry); /* done with this */
6055 conn->dns_entry = NULL;
6056 }
6057
6058 /* if the transfer was completed in a paused state there can be buffered
6059 data left to write and then kill */
6060 free(data->state.tempwrite);
6061 data->state.tempwrite = NULL;
6062
6063 /* if data->set.reuse_forbid is TRUE, it means the libcurl client has
6064 forced us to close this connection. This is ignored for requests taking
6065 place in a NTLM authentication handshake
6066
6067 if conn->bits.close is TRUE, it means that the connection should be
6068 closed in spite of all our efforts to be nice, due to protocol
6069 restrictions in our or the server's end
6070
6071 if premature is TRUE, it means this connection was said to be DONE before
6072 the entire request operation is complete and thus we can't know in what
6073 state it is for re-using, so we're forced to close it. In a perfect world
6074 we can add code that keep track of if we really must close it here or not,
6075 but currently we have no such detail knowledge.
6076 */
6077
6078 if((data->set.reuse_forbid
6079 #if defined(USE_NTLM)
6080 && !(conn->ntlm.state == NTLMSTATE_TYPE2 ||
6081 conn->proxyntlm.state == NTLMSTATE_TYPE2)
6082 #endif
6083 ) || conn->bits.close || premature) {
6084 CURLcode res2 = Curl_disconnect(conn, premature); /* close connection */
6085
6086 /* If we had an error already, make sure we return that one. But
6087 if we got a new error, return that. */
6088 if(!result && res2)
6089 result = res2;
6090 }
6091 else {
6092 /* the connection is no longer in use */
6093 if(ConnectionDone(data, conn)) {
6094 /* remember the most recently used connection */
6095 data->state.lastconnect = conn;
6096
6097 infof(data, "Connection #%ld to host %s left intact\n",
6098 conn->connection_id,
6099 conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname);
6100 }
6101 else
6102 data->state.lastconnect = NULL;
6103 }
6104
6105 *connp = NULL; /* to make the caller of this function better detect that
6106 this was either closed or handed over to the connection
6107 cache here, and therefore cannot be used from this point on
6108 */
6109 Curl_free_request_state(data);
6110
6111 return result;
6112 }
6113
6114 /*
6115 * do_init() inits the readwrite session. This is inited each time (in the DO
6116 * function before the protocol-specific DO functions are invoked) for a
6117 * transfer, sometimes multiple times on the same SessionHandle. Make sure
6118 * nothing in here depends on stuff that are setup dynamically for the
6119 * transfer.
6120 */
6121
do_init(struct connectdata * conn)6122 static CURLcode do_init(struct connectdata *conn)
6123 {
6124 struct SessionHandle *data = conn->data;
6125 struct SingleRequest *k = &data->req;
6126
6127 data->state.done = FALSE; /* Curl_done() is not called yet */
6128 conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */
6129 data->state.expect100header = FALSE;
6130
6131 if(data->set.opt_no_body)
6132 /* in HTTP lingo, no body means using the HEAD request... */
6133 data->set.httpreq = HTTPREQ_HEAD;
6134 else if(HTTPREQ_HEAD == data->set.httpreq)
6135 /* ... but if unset there really is no perfect method that is the
6136 "opposite" of HEAD but in reality most people probably think GET
6137 then. The important thing is that we can't let it remain HEAD if the
6138 opt_no_body is set FALSE since then we'll behave wrong when getting
6139 HTTP. */
6140 data->set.httpreq = HTTPREQ_GET;
6141
6142 k->start = Curl_tvnow(); /* start time */
6143 k->now = k->start; /* current time is now */
6144 k->header = TRUE; /* assume header */
6145
6146 k->bytecount = 0;
6147
6148 k->buf = data->state.buffer;
6149 k->uploadbuf = data->state.uploadbuffer;
6150 k->hbufp = data->state.headerbuff;
6151 k->ignorebody=FALSE;
6152
6153 Curl_speedinit(data);
6154
6155 Curl_pgrsSetUploadCounter(data, 0);
6156 Curl_pgrsSetDownloadCounter(data, 0);
6157
6158 return CURLE_OK;
6159 }
6160
6161 /*
6162 * do_complete is called when the DO actions are complete.
6163 *
6164 * We init chunking and trailer bits to their default values here immediately
6165 * before receiving any header data for the current request in the pipeline.
6166 */
do_complete(struct connectdata * conn)6167 static void do_complete(struct connectdata *conn)
6168 {
6169 conn->data->req.chunk=FALSE;
6170 conn->data->req.maxfd = (conn->sockfd>conn->writesockfd?
6171 conn->sockfd:conn->writesockfd)+1;
6172 Curl_pgrsTime(conn->data, TIMER_PRETRANSFER);
6173 }
6174
Curl_do(struct connectdata ** connp,bool * done)6175 CURLcode Curl_do(struct connectdata **connp, bool *done)
6176 {
6177 CURLcode result=CURLE_OK;
6178 struct connectdata *conn = *connp;
6179 struct SessionHandle *data = conn->data;
6180
6181 if(conn->handler->do_it) {
6182 /* generic protocol-specific function pointer set in curl_connect() */
6183 result = conn->handler->do_it(conn, done);
6184
6185 /* This was formerly done in transfer.c, but we better do it here */
6186 if((CURLE_SEND_ERROR == result) && conn->bits.reuse) {
6187 /*
6188 * If the connection is using an easy handle, call reconnect
6189 * to re-establish the connection. Otherwise, let the multi logic
6190 * figure out how to re-establish the connection.
6191 */
6192 if(!data->multi) {
6193 result = Curl_reconnect_request(connp);
6194
6195 if(!result) {
6196 /* ... finally back to actually retry the DO phase */
6197 conn = *connp; /* re-assign conn since Curl_reconnect_request
6198 creates a new connection */
6199 result = conn->handler->do_it(conn, done);
6200 }
6201 }
6202 else
6203 return result;
6204 }
6205
6206 if(!result && *done)
6207 /* do_complete must be called after the protocol-specific DO function */
6208 do_complete(conn);
6209 }
6210 return result;
6211 }
6212
6213 /*
6214 * Curl_do_more() is called during the DO_MORE multi state. It is basically a
6215 * second stage DO state which (wrongly) was introduced to support FTP's
6216 * second connection.
6217 *
6218 * TODO: A future libcurl should be able to work away this state.
6219 *
6220 * 'complete' can return 0 for incomplete, 1 for done and -1 for go back to
6221 * DOING state there's more work to do!
6222 */
6223
Curl_do_more(struct connectdata * conn,int * complete)6224 CURLcode Curl_do_more(struct connectdata *conn, int *complete)
6225 {
6226 CURLcode result=CURLE_OK;
6227
6228 *complete = 0;
6229
6230 if(conn->handler->do_more)
6231 result = conn->handler->do_more(conn, complete);
6232
6233 if(!result && (*complete == 1))
6234 /* do_complete must be called after the protocol-specific DO function */
6235 do_complete(conn);
6236
6237 return result;
6238 }
6239