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) {
293  Curl_safefree(data->change.referer);
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)
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. */
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 */
424  curl_multi_cleanup(data->multi_easy);
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 */
439  Curl_safefree(data->state.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 */
447  Curl_safefree(data->state.first_host);
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) {
456  Curl_safefree(data->change.referer);
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);
468  Curl_safefree(data->state.headerbuff);
469 
471 
473 
474  Curl_safefree(data->info.contenttype);
475  Curl_safefree(data->info.wouldredirect);
476 
477  /* this destroys the channel and we cannot use it anymore after this */
478  Curl_resolver_cleanup(data->state.resolver);
479 
482 
483  Curl_mime_cleanpart(&data->set.mimepost);
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 
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 
657  data->magic = CURLEASY_MAGIC_NUMBER;
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"));
672  }
673 
674  Curl_mime_initpart(&data->set.mimepost, data);
675 
676  data->state.headerbuff = malloc(HEADERSIZE);
677  if(!data->state.headerbuff) {
678  DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n"));
680  }
681  else {
683 
684  data->state.headersize = HEADERSIZE;
685 
687 
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 
698  Curl_http2_init_state(&data->state);
699  }
700 
701  if(result) {
702  Curl_resolver_cleanup(data->state.resolver);
703  free(data->state.buffer);
704  free(data->state.headerbuff);
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 */
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  */
754  va_arg(param, char *));
755  break;
756  case CURLOPT_EGDSOCKET:
757  /*
758  * The Entropy Gathering Daemon socket pathname
759  */
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 */
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);
955  data->set.ssl.primary.version = C_SSLVERSION_VALUE(arg);
956  data->set.ssl.primary.version_max = C_SSLVERSION_MAX_VALUE(arg);
957 #else
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);
968  data->set.proxy_ssl.primary.version = C_SSLVERSION_VALUE(arg);
969  data->set.proxy_ssl.primary.version_max = C_SSLVERSION_MAX_VALUE(arg);
970 #else
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  */
1016  data->set.http_disable_hostname_check_before_authentication =
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))))
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)
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) {
1248  curl_slist_free_all(data->change.cookielist);
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)
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 */
1305  Curl_cookie_clearall(data->cookies);
1307  }
1308  else if(strcasecompare(argptr, "SESS")) {
1309  /* clear session cookies */
1311  Curl_cookie_clearsess(data->cookies);
1313  }
1314  else if(strcasecompare(argptr, "FLUSH")) {
1315  /* flush cookies to file, takes care of the locking */
1317  }
1318  else if(strcasecompare(argptr, "RELOAD")) {
1319  /* reload cookies from file */
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) {
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  */
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 */
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))
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  */
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  */
1871  va_arg(param, char *));
1872  break;
1873  case CURLOPT_PROXYPASSWORD:
1874  /*
1875  * authentication password to use in the operation
1876  */
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 */
1947  data->set.fwrite_func = (curl_write_callback)fwrite;
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 */
1960  data->set.fread_func_set = (curl_read_callback)fread;
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  */
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  */
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  */
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  */
2061  va_arg(param, char *));
2062  break;
2063  case CURLOPT_KEYPASSWD:
2064  /*
2065  * String that holds the SSL or SSH private key password.
2066  */
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  */
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  */
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  */
2150  data->set.proxy_ssl.primary.verifypeer =
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  */
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
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
2222  break;
2223  case CURLOPT_SSL_FALSESTART:
2224  /*
2225  * Enable TLS false start.
2226  */
2227  if(!Curl_ssl_false_start()) {
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
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
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
2267  break;
2268  case CURLOPT_CAINFO:
2269  /*
2270  * Set CA info for SSL connection. Specify file name of the CA certificate
2271  */
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  */
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. */
2292  va_arg(param, char *));
2293  else
2294 #endif
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. */
2306  va_arg(param, char *));
2307  else
2308 #endif
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  */
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  */
2325  va_arg(param, char *));
2326  break;
2327  case CURLOPT_ISSUERCERT:
2328  /*
2329  * Set Issuer certificate file
2330  * to check certificates issuer
2331  */
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"));
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 */
2422  Curl_cookie_cleanup(data->cookies);
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) {
2428  data->set.general_ssl.max_ssl_sessions = data->share->max_ssl_sessions;
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);
2463  data->set.ssl.enable_beast = arg&CURLSSLOPT_ALLOW_BEAST?TRUE:FALSE;
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);
2469  data->set.proxy_ssl.enable_beast = arg&CURLSSLOPT_ALLOW_BEAST?TRUE:FALSE;
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;
2568  data->set.proxy_ssl.primary.sessionid = data->set.ssl.primary.sessionid;
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 */
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  */
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  */
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  */
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
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) {
2953  Curl_http2_remove_child(data->set.stream_depends_on, data);
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: */
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) {
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);
3138  Curl_conncache_remove_conn(data->state.conn_cache, conn);
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 */
3148  if(Curl_pipeline_wanted(data->multi, CURLPIPE_ANY)) {
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 
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) {
3463  Curl_conncache_foreach(data->state.conn_cache, data,
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) &&
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) &&
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 
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) {
3590  continue;
3591  }
3592  else if(rh) {
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;
3688  if(check->proxy_ssl[FIRSTSOCKET].state != ssl_connection_complete)
3689  continue;
3690  }
3691  else {
3692  if(!Curl_ssl_config_matches(&needle->ssl_config,
3693  &check->ssl_config))
3694  continue;
3695  if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete)
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 */
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:
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");
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 
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;
4269  conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy;
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 
4277  conn->ssl_config.verifystatus = data->set.ssl.primary.verifystatus;
4278  conn->ssl_config.verifypeer = data->set.ssl.primary.verifypeer;
4279  conn->ssl_config.verifyhost = data->set.ssl.primary.verifyhost;
4281  data->set.proxy_ssl.primary.verifystatus;
4282  conn->proxy_ssl_config.verifypeer = data->set.proxy_ssl.primary.verifypeer;
4283  conn->proxy_ssl_config.verifyhost = data->set.proxy_ssl.primary.verifyhost;
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 */
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;
4340  conn->closesocket_client = data->set.closesocket_client;
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__)
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)
4852  s->range = aprintf("%" CURL_FORMAT_CURL_OFF_TU "-", 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
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");
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");
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... */
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. */
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)
5672  }
5673 
5674  /* Allocate the password portion buffer */
5675  if(!result && passwdp && plen) {
5676  pbuf = malloc(plen + 1);
5677  if(!pbuf) {
5678  free(ubuf);
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);
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)
5940 
5941  /* Store the options, null if not set */
5942  if(!result && options[0]) {
5943  conn->options = strdup(options);
5944 
5945  if(!conn->options)
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)
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);
6211  }
6212  else
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)
6243 
6244  else if(!hostaddr) {
6245  failf(data, "Couldn't resolve host '%s'", connhost->dispname);
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)
6265 
6266  else if(!hostaddr) {
6267  failf(data, "Couldn't resolve proxy '%s'", host->dispname);
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) {
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) {
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 
6448  Curl_safefree(data->state.pathbuffer);
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) {
6460  Curl_safefree(data->state.pathbuffer);
6461  data->state.path = NULL;
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) {
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) {
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) {
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) {
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
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  *************************************************************/
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 
6655  Curl_conncache_add_conn(data->state.conn_cache, conn);
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  */
6688  data->set.ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_ORIG];
6689  data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY];
6690  data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_ORIG];
6691  data->set.proxy_ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY];
6692  data->set.ssl.primary.random_file = data->set.str[STRING_SSL_RANDOM_FILE];
6693  data->set.proxy_ssl.primary.random_file =
6694  data->set.str[STRING_SSL_RANDOM_FILE];
6695  data->set.ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
6696  data->set.proxy_ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
6697  data->set.ssl.primary.cipher_list =
6699  data->set.proxy_ssl.primary.cipher_list =
6701 
6702  data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_ORIG];
6703  data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY];
6704  data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_ORIG];
6705  data->set.proxy_ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY];
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];
6709  data->set.proxy_ssl.cert_type = data->set.str[STRING_CERT_TYPE_PROXY];
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];
6713  data->set.proxy_ssl.key_type = data->set.str[STRING_KEY_TYPE_PROXY];
6714  data->set.ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_ORIG];
6715  data->set.proxy_ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_PROXY];
6716  data->set.ssl.primary.clientcert = data->set.str[STRING_CERT_ORIG];
6717  data->set.proxy_ssl.primary.clientcert = data->set.str[STRING_CERT_PROXY];
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 
6725  if(!Curl_clone_primary_ssl_config(&data->set.ssl.primary,
6726  &conn->ssl_config)) {
6728  goto out;
6729  }
6730 
6731  if(!Curl_clone_primary_ssl_config(&data->set.proxy_ssl.primary,
6732  &conn->proxy_ssl_config)) {
6734  goto out;
6735  }
6736 
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. */
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  */
6867  Curl_conncache_add_conn(data->state.conn_cache, conn);
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");
6877  data->state.authhost.picked = CURLAUTH_NONE;
6878  data->state.authhost.done = FALSE;
6879  }
6880 
6881  if((data->state.authproxy.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
6882  data->state.authproxy.done) {
6883  infof(data, "NTLM-proxy picked AND auth done set, clear picked!\n");
6884  data->state.authproxy.picked = CURLAUTH_NONE;
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 
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 
7094 
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 }
Curl_share
Definition: share.h:39
Curl_mime_initpart
void Curl_mime_initpart(curl_mimepart *part, struct Curl_easy *easy)
Definition: mime.c:1161
DOT_CHAR
#define DOT_CHAR
Definition: curl_setup.h:467
STRING_KEY_PASSWD_PROXY
@ STRING_KEY_PASSWD_PROXY
Definition: urldata.h:1402
TIMER_CONNECT
@ TIMER_CONNECT
Definition: progress.h:53
connectdata::proxy_ssl
struct ssl_connect_data proxy_ssl[2]
Definition: urldata.h:880
UserDefined::verbose
bool verbose
Definition: urldata.h:1627
Curl_hash_next_element
struct curl_hash_element * Curl_hash_next_element(struct curl_hash_iterator *iter)
Definition: hash.c:292
STARTS_WITH_DRIVE_PREFIX
#define STARTS_WITH_DRIVE_PREFIX(str)
connectdata::port
long port
Definition: urldata.h:833
PROTOPT_CREDSPERREQUEST
#define PROTOPT_CREDSPERREQUEST
Definition: urldata.h:709
connectdata::localport
unsigned short localport
Definition: urldata.h:1015
warnless.h
curl_slist_append
CURL_EXTERN struct curl_slist * curl_slist_append(struct curl_slist *, const char *)
Definition: slist.c:89
HTTPREQ_POST_FORM
@ HTTPREQ_POST_FORM
Definition: urldata.h:1135
STRING_CUSTOMREQUEST
@ STRING_CUSTOMREQUEST
Definition: urldata.h:1392
Curl_ssl::have_pinnedpubkey
unsigned have_pinnedpubkey
Definition: vtls.h:38
ptr
UNITTEST_START char * ptr
Definition: unit1330.c:38
check
ROSCPP_DECL bool check()
connectdata::seek_func
curl_seek_callback seek_func
Definition: urldata.h:957
Curl_mime_cleanpart
void Curl_mime_cleanpart(curl_mimepart *part)
Definition: mime.c:1097
CURL_LOCK_DATA_DNS
@ CURL_LOCK_DATA_DNS
Definition: curl.h:2537
Curl_dupset
CURLcode Curl_dupset(struct Curl_easy *dst, struct Curl_easy *src)
Definition: url.c:362
hostname::name
char * name
Definition: urldata.h:444
options
static int options(struct mg_connection *conn)
Definition: server.cpp:29
p
const char ** p
Definition: unit1394.c:76
connclose
#define connclose(x, y)
Definition: connect.h:140
Curl_setup_transfer
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
STRING_MAIL_FROM
@ STRING_MAIL_FROM
Definition: urldata.h:1451
STRING_SSL_CAPATH_ORIG
@ STRING_SSL_CAPATH_ORIG
Definition: urldata.h:1413
Curl_oldest_idle_connection
struct connectdata * Curl_oldest_idle_connection(struct Curl_easy *data)
Definition: url.c:3300
curl_slist::next
struct curl_slist * next
Definition: curl.h:2334
curlx_sltous
unsigned short curlx_sltous(long slnum)
Definition: warnless.c:308
ConnectBits::httpproxy
bool httpproxy
Definition: urldata.h:383
connectdata::closesocket_client
void * closesocket_client
Definition: urldata.h:793
STRING_COOKIE
@ STRING_COOKIE
Definition: urldata.h:1390
connectdata::socks_proxy
struct proxy_info socks_proxy
Definition: urldata.h:830
strdup
#define strdup(ptr)
Definition: curl_memory.h:122
CURLPROTO_IMAPS
#define CURLPROTO_IMAPS
Definition: curl.h:855
CURLPROTO_POP3S
#define CURLPROTO_POP3S
Definition: curl.h:857
pipeline.h
CURLAUTH_NONE
#define CURLAUTH_NONE
Definition: curl.h:694
STRING_USERAGENT
@ STRING_USERAGENT
Definition: urldata.h:1423
connectdata::bits
struct ConnectBits bits
Definition: urldata.h:885
CURLPROXY_HTTP_1_0
@ CURLPROXY_HTTP_1_0
Definition: curl.h:665
Curl_handler::connection_check
unsigned int(* connection_check)(struct connectdata *conn, unsigned int checks_to_perform)
Definition: urldata.h:688
ssl_primary_config::verifypeer
bool verifypeer
Definition: urldata.h:210
connectdata::send_pipe
struct curl_llist send_pipe
Definition: urldata.h:947
CURLAUTH_GSSAPI
#define CURLAUTH_GSSAPI
Definition: curl.h:701
Curl_connect
CURLcode Curl_connect(struct Curl_easy *data, struct connectdata **in_connect, bool *asyncp, bool *protocol_done)
Definition: url.c:7011
CURLHEADER_SEPARATE
#define CURLHEADER_SEPARATE
Definition: curl.h:839
Curl_handler::disconnect
CURLcode(* disconnect)(struct connectdata *, bool dead_connection)
Definition: urldata.h:678
curl_write_callback
size_t(* curl_write_callback)(char *buffer, size_t size, size_t nitems, void *outstream)
Definition: curl.h:243
Curl_protocol_connecting
CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done)
Definition: url.c:3997
RTSPREQ_ANNOUNCE
@ RTSPREQ_ANNOUNCE
Definition: urldata.h:1148
Curl_safefree
#define Curl_safefree(ptr)
Definition: memdebug.h:170
FIRSTSOCKET
#define FIRSTSOCKET
Definition: urldata.h:485
resolve_server
static CURLcode resolve_server(struct Curl_easy *data, struct connectdata *conn, bool *async)
Definition: url.c:6169
CURL_TLSAUTH_NONE
@ CURL_TLSAUTH_NONE
Definition: curl.h:1935
Curl_doing_getsock
int Curl_doing_getsock(struct connectdata *conn, curl_socket_t *socks, int numsocks)
Definition: url.c:3982
protocols
static const struct Curl_handler *const protocols[]
Definition: url.c:161
connectdata::created
struct curltime created
Definition: urldata.h:867
ConnectBits::ftp_use_epsv
bool ftp_use_epsv
Definition: urldata.h:412
transfer.h
curl_read_callback
size_t(* curl_read_callback)(char *buffer, size_t size, size_t nitems, void *instream)
Definition: curl.h:354
strerror.h
Curl_multi_max_host_connections
size_t Curl_multi_max_host_connections(struct Curl_multi *multi)
Definition: multi.c:3059
CURL_RTSPREQ_TEARDOWN
@ CURL_RTSPREQ_TEARDOWN
Definition: curl.h:1889
CURLAUTH_NTLM
#define CURLAUTH_NTLM
Definition: curl.h:702
ssl_connection_complete
@ ssl_connection_complete
Definition: urldata.h:188
CURLAUTH_DIGEST
#define CURLAUTH_DIGEST
Definition: curl.h:696
Curl_closesocket
int Curl_closesocket(struct connectdata *conn, curl_socket_t sock)
Definition: connect.c:1280
Curl_inet_pton
int Curl_inet_pton(int af, const char *src, void *dst)
Definition: inet_pton.c:66
Curl_freeset
void Curl_freeset(struct Curl_easy *data)
Definition: url.c:284
connectdata::ip_version
long ip_version
Definition: urldata.h:899
http_proxy.h
http_conn
Definition: http.h:203
Curl_handler_rtsp
const struct Curl_handler Curl_handler_rtsp
Definition: lib/rtsp.c:108
curl_easy_unescape
CURL_EXTERN char * curl_easy_unescape(CURL *handle, const char *string, int length, int *outlength)
proxy_info::port
long port
Definition: urldata.h:751
CURLPROTO_TFTP
#define CURLPROTO_TFTP
Definition: curl.h:853
CURLPROTO_ALL
#define CURLPROTO_ALL
Definition: curl.h:870
RTSPREQ_PLAY
@ RTSPREQ_PLAY
Definition: urldata.h:1150
detect_proxy
static char * detect_proxy(struct connectdata *conn)
Definition: url.c:5011
Curl_proxy_connect
CURLcode Curl_proxy_connect(struct connectdata *conn, int sockindex)
Definition: http_proxy.c:72
proxy_info::passwd
char * passwd
Definition: urldata.h:754
UserDefined::httpreq
Curl_HttpReq httpreq
Definition: urldata.h:1574
Curl_handler_ldap
const struct Curl_handler Curl_handler_ldap
Definition: ldap.c:138
Curl_handler::connect_it
CURLcode(* connect_it)(struct connectdata *, bool *done)
Definition: urldata.h:642
HTTPREQ_PUT
@ HTTPREQ_PUT
Definition: urldata.h:1137
CURLE_URL_MALFORMAT
@ CURLE_URL_MALFORMAT
Definition: curl.h:456
snprintf
#define snprintf
Definition: curl_printf.h:42
CURLPIPE_MULTIPLEX
#define CURLPIPE_MULTIPLEX
Definition: http2-download.c:41
CURLE_NOT_BUILT_IN
@ CURLE_NOT_BUILT_IN
Definition: curl.h:457
STRING_SET_URL
@ STRING_SET_URL
Definition: urldata.h:1412
STRING_SSL_ISSUERCERT_PROXY
@ STRING_SSL_ISSUERCERT_PROXY
Definition: urldata.h:1427
curl_httppost
Definition: curl.h:157
CURLE_COULDNT_RESOLVE_PROXY
@ CURLE_COULDNT_RESOLVE_PROXY
Definition: curl.h:459
STRING_KEY_TYPE_PROXY
@ STRING_KEY_TYPE_PROXY
Definition: urldata.h:1404
CURL_CA_BUNDLE
#define CURL_CA_BUNDLE
Definition: config-dos.h:156
connectdata::localportrange
int localportrange
Definition: urldata.h:1016
sendf.h
SSL_EXTRA
#define SSL_EXTRA
connectdata::options
char * options
Definition: urldata.h:859
NTLMSTATE_NONE
@ NTLMSTATE_NONE
Definition: urldata.h:293
Curl_llist_init
void Curl_llist_init(struct curl_llist *l, curl_llist_dtor dtor)
Definition: llist.c:37
multiif.h
s
XmlRpcServer s
Curl_conncache_add_conn
CURLcode Curl_conncache_add_conn(struct conncache *connc, struct connectdata *conn)
Definition: conncache.c:191
Curl_clone_primary_ssl_config
bool Curl_clone_primary_ssl_config(struct ssl_primary_config *source, struct ssl_primary_config *dest)
Definition: vtls.c:106
Curl_handler_tftp
const struct Curl_handler Curl_handler_tftp
Definition: tftp.c:169
CURL_HTTP_VERSION_1_0
@ CURL_HTTP_VERSION_1_0
Definition: curl.h:1863
CURL_RTSPREQ_DESCRIBE
@ CURL_RTSPREQ_DESCRIBE
Definition: curl.h:1884
connectdata::host
struct hostname host
Definition: urldata.h:825
data
Definition: debug.c:29
Curl_http2_add_child
#define Curl_http2_add_child(x, y, z)
Definition: http2.h:74
connectdata::seek_client
void * seek_client
Definition: urldata.h:958
STRING_KEY_TYPE_ORIG
@ STRING_KEY_TYPE_ORIG
Definition: urldata.h:1403
DEBUGF
#define DEBUGF(x)
Definition: curl_setup_once.h:409
CURLPROTO_RTMPS
#define CURLPROTO_RTMPS
Definition: curl.h:865
connectdata::handler
const struct Curl_handler * handler
Definition: urldata.h:896
STRING_MAIL_AUTH
@ STRING_MAIL_AUTH
Definition: urldata.h:1452
parse_connect_to_string
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
Curl_easy::multi
struct Curl_multi * multi
Definition: urldata.h:1746
CURLE_OUT_OF_MEMORY
@ CURLE_OUT_OF_MEMORY
Definition: curl.h:488
Curl_urldecode
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
Curl_ssl::have_certinfo
unsigned have_certinfo
Definition: vtls.h:37
MAX_CURL_PASSWORD_LENGTH
#define MAX_CURL_PASSWORD_LENGTH
Definition: urldata.h:1169
Curl_multi
Definition: multihandle.h:71
PROTOPT_ALPN_NPN
#define PROTOPT_ALPN_NPN
Definition: urldata.h:710
connectdata::connect_state
struct http_connect_state * connect_state
Definition: urldata.h:1017
curl_closesocket_callback
int(* curl_closesocket_callback)(void *clientp, curl_socket_t item)
Definition: curl.h:391
curl_opensocket_callback
curl_socket_t(* curl_opensocket_callback)(void *clientp, curlsocktype purpose, struct curl_sockaddr *address)
Definition: curl.h:386
RTSPREQ_SETUP
@ RTSPREQ_SETUP
Definition: urldata.h:1149
curl_hash_iterator
Definition: hash.h:66
escape.h
STRING_SSL_CRLFILE_PROXY
@ STRING_SSL_CRLFILE_PROXY
Definition: urldata.h:1425
STRING_TARGET
@ STRING_TARGET
Definition: urldata.h:1464
RTSPREQ_NONE
@ RTSPREQ_NONE
Definition: urldata.h:1145
connectdata::dynamically_allocated_data::userpwd
char * userpwd
Definition: urldata.h:914
inet_pton.h
proxy_info::host
struct hostname host
Definition: urldata.h:750
ALL_CONTENT_ENCODINGS
#define ALL_CONTENT_ENCODINGS
Definition: content_encoding.h:34
share.h
Curl_RtspReq
Curl_RtspReq
Definition: urldata.h:1144
Curl_pipeline_leave_write
void Curl_pipeline_leave_write(struct connectdata *conn)
Definition: pipeline.c:366
connectdata::readchannel_inuse
bool readchannel_inuse
Definition: urldata.h:943
RTSPREQ_SET_PARAMETER
@ RTSPREQ_SET_PARAMETER
Definition: urldata.h:1154
Curl_cookie_cleanup
void Curl_cookie_cleanup(struct CookieInfo *c)
Definition: cookie.c:1308
Curl_dedotdotify
char * Curl_dedotdotify(const char *input)
Definition: dotdot.c:53
connectdata::tempsock
curl_socket_t tempsock[2]
Definition: urldata.h:870
connectdata::dynamically_allocated_data::rtsp_transport
char * rtsp_transport
Definition: urldata.h:919
Curl_sendpipe_head
bool Curl_sendpipe_head(struct Curl_easy *data, struct connectdata *conn)
Definition: pipeline.c:311
setup_range
static CURLcode setup_range(struct Curl_easy *data)
Definition: url.c:4843
gopher.h
Curl_connecthost
CURLcode Curl_connecthost(struct connectdata *conn, const struct Curl_dns_entry *remotehost)
Definition: connect.c:1144
tftp.h
ConnectBits::conn_to_host
bool conn_to_host
Definition: urldata.h:378
calloc
#define calloc(nbelem, size)
Definition: curl_memory.h:126
is_ASCII_name
static bool is_ASCII_name(const char *hostname)
Definition: url.c:4093
UserDefined::postfields
void * postfields
Definition: urldata.h:1500
get_protocol_family
static unsigned int get_protocol_family(unsigned int protocol)
Definition: url.c:7113
PROTOPT_SSL
#define PROTOPT_SSL
Definition: urldata.h:698
proxy_info_matches
static bool proxy_info_matches(const struct proxy_info *data, const struct proxy_info *needle)
Definition: url.c:3345
Curl_strntoupper
void Curl_strntoupper(char *dest, const char *src, size_t n)
Definition: strcase.c:158
Curl_resolv_unlock
void Curl_resolv_unlock(struct Curl_easy *data, struct Curl_dns_entry *dns)
Definition: hostip.c:722
fwrite
size_t fwrite(const void *, size_t, size_t, FILE *)
Curl_pgrsSetDownloadCounter
void Curl_pgrsSetDownloadCounter(struct Curl_easy *data, curl_off_t size)
Definition: progress.c:286
connectdata::passwd
char * passwd
Definition: urldata.h:858
Curl_SOCKS5
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
curl_multi_remove_handle
CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle, CURL *curl_handle)
Curl_send_plain
ssize_t Curl_send_plain(struct connectdata *conn, int num, const void *mem, size_t len, CURLcode *code)
Definition: sendf.c:351
Curl_cookie_clearsess
void Curl_cookie_clearsess(struct CookieInfo *cookies)
Definition: cookie.c:1270
Curl_http2_cleanup_dependencies
#define Curl_http2_cleanup_dependencies(x)
Definition: http2.h:76
Curl_ssl_close_all
#define Curl_ssl_close_all(x)
Definition: vtls.h:254
CURL_RTSPREQ_SETUP
@ CURL_RTSPREQ_SETUP
Definition: curl.h:1886
set_login
static CURLcode set_login(struct connectdata *conn, const char *user, const char *passwd, const char *options)
Definition: url.c:5908
reuse_conn
static void reuse_conn(struct connectdata *old_conn, struct connectdata *conn)
Definition: url.c:6284
Curl_hash_start_iterate
void Curl_hash_start_iterate(struct curl_hash *hash, struct curl_hash_iterator *iter)
Definition: hash.c:283
SECONDARYSOCKET
#define SECONDARYSOCKET
Definition: urldata.h:486
Curl_easy::set
struct UserDefined set
Definition: urldata.h:1754
SingleRequest::now
struct curltime now
Definition: urldata.h:535
path
const char * path
Definition: util.c:192
UserDefined
Definition: urldata.h:1477
str
const char * str
Definition: unit1398.c:33
SingleRequest::hbufp
char * hbufp
Definition: urldata.h:546
ConnectBits::reuse
bool reuse
Definition: urldata.h:377
create_conn
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,...
Definition: url.c:6383
Curl_handler_pop3s
const struct Curl_handler Curl_handler_pop3s
STRING_SSL_CAFILE_ORIG
@ STRING_SSL_CAFILE_ORIG
Definition: urldata.h:1415
curl_slist
Definition: curl.h:2332
hostname
Definition: urldata.h:441
Curl_set_dns_servers
CURLcode Curl_set_dns_servers(struct Curl_easy *data, char *servers)
Definition: hostsyn.c:62
STRING_LAST
@ STRING_LAST
Definition: urldata.h:1474
UserDefined::httpversion
long httpversion
Definition: urldata.h:1575
CURLPROTO_RTMPE
#define CURLPROTO_RTMPE
Definition: curl.h:863
connectdata
Definition: urldata.h:779
CURL_LOCK_ACCESS_SINGLE
@ CURL_LOCK_ACCESS_SINGLE
Definition: curl.h:2545
urldata.h
LIBCURL_NAME
#define LIBCURL_NAME
Definition: urldata.h:1775
CURLPROTO_RTMPTS
#define CURLPROTO_RTMPTS
Definition: curl.h:866
Curl_open
CURLcode Curl_open(struct Curl_easy **curl)
Curl_open()
Definition: url.c:644
STRING_LASTZEROTERMINATED
@ STRING_LASTZEROTERMINATED
Definition: urldata.h:1467
free_fixed_hostname
static void free_fixed_hostname(struct hostname *host)
Definition: url.c:4170
connectdata::dynamically_allocated_data::ref
char * ref
Definition: urldata.h:916
Curl_handler::scheme
const char * scheme
Definition: urldata.h:621
Curl_handler::connecting
CURLcode(* connecting)(struct connectdata *, bool *done)
Definition: urldata.h:645
C_SSLVERSION_MAX_VALUE
#define C_SSLVERSION_MAX_VALUE(x)
Definition: url.c:716
curl_ldap.h
STRING_SERVICE_NAME
@ STRING_SERVICE_NAME
Definition: urldata.h:1449
curl_ftpfile
curl_ftpfile
Definition: ftp.h:93
Curl_disconnect
CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
Definition: url.c:3097
CURL_FORMAT_CURL_OFF_TU
#define CURL_FORMAT_CURL_OFF_TU
Definition: system.h:374
ssl_primary_config::verifystatus
bool verifystatus
Definition: urldata.h:212
curl_chunk_bgn_callback
long(* curl_chunk_bgn_callback)(const void *transfer_info, void *ptr, int remains)
Definition: curl.h:312
Curl_init_userdefined
CURLcode Curl_init_userdefined(struct UserDefined *set)
Definition: url.c:507
ZERO_NULL
#define ZERO_NULL
Definition: curlx.c:131
STRING_PROXYUSERNAME
@ STRING_PROXYUSERNAME
Definition: urldata.h:1431
CURLPROTO_RTSP
#define CURLPROTO_RTSP
Definition: curl.h:860
strcase.h
content_encoding.h
parse_remote_port
static CURLcode parse_remote_port(struct Curl_easy *data, struct connectdata *conn)
Definition: url.c:5736
hostip.h
STRING_BEARER
@ STRING_BEARER
Definition: urldata.h:1460
Curl_handler_smtps
const struct Curl_handler Curl_handler_smtps
curl_sshkeycallback
int(* curl_sshkeycallback)(CURL *easy, const struct curl_khkey *knownkey, const struct curl_khkey *foundkey, enum curl_khmatch, void *clientp)
Definition: curl.h:759
TIMER_NAMELOOKUP
@ TIMER_NAMELOOKUP
Definition: progress.h:52
connectdata::dynamically_allocated_data::accept_encoding
char * accept_encoding
Definition: urldata.h:913
connectdata::sock
curl_socket_t sock[2]
Definition: urldata.h:868
gethandleathead
static struct Curl_easy * gethandleathead(struct curl_llist *pipeline)
Definition: url.c:3239
memcpy
memcpy(filename, filename1, strlen(filename1))
strdup.h
curl_ftpauth
curl_ftpauth
Definition: curl.h:810
curlx_sotouz
size_t curlx_sotouz(curl_off_t sonum)
Definition: warnless.c:347
connectdata::trailer
char * trailer
Definition: urldata.h:985
HEADERSIZE
#define HEADERSIZE
Definition: urldata.h:144
CURL_RTSPREQ_PAUSE
@ CURL_RTSPREQ_PAUSE
Definition: curl.h:1888
curl_strnequal
CURL_EXTERN int curl_strnequal(const char *s1, const char *s2, size_t n)
Definition: strcase.c:174
ConnectBits::tls_enable_npn
bool tls_enable_npn
Definition: urldata.h:434
STRING_KEY_PROXY
@ STRING_KEY_PROXY
Definition: urldata.h:1400
connectdata::dynamically_allocated_data::te
char * te
Definition: urldata.h:920
curl_hash_element::ptr
void * ptr
Definition: hash.h:61
memdebug.h
Curl_recv_plain
ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf, size_t len, CURLcode *code)
Definition: sendf.c:425
CURL_SOCKET_BAD
#define CURL_SOCKET_BAD
Definition: curl.h:131
login
static char * login
Definition: unit1304.c:26
SingleRequest::header
bool header
Definition: urldata.h:536
Curl_multi_max_total_connections
size_t Curl_multi_max_total_connections(struct Curl_multi *multi)
Definition: multi.c:3064
Curl_ssl_set_engine
#define Curl_ssl_set_engine(x, y)
Definition: vtls.h:257
Curl_handler::flags
unsigned int flags
Definition: urldata.h:694
STRING_NOPROXY
@ STRING_NOPROXY
Definition: urldata.h:1433
connectdata::dynamically_allocated_data::cookiehost
char * cookiehost
Definition: urldata.h:918
CONNCHECK_ISDEAD
#define CONNCHECK_ISDEAD
Definition: urldata.h:716
Curl_memdup
void * Curl_memdup(const void *src, size_t length)
Definition: strdup.c:68
Curl_initinfo
CURLcode Curl_initinfo(struct Curl_easy *data)
Definition: lib/getinfo.c:45
ConnectBits::tls_enable_alpn
bool tls_enable_alpn
Definition: urldata.h:435
connectdata::fclosesocket
curl_closesocket_callback fclosesocket
Definition: urldata.h:792
CURL_DEFAULT_PROXY_PORT
#define CURL_DEFAULT_PROXY_PORT
Definition: url.h:69
STRING_KEY_PASSWD_ORIG
@ STRING_KEY_PASSWD_ORIG
Definition: urldata.h:1401
ftp.h
CURLPROTO_RTMPT
#define CURLPROTO_RTMPT
Definition: curl.h:862
Curl_handler_dict
const struct Curl_handler Curl_handler_dict
Definition: dict.c:73
connectdata::data
struct Curl_easy * data
Definition: urldata.h:783
CURLE_OK
@ CURLE_OK
Definition: curl.h:453
RTSPREQ_OPTIONS
@ RTSPREQ_OPTIONS
Definition: urldata.h:1146
connectdata::conn_to_port
int conn_to_port
Definition: urldata.h:835
Curl_removeHandleFromPipeline
int Curl_removeHandleFromPipeline(struct Curl_easy *handle, struct curl_llist *pipeline)
Definition: url.c:3206
C_SSLVERSION_VALUE
#define C_SSLVERSION_VALUE(x)
Definition: url.c:715
CURLPROTO_FILE
#define CURLPROTO_FILE
Definition: curl.h:852
Curl_pgrsTime
void Curl_pgrsTime(struct Curl_easy *data, timerid timer)
Definition: progress.c:162
connectdata::send
Curl_send * send[2]
Definition: urldata.h:874
CURLSSLOPT_NO_REVOKE
#define CURLSSLOPT_NO_REVOKE
Definition: curl.h:785
Curl_dns_entry::inuse
long inuse
Definition: hostip.h:70
connectdata::ip_addr_str
char ip_addr_str[MAX_IPADR_LEN]
Definition: urldata.h:819
proxy_info::proxytype
curl_proxytype proxytype
Definition: urldata.h:752
SOCKET_READABLE
#define SOCKET_READABLE(x, z)
Definition: select.h:79
CURLPROTO_HTTPS
#define CURLPROTO_HTTPS
Definition: curl.h:843
proxy_info
Definition: urldata.h:749
RTSPREQ_GET_PARAMETER
@ RTSPREQ_GET_PARAMETER
Definition: urldata.h:1153
Curl_resolv_timeout
int Curl_resolv_timeout(struct connectdata *conn, const char *hostname, int port, struct Curl_dns_entry **entry, time_t timeoutms)
Definition: hostip.c:566
CURL_DEFAULT_PASSWORD
#define CURL_DEFAULT_PASSWORD
Definition: urldata.h:61
parse_connect_to_host_port
static CURLcode parse_connect_to_host_port(struct Curl_easy *data, const char *host, char **hostname_result, int *port_result)
Definition: url.c:5957
Curl_tvnow
#define Curl_tvnow()
Definition: timeval.h:57
STRING_SSL_PINNEDPUBLICKEY_ORIG
@ STRING_SSL_PINNEDPUBLICKEY_ORIG
Definition: urldata.h:1417
CURL_REDIR_POST_ALL
#define CURL_REDIR_POST_ALL
Definition: curl.h:1949
READBUFFER_MIN
#define READBUFFER_MIN
Definition: url.c:146
Curl_ssl_config_matches
bool Curl_ssl_config_matches(struct ssl_primary_config *data, struct ssl_primary_config *needle)
Definition: vtls.c:86
Curl_handler::protocol
unsigned int protocol
Definition: urldata.h:692
curl_chunk_end_callback
long(* curl_chunk_end_callback)(void *ptr)
Definition: curl.h:326
STRING_SSL_EGDSOCKET
@ STRING_SSL_EGDSOCKET
Definition: urldata.h:1421
CURLPROTO_HTTP
#define CURLPROTO_HTTP
Definition: curl.h:842
HTTPREQ_HEAD
@ HTTPREQ_HEAD
Definition: urldata.h:1138
CURLEASY_MAGIC_NUMBER
#define CURLEASY_MAGIC_NUMBER
Definition: urldata.h:146
curl_usessl
curl_usessl
Definition: curl.h:766
Curl_speedinit
void Curl_speedinit(struct Curl_easy *data)
Definition: speedcheck.c:31
GETSOCK_BLANK
#define GETSOCK_BLANK
Definition: multiif.h:42
connectdata::proxy_ssl_config
struct ssl_primary_config proxy_ssl_config
Definition: urldata.h:882
curl_slist_free_all
CURL_EXTERN void curl_slist_free_all(struct curl_slist *)
Definition: slist.c:129
CURLPROTO_SMTP
#define CURLPROTO_SMTP
Definition: curl.h:858
Curl_handler::doing_getsock
int(* doing_getsock)(struct connectdata *conn, curl_socket_t *socks, int numsocks)
Definition: urldata.h:656
curl_llist_element::ptr
void * ptr
Definition: llist.h:31
UserDefined::str
char * str[STRING_LAST]
Definition: urldata.h:1655
rc
UNITTEST_START int rc
Definition: unit1301.c:31
Curl_ssl_cert_status_request
#define Curl_ssl_cert_status_request()
Definition: vtls.h:270
Curl_conncache_remove_conn
void Curl_conncache_remove_conn(struct conncache *connc, struct connectdata *conn)
Definition: conncache.c:235
BUNDLE_PIPELINING
#define BUNDLE_PIPELINING
Definition: conncache.h:35
ConnectBits::conn_to_port
bool conn_to_port
Definition: urldata.h:380
RTSPREQ_DESCRIBE
@ RTSPREQ_DESCRIBE
Definition: urldata.h:1147
Curl_resolver_asynch
#define Curl_resolver_asynch()
Definition: asyn.h:163
size_t
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
Definition: typecheck-gcc.h:518
realloc
#define realloc(ptr, size)
Definition: curl_memory.h:128
CURL_RTSPREQ_SET_PARAMETER
@ CURL_RTSPREQ_SET_PARAMETER
Definition: curl.h:1891
Curl_handler_file
const struct Curl_handler Curl_handler_file
Definition: file.c:96
connectdata::dynamically_allocated_data::proxyuserpwd
char * proxyuserpwd
Definition: urldata.h:911
curl_ssl_ctx_callback
CURLcode(* curl_ssl_ctx_callback)(CURL *curl, void *ssl_ctx, void *userptr)
Definition: curl.h:657
STRING_PRE_PROXY
@ STRING_PRE_PROXY
Definition: urldata.h:1409
Curl_hostcache_prune
void Curl_hostcache_prune(struct Curl_easy *data)
Definition: hostip.c:257
failf
#define failf
Definition: sendf.h:48
connectdata::ssl_config
struct ssl_primary_config ssl_config
Definition: urldata.h:881
Curl_resolver_cleanup
void Curl_resolver_cleanup(void *resolver)
curl_proxytype
curl_proxytype
Definition: curl.h:662
Curl_ssl::have_ca_path
unsigned have_ca_path
Definition: vtls.h:36
Curl_handler_dummy
static const struct Curl_handler Curl_handler_dummy
Definition: url.c:263
non-ascii.h
Curl_llist_remove
void Curl_llist_remove(struct curl_llist *list, struct curl_llist_element *e, void *user)
Definition: llist.c:93
Curl_updateconninfo
void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
Definition: connect.c:664
inet_ntop.h
Curl_handler::doing
CURLcode(* doing)(struct connectdata *, bool *done)
Definition: urldata.h:646
PROTOPT_NONE
#define PROTOPT_NONE
Definition: urldata.h:697
strcasecompare
#define strcasecompare(a, b)
Definition: strcase.h:35
ConnectBits::netrc
bool netrc
Definition: urldata.h:420
connect.h
FALSE
#define FALSE
Definition: curl_setup_once.h:347
ConnectBits::protoconnstart
bool protoconnstart
Definition: urldata.h:395
ConnectBits::proxy_user_passwd
bool proxy_user_passwd
Definition: urldata.h:386
CURLRESOLV_PENDING
#define CURLRESOLV_PENDING
Definition: hostip.h:84
conncache
Definition: conncache.h:26
create_conn_helper_init_proxy
static CURLcode create_conn_helper_init_proxy(struct connectdata *conn)
Definition: url.c:5315
connectbundle::num_connections
size_t num_connections
Definition: conncache.h:40
len
size_t len
Definition: curl_sasl.c:84
Curl_flush_cookies
void Curl_flush_cookies(struct Curl_easy *data, int cleanup)
Definition: cookie.c:1446
connectdata::conn_to_host
struct hostname conn_to_host
Definition: urldata.h:827
Curl_setopt
CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option, va_list param)
Definition: url.c:718
Curl_share_lock
CURLSHcode Curl_share_lock(struct Curl_easy *data, curl_lock_data type, curl_lock_access accesstype)
Definition: share.c:213
curl_llist_element::next
struct curl_llist_element * next
Definition: llist.h:33
ConnectBits::socksproxy
bool socksproxy
Definition: urldata.h:384
Curl_llist_destroy
void Curl_llist_destroy(struct curl_llist *list, void *user)
Definition: llist.c:130
Curl_free_request_state
void Curl_free_request_state(struct Curl_easy *data)
Definition: url.c:4923
DEBUGASSERT
#define DEBUGASSERT(x)
Definition: curl_setup_once.h:420
TIMER_APPCONNECT
@ TIMER_APPCONNECT
Definition: progress.h:54
parse_proxy
static CURLcode parse_proxy(struct Curl_easy *data, struct connectdata *conn, char *proxy, curl_proxytype proxytype)
Definition: url.c:5082
Curl_handler::done
Curl_done_func done
Definition: urldata.h:628
CURLPROTO_GOPHER
#define CURLPROTO_GOPHER
Definition: curl.h:867
curl_multi_cleanup
CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle)
Curl_safe_strcasecompare
int Curl_safe_strcasecompare(const char *first, const char *second)
Definition: strcase.c:124
connectdata::socktype
int socktype
Definition: urldata.h:823
parse_connect_to_slist
static CURLcode parse_connect_to_slist(struct Curl_easy *data, struct connectdata *conn, struct curl_slist *conn_to_host)
Definition: url.c:6122
curl_memory.h
Curl_pipeline_penalized
bool Curl_pipeline_penalized(struct Curl_easy *data, struct connectdata *conn)
Definition: pipeline.c:59
Curl_ssl_free_certinfo
#define Curl_ssl_free_certinfo(x)
Definition: vtls.h:266
CURLPROXY_SOCKS5_HOSTNAME
@ CURLPROXY_SOCKS5_HOSTNAME
Definition: curl.h:672
curl_socket_t
int curl_socket_t
Definition: curl.h:130
curl_off_t
CURL_TYPEOF_CURL_OFF_T curl_off_t
Definition: system.h:420
ConnectBits::ftp_use_eprt
bool ftp_use_eprt
Definition: urldata.h:416
CURL_NETRC_OPTION
CURL_NETRC_OPTION
Definition: curl.h:1898
Curl_connect_ongoing
bool Curl_connect_ongoing(struct connectdata *conn)
Definition: http_proxy.c:144
Curl_recvpipe_head
bool Curl_recvpipe_head(struct Curl_easy *data, struct connectdata *conn)
Definition: pipeline.c:304
Curl_handler::defport
long defport
Definition: urldata.h:691
Curl_conncache_find_bundle
struct connectbundle * Curl_conncache_find_bundle(struct connectdata *conn, struct conncache *connc)
Definition: conncache.c:145
curl_llist_element
Definition: llist.h:30
curl
static CURL * curl
Definition: sessioninfo.c:35
curl_fnmatch_callback
int(* curl_fnmatch_callback)(void *ptr, const char *pattern, const char *string)
Definition: curl.h:335
DEFAULT_CONNCACHE_SIZE
#define DEFAULT_CONNCACHE_SIZE
Definition: urldata.h:72
CURLPROXY_SOCKS5
@ CURLPROXY_SOCKS5
Definition: curl.h:670
Curl_resolver_init
CURLcode Curl_resolver_init(void **resolver)
CURLPROTO_RTMPTE
#define CURLPROTO_RTMPTE
Definition: curl.h:864
MAX_CURL_USER_LENGTH
#define MAX_CURL_USER_LENGTH
Definition: urldata.h:1168
Curl_cookie_add
struct Cookie * Curl_cookie_add(struct Curl_easy *data, struct CookieInfo *c, bool httpheader, char *lineptr, const char *domain, const char *path)
Definition: cookie.c:364
STRING_PROXYPASSWORD
@ STRING_PROXYPASSWORD
Definition: urldata.h:1432
CURL_TLSAUTH_SRP
@ CURL_TLSAUTH_SRP
Definition: curl.h:1936
CURL_NETRC_REQUIRED
@ CURL_NETRC_REQUIRED
Definition: curl.h:1903
findprotocol
static CURLcode findprotocol(struct Curl_easy *data, struct connectdata *conn, const char *protostr)
Definition: url.c:4354
STRING_SSL_CAPATH_PROXY
@ STRING_SSL_CAPATH_PROXY
Definition: urldata.h:1414
CURLPIPE_HTTP1
#define CURLPIPE_HTTP1
Definition: multi.h:83
UrlState
Definition: urldata.h:1227
ssl_primary_config::verifyhost
bool verifyhost
Definition: urldata.h:211
STRING_RTSP_TRANSPORT
@ STRING_RTSP_TRANSPORT
Definition: urldata.h:1437
parse_url_login
static CURLcode parse_url_login(struct Curl_easy *data, struct connectdata *conn, char **userptr, char **passwdptr, char **optionsptr)
Definition: url.c:5494
CURLAUTH_NTLM_WB
#define CURLAUTH_NTLM_WB
Definition: curl.h:704
speedcheck.h
conncache.h
STRING_SSL_PINNEDPUBLICKEY_PROXY
@ STRING_SSL_PINNEDPUBLICKEY_PROXY
Definition: urldata.h:1418
Curl_protocol_doing
CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done)
Definition: url.c:4017
malloc
#define malloc(size)
Definition: curl_memory.h:124
SingleRequest::bytecount
curl_off_t bytecount
Definition: urldata.h:524
CURLPROXY_HTTPS
@ CURLPROXY_HTTPS
Definition: curl.h:667
curl_ntlm_wb.h
hostname::dispname
const char * dispname
Definition: urldata.h:445
Curl_handler_gopher
const struct Curl_handler Curl_handler_gopher
Definition: gopher.c:53
connectdata::ssl
struct ssl_connect_data ssl[2]
Definition: urldata.h:879
Curl_protocol_getsock
int Curl_protocol_getsock(struct connectdata *conn, curl_socket_t *socks, int numsocks)
Definition: url.c:3973
Curl_http2_remove_child
#define Curl_http2_remove_child(x, y)
Definition: http2.h:75
parse_proxy_auth
static CURLcode parse_proxy_auth(struct Curl_easy *data, struct connectdata *conn)
Definition: url.c:5287
strncasecompare
#define strncasecompare(a, b, c)
Definition: strcase.h:36
CURLRESOLV_TIMEDOUT
#define CURLRESOLV_TIMEDOUT
Definition: hostip.h:81
SingleRequest::buf
char * buf
Definition: urldata.h:576
CURLPROXY_HTTP
@ CURLPROXY_HTTP
Definition: curl.h:663
Curl_dns_entry
Definition: hostip.h:65
max_pipeline_length
static size_t max_pipeline_length(struct Curl_multi *multi)
Definition: url.c:3470
cookie.h
conn_free
static void conn_free(struct connectdata *conn)
Definition: url.c:3016
Curl_ssl::support_https_proxy
unsigned support_https_proxy
Definition: vtls.h:41
CURL_DEFAULT_USER
#define CURL_DEFAULT_USER
Definition: urldata.h:60
connectdata::localdev
char * localdev
Definition: urldata.h:1014
CURLPROXY_SOCKS4
@ CURLPROXY_SOCKS4
Definition: curl.h:668
STRING_OPTIONS
@ STRING_OPTIONS
Definition: urldata.h:1430
hostname::rawalloc
char * rawalloc
Definition: urldata.h:442
RTSPREQ_PAUSE
@ RTSPREQ_PAUSE
Definition: urldata.h:1151
fprintf
#define fprintf
Definition: curl_printf.h:41
connectbundle::multiuse
int multiuse
Definition: conncache.h:39
connectdata::recv
Curl_recv * recv[2]
Definition: urldata.h:873
CURL_RTSPREQ_PLAY
@ CURL_RTSPREQ_PLAY
Definition: curl.h:1887
Curl_set_dns_interface
CURLcode Curl_set_dns_interface(struct Curl_easy *data, const char *interf)
Definition: hostsyn.c:75
ConnectBits::user_passwd
bool user_passwd
Definition: urldata.h:385
Curl_dns_entry::addr
Curl_addrinfo * addr
Definition: hostip.h:66
Curl_timeleft
time_t Curl_timeleft(struct Curl_easy *data, struct curltime *nowp, bool duringconnect)
Definition: connect.c:182
Curl_pipeline_site_blacklisted
bool Curl_pipeline_site_blacklisted(struct Curl_easy *handle, struct connectdata *conn)
Definition: pipeline.c:164
connectdata::writechannel_inuse
bool writechannel_inuse
Definition: urldata.h:945
Curl_verboseconnect
void Curl_verboseconnect(struct connectdata *conn)
Definition: url.c:3961
CURLE_NO_CONNECTION_AVAILABLE
@ CURLE_NO_CONNECTION_AVAILABLE
Definition: curl.h:571
Curl_handler_imaps
const struct Curl_handler Curl_handler_imaps
call_disconnect_if_dead
static int call_disconnect_if_dead(struct connectdata *conn, void *param)
Definition: url.c:3444
Curl_easy::state
struct UrlState state
Definition: urldata.h:1761
prune_dead_connections
static void prune_dead_connections(struct Curl_easy *data)
Definition: url.c:3457
CURL_RTSPREQ_RECEIVE
@ CURL_RTSPREQ_RECEIVE
Definition: curl.h:1893
STRING_SSL_CIPHER_LIST_ORIG
@ STRING_SSL_CIPHER_LIST_ORIG
Definition: urldata.h:1419
connectdata::oauth_bearer
char * oauth_bearer
Definition: urldata.h:861
STRING_COOKIEJAR
@ STRING_COOKIEJAR
Definition: urldata.h:1391
WildcardData
Definition: wildcard.h:46
conn_reset_all_postponed_data
#define conn_reset_all_postponed_data(c)
Definition: url.c:3013
auth
Definition: urldata.h:1171
CURL_RTSPREQ_GET_PARAMETER
@ CURL_RTSPREQ_GET_PARAMETER
Definition: curl.h:1890
STRING_PROXY
@ STRING_PROXY
Definition: urldata.h:1408
ConnectionExists
static bool ConnectionExists(struct Curl_easy *data, struct connectdata *needle, struct connectdata **usethis, bool *force_reuse, bool *waitpipe)
Definition: url.c:3489
curl_progress_callback
int(* curl_progress_callback)(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
Definition: curl.h:203
ConnectBits::proxy
bool proxy
Definition: urldata.h:382
READBUFFER_MAX
#define READBUFFER_MAX
Definition: url.c:145
CURL_HTTP_VERSION_2
#define CURL_HTTP_VERSION_2
Definition: curl.h:1876
connectdata::remote_port
int remote_port
Definition: urldata.h:834
find_oldest_idle_connection_in_bundle
static struct connectdata * find_oldest_idle_connection_in_bundle(struct Curl_easy *data, struct connectbundle *bundle)
Definition: url.c:3365
free
#define free(ptr)
Definition: curl_memory.h:130
Curl_multi::max_pipeline_length
long max_pipeline_length
Definition: multihandle.h:130
ConnectBits::tcp_fastopen
bool tcp_fastopen
Definition: urldata.h:433
curl_mime_s
Definition: mime.h:88
CONNRESULT_DEAD
#define CONNRESULT_DEAD
Definition: urldata.h:719
dotdot.h
Curl_ssl_false_start
#define Curl_ssl_false_start()
Definition: vtls.h:271
PGRS_HIDE
#define PGRS_HIDE
Definition: progress.h:69
connectdata::secondary_port
unsigned short secondary_port
Definition: urldata.h:837
CURLAUTH_DIGEST_IE
#define CURLAUTH_DIGEST_IE
Definition: curl.h:703
Curl_getoff_all_pipelines
void Curl_getoff_all_pipelines(struct Curl_easy *data, struct connectdata *conn)
Definition: url.c:3251
RTSPREQ_TEARDOWN
@ RTSPREQ_TEARDOWN
Definition: urldata.h:1152
connectdata::bundle
struct connectbundle * bundle
Definition: urldata.h:1018
SocketIsDead
static bool SocketIsDead(curl_socket_t sock)
Definition: url.c:3163
override_login
static CURLcode override_login(struct Curl_easy *data, struct connectdata *conn, char **userp, char **passwdp, char **optionsp)
Definition: url.c:5854
HTTPREQ_POST_MIME
@ HTTPREQ_POST_MIME
Definition: urldata.h:1136
Curl_SOCKS4
CURLcode Curl_SOCKS4(const char *proxy_user, const char *hostname, int remote_port, int sockindex, struct connectdata *conn)
Definition: socks.c:108
set
ROSCPP_DECL void set(const std::string &key, bool b)
HTTPREQ_POST
@ HTTPREQ_POST
Definition: urldata.h:1134
connectdata::secondaryhostname
char * secondaryhostname
Definition: urldata.h:826
curlx_sltoui
unsigned int curlx_sltoui(long slnum)
Definition: warnless.c:286
STRING_COPYPOSTFIELDS
@ STRING_COPYPOSTFIELDS
Definition: urldata.h:1472
multihandle.h
allocate_conn
static struct connectdata * allocate_conn(struct Curl_easy *data)
Definition: url.c:4197
llist_dtor
static void llist_dtor(void *user, void *element)
Definition: url.c:4187
connectdata::dynamically_allocated_data::uagent
char * uagent
Definition: urldata.h:912
dupstring
dupstring
Definition: urldata.h:1385
connectbundle::conn_list
struct curl_llist conn_list
Definition: conncache.h:41
Curl_convert_close
#define Curl_convert_close(x)
Definition: non-ascii.h:55
curltime
Definition: timeval.h:32
Curl_parsenetrc
int Curl_parsenetrc(const char *host, char **loginp, char **passwordp, char *netrcfile)
Definition: netrc.c:53
Curl_digest_cleanup
void Curl_digest_cleanup(struct Curl_easy *data)
Definition: http_digest.c:174
conncache::hash
struct curl_hash hash
Definition: conncache.h:48
CURL_RTSPREQ_ANNOUNCE
@ CURL_RTSPREQ_ANNOUNCE
Definition: curl.h:1885
connectdata::now
struct curltime now
Definition: urldata.h:866
name
const char * name
Definition: curl_sasl.c:83
Curl_cookie_loadfiles
void Curl_cookie_loadfiles(struct Curl_easy *data)
Definition: cookie.c:262
CURLOPT_SERVER_RESPONSE_TIMEOUT
#define CURLOPT_SERVER_RESPONSE_TIMEOUT
Definition: curl.h:1291
CURLPROTO_DICT
#define CURLPROTO_DICT
Definition: curl.h:851
CURLPROTO_TELNET
#define CURLPROTO_TELNET
Definition: curl.h:848
checkprefix
#define checkprefix(a, b)
Definition: strcase.h:46
ConnectBits::ipv6_ip
bool ipv6_ip
Definition: urldata.h:387
http_ntlm.h
telnet.h
curl_TimeCond
curl_TimeCond
Definition: curl.h:1952
STRING_SSL_CRLFILE_ORIG
@ STRING_SSL_CRLFILE_ORIG
Definition: urldata.h:1424
STRING_SSL_CIPHER_LIST_PROXY
@ STRING_SSL_CIPHER_LIST_PROXY
Definition: urldata.h:1420
STRING_CERT_PROXY
@ STRING_CERT_PROXY
Definition: urldata.h:1387
UserDefined::postfieldsize
curl_off_t postfieldsize
Definition: urldata.h:1502
ConnectBits::userpwd_in_url
bool userpwd_in_url
Definition: urldata.h:421
Curl_protocol_connect
CURLcode Curl_protocol_connect(struct connectdata *conn, bool *protocol_done)
Definition: url.c:4036
curl_setup.h
curl_llist
Definition: llist.h:36
now
struct curltime now
Definition: unit1399.c:83
CURLPROTO_IMAP
#define CURLPROTO_IMAP
Definition: curl.h:854
url.h
Curl_resolver_cancel
void Curl_resolver_cancel(struct connectdata *conn)
STRING_SSL_RANDOM_FILE
@ STRING_SSL_RANDOM_FILE
Definition: urldata.h:1422
Curl_close
CURLcode Curl_close(struct Curl_easy *data)
Definition: url.c:405
STRING_CERT_TYPE_ORIG
@ STRING_CERT_TYPE_ORIG
Definition: urldata.h:1388
UrlState::path
char * path
Definition: urldata.h:1321
STRING_ENCODING
@ STRING_ENCODING
Definition: urldata.h:1395
Curl_persistconninfo
void Curl_persistconninfo(struct connectdata *conn)
Definition: connect.c:600
PROTOPT_PROXY_AS_HTTP
#define PROTOPT_PROXY_AS_HTTP
Definition: urldata.h:713
easyif.h
Curl_wildcard_dtor
void Curl_wildcard_dtor(struct WildcardData *wc)
Definition: wildcard.c:41
BUNDLE_MULTIPLEX
#define BUNDLE_MULTIPLEX
Definition: conncache.h:36
state
#define state(x, y)
Definition: ftp.c:100
curl_printf.h
CURLPROTO_SMTPS
#define CURLPROTO_SMTPS
Definition: curl.h:859
Curl_cookie_init
struct CookieInfo * Curl_cookie_init(struct Curl_easy *data, const char *file, struct CookieInfo *inc, bool newsession)
Definition: cookie.c:974
connectdata::inuse
bool inuse
Definition: urldata.h:795
check_noproxy
static bool check_noproxy(const char *name, const char *no_proxy)
Definition: url.c:4935
CURLPROTO_POP3
#define CURLPROTO_POP3
Definition: curl.h:856
Curl_handler_pop3
const struct Curl_handler Curl_handler_pop3
Definition: pop3.c:113
CURLPROTO_SFTP
#define CURLPROTO_SFTP
Definition: curl.h:847
progress.h
CURLSSLOPT_ALLOW_BEAST
#define CURLSSLOPT_ALLOW_BEAST
Definition: curl.h:781
fix_hostname
static void fix_hostname(struct connectdata *conn, struct hostname *host)
Definition: url.c:4107
FTPFILE_MULTICWD
@ FTPFILE_MULTICWD
Definition: ftp.h:94
curl_seek_callback
int(* curl_seek_callback)(void *instream, curl_off_t offset, int origin)
Definition: curl.h:343
CURLE_UNKNOWN_OPTION
@ CURLE_UNKNOWN_OPTION
Definition: curl.h:513
CURLPROTO_LDAPS
#define CURLPROTO_LDAPS
Definition: curl.h:850
CURLE_COULDNT_RESOLVE_HOST
@ CURLE_COULDNT_RESOLVE_HOST
Definition: curl.h:460
RTSPREQ_RECEIVE
@ RTSPREQ_RECEIVE
Definition: urldata.h:1156
ConnectBits::socksproxy_connecting
bool socksproxy_connecting
Definition: urldata.h:438
Curl_handler_telnet
const struct Curl_handler Curl_handler_telnet
Definition: telnet.c:180
connectdata::http_proxy
struct proxy_info http_proxy
Definition: urldata.h:831
Curl_connected_proxy
CURLcode Curl_connected_proxy(struct connectdata *conn, int sockindex)
Definition: url.c:3911
CURLPROTO_FTPS
#define CURLPROTO_FTPS
Definition: curl.h:845
SingleRequest
Definition: urldata.h:516
CURLPROTO_SMB
#define CURLPROTO_SMB
Definition: curl.h:868
connectdata::scope_id
unsigned int scope_id
Definition: urldata.h:821
RTSPREQ_RECORD
@ RTSPREQ_RECORD
Definition: urldata.h:1155
setup_connection_internals
static CURLcode setup_connection_internals(struct connectdata *conn)
Definition: url.c:4880
http_digest.h
netrc.h
imap.h
PROTOPT_NEEDSPWD
#define PROTOPT_NEEDSPWD
Definition: urldata.h:707
PROTOPT_URLOPTIONS
#define PROTOPT_URLOPTIONS
Definition: urldata.h:712
disconnect_if_dead
static bool disconnect_if_dead(struct connectdata *conn, struct Curl_easy *data)
Definition: url.c:3404
MASTERBUF_SIZE
#define MASTERBUF_SIZE
Definition: urldata.h:140
formdata.h
STRING_SSL_CAFILE_PROXY
@ STRING_SSL_CAFILE_PROXY
Definition: urldata.h:1416
dict.h
Curl_convert_init
#define Curl_convert_init(x)
Definition: non-ascii.h:53
connectdata::user
char * user
Definition: urldata.h:857
CURLAUTH_BASIC
#define CURLAUTH_BASIC
Definition: curl.h:695
Curl_easy::next
struct Curl_easy * next
Definition: urldata.h:1726
Curl_multi_handlePipeBreak
void Curl_multi_handlePipeBreak(struct Curl_easy *data)
Definition: multi.c:795
hostname::encalloc
char * encalloc
Definition: urldata.h:443
vtls.h
TOLOWER
#define TOLOWER(x)
Definition: curl_setup_once.h:296
STRING_USERNAME
@ STRING_USERNAME
Definition: urldata.h:1428
curl_debug_callback
int(* curl_debug_callback)(CURL *handle, curl_infotype type, char *data, size_t size, void *userptr)
Definition: curl.h:439
port
static unsigned short port
Definition: sockfilt.c:137
STRING_KEY_ORIG
@ STRING_KEY_ORIG
Definition: urldata.h:1399
i
unsigned int i
Definition: unit1303.c:79
IsPipeliningPossible
static int IsPipeliningPossible(const struct Curl_easy *handle, const struct connectdata *conn)
Definition: url.c:3182
curl_sockopt_callback
int(* curl_sockopt_callback)(void *clientp, curl_socket_t curlfd, curlsocktype purpose)
Definition: curl.h:371
Curl_http2_init_state
#define Curl_http2_init_state(x)
Definition: http2.h:70
curl_getenv
CURL_EXTERN char * curl_getenv(const char *variable)
Definition: getenv.c:51
STRING_CERT_ORIG
@ STRING_CERT_ORIG
Definition: urldata.h:1386
select.h
result
UNITTEST_START int result
Definition: unit1304.c:49
CookieInfo
Definition: cookie.h:48
Curl_pipeline_wanted
bool Curl_pipeline_wanted(const struct Curl_multi *multi, int bits)
Definition: multi.c:790
connectbundle
Definition: conncache.h:38
Curl_share_unlock
CURLSHcode Curl_share_unlock(struct Curl_easy *data, curl_lock_data type)
Definition: share.c:231
TRUE
#define TRUE
Definition: multi-debugcallback.c:38
CURLAUTH_NEGOTIATE
#define CURLAUTH_NEGOTIATE
Definition: curl.h:697
STRING_DEVICE
@ STRING_DEVICE
Definition: urldata.h:1394
proxy_info::user
char * user
Definition: urldata.h:753
fread
size_t fread(void *, size_t, size_t, FILE *)
STRING_SSL_ISSUERCERT_ORIG
@ STRING_SSL_ISSUERCERT_ORIG
Definition: urldata.h:1426
ISXDIGIT
#define ISXDIGIT(x)
Definition: curl_setup_once.h:285
GOOD_EASY_HANDLE
#define GOOD_EASY_HANDLE(x)
Definition: urldata.h:147
param
T param(const std::string &param_name, const T &default_val)
Curl_conncache_foreach
void Curl_conncache_foreach(struct conncache *connc, void *param, int(*func)(struct connectdata *conn, void *param))
Definition: conncache.c:264
READBUFFER_SIZE
#define READBUFFER_SIZE
Definition: url.c:144
Curl_free_primary_ssl_config
void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc)
Definition: vtls.c:126
BUNDLE_UNKNOWN
#define BUNDLE_UNKNOWN
Definition: conncache.h:34
CURL_DEFAULT_HTTPS_PROXY_PORT
#define CURL_DEFAULT_HTTPS_PROXY_PORT
Definition: url.h:70
STRING_RTSP_STREAM_URI
@ STRING_RTSP_STREAM_URI
Definition: urldata.h:1436
LEAST_PATH_ALLOC
#define LEAST_PATH_ALLOC
CURL_NETRC_IGNORED
@ CURL_NETRC_IGNORED
Definition: curl.h:1899
CURLPROTO_RTMP
#define CURLPROTO_RTMP
Definition: curl.h:861
Curl_set_dns_local_ip4
CURLcode Curl_set_dns_local_ip4(struct Curl_easy *data, const char *local_ip4)
Definition: hostsyn.c:87
ConnectBits::type_set
bool type_set
Definition: urldata.h:430
Curl_tvdiff
#define Curl_tvdiff(x, y)
Definition: timeval.h:58
ConnectBits::close
bool close
Definition: urldata.h:376
getinfo.h
Curl_http2_init_userset
#define Curl_http2_init_userset(x)
Definition: http2.h:71
curl_llist::head
struct curl_llist_element * head
Definition: llist.h:37
connectdata::dynamically_allocated_data::rangeline
char * rangeline
Definition: urldata.h:915
curl_mime_subparts
CURL_EXTERN CURLcode curl_mime_subparts(curl_mimepart *part, curl_mime *subparts)
Definition: mime.c:1392
CURLoption
CURLoption
Definition: curl.h:908
Curl_easy
Definition: urldata.h:1724
connectdata::given
const struct Curl_handler * given
Definition: urldata.h:897
CURLE_OPERATION_TIMEDOUT
@ CURLE_OPERATION_TIMEDOUT
Definition: curl.h:493
Curl_set_dns_local_ip6
CURLcode Curl_set_dns_local_ip6(struct Curl_easy *data, const char *local_ip6)
Definition: hostsyn.c:99
file.h
Curl_handler_ftp
const struct Curl_handler Curl_handler_ftp
Definition: ftp.c:166
Curl_ssl
Definition: vtls.h:29
curl_conv_callback
CURLcode(* curl_conv_callback)(char *buffer, size_t length)
Definition: curl.h:655
PROTOPT_NONETWORK
#define PROTOPT_NONETWORK
Definition: urldata.h:706
mime.h
HTTPREQ_GET
@ HTTPREQ_GET
Definition: urldata.h:1133
Curl_cookie_clearall
void Curl_cookie_clearall(struct CookieInfo *cookies)
Definition: cookie.c:1235
curl_ioctl_callback
curlioerr(* curl_ioctl_callback)(CURL *handle, int cmd, void *clientp)
Definition: curl.h:406
connectdata::recv_pipe
struct curl_llist recv_pipe
Definition: urldata.h:949
Curl_init_do
CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn)
Definition: url.c:7061
curlx_sltosi
int curlx_sltosi(long slnum)
Definition: warnless.c:264
ConnectBits::tunnel_proxy
bool tunnel_proxy
Definition: urldata.h:400
setstropt
static CURLcode setstropt(char **charp, const char *s)
Definition: url.c:304
CURLSSH_AUTH_DEFAULT
#define CURLSSH_AUTH_DEFAULT
Definition: curl.h:716
CURL_LOCK_DATA_COOKIE
@ CURL_LOCK_DATA_COOKIE
Definition: curl.h:2536
http_negotiate.h
http2.h
ConnectBits::do_more
bool do_more
Definition: urldata.h:391
STRING_SET_RANGE
@ STRING_SET_RANGE
Definition: urldata.h:1410
CURLPROTO_SCP
#define CURLPROTO_SCP
Definition: curl.h:846
CURL_RTSPREQ_OPTIONS
@ CURL_RTSPREQ_OPTIONS
Definition: curl.h:1883
STRING_KRB_LEVEL
@ STRING_KRB_LEVEL
Definition: urldata.h:1405
curl_ftpccc
curl_ftpccc
Definition: curl.h:802
STRING_FTP_ALTERNATIVE_TO_USER
@ STRING_FTP_ALTERNATIVE_TO_USER
Definition: urldata.h:1397
CURLE_COULDNT_CONNECT
@ CURLE_COULDNT_CONNECT
Definition: curl.h:461
connectdata::master_buffer
char * master_buffer
Definition: urldata.h:951
signalPipeClose
static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke)
Definition: url.c:3265
Curl_handler::proto_getsock
int(* proto_getsock)(struct connectdata *conn, curl_socket_t *socks, int numsocks)
Definition: urldata.h:650
STRING_FTPPORT
@ STRING_FTPPORT
Definition: urldata.h:1398
STRING_NETRC_FILE
@ STRING_NETRC_FILE
Definition: urldata.h:1406
Curl_handler
Definition: urldata.h:620
curl_hash_element
Definition: hash.h:59
data
UNITTEST_START struct Curl_easy data
Definition: unit1399.c:82
infof
#define infof
Definition: sendf.h:44
ssh.h
parseurlandfillconn
static CURLcode parseurlandfillconn(struct Curl_easy *data, struct connectdata *conn, bool *prot_missing, char **userp, char **passwdp, char **optionsp)
Definition: url.c:4399
CURL_LOCK_DATA_SHARE
@ CURL_LOCK_DATA_SHARE
Definition: curl.h:2535
connectdata::dns_entry
struct Curl_dns_entry * dns_entry
Definition: urldata.h:808
Curl_setup_conn
CURLcode Curl_setup_conn(struct connectdata *conn, bool *protocol_done)
Definition: url.c:6933
Curl_ssl::have_ssl_ctx
unsigned have_ssl_ctx
Definition: vtls.h:39
curlx_ultous
unsigned short curlx_ultous(unsigned long ulnum)
Definition: warnless.c:124
ConnectBits::proxy_connect_closed
bool proxy_connect_closed
Definition: urldata.h:425
ISALPHA
#define ISALPHA(x)
Definition: curl_setup_once.h:287
curl_slist::data
char * data
Definition: curl.h:2333
Curl_pgrsSetUploadCounter
void Curl_pgrsSetUploadCounter(struct Curl_easy *data, curl_off_t size)
Definition: progress.c:304
Curl_ssl_close
#define Curl_ssl_close(x, y)
Definition: vtls.h:255
STRING_SET_REFERER
@ STRING_SET_REFERER
Definition: urldata.h:1411
CURLE_BAD_FUNCTION_ARGUMENT
@ CURLE_BAD_FUNCTION_ARGUMENT
Definition: curl.h:508
aprintf
#define aprintf
Definition: curl_printf.h:46
connectdata::allocptr
struct connectdata::dynamically_allocated_data allocptr
connectdata::dynamically_allocated_data::host
char * host
Definition: urldata.h:917
STRING_DEFAULT_PROTOCOL
@ STRING_DEFAULT_PROTOCOL
Definition: urldata.h:1393
Curl_handler_smtp
const struct Curl_handler Curl_handler_smtp
Definition: smtp.c:113
http.h
PROTOPT_NOURLQUERY
#define PROTOPT_NOURLQUERY
Definition: urldata.h:708
CURLPROXY_SOCKS4A
@ CURLPROXY_SOCKS4A
Definition: curl.h:671
CURLE_UNSUPPORTED_PROTOCOL
@ CURLE_UNSUPPORTED_PROTOCOL
Definition: curl.h:454
curl_xferinfo_callback
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
Curl_handler_imap
const struct Curl_handler Curl_handler_imap
Definition: imap.c:117
parse_login_details
static CURLcode parse_login_details(const char *login, const size_t len, char **userptr, char **passwdptr, char **optionsptr)
Definition: url.c:5624
Curl_ssl::sizeof_ssl_backend_data
size_t sizeof_ssl_backend_data
Definition: vtls.h:43
Curl_handler_http
const struct Curl_handler Curl_handler_http
Definition: http.c:108
CURLcode
CURLcode
Definition: curl.h:452
STRING_PASSWORD
@ STRING_PASSWORD
Definition: urldata.h:1429
strtok.h
Curl_ssl_set_engine_default
#define Curl_ssl_set_engine_default(x)
Definition: vtls.h:258
CONNECT_FIRSTSOCKET_PROXY_SSL
#define CONNECT_FIRSTSOCKET_PROXY_SSL()
Definition: url.h:84
PROTO_FAMILY_HTTP
#define PROTO_FAMILY_HTTP
Definition: urldata.h:66
STRING_RTSP_SESSION_ID
@ STRING_RTSP_SESSION_ID
Definition: urldata.h:1435
socks.h
curl_llist_dtor
void(* curl_llist_dtor)(void *, void *)
Definition: llist.h:28
SingleRequest::start
struct curltime start
Definition: urldata.h:534
CURLPIPE_ANY
#define CURLPIPE_ANY
Definition: multihandle.h:68
curl_rtmp.h
CURL_RTSPREQ_RECORD
@ CURL_RTSPREQ_RECORD
Definition: curl.h:1892
SingleRequest::ignorebody
bool ignorebody
Definition: urldata.h:584
setstropt_userpwd
static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp)
Definition: url.c:323
STRING_CERT_TYPE_PROXY
@ STRING_CERT_TYPE_PROXY
Definition: urldata.h:1389
ConnectBits::tcpconnect
bool tcpconnect[2]
Definition: urldata.h:393
connectdata::connection_id
long connection_id
Definition: urldata.h:801
Curl_expire_clear
void Curl_expire_clear(struct Curl_easy *data)
Definition: multi.c:3006
Curl_pipeline_leave_read
void Curl_pipeline_leave_read(struct connectdata *conn)
Definition: pipeline.c:374
CURLPROTO_FTP
#define CURLPROTO_FTP
Definition: curl.h:844
CURLPROTO_LDAP
#define CURLPROTO_LDAP
Definition: curl.h:849
STRING_FTP_ACCOUNT
@ STRING_FTP_ACCOUNT
Definition: urldata.h:1396
CURLPROTO_SMBS
#define CURLPROTO_SMBS
Definition: curl.h:869
curl_llist::size
size_t size
Definition: llist.h:40


rc_tagdetect_client
Author(s): Monika Florek-Jasinska , Raphael Schaller
autogenerated on Sun May 15 2022 02:25:01