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