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