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