source: UsbWattMeter/trunk/curl-7.47.1/lib/url.c@ 164

Last change on this file since 164 was 164, checked in by coas-nagasima, 6 years ago

TOPPERS/ECNLサンプルアプリ「USB充電器電力計」を追加

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