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