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