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