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


rc_tagdetect_client
Author(s): Monika Florek-Jasinska , Raphael Schaller
autogenerated on Sat Feb 13 2021 03:42:16