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