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