Resync
[CMakeLuaTailorHgBridge.git] / CMakeLua / Utilities / cmcurl / url.c
blobdf1d8cde9fd82c8aa202d0e4e5a763f1eeadb16a
1 /***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
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.
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.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 * $Id: url.c,v 1.3 2007/05/03 17:03:13 king Exp $
22 ***************************************************************************/
24 /* -- WIN32 approved -- */
26 #include "setup.h"
28 #include <stdio.h>
29 #include <string.h>
30 #include <stdarg.h>
31 #include <stdlib.h>
32 #include <ctype.h>
33 #ifdef HAVE_SYS_TYPES_H
34 #include <sys/types.h>
35 #endif
36 #ifdef HAVE_SYS_STAT_H
37 #include <sys/stat.h>
38 #endif
39 #include <errno.h>
41 #ifdef WIN32
42 #include <time.h>
43 #include <io.h>
44 #else
45 #ifdef HAVE_SYS_SOCKET_H
46 #include <sys/socket.h>
47 #endif
48 #include <netinet/in.h>
49 #ifdef HAVE_SYS_TIME_H
50 #include <sys/time.h>
51 #endif
52 #ifdef HAVE_UNISTD_H
53 #include <unistd.h>
54 #endif
55 #include <netdb.h>
56 #ifdef HAVE_ARPA_INET_H
57 #include <arpa/inet.h>
58 #endif
59 #ifdef HAVE_NET_IF_H
60 #include <net/if.h>
61 #endif
62 #include <sys/ioctl.h>
63 #include <signal.h>
65 #ifdef HAVE_SYS_PARAM_H
66 #include <sys/param.h>
67 #endif
69 #ifdef VMS
70 #include <in.h>
71 #include <inet.h>
72 #endif
74 #ifdef HAVE_SETJMP_H
75 #include <setjmp.h>
76 #endif
78 #ifndef HAVE_SOCKET
79 #error "We can't compile without socket() support!"
80 #endif
81 #endif
83 #ifdef USE_LIBIDN
84 #include <idna.h>
85 #include <tld.h>
86 #include <stringprep.h>
87 #ifdef HAVE_IDN_FREE_H
88 #include <idn-free.h>
89 #else
90 void idn_free (void *ptr); /* prototype from idn-free.h, not provided by
91 libidn 0.4.5's make install! */
92 #endif
93 #ifndef HAVE_IDN_FREE
94 /* if idn_free() was not found in this version of libidn, use plain free()
95 instead */
96 #define idn_free(x) (free)(x)
97 #endif
98 #endif /* USE_LIBIDN */
100 #include "urldata.h"
101 #include "netrc.h"
103 #include "formdata.h"
104 #include "base64.h"
105 #include "sslgen.h"
106 #include "hostip.h"
107 #include "transfer.h"
108 #include "sendf.h"
109 #include "progress.h"
110 #include "cookie.h"
111 #include "strequal.h"
112 #include "strerror.h"
113 #include "escape.h"
114 #include "strtok.h"
115 #include "share.h"
116 #include "content_encoding.h"
117 #include "http_digest.h"
118 #include "http_negotiate.h"
119 #include "select.h"
120 #include "multiif.h"
121 #include "easyif.h"
123 /* And now for the protocols */
124 #include "ftp.h"
125 #include "dict.h"
126 #include "telnet.h"
127 #include "tftp.h"
128 #include "http.h"
129 #include "file.h"
130 #include "ldap.h"
131 #include "ssh.h"
132 #include "url.h"
133 #include "connect.h"
134 #include "inet_ntop.h"
135 #include "http_ntlm.h"
136 #include "socks.h"
137 #include <ca-bundle.h>
139 #if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
140 #include "inet_ntoa_r.h"
141 #endif
143 #define _MPRINTF_REPLACE /* use our functions only */
144 #include <curl/mprintf.h>
146 #ifdef HAVE_KRB4
147 #include "krb4.h"
148 #endif
149 #include "memory.h"
151 /* The last #include file should be: */
152 #include "memdebug.h"
154 /* Local static prototypes */
155 static long ConnectionKillOne(struct SessionHandle *data);
156 static bool ConnectionExists(struct SessionHandle *data,
157 struct connectdata *needle,
158 struct connectdata **usethis);
159 static long ConnectionStore(struct SessionHandle *data,
160 struct connectdata *conn);
161 static bool IsPipeliningPossible(struct SessionHandle *handle);
162 static bool IsPipeliningEnabled(struct SessionHandle *handle);
163 static void conn_free(struct connectdata *conn);
165 static void signalPipeClose(struct curl_llist *pipe);
167 #define MAX_PIPELINE_LENGTH 5
170 * We use this ZERO_NULL to avoid picky compiler warnings,
171 * when assigning a NULL pointer to a function pointer var.
174 #define ZERO_NULL 0
176 #ifndef USE_ARES
177 /* not for ares builds */
179 #ifndef WIN32
180 /* not for WIN32 builds */
182 #ifdef HAVE_SIGSETJMP
183 extern sigjmp_buf curl_jmpenv;
184 #endif
186 #ifdef SIGALRM
187 static
188 RETSIGTYPE alarmfunc(int sig)
190 /* this is for "-ansi -Wall -pedantic" to stop complaining! (rabe) */
191 (void)sig;
192 #ifdef HAVE_SIGSETJMP
193 siglongjmp(curl_jmpenv, 1);
194 #endif
195 /*return;*/ /* not reahed, and has no effect anyway */
197 #endif /* SIGALRM */
198 #endif /* WIN32 */
199 #endif /* USE_ARES */
201 void Curl_safefree(void *ptr)
203 if(ptr)
204 free(ptr);
207 static void close_connections(struct SessionHandle *data)
209 /* Loop through all open connections and kill them one by one */
210 while(-1 != ConnectionKillOne(data))
211 ; /* empty loop */
215 * This is the internal function curl_easy_cleanup() calls. This should
216 * cleanup and free all resources associated with this sessionhandle.
218 * NOTE: if we ever add something that attempts to write to a socket or
219 * similar here, we must ignore SIGPIPE first. It is currently only done
220 * when curl_easy_perform() is invoked.
223 CURLcode Curl_close(struct SessionHandle *data)
225 struct Curl_multi *m = data->multi;
227 #ifdef CURLDEBUG
228 /* only for debugging, scan through all connections and see if there's a
229 pipe reference still identifying this handle */
231 if(data->state.is_in_pipeline)
232 fprintf(stderr, "CLOSED when in pipeline!\n");
234 if(data->state.connc && data->state.connc->type == CONNCACHE_MULTI) {
235 struct conncache *c = data->state.connc;
236 int i;
237 struct curl_llist *pipe;
238 struct curl_llist_element *curr;
239 struct connectdata *connptr;
241 for(i=0; i< c->num; i++) {
242 connptr = c->connects[i];
243 if(!connptr)
244 continue;
246 pipe = connptr->send_pipe;
247 if(pipe) {
248 for (curr = pipe->head; curr; curr=curr->next) {
249 if(data == (struct SessionHandle *) curr->ptr) {
250 fprintf(stderr,
251 "MAJOR problem we %p are still in send pipe for %p done %d\n",
252 data, connptr, connptr->bits.done);
256 pipe = connptr->recv_pipe;
257 if(pipe) {
258 for (curr = pipe->head; curr; curr=curr->next) {
259 if(data == (struct SessionHandle *) curr->ptr) {
260 fprintf(stderr,
261 "MAJOR problem we %p are still in recv pipe for %p done %d\n",
262 data, connptr, connptr->bits.done);
268 #endif
270 if(m)
271 /* This handle is still part of a multi handle, take care of this first
272 and detach this handle from there. */
273 Curl_multi_rmeasy(data->multi, data);
275 data->magic = 0; /* force a clear AFTER the possibly enforced removal from
276 the multi handle, since that function uses the magic
277 field! */
279 if(data->state.connc) {
281 if(data->state.connc->type == CONNCACHE_PRIVATE) {
282 /* close all connections still alive that are in the private connection
283 cache, as we no longer have the pointer left to the shared one. */
284 close_connections(data);
286 /* free the connection cache if allocated privately */
287 Curl_rm_connc(data->state.connc);
291 if(data->state.shared_conn) {
292 /* marked to be used by a pending connection so we can't kill this handle
293 just yet */
294 data->state.closed = TRUE;
295 return CURLE_OK;
298 if ( ! (data->share && data->share->hostcache) ) {
299 if ( !Curl_global_host_cache_use(data)) {
300 Curl_hash_destroy(data->dns.hostcache);
304 /* Free the pathbuffer */
305 Curl_safefree(data->reqdata.pathbuffer);
306 Curl_safefree(data->reqdata.proto.generic);
308 /* Close down all open SSL info and sessions */
309 Curl_ssl_close_all(data);
310 Curl_safefree(data->state.first_host);
311 Curl_safefree(data->state.scratch);
313 if(data->change.referer_alloc)
314 free(data->change.referer);
316 if(data->change.url_alloc)
317 free(data->change.url);
319 Curl_safefree(data->state.headerbuff);
321 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
322 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
323 if(data->set.cookiejar) {
324 if(data->change.cookielist) {
325 /* If there is a list of cookie files to read, do it first so that
326 we have all the told files read before we write the new jar */
327 Curl_cookie_loadfiles(data);
330 /* we have a "destination" for all the cookies to get dumped to */
331 if(Curl_cookie_output(data->cookies, data->set.cookiejar))
332 infof(data, "WARNING: failed to save cookies in %s\n",
333 data->set.cookiejar);
335 else {
336 if(data->change.cookielist)
337 /* since nothing is written, we can just free the list of cookie file
338 names */
339 curl_slist_free_all(data->change.cookielist); /* clean up list */
342 if( !data->share || (data->cookies != data->share->cookies) ) {
343 Curl_cookie_cleanup(data->cookies);
345 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
346 #endif
348 Curl_digest_cleanup(data);
350 Curl_safefree(data->info.contenttype);
352 /* this destroys the channel and we cannot use it anymore after this */
353 ares_destroy(data->state.areschannel);
355 #if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
356 /* close iconv conversion descriptors */
357 if (data->inbound_cd != (iconv_t)-1) {
358 iconv_close(data->inbound_cd);
360 if (data->outbound_cd != (iconv_t)-1) {
361 iconv_close(data->outbound_cd);
363 if (data->utf8_cd != (iconv_t)-1) {
364 iconv_close(data->utf8_cd);
366 #endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
368 /* No longer a dirty share, if it exists */
369 if (data->share)
370 data->share->dirty--;
372 free(data);
373 return CURLE_OK;
376 /* create a connection cache of a private or multi type */
377 struct conncache *Curl_mk_connc(int type,
378 int amount) /* set -1 to use default */
380 /* It is subject for debate how many default connections to have for a multi
381 connection cache... */
382 int default_amount = amount == -1?
383 ((type == CONNCACHE_PRIVATE)?5:10):amount;
384 struct conncache *c;
386 c= calloc(sizeof(struct conncache), 1);
387 if(!c)
388 return NULL;
390 c->connects = calloc(sizeof(struct connectdata *), default_amount);
391 if(!c->connects) {
392 free(c);
393 return NULL;
396 c->num = default_amount;
398 return c;
401 /* Change number of entries of a connection cache */
402 CURLcode Curl_ch_connc(struct SessionHandle *data,
403 struct conncache *c,
404 long newamount)
406 long i;
407 struct connectdata **newptr;
409 if(newamount < 1)
410 newamount = 1; /* we better have at least one entry */
412 if(!c) {
413 /* we get a NULL pointer passed in as connection cache, which means that
414 there is no cache created for this SessionHandle just yet, we create a
415 brand new with the requested size.
417 data->state.connc = Curl_mk_connc(CONNCACHE_PRIVATE, newamount);
418 if(!data->state.connc)
419 return CURLE_OUT_OF_MEMORY;
420 return CURLE_OK;
423 if(newamount < c->num) {
424 /* Since this number is *decreased* from the existing number, we must
425 close the possibly open connections that live on the indexes that
426 are being removed!
428 NOTE: for conncache_multi cases we must make sure that we only
429 close handles not in use.
431 for(i=newamount; i< c->num; i++)
432 Curl_disconnect(c->connects[i]);
434 /* If the most recent connection is no longer valid, mark it
435 invalid. */
436 if(data->state.lastconnect <= newamount)
437 data->state.lastconnect = -1;
439 if(newamount > 0) {
440 newptr= (struct connectdata **)
441 realloc(c->connects, sizeof(struct connectdata *) * newamount);
442 if(!newptr)
443 /* we closed a few connections in vain, but so what? */
444 return CURLE_OUT_OF_MEMORY;
446 /* nullify the newly added pointers */
447 for(i=c->num; i<newamount; i++)
448 newptr[i] = NULL;
450 c->connects = newptr;
451 c->num = newamount;
453 /* we no longer support less than 1 as size for the connection cache, and
454 I'm not sure it ever worked to set it to zero */
455 return CURLE_OK;
458 /* Free a connection cache. This is called from Curl_close() and
459 curl_multi_cleanup(). */
460 void Curl_rm_connc(struct conncache *c)
462 if(c->connects) {
463 int i;
464 for(i = 0; i < c->num; ++i)
465 conn_free(c->connects[i]);
467 free(c->connects);
470 free(c);
474 * Curl_open()
476 * @param curl is a pointer to a sessionhandle pointer that gets set by this
477 * function.
478 * @return CURLcode
481 CURLcode Curl_open(struct SessionHandle **curl)
483 CURLcode res = CURLE_OK;
484 struct SessionHandle *data;
486 /* Very simple start-up: alloc the struct, init it with zeroes and return */
487 data = (struct SessionHandle *)calloc(1, sizeof(struct SessionHandle));
488 if(!data)
489 /* this is a very serious error */
490 return CURLE_OUT_OF_MEMORY;
492 data->magic = CURLEASY_MAGIC_NUMBER;
494 #ifdef USE_ARES
495 if(ARES_SUCCESS != ares_init(&data->state.areschannel)) {
496 free(data);
497 return CURLE_FAILED_INIT;
499 /* make sure that all other returns from this function should destroy the
500 ares channel before returning error! */
501 #endif
503 /* We do some initial setup here, all those fields that can't be just 0 */
505 data->state.headerbuff=(char*)malloc(HEADERSIZE);
506 if(!data->state.headerbuff)
507 res = CURLE_OUT_OF_MEMORY;
508 else {
509 data->state.headersize=HEADERSIZE;
511 data->set.out = stdout; /* default output to stdout */
512 data->set.in = stdin; /* default input from stdin */
513 data->set.err = stderr; /* default stderr to stderr */
515 /* use fwrite as default function to store output */
516 data->set.fwrite = (curl_write_callback)fwrite;
518 /* use fread as default function to read input */
519 data->set.fread = (curl_read_callback)fread;
521 /* conversion callbacks for non-ASCII hosts */
522 data->set.convfromnetwork = (curl_conv_callback)ZERO_NULL;
523 data->set.convtonetwork = (curl_conv_callback)ZERO_NULL;
524 data->set.convfromutf8 = (curl_conv_callback)ZERO_NULL;
526 #if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
527 /* conversion descriptors for iconv calls */
528 data->outbound_cd = (iconv_t)-1;
529 data->inbound_cd = (iconv_t)-1;
530 data->utf8_cd = (iconv_t)-1;
531 #endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
533 data->set.infilesize = -1; /* we don't know any size */
534 data->set.postfieldsize = -1;
535 data->set.maxredirs = -1; /* allow any amount by default */
536 data->state.current_speed = -1; /* init to negative == impossible */
538 data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */
539 data->set.ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */
540 data->set.ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */
541 data->set.ftp_filemethod = FTPFILE_MULTICWD;
542 data->set.dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
544 /* make libcurl quiet by default: */
545 data->set.hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */
546 data->progress.flags |= PGRS_HIDE;
548 /* Set the default size of the SSL session ID cache */
549 data->set.ssl.numsessions = 5;
551 data->set.proxyport = 1080;
552 data->set.proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
553 data->set.httpauth = CURLAUTH_BASIC; /* defaults to basic */
554 data->set.proxyauth = CURLAUTH_BASIC; /* defaults to basic */
556 /* This no longer creates a connection cache here. It is instead made on
557 the first call to curl_easy_perform() or when the handle is added to a
558 multi stack. */
560 data->set.ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
561 type */
563 /* most recent connection is not yet defined */
564 data->state.lastconnect = -1;
566 Curl_easy_initHandleData(data);
569 * libcurl 7.10 introduced SSL verification *by default*! This needs to be
570 * switched off unless wanted.
572 data->set.ssl.verifypeer = TRUE;
573 data->set.ssl.verifyhost = 2;
574 data->set.ssl.sessionid = TRUE; /* session ID caching enabled by default */
575 #ifdef CURL_CA_BUNDLE
576 /* This is our preferred CA cert bundle since install time */
577 data->set.ssl.CAfile = (char *)CURL_CA_BUNDLE;
578 #endif
581 if(res) {
582 ares_destroy(data->state.areschannel);
583 if(data->state.headerbuff)
584 free(data->state.headerbuff);
585 free(data);
586 data = NULL;
588 else
589 *curl = data;
591 return res;
594 CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
595 va_list param)
597 char *argptr;
598 CURLcode result = CURLE_OK;
600 switch(option) {
601 case CURLOPT_DNS_CACHE_TIMEOUT:
602 data->set.dns_cache_timeout = va_arg(param, int);
603 break;
604 case CURLOPT_DNS_USE_GLOBAL_CACHE:
606 int use_cache = va_arg(param, int);
607 if (use_cache) {
608 Curl_global_host_cache_init();
611 data->set.global_dns_cache = (bool)(0 != use_cache);
613 break;
614 case CURLOPT_SSL_CIPHER_LIST:
615 /* set a list of cipher we want to use in the SSL connection */
616 data->set.ssl.cipher_list = va_arg(param, char *);
617 break;
619 case CURLOPT_RANDOM_FILE:
621 * This is the path name to a file that contains random data to seed
622 * the random SSL stuff with. The file is only used for reading.
624 data->set.ssl.random_file = va_arg(param, char *);
625 break;
626 case CURLOPT_EGDSOCKET:
628 * The Entropy Gathering Daemon socket pathname
630 data->set.ssl.egdsocket = va_arg(param, char *);
631 break;
632 case CURLOPT_MAXCONNECTS:
634 * Set the absolute number of maximum simultaneous alive connection that
635 * libcurl is allowed to have.
637 result = Curl_ch_connc(data, data->state.connc, va_arg(param, long));
638 break;
639 case CURLOPT_FORBID_REUSE:
641 * When this transfer is done, it must not be left to be reused by a
642 * subsequent transfer but shall be closed immediately.
644 data->set.reuse_forbid = (bool)(0 != va_arg(param, long));
645 break;
646 case CURLOPT_FRESH_CONNECT:
648 * This transfer shall not use a previously cached connection but
649 * should be made with a fresh new connect!
651 data->set.reuse_fresh = (bool)(0 != va_arg(param, long));
652 break;
653 case CURLOPT_VERBOSE:
655 * Verbose means infof() calls that give a lot of information about
656 * the connection and transfer procedures as well as internal choices.
658 data->set.verbose = (bool)(0 != va_arg(param, long));
659 break;
660 case CURLOPT_HEADER:
662 * Set to include the header in the general data output stream.
664 data->set.include_header = (bool)(0 != va_arg(param, long));
665 break;
666 case CURLOPT_NOPROGRESS:
668 * Shut off the internal supported progress meter
670 data->set.hide_progress = (bool)(0 != va_arg(param, long));
671 if(data->set.hide_progress)
672 data->progress.flags |= PGRS_HIDE;
673 else
674 data->progress.flags &= ~PGRS_HIDE;
675 break;
676 case CURLOPT_NOBODY:
678 * Do not include the body part in the output data stream.
680 data->set.opt_no_body = (bool)(0 != va_arg(param, long));
681 if(data->set.opt_no_body)
682 /* in HTTP lingo, this means using the HEAD request */
683 data->set.httpreq = HTTPREQ_HEAD;
684 break;
685 case CURLOPT_FAILONERROR:
687 * Don't output the >=300 error code HTML-page, but instead only
688 * return error.
690 data->set.http_fail_on_error = (bool)(0 != va_arg(param, long));
691 break;
692 case CURLOPT_UPLOAD:
693 case CURLOPT_PUT:
695 * We want to sent data to the remote host. If this is HTTP, that equals
696 * using the PUT request.
698 data->set.upload = (bool)(0 != va_arg(param, long));
699 if(data->set.upload)
700 /* If this is HTTP, PUT is what's needed to "upload" */
701 data->set.httpreq = HTTPREQ_PUT;
702 break;
703 case CURLOPT_FILETIME:
705 * Try to get the file time of the remote document. The time will
706 * later (possibly) become available using curl_easy_getinfo().
708 data->set.get_filetime = (bool)(0 != va_arg(param, long));
709 break;
710 case CURLOPT_FTP_CREATE_MISSING_DIRS:
712 * An FTP option that modifies an upload to create missing directories on
713 * the server.
715 data->set.ftp_create_missing_dirs = (bool)(0 != va_arg(param, long));
716 break;
717 case CURLOPT_FTP_RESPONSE_TIMEOUT:
719 * An FTP option that specifies how quickly an FTP response must be
720 * obtained before it is considered failure.
722 data->set.ftp_response_timeout = va_arg( param , long );
723 break;
724 case CURLOPT_FTPLISTONLY:
726 * An FTP option that changes the command to one that asks for a list
727 * only, no file info details.
729 data->set.ftp_list_only = (bool)(0 != va_arg(param, long));
730 break;
731 case CURLOPT_FTPAPPEND:
733 * We want to upload and append to an existing (FTP) file.
735 data->set.ftp_append = (bool)(0 != va_arg(param, long));
736 break;
737 case CURLOPT_FTP_FILEMETHOD:
739 * How do access files over FTP.
741 data->set.ftp_filemethod = (curl_ftpfile)va_arg(param, long);
742 break;
743 case CURLOPT_NETRC:
745 * Parse the $HOME/.netrc file
747 data->set.use_netrc = (enum CURL_NETRC_OPTION)va_arg(param, long);
748 break;
749 case CURLOPT_NETRC_FILE:
751 * Use this file instead of the $HOME/.netrc file
753 data->set.netrc_file = va_arg(param, char *);
754 break;
755 case CURLOPT_TRANSFERTEXT:
757 * This option was previously named 'FTPASCII'. Renamed to work with
758 * more protocols than merely FTP.
760 * Transfer using ASCII (instead of BINARY).
762 data->set.prefer_ascii = (bool)(0 != va_arg(param, long));
763 break;
764 case CURLOPT_TIMECONDITION:
766 * Set HTTP time condition. This must be one of the defines in the
767 * curl/curl.h header file.
769 data->set.timecondition = (curl_TimeCond)va_arg(param, long);
770 break;
771 case CURLOPT_TIMEVALUE:
773 * This is the value to compare with the remote document with the
774 * method set with CURLOPT_TIMECONDITION
776 data->set.timevalue = (time_t)va_arg(param, long);
777 break;
778 case CURLOPT_SSLVERSION:
780 * Set explicit SSL version to try to connect with, as some SSL
781 * implementations are lame.
783 data->set.ssl.version = va_arg(param, long);
784 break;
786 #ifndef CURL_DISABLE_HTTP
787 case CURLOPT_AUTOREFERER:
789 * Switch on automatic referer that gets set if curl follows locations.
791 data->set.http_auto_referer = (bool)(0 != va_arg(param, long));
792 break;
794 case CURLOPT_ENCODING:
796 * String to use at the value of Accept-Encoding header.
798 * If the encoding is set to "" we use an Accept-Encoding header that
799 * encompasses all the encodings we support.
800 * If the encoding is set to NULL we don't send an Accept-Encoding header
801 * and ignore an received Content-Encoding header.
804 data->set.encoding = va_arg(param, char *);
805 if(data->set.encoding && !*data->set.encoding)
806 data->set.encoding = (char*)ALL_CONTENT_ENCODINGS;
807 break;
809 case CURLOPT_FOLLOWLOCATION:
811 * Follow Location: header hints on a HTTP-server.
813 data->set.http_follow_location = (bool)(0 != va_arg(param, long));
814 break;
816 case CURLOPT_UNRESTRICTED_AUTH:
818 * Send authentication (user+password) when following locations, even when
819 * hostname changed.
821 data->set.http_disable_hostname_check_before_authentication =
822 (bool)(0 != va_arg(param, long));
823 break;
825 case CURLOPT_MAXREDIRS:
827 * The maximum amount of hops you allow curl to follow Location:
828 * headers. This should mostly be used to detect never-ending loops.
830 data->set.maxredirs = va_arg(param, long);
831 break;
833 case CURLOPT_POST:
834 /* Does this option serve a purpose anymore? Yes it does, when
835 CURLOPT_POSTFIELDS isn't used and the POST data is read off the
836 callback! */
837 if(va_arg(param, long)) {
838 data->set.httpreq = HTTPREQ_POST;
839 data->set.opt_no_body = FALSE; /* this is implied */
841 else
842 data->set.httpreq = HTTPREQ_GET;
843 break;
845 case CURLOPT_POSTFIELDS:
847 * A string with POST data. Makes curl HTTP POST. Even if it is NULL.
849 data->set.postfields = va_arg(param, char *);
850 data->set.httpreq = HTTPREQ_POST;
851 break;
853 case CURLOPT_POSTFIELDSIZE:
855 * The size of the POSTFIELD data to prevent libcurl to do strlen() to
856 * figure it out. Enables binary posts.
858 data->set.postfieldsize = va_arg(param, long);
859 break;
861 case CURLOPT_POSTFIELDSIZE_LARGE:
863 * The size of the POSTFIELD data to prevent libcurl to do strlen() to
864 * figure it out. Enables binary posts.
866 data->set.postfieldsize = va_arg(param, curl_off_t);
867 break;
869 case CURLOPT_HTTPPOST:
871 * Set to make us do HTTP POST
873 data->set.httppost = va_arg(param, struct curl_httppost *);
874 data->set.httpreq = HTTPREQ_POST_FORM;
875 data->set.opt_no_body = FALSE; /* this is implied */
876 break;
878 case CURLOPT_REFERER:
880 * String to set in the HTTP Referer: field.
882 if(data->change.referer_alloc) {
883 free(data->change.referer);
884 data->change.referer_alloc = FALSE;
886 data->set.set_referer = va_arg(param, char *);
887 data->change.referer = data->set.set_referer;
888 break;
890 case CURLOPT_USERAGENT:
892 * String to use in the HTTP User-Agent field
894 data->set.useragent = va_arg(param, char *);
895 break;
897 case CURLOPT_HTTPHEADER:
899 * Set a list with HTTP headers to use (or replace internals with)
901 data->set.headers = va_arg(param, struct curl_slist *);
902 break;
904 case CURLOPT_HTTP200ALIASES:
906 * Set a list of aliases for HTTP 200 in response header
908 data->set.http200aliases = va_arg(param, struct curl_slist *);
909 break;
911 #if !defined(CURL_DISABLE_COOKIES)
912 case CURLOPT_COOKIE:
914 * Cookie string to send to the remote server in the request.
916 data->set.cookie = va_arg(param, char *);
917 break;
919 case CURLOPT_COOKIEFILE:
921 * Set cookie file to read and parse. Can be used multiple times.
923 argptr = (char *)va_arg(param, void *);
924 if(argptr) {
925 struct curl_slist *cl;
926 /* append the cookie file name to the list of file names, and deal with
927 them later */
928 cl = curl_slist_append(data->change.cookielist, argptr);
930 if(!cl)
931 return CURLE_OUT_OF_MEMORY;
933 data->change.cookielist = cl;
935 break;
937 case CURLOPT_COOKIEJAR:
939 * Set cookie file name to dump all cookies to when we're done.
941 data->set.cookiejar = (char *)va_arg(param, void *);
944 * Activate the cookie parser. This may or may not already
945 * have been made.
947 data->cookies = Curl_cookie_init(data, NULL, data->cookies,
948 data->set.cookiesession);
949 break;
951 case CURLOPT_COOKIESESSION:
953 * Set this option to TRUE to start a new "cookie session". It will
954 * prevent the forthcoming read-cookies-from-file actions to accept
955 * cookies that are marked as being session cookies, as they belong to a
956 * previous session.
958 * In the original Netscape cookie spec, "session cookies" are cookies
959 * with no expire date set. RFC2109 describes the same action if no
960 * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds
961 * a 'Discard' action that can enforce the discard even for cookies that
962 * have a Max-Age.
964 * We run mostly with the original cookie spec, as hardly anyone implements
965 * anything else.
967 data->set.cookiesession = (bool)(0 != va_arg(param, long));
968 break;
970 case CURLOPT_COOKIELIST:
971 argptr = va_arg(param, char *);
973 if(argptr == NULL)
974 break;
976 if(strequal(argptr, "ALL")) {
977 /* clear all cookies */
978 Curl_cookie_clearall(data->cookies);
979 break;
981 else if(strequal(argptr, "SESS")) {
982 /* clear session cookies */
983 Curl_cookie_clearsess(data->cookies);
984 break;
987 if(!data->cookies)
988 /* if cookie engine was not running, activate it */
989 data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE);
991 argptr = strdup(argptr);
992 if(!argptr) {
993 result = CURLE_OUT_OF_MEMORY;
994 break;
997 if(checkprefix("Set-Cookie:", argptr))
998 /* HTTP Header format line */
999 Curl_cookie_add(data, data->cookies, TRUE, argptr + 11, NULL, NULL);
1001 else
1002 /* Netscape format line */
1003 Curl_cookie_add(data, data->cookies, FALSE, argptr, NULL, NULL);
1005 free(argptr);
1006 break;
1007 #endif /* CURL_DISABLE_COOKIES */
1009 case CURLOPT_HTTPGET:
1011 * Set to force us do HTTP GET
1013 if(va_arg(param, long)) {
1014 data->set.httpreq = HTTPREQ_GET;
1015 data->set.upload = FALSE; /* switch off upload */
1016 data->set.opt_no_body = FALSE; /* this is implied */
1018 break;
1020 case CURLOPT_HTTP_VERSION:
1022 * This sets a requested HTTP version to be used. The value is one of
1023 * the listed enums in curl/curl.h.
1025 data->set.httpversion = va_arg(param, long);
1026 break;
1028 case CURLOPT_HTTPPROXYTUNNEL:
1030 * Tunnel operations through the proxy instead of normal proxy use
1032 data->set.tunnel_thru_httpproxy = (bool)(0 != va_arg(param, long));
1033 break;
1035 case CURLOPT_CUSTOMREQUEST:
1037 * Set a custom string to use as request
1039 data->set.customrequest = va_arg(param, char *);
1041 /* we don't set
1042 data->set.httpreq = HTTPREQ_CUSTOM;
1043 here, we continue as if we were using the already set type
1044 and this just changes the actual request keyword */
1045 break;
1047 case CURLOPT_PROXYPORT:
1049 * Explicitly set HTTP proxy port number.
1051 data->set.proxyport = va_arg(param, long);
1052 break;
1054 case CURLOPT_HTTPAUTH:
1056 * Set HTTP Authentication type BITMASK.
1059 long auth = va_arg(param, long);
1060 /* switch off bits we can't support */
1061 #ifndef USE_NTLM
1062 auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
1063 #endif
1064 #ifndef HAVE_GSSAPI
1065 auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */
1066 #endif
1067 if(!auth)
1068 return CURLE_FAILED_INIT; /* no supported types left! */
1070 data->set.httpauth = auth;
1072 break;
1074 case CURLOPT_PROXYAUTH:
1076 * Set HTTP Authentication type BITMASK.
1079 long auth = va_arg(param, long);
1080 /* switch off bits we can't support */
1081 #ifndef USE_NTLM
1082 auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
1083 #endif
1084 #ifndef HAVE_GSSAPI
1085 auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */
1086 #endif
1087 if(!auth)
1088 return CURLE_FAILED_INIT; /* no supported types left! */
1090 data->set.proxyauth = auth;
1092 break;
1093 #endif /* CURL_DISABLE_HTTP */
1095 case CURLOPT_PROXY:
1097 * Set proxy server:port to use as HTTP proxy.
1099 * If the proxy is set to "" we explicitly say that we don't want to use a
1100 * proxy (even though there might be environment variables saying so).
1102 * Setting it to NULL, means no proxy but allows the environment variables
1103 * to decide for us.
1105 data->set.proxy = va_arg(param, char *);
1106 break;
1108 case CURLOPT_WRITEHEADER:
1110 * Custom pointer to pass the header write callback function
1112 data->set.writeheader = (void *)va_arg(param, void *);
1113 break;
1114 case CURLOPT_ERRORBUFFER:
1116 * Error buffer provided by the caller to get the human readable
1117 * error string in.
1119 data->set.errorbuffer = va_arg(param, char *);
1120 break;
1121 case CURLOPT_FILE:
1123 * FILE pointer to write to or include in the data write callback
1125 data->set.out = va_arg(param, FILE *);
1126 break;
1127 case CURLOPT_FTPPORT:
1129 * Use FTP PORT, this also specifies which IP address to use
1131 data->set.ftpport = va_arg(param, char *);
1132 data->set.ftp_use_port = (bool)(NULL != data->set.ftpport);
1133 break;
1135 case CURLOPT_FTP_USE_EPRT:
1136 data->set.ftp_use_eprt = (bool)(0 != va_arg(param, long));
1137 break;
1139 case CURLOPT_FTP_USE_EPSV:
1140 data->set.ftp_use_epsv = (bool)(0 != va_arg(param, long));
1141 break;
1143 case CURLOPT_FTP_SSL_CCC:
1144 data->set.ftp_use_ccc = (bool)(0 != va_arg(param, long));
1145 break;
1147 case CURLOPT_FTP_SKIP_PASV_IP:
1149 * Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the
1150 * bypass of the IP address in PASV responses.
1152 data->set.ftp_skip_ip = (bool)(0 != va_arg(param, long));
1153 break;
1155 case CURLOPT_INFILE:
1157 * FILE pointer to read the file to be uploaded from. Or possibly
1158 * used as argument to the read callback.
1160 data->set.in = va_arg(param, FILE *);
1161 break;
1162 case CURLOPT_INFILESIZE:
1164 * If known, this should inform curl about the file size of the
1165 * to-be-uploaded file.
1167 data->set.infilesize = va_arg(param, long);
1168 break;
1169 case CURLOPT_INFILESIZE_LARGE:
1171 * If known, this should inform curl about the file size of the
1172 * to-be-uploaded file.
1174 data->set.infilesize = va_arg(param, curl_off_t);
1175 break;
1176 case CURLOPT_LOW_SPEED_LIMIT:
1178 * The low speed limit that if transfers are below this for
1179 * CURLOPT_LOW_SPEED_TIME, the transfer is aborted.
1181 data->set.low_speed_limit=va_arg(param, long);
1182 break;
1183 case CURLOPT_MAX_SEND_SPEED_LARGE:
1185 * The max speed limit that sends transfer more than
1186 * CURLOPT_MAX_SEND_PER_SECOND bytes per second the transfer is
1187 * throttled..
1189 data->set.max_send_speed=va_arg(param, curl_off_t);
1190 break;
1191 case CURLOPT_MAX_RECV_SPEED_LARGE:
1193 * The max speed limit that sends transfer more than
1194 * CURLOPT_MAX_RECV_PER_SECOND bytes per second the transfer is
1195 * throttled..
1197 data->set.max_recv_speed=va_arg(param, curl_off_t);
1198 break;
1199 case CURLOPT_LOW_SPEED_TIME:
1201 * The low speed time that if transfers are below the set
1202 * CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted.
1204 data->set.low_speed_time=va_arg(param, long);
1205 break;
1206 case CURLOPT_URL:
1208 * The URL to fetch.
1210 if(data->change.url_alloc) {
1211 /* the already set URL is allocated, free it first! */
1212 free(data->change.url);
1213 data->change.url_alloc=FALSE;
1215 data->set.set_url = va_arg(param, char *);
1216 data->change.url = data->set.set_url;
1217 data->change.url_changed = TRUE;
1218 break;
1219 case CURLOPT_PORT:
1221 * The port number to use when getting the URL
1223 data->set.use_port = va_arg(param, long);
1224 break;
1225 case CURLOPT_TIMEOUT:
1227 * The maximum time you allow curl to use for a single transfer
1228 * operation.
1230 data->set.timeout = va_arg(param, long);
1231 break;
1232 case CURLOPT_CONNECTTIMEOUT:
1234 * The maximum time you allow curl to use to connect.
1236 data->set.connecttimeout = va_arg(param, long);
1237 break;
1239 case CURLOPT_USERPWD:
1241 * user:password to use in the operation
1243 data->set.userpwd = va_arg(param, char *);
1244 break;
1245 case CURLOPT_POSTQUOTE:
1247 * List of RAW FTP commands to use after a transfer
1249 data->set.postquote = va_arg(param, struct curl_slist *);
1250 break;
1251 case CURLOPT_PREQUOTE:
1253 * List of RAW FTP commands to use prior to RETR (Wesley Laxton)
1255 data->set.prequote = va_arg(param, struct curl_slist *);
1256 break;
1257 case CURLOPT_QUOTE:
1259 * List of RAW FTP commands to use before a transfer
1261 data->set.quote = va_arg(param, struct curl_slist *);
1262 break;
1263 case CURLOPT_PROGRESSFUNCTION:
1265 * Progress callback function
1267 data->set.fprogress = va_arg(param, curl_progress_callback);
1268 if(data->set.fprogress)
1269 data->progress.callback = TRUE; /* no longer internal */
1270 else
1271 data->progress.callback = FALSE; /* NULL enforces internal */
1273 break;
1274 case CURLOPT_PROGRESSDATA:
1276 * Custom client data to pass to the progress callback
1278 data->set.progress_client = va_arg(param, void *);
1279 break;
1280 case CURLOPT_PROXYUSERPWD:
1282 * user:password needed to use the proxy
1284 data->set.proxyuserpwd = va_arg(param, char *);
1285 break;
1286 case CURLOPT_RANGE:
1288 * What range of the file you want to transfer
1290 data->set.set_range = va_arg(param, char *);
1291 break;
1292 case CURLOPT_RESUME_FROM:
1294 * Resume transfer at the give file position
1296 data->set.set_resume_from = va_arg(param, long);
1297 break;
1298 case CURLOPT_RESUME_FROM_LARGE:
1300 * Resume transfer at the give file position
1302 data->set.set_resume_from = va_arg(param, curl_off_t);
1303 break;
1304 case CURLOPT_DEBUGFUNCTION:
1306 * stderr write callback.
1308 data->set.fdebug = va_arg(param, curl_debug_callback);
1310 * if the callback provided is NULL, it'll use the default callback
1312 break;
1313 case CURLOPT_DEBUGDATA:
1315 * Set to a void * that should receive all error writes. This
1316 * defaults to CURLOPT_STDERR for normal operations.
1318 data->set.debugdata = va_arg(param, void *);
1319 break;
1320 case CURLOPT_STDERR:
1322 * Set to a FILE * that should receive all error writes. This
1323 * defaults to stderr for normal operations.
1325 data->set.err = va_arg(param, FILE *);
1326 if(!data->set.err)
1327 data->set.err = stderr;
1328 break;
1329 case CURLOPT_HEADERFUNCTION:
1331 * Set header write callback
1333 data->set.fwrite_header = va_arg(param, curl_write_callback);
1334 break;
1335 case CURLOPT_WRITEFUNCTION:
1337 * Set data write callback
1339 data->set.fwrite = va_arg(param, curl_write_callback);
1340 if(!data->set.fwrite)
1341 /* When set to NULL, reset to our internal default function */
1342 data->set.fwrite = (curl_write_callback)fwrite;
1343 break;
1344 case CURLOPT_READFUNCTION:
1346 * Read data callback
1348 data->set.fread = va_arg(param, curl_read_callback);
1349 if(!data->set.fread)
1350 /* When set to NULL, reset to our internal default function */
1351 data->set.fread = (curl_read_callback)fread;
1352 break;
1353 case CURLOPT_CONV_FROM_NETWORK_FUNCTION:
1355 * "Convert from network encoding" callback
1357 data->set.convfromnetwork = va_arg(param, curl_conv_callback);
1358 break;
1359 case CURLOPT_CONV_TO_NETWORK_FUNCTION:
1361 * "Convert to network encoding" callback
1363 data->set.convtonetwork = va_arg(param, curl_conv_callback);
1364 break;
1365 case CURLOPT_CONV_FROM_UTF8_FUNCTION:
1367 * "Convert from UTF-8 encoding" callback
1369 data->set.convfromutf8 = va_arg(param, curl_conv_callback);
1370 break;
1371 case CURLOPT_IOCTLFUNCTION:
1373 * I/O control callback. Might be NULL.
1375 data->set.ioctl = va_arg(param, curl_ioctl_callback);
1376 break;
1377 case CURLOPT_IOCTLDATA:
1379 * I/O control data pointer. Might be NULL.
1381 data->set.ioctl_client = va_arg(param, void *);
1382 break;
1383 case CURLOPT_SSLCERT:
1385 * String that holds file name of the SSL certificate to use
1387 data->set.cert = va_arg(param, char *);
1388 break;
1389 case CURLOPT_SSLCERTTYPE:
1391 * String that holds file type of the SSL certificate to use
1393 data->set.cert_type = va_arg(param, char *);
1394 break;
1395 case CURLOPT_SSLKEY:
1397 * String that holds file name of the SSL certificate to use
1399 data->set.key = va_arg(param, char *);
1400 break;
1401 case CURLOPT_SSLKEYTYPE:
1403 * String that holds file type of the SSL certificate to use
1405 data->set.key_type = va_arg(param, char *);
1406 break;
1407 case CURLOPT_SSLKEYPASSWD:
1409 * String that holds the SSL private key password.
1411 data->set.key_passwd = va_arg(param, char *);
1412 break;
1413 case CURLOPT_SSLENGINE:
1415 * String that holds the SSL crypto engine.
1417 argptr = va_arg(param, char *);
1418 if (argptr && argptr[0])
1419 result = Curl_ssl_set_engine(data, argptr);
1420 break;
1422 case CURLOPT_SSLENGINE_DEFAULT:
1424 * flag to set engine as default.
1426 result = Curl_ssl_set_engine_default(data);
1427 break;
1428 case CURLOPT_CRLF:
1430 * Kludgy option to enable CRLF conversions. Subject for removal.
1432 data->set.crlf = (bool)(0 != va_arg(param, long));
1433 break;
1435 case CURLOPT_INTERFACE:
1437 * Set what interface or address/hostname to bind the socket to when
1438 * performing an operation and thus what from-IP your connection will use.
1440 data->set.device = va_arg(param, char *);
1441 break;
1442 case CURLOPT_LOCALPORT:
1444 * Set what local port to bind the socket to when performing an operation.
1446 data->set.localport = (unsigned short) va_arg(param, long);
1447 break;
1448 case CURLOPT_LOCALPORTRANGE:
1450 * Set number of local ports to try, starting with CURLOPT_LOCALPORT.
1452 data->set.localportrange = (int) va_arg(param, long);
1453 break;
1454 case CURLOPT_KRB4LEVEL:
1456 * A string that defines the krb4 security level.
1458 data->set.krb4_level = va_arg(param, char *);
1459 data->set.krb4 = (bool)(NULL != data->set.krb4_level);
1460 break;
1461 case CURLOPT_SSL_VERIFYPEER:
1463 * Enable peer SSL verifying.
1465 data->set.ssl.verifypeer = va_arg(param, long);
1466 break;
1467 case CURLOPT_SSL_VERIFYHOST:
1469 * Enable verification of the CN contained in the peer certificate
1471 data->set.ssl.verifyhost = va_arg(param, long);
1472 break;
1473 case CURLOPT_SSL_CTX_FUNCTION:
1475 * Set a SSL_CTX callback
1477 data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback);
1478 break;
1479 case CURLOPT_SSL_CTX_DATA:
1481 * Set a SSL_CTX callback parameter pointer
1483 data->set.ssl.fsslctxp = va_arg(param, void *);
1484 break;
1485 case CURLOPT_CAINFO:
1487 * Set CA info for SSL connection. Specify file name of the CA certificate
1489 data->set.ssl.CAfile = va_arg(param, char *);
1490 break;
1491 case CURLOPT_CAPATH:
1493 * Set CA path info for SSL connection. Specify directory name of the CA
1494 * certificates which have been prepared using openssl c_rehash utility.
1496 /* This does not work on windows. */
1497 data->set.ssl.CApath = va_arg(param, char *);
1498 break;
1499 case CURLOPT_TELNETOPTIONS:
1501 * Set a linked list of telnet options
1503 data->set.telnet_options = va_arg(param, struct curl_slist *);
1504 break;
1506 case CURLOPT_BUFFERSIZE:
1508 * The application kindly asks for a differently sized receive buffer.
1509 * If it seems reasonable, we'll use it.
1511 data->set.buffer_size = va_arg(param, long);
1513 if((data->set.buffer_size> (BUFSIZE -1 )) ||
1514 (data->set.buffer_size < 1))
1515 data->set.buffer_size = 0; /* huge internal default */
1517 break;
1519 case CURLOPT_NOSIGNAL:
1521 * The application asks not to set any signal() or alarm() handlers,
1522 * even when using a timeout.
1524 data->set.no_signal = (bool)(0 != va_arg(param, long));
1525 break;
1527 case CURLOPT_SHARE:
1529 struct Curl_share *set;
1530 set = va_arg(param, struct Curl_share *);
1532 /* disconnect from old share, if any */
1533 if(data->share) {
1534 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
1536 if(data->dns.hostcachetype == HCACHE_SHARED) {
1537 data->dns.hostcache = NULL;
1538 data->dns.hostcachetype = HCACHE_NONE;
1541 if(data->share->cookies == data->cookies)
1542 data->cookies = NULL;
1544 data->share->dirty--;
1546 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
1547 data->share = NULL;
1550 /* use new share if it set */
1551 data->share = set;
1552 if(data->share) {
1554 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
1556 data->share->dirty++;
1558 if(data->share->hostcache) {
1559 /* use shared host cache, first free the private one if any */
1560 if(data->dns.hostcachetype == HCACHE_PRIVATE)
1561 Curl_hash_destroy(data->dns.hostcache);
1563 data->dns.hostcache = data->share->hostcache;
1564 data->dns.hostcachetype = HCACHE_SHARED;
1566 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
1567 if(data->share->cookies) {
1568 /* use shared cookie list, first free own one if any */
1569 if (data->cookies)
1570 Curl_cookie_cleanup(data->cookies);
1571 data->cookies = data->share->cookies;
1573 #endif /* CURL_DISABLE_HTTP */
1574 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
1577 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
1578 /* check cookie list is set */
1579 if(!data->cookies)
1580 data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE );
1581 #endif /* CURL_DISABLE_HTTP */
1582 /* check for host cache not needed,
1583 * it will be done by curl_easy_perform */
1585 break;
1587 case CURLOPT_PROXYTYPE:
1589 * Set proxy type. HTTP/SOCKS4/SOCKS5
1591 data->set.proxytype = (curl_proxytype)va_arg(param, long);
1592 break;
1594 case CURLOPT_PRIVATE:
1596 * Set private data pointer.
1598 data->set.private_data = va_arg(param, char *);
1599 break;
1601 case CURLOPT_MAXFILESIZE:
1603 * Set the maximum size of a file to download.
1605 data->set.max_filesize = va_arg(param, long);
1606 break;
1608 case CURLOPT_FTP_SSL:
1610 * Make FTP transfers attempt to use SSL/TLS.
1612 data->set.ftp_ssl = (curl_ftpssl)va_arg(param, long);
1613 break;
1615 case CURLOPT_FTPSSLAUTH:
1617 * Set a specific auth for FTP-SSL transfers.
1619 data->set.ftpsslauth = (curl_ftpauth)va_arg(param, long);
1620 break;
1622 case CURLOPT_IPRESOLVE:
1623 data->set.ip_version = va_arg(param, long);
1624 break;
1626 case CURLOPT_MAXFILESIZE_LARGE:
1628 * Set the maximum size of a file to download.
1630 data->set.max_filesize = va_arg(param, curl_off_t);
1631 break;
1633 case CURLOPT_TCP_NODELAY:
1635 * Enable or disable TCP_NODELAY, which will disable/enable the Nagle
1636 * algorithm
1638 data->set.tcp_nodelay = (bool)(0 != va_arg(param, long));
1639 break;
1642 case CURLOPT_SOURCE_URL:
1643 case CURLOPT_SOURCE_USERPWD:
1644 case CURLOPT_SOURCE_QUOTE:
1645 case CURLOPT_SOURCE_PREQUOTE:
1646 case CURLOPT_SOURCE_POSTQUOTE:
1647 These former 3rd party transfer options are deprecated */
1649 case CURLOPT_FTP_ACCOUNT:
1650 data->set.ftp_account = va_arg(param, char *);
1651 break;
1653 case CURLOPT_IGNORE_CONTENT_LENGTH:
1654 data->set.ignorecl = (bool)(0 != va_arg(param, long));
1655 break;
1657 case CURLOPT_CONNECT_ONLY:
1659 * No data transfer, set up connection and let application use the socket
1661 data->set.connect_only = (bool)(0 != va_arg(param, long));
1662 break;
1664 case CURLOPT_FTP_ALTERNATIVE_TO_USER:
1665 data->set.ftp_alternative_to_user = va_arg(param, char *);
1666 break;
1668 case CURLOPT_SOCKOPTFUNCTION:
1670 * socket callback function: called after socket() but before connect()
1672 data->set.fsockopt = va_arg(param, curl_sockopt_callback);
1673 break;
1675 case CURLOPT_SOCKOPTDATA:
1677 * socket callback data pointer. Might be NULL.
1679 data->set.sockopt_client = va_arg(param, void *);
1680 break;
1682 case CURLOPT_SSL_SESSIONID_CACHE:
1683 data->set.ssl.sessionid = (bool)(0 != va_arg(param, long));
1684 break;
1686 case CURLOPT_SSH_AUTH_TYPES:
1687 data->set.ssh_auth_types = va_arg(param, long);
1688 break;
1690 case CURLOPT_SSH_PUBLIC_KEYFILE:
1692 * Use this file instead of the $HOME/.ssh/id_dsa.pub file
1694 data->set.ssh_public_key = va_arg(param, char *);
1695 break;
1697 case CURLOPT_SSH_PRIVATE_KEYFILE:
1699 * Use this file instead of the $HOME/.ssh/id_dsa file
1701 data->set.ssh_private_key = va_arg(param, char *);
1702 break;
1704 default:
1705 /* unknown tag and its companion, just ignore: */
1706 result = CURLE_FAILED_INIT; /* correct this */
1707 break;
1710 return result;
1713 static void conn_free(struct connectdata *conn)
1715 if (!conn)
1716 return;
1718 /* close possibly still open sockets */
1719 if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
1720 sclose(conn->sock[SECONDARYSOCKET]);
1721 if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET])
1722 sclose(conn->sock[FIRSTSOCKET]);
1724 Curl_safefree(conn->user);
1725 Curl_safefree(conn->passwd);
1726 Curl_safefree(conn->proxyuser);
1727 Curl_safefree(conn->proxypasswd);
1728 Curl_safefree(conn->allocptr.proxyuserpwd);
1729 Curl_safefree(conn->allocptr.uagent);
1730 Curl_safefree(conn->allocptr.userpwd);
1731 Curl_safefree(conn->allocptr.accept_encoding);
1732 Curl_safefree(conn->allocptr.rangeline);
1733 Curl_safefree(conn->allocptr.ref);
1734 Curl_safefree(conn->allocptr.host);
1735 Curl_safefree(conn->allocptr.cookiehost);
1736 Curl_safefree(conn->ip_addr_str);
1737 Curl_safefree(conn->trailer);
1738 Curl_safefree(conn->host.rawalloc); /* host name buffer */
1739 Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */
1741 Curl_llist_destroy(conn->send_pipe, NULL);
1742 Curl_llist_destroy(conn->recv_pipe, NULL);
1744 /* possible left-overs from the async name resolvers */
1745 #if defined(USE_ARES)
1746 Curl_safefree(conn->async.hostname);
1747 Curl_safefree(conn->async.os_specific);
1748 #elif defined(CURLRES_THREADED)
1749 Curl_destroy_thread_data(&conn->async);
1750 #endif
1752 Curl_free_ssl_config(&conn->ssl_config);
1754 free(conn); /* free all the connection oriented data */
1757 CURLcode Curl_disconnect(struct connectdata *conn)
1759 struct SessionHandle *data;
1760 if(!conn)
1761 return CURLE_OK; /* this is closed and fine already */
1762 data = conn->data;
1764 if(!data) {
1765 DEBUGF(infof(data, "DISCONNECT without easy handle, ignoring\n"));
1766 return CURLE_OK;
1769 #if defined(CURLDEBUG) && defined(AGGRESIVE_TEST)
1770 /* scan for DNS cache entries still marked as in use */
1771 Curl_hash_apply(data->hostcache,
1772 NULL, Curl_scan_cache_used);
1773 #endif
1775 Curl_expire(data, 0); /* shut off timers */
1776 Curl_hostcache_prune(data); /* kill old DNS cache entries */
1779 * The range string is usually freed in curl_done(), but we might
1780 * get here *instead* if we fail prematurely. Thus we need to be able
1781 * to free this resource here as well.
1783 if(data->reqdata.rangestringalloc) {
1784 free(data->reqdata.range);
1785 data->reqdata.rangestringalloc = FALSE;
1788 if((conn->ntlm.state != NTLMSTATE_NONE) ||
1789 (conn->proxyntlm.state != NTLMSTATE_NONE)) {
1790 /* Authentication data is a mix of connection-related and sessionhandle-
1791 related stuff. NTLM is connection-related so when we close the shop
1792 we shall forget. */
1793 data->state.authhost.done = FALSE;
1794 data->state.authhost.picked =
1795 data->state.authhost.want;
1797 data->state.authproxy.done = FALSE;
1798 data->state.authproxy.picked =
1799 data->state.authproxy.want;
1801 data->state.authproblem = FALSE;
1803 Curl_ntlm_cleanup(conn);
1806 if(conn->curl_disconnect)
1807 /* This is set if protocol-specific cleanups should be made */
1808 conn->curl_disconnect(conn);
1810 if(-1 != conn->connectindex) {
1811 /* unlink ourselves! */
1812 infof(data, "Closing connection #%ld\n", conn->connectindex);
1813 if(data->state.connc)
1814 /* only clear the table entry if we still know in which cache we
1815 used to be in */
1816 data->state.connc->connects[conn->connectindex] = NULL;
1819 #ifdef USE_LIBIDN
1820 if(conn->host.encalloc)
1821 idn_free(conn->host.encalloc); /* encoded host name buffer, must be freed
1822 with idn_free() since this was allocated
1823 by libidn */
1824 if(conn->proxy.encalloc)
1825 idn_free(conn->proxy.encalloc); /* encoded proxy name buffer, must be
1826 freed with idn_free() since this was
1827 allocated by libidn */
1828 #endif
1830 Curl_ssl_close(conn);
1832 /* Indicate to all handles on the pipe that we're dead */
1833 if (IsPipeliningEnabled(data)) {
1834 signalPipeClose(conn->send_pipe);
1835 signalPipeClose(conn->recv_pipe);
1838 conn_free(conn);
1840 return CURLE_OK;
1844 * This function should return TRUE if the socket is to be assumed to
1845 * be dead. Most commonly this happens when the server has closed the
1846 * connection due to inactivity.
1848 static bool SocketIsDead(curl_socket_t sock)
1850 int sval;
1851 bool ret_val = TRUE;
1853 sval = Curl_select(sock, CURL_SOCKET_BAD, 0);
1854 if(sval == 0)
1855 /* timeout */
1856 ret_val = FALSE;
1858 return ret_val;
1861 static bool IsPipeliningPossible(struct SessionHandle *handle)
1863 if (handle->multi && Curl_multi_canPipeline(handle->multi) &&
1864 (handle->set.httpreq == HTTPREQ_GET ||
1865 handle->set.httpreq == HTTPREQ_HEAD) &&
1866 handle->set.httpversion != CURL_HTTP_VERSION_1_0)
1867 return TRUE;
1869 return FALSE;
1872 static bool IsPipeliningEnabled(struct SessionHandle *handle)
1874 if (handle->multi && Curl_multi_canPipeline(handle->multi))
1875 return TRUE;
1877 return FALSE;
1880 void Curl_addHandleToPipeline(struct SessionHandle *data,
1881 struct curl_llist *pipe)
1883 #ifdef CURLDEBUG
1884 if(!IsPipeliningPossible(data)) {
1885 /* when not pipelined, there MUST be no handle in the list already */
1886 if(pipe->head)
1887 infof(data, "PIPE when no PIPE supposed!\n");
1889 #endif
1890 Curl_llist_insert_next(pipe, pipe->tail, data);
1894 int Curl_removeHandleFromPipeline(struct SessionHandle *handle,
1895 struct curl_llist *pipe)
1897 struct curl_llist_element *curr;
1899 curr = pipe->head;
1900 while (curr) {
1901 if (curr->ptr == handle) {
1902 Curl_llist_remove(pipe, curr, NULL);
1903 return 1; /* we removed a handle */
1905 curr = curr->next;
1908 return 0;
1911 #if 0 /* this code is saved here as it is useful for debugging purposes */
1912 static void Curl_printPipeline(struct curl_llist *pipe)
1914 struct curl_llist_element *curr;
1916 curr = pipe->head;
1917 while (curr) {
1918 struct SessionHandle *data = (struct SessionHandle *) curr->ptr;
1919 infof(data, "Handle in pipeline: %s\n",
1920 data->reqdata.path);
1921 curr = curr->next;
1924 #endif
1926 bool Curl_isHandleAtHead(struct SessionHandle *handle,
1927 struct curl_llist *pipe)
1929 struct curl_llist_element *curr = pipe->head;
1930 if (curr) {
1931 return (bool)(curr->ptr == handle);
1934 return FALSE;
1937 static void signalPipeClose(struct curl_llist *pipe)
1939 struct curl_llist_element *curr;
1941 curr = pipe->head;
1942 while (curr) {
1943 struct curl_llist_element *next = curr->next;
1944 struct SessionHandle *data = (struct SessionHandle *) curr->ptr;
1946 #ifdef CURLDEBUG /* debug-only code */
1947 if(data->magic != CURLEASY_MAGIC_NUMBER) {
1948 /* MAJOR BADNESS */
1949 fprintf(stderr, "signalPipeClose() found BAAD easy handle\n");
1951 else
1952 #endif
1954 data->state.pipe_broke = TRUE;
1955 Curl_llist_remove(pipe, curr, NULL);
1956 curr = next;
1962 * Given one filled in connection struct (named needle), this function should
1963 * detect if there already is one that has all the significant details
1964 * exactly the same and thus should be used instead.
1966 * If there is a match, this function returns TRUE - and has marked the
1967 * connection as 'in-use'. It must later be called with ConnectionDone() to
1968 * return back to 'idle' (unused) state.
1970 static bool
1971 ConnectionExists(struct SessionHandle *data,
1972 struct connectdata *needle,
1973 struct connectdata **usethis)
1975 long i;
1976 struct connectdata *check;
1977 bool canPipeline = IsPipeliningPossible(data);
1979 for(i=0; i< data->state.connc->num; i++) {
1980 bool match = FALSE;
1982 * Note that if we use a HTTP proxy, we check connections to that
1983 * proxy and not to the actual remote server.
1985 check = data->state.connc->connects[i];
1986 if(!check)
1987 /* NULL pointer means not filled-in entry */
1988 continue;
1990 if (check->connectindex == -1) {
1991 check->connectindex = i; /* Set this appropriately since it might have
1992 been set to -1 when the easy was removed
1993 from the multi */
1996 infof(data, "Examining connection #%ld for reuse\n", check->connectindex);
1998 if(check->inuse && !canPipeline) {
1999 /* can only happen within multi handles, and means that another easy
2000 handle is using this connection */
2001 continue;
2004 #ifdef CURLRES_ASYNCH
2005 /* ip_addr_str is NULL only if the resolving of the name hasn't completed
2006 yet and until then we don't re-use this connection */
2007 if (!check->ip_addr_str) {
2008 infof(data,
2009 "Connection #%ld has not finished name resolve, can't reuse\n",
2010 check->connectindex);
2011 continue;
2013 #endif
2015 if (check->send_pipe->size +
2016 check->recv_pipe->size >= MAX_PIPELINE_LENGTH) {
2017 infof(data, "Connection #%ld has its pipeline full, can't reuse\n",
2018 check->connectindex);
2019 continue;
2022 if (data->state.is_in_pipeline && check->bits.close) {
2023 /* Don't pick a connection that is going to be closed */
2024 infof(data, "Connection #%ld has been marked for close, can't reuse\n",
2025 check->connectindex);
2026 continue;
2029 if((needle->protocol&PROT_SSL) != (check->protocol&PROT_SSL))
2030 /* don't do mixed SSL and non-SSL connections */
2031 continue;
2033 if(!needle->bits.httpproxy || needle->protocol&PROT_SSL) {
2034 /* The requested connection does not use a HTTP proxy or it
2035 uses SSL. */
2037 if(!(needle->protocol&PROT_SSL) && check->bits.httpproxy)
2038 /* we don't do SSL but the cached connection has a proxy,
2039 then don't match this */
2040 continue;
2042 if(strequal(needle->protostr, check->protostr) &&
2043 strequal(needle->host.name, check->host.name) &&
2044 (needle->remote_port == check->remote_port) ) {
2045 if(needle->protocol & PROT_SSL) {
2046 /* This is SSL, verify that we're using the same
2047 ssl options as well */
2048 if(!Curl_ssl_config_matches(&needle->ssl_config,
2049 &check->ssl_config)) {
2050 infof(data,
2051 "Connection #%ld has different SSL parameters, "
2052 "can't reuse\n",
2053 check->connectindex );
2054 continue;
2057 if((needle->protocol & PROT_FTP) ||
2058 ((needle->protocol & PROT_HTTP) &&
2059 (data->state.authhost.want==CURLAUTH_NTLM))) {
2060 /* This is FTP or HTTP+NTLM, verify that we're using the same name
2061 and password as well */
2062 if(!strequal(needle->user, check->user) ||
2063 !strequal(needle->passwd, check->passwd)) {
2064 /* one of them was different */
2065 continue;
2068 match = TRUE;
2071 else { /* The requested needle connection is using a proxy,
2072 is the checked one using the same? */
2073 if(check->bits.httpproxy &&
2074 strequal(needle->proxy.name, check->proxy.name) &&
2075 needle->port == check->port) {
2076 /* This is the same proxy connection, use it! */
2077 match = TRUE;
2081 if(match) {
2082 if (!IsPipeliningEnabled(data)) {
2083 /* The check for a dead socket makes sense only in the
2084 non-pipelining case */
2085 bool dead = SocketIsDead(check->sock[FIRSTSOCKET]);
2086 if(dead) {
2087 check->data = data;
2088 infof(data, "Connection #%d seems to be dead!\n", i);
2090 Curl_disconnect(check); /* disconnect resources */
2091 data->state.connc->connects[i]=NULL; /* nothing here */
2093 return FALSE;
2097 check->inuse = TRUE; /* mark this as being in use so that no other
2098 handle in a multi stack may nick it */
2100 if (canPipeline) {
2101 /* Mark the connection as being in a pipeline */
2102 check->is_in_pipeline = TRUE;
2105 check->connectindex = i; /* Set this appropriately since it might have
2106 been set to -1 when the easy was removed
2107 from the multi */
2108 *usethis = check;
2109 return TRUE; /* yes, we found one to use! */
2113 return FALSE; /* no matching connecting exists */
2119 * This function frees/closes a connection in the connection cache. This
2120 * should take the previously set policy into account when deciding which
2121 * of the connections to kill.
2123 static long
2124 ConnectionKillOne(struct SessionHandle *data)
2126 long i;
2127 struct connectdata *conn;
2128 long highscore=-1;
2129 long connindex=-1;
2130 long score;
2131 struct timeval now;
2133 now = Curl_tvnow();
2135 for(i=0; data->state.connc && (i< data->state.connc->num); i++) {
2136 conn = data->state.connc->connects[i];
2138 if(!conn || conn->inuse)
2139 continue;
2141 /* Set higher score for the age passed since the connection was used */
2142 score = Curl_tvdiff(now, conn->now);
2144 if(score > highscore) {
2145 highscore = score;
2146 connindex = i;
2149 if(connindex >= 0) {
2150 /* Set the connection's owner correctly */
2151 conn = data->state.connc->connects[connindex];
2152 conn->data = data;
2154 /* the winner gets the honour of being disconnected */
2155 (void)Curl_disconnect(conn);
2157 /* clean the array entry */
2158 data->state.connc->connects[connindex] = NULL;
2161 return connindex; /* return the available index or -1 */
2164 /* this connection can now be marked 'idle' */
2165 static void
2166 ConnectionDone(struct connectdata *conn)
2168 conn->inuse = FALSE;
2169 if (!conn->send_pipe && !conn->recv_pipe)
2170 conn->is_in_pipeline = FALSE;
2174 * The given input connection struct pointer is to be stored. If the "cache"
2175 * is already full, we must clean out the most suitable using the previously
2176 * set policy.
2178 * The given connection should be unique. That must've been checked prior to
2179 * this call.
2181 static long
2182 ConnectionStore(struct SessionHandle *data,
2183 struct connectdata *conn)
2185 long i;
2186 for(i=0; i< data->state.connc->num; i++) {
2187 if(!data->state.connc->connects[i])
2188 break;
2190 if(i == data->state.connc->num) {
2191 /* there was no room available, kill one */
2192 i = ConnectionKillOne(data);
2193 if(-1 != i)
2194 infof(data, "Connection (#%d) was killed to make room (holds %d)\n",
2195 i, data->state.connc->num);
2196 else
2197 infof(data, "This connection did not fit in the connection cache\n");
2200 conn->connectindex = i; /* Make the child know where the pointer to this
2201 particular data is stored. But note that this -1
2202 if this is not within the cache and this is
2203 probably not checked for everywhere (yet). */
2204 conn->inuse = TRUE;
2205 if(-1 != i) {
2206 /* Only do this if a true index was returned, if -1 was returned there
2207 is no room in the cache for an unknown reason and we cannot store
2208 this there.
2210 TODO: make sure we really can work with more handles than positions in
2211 the cache, or possibly we should (allow to automatically) resize the
2212 connection cache when we add more easy handles to a multi handle!
2214 data->state.connc->connects[i] = conn; /* fill in this */
2215 conn->data = data;
2218 return i;
2221 static CURLcode ConnectPlease(struct SessionHandle *data,
2222 struct connectdata *conn,
2223 struct Curl_dns_entry *hostaddr,
2224 bool *connected)
2226 CURLcode result;
2227 Curl_addrinfo *addr;
2228 char *hostname = conn->bits.httpproxy?conn->proxy.name:conn->host.name;
2230 infof(data, "About to connect() to %s%s port %d (#%d)\n",
2231 conn->bits.httpproxy?"proxy ":"",
2232 hostname, conn->port, conn->connectindex);
2234 /*************************************************************
2235 * Connect to server/proxy
2236 *************************************************************/
2237 result= Curl_connecthost(conn,
2238 hostaddr,
2239 &conn->sock[FIRSTSOCKET],
2240 &addr,
2241 connected);
2242 if(CURLE_OK == result) {
2243 /* All is cool, then we store the current information */
2244 conn->dns_entry = hostaddr;
2245 conn->ip_addr = addr;
2247 Curl_store_ip_addr(conn);
2249 switch(data->set.proxytype) {
2250 case CURLPROXY_SOCKS5:
2251 result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, conn);
2252 break;
2253 case CURLPROXY_HTTP:
2254 /* do nothing here. handled later. */
2255 break;
2256 case CURLPROXY_SOCKS4:
2257 result = Curl_SOCKS4(conn->proxyuser, conn);
2258 break;
2259 default:
2260 failf(data, "unknown proxytype option given");
2261 result = CURLE_COULDNT_CONNECT;
2262 break;
2266 return result;
2270 * verboseconnect() displays verbose information after a connect
2272 static void verboseconnect(struct connectdata *conn)
2274 infof(conn->data, "Connected to %s (%s) port %d (#%d)\n",
2275 conn->bits.httpproxy ? conn->proxy.dispname : conn->host.dispname,
2276 conn->ip_addr_str, conn->port, conn->connectindex);
2279 int Curl_protocol_getsock(struct connectdata *conn,
2280 curl_socket_t *socks,
2281 int numsocks)
2283 if(conn->curl_proto_getsock)
2284 return conn->curl_proto_getsock(conn, socks, numsocks);
2285 return GETSOCK_BLANK;
2288 int Curl_doing_getsock(struct connectdata *conn,
2289 curl_socket_t *socks,
2290 int numsocks)
2292 if(conn && conn->curl_doing_getsock)
2293 return conn->curl_doing_getsock(conn, socks, numsocks);
2294 return GETSOCK_BLANK;
2298 * We are doing protocol-specific connecting and this is being called over and
2299 * over from the multi interface until the connection phase is done on
2300 * protocol layer.
2303 CURLcode Curl_protocol_connecting(struct connectdata *conn,
2304 bool *done)
2306 CURLcode result=CURLE_OK;
2308 if(conn && conn->curl_connecting) {
2309 *done = FALSE;
2310 result = conn->curl_connecting(conn, done);
2312 else
2313 *done = TRUE;
2315 return result;
2319 * We are DOING this is being called over and over from the multi interface
2320 * until the DOING phase is done on protocol layer.
2323 CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done)
2325 CURLcode result=CURLE_OK;
2327 if(conn && conn->curl_doing) {
2328 *done = FALSE;
2329 result = conn->curl_doing(conn, done);
2331 else
2332 *done = TRUE;
2334 return result;
2338 * We have discovered that the TCP connection has been successful, we can now
2339 * proceed with some action.
2342 CURLcode Curl_protocol_connect(struct connectdata *conn,
2343 bool *protocol_done)
2345 CURLcode result=CURLE_OK;
2346 struct SessionHandle *data = conn->data;
2348 *protocol_done = FALSE;
2350 if(conn->bits.tcpconnect && conn->bits.protoconnstart) {
2351 /* We already are connected, get back. This may happen when the connect
2352 worked fine in the first call, like when we connect to a local server
2353 or proxy. Note that we don't know if the protocol is actually done.
2355 Unless this protocol doesn't have any protocol-connect callback, as
2356 then we know we're done. */
2357 if(!conn->curl_connecting)
2358 *protocol_done = TRUE;
2360 return CURLE_OK;
2363 if(!conn->bits.tcpconnect) {
2365 Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
2367 if(data->set.verbose)
2368 verboseconnect(conn);
2371 if(!conn->bits.protoconnstart) {
2372 if(conn->curl_connect) {
2373 /* is there a protocol-specific connect() procedure? */
2375 /* Set start time here for timeout purposes in the connect procedure, it
2376 is later set again for the progress meter purpose */
2377 conn->now = Curl_tvnow();
2379 /* Call the protocol-specific connect function */
2380 result = conn->curl_connect(conn, protocol_done);
2382 else
2383 *protocol_done = TRUE;
2385 /* it has started, possibly even completed but that knowledge isn't stored
2386 in this bit! */
2387 if (!result)
2388 conn->bits.protoconnstart = TRUE;
2391 return result; /* pass back status */
2395 * Helpers for IDNA convertions.
2397 #ifdef USE_LIBIDN
2398 static bool is_ASCII_name(const char *hostname)
2400 const unsigned char *ch = (const unsigned char*)hostname;
2402 while (*ch) {
2403 if (*ch++ & 0x80)
2404 return FALSE;
2406 return TRUE;
2410 * Check if characters in hostname is allowed in Top Level Domain.
2412 static bool tld_check_name(struct SessionHandle *data,
2413 const char *ace_hostname)
2415 size_t err_pos;
2416 char *uc_name = NULL;
2417 int rc;
2419 /* Convert (and downcase) ACE-name back into locale's character set */
2420 rc = idna_to_unicode_lzlz(ace_hostname, &uc_name, 0);
2421 if (rc != IDNA_SUCCESS)
2422 return (FALSE);
2424 rc = tld_check_lz(uc_name, &err_pos, NULL);
2425 if (rc == TLD_INVALID)
2426 infof(data, "WARNING: %s; pos %u = `%c'/0x%02X\n",
2427 #ifdef HAVE_TLD_STRERROR
2428 tld_strerror((Tld_rc)rc),
2429 #else
2430 "<no msg>",
2431 #endif
2432 err_pos, uc_name[err_pos],
2433 uc_name[err_pos] & 255);
2434 else if (rc != TLD_SUCCESS)
2435 infof(data, "WARNING: TLD check for %s failed; %s\n",
2436 uc_name,
2437 #ifdef HAVE_TLD_STRERROR
2438 tld_strerror((Tld_rc)rc)
2439 #else
2440 "<no msg>"
2441 #endif
2443 if (uc_name)
2444 idn_free(uc_name);
2445 return (bool)(rc == TLD_SUCCESS);
2447 #endif
2449 static void fix_hostname(struct SessionHandle *data,
2450 struct connectdata *conn, struct hostname *host)
2452 /* set the name we use to display the host name */
2453 host->dispname = host->name;
2455 #ifdef USE_LIBIDN
2456 /*************************************************************
2457 * Check name for non-ASCII and convert hostname to ACE form.
2458 *************************************************************/
2459 if (!is_ASCII_name(host->name) &&
2460 stringprep_check_version(LIBIDN_REQUIRED_VERSION)) {
2461 char *ace_hostname = NULL;
2462 int rc = idna_to_ascii_lz(host->name, &ace_hostname, 0);
2463 infof (data, "Input domain encoded as `%s'\n",
2464 stringprep_locale_charset ());
2465 if (rc != IDNA_SUCCESS)
2466 infof(data, "Failed to convert %s to ACE; %s\n",
2467 host->name, Curl_idn_strerror(conn,rc));
2468 else {
2469 /* tld_check_name() displays a warning if the host name contains
2470 "illegal" characters for this TLD */
2471 (void)tld_check_name(data, ace_hostname);
2473 host->encalloc = ace_hostname;
2474 /* change the name pointer to point to the encoded hostname */
2475 host->name = host->encalloc;
2478 #else
2479 (void)data; /* never used */
2480 (void)conn; /* never used */
2481 #endif
2485 * Parse URL and fill in the relevant members of the connection struct.
2487 static CURLcode ParseURLAndFillConnection(struct SessionHandle *data,
2488 struct connectdata *conn)
2490 char *at;
2491 char *tmp;
2493 char *path = data->reqdata.path;
2495 /*************************************************************
2496 * Parse the URL.
2498 * We need to parse the url even when using the proxy, because we will need
2499 * the hostname and port in case we are trying to SSL connect through the
2500 * proxy -- and we don't know if we will need to use SSL until we parse the
2501 * url ...
2502 ************************************************************/
2503 if((2 == sscanf(data->change.url, "%15[^:]:%[^\n]",
2504 conn->protostr,
2505 path)) && strequal(conn->protostr, "file")) {
2506 if(path[0] == '/' && path[1] == '/') {
2507 /* Allow omitted hostname (e.g. file:/<path>). This is not strictly
2508 * speaking a valid file: URL by RFC 1738, but treating file:/<path> as
2509 * file://localhost/<path> is similar to how other schemes treat missing
2510 * hostnames. See RFC 1808. */
2512 /* This cannot be done with strcpy() in a portable manner, since the
2513 memory areas overlap! */
2514 memmove(path, path + 2, strlen(path + 2)+1);
2517 * we deal with file://<host>/<path> differently since it supports no
2518 * hostname other than "localhost" and "127.0.0.1", which is unique among
2519 * the URL protocols specified in RFC 1738
2521 if(path[0] != '/') {
2522 /* the URL included a host name, we ignore host names in file:// URLs
2523 as the standards don't define what to do with them */
2524 char *ptr=strchr(path, '/');
2525 if(ptr) {
2526 /* there was a slash present
2528 RFC1738 (section 3.1, page 5) says:
2530 The rest of the locator consists of data specific to the scheme,
2531 and is known as the "url-path". It supplies the details of how the
2532 specified resource can be accessed. Note that the "/" between the
2533 host (or port) and the url-path is NOT part of the url-path.
2535 As most agents use file://localhost/foo to get '/foo' although the
2536 slash preceding foo is a separator and not a slash for the path,
2537 a URL as file://localhost//foo must be valid as well, to refer to
2538 the same file with an absolute path.
2541 if(ptr[1] && ('/' == ptr[1]))
2542 /* if there was two slashes, we skip the first one as that is then
2543 used truly as a separator */
2544 ptr++;
2546 /* This cannot be made with strcpy, as the memory chunks overlap! */
2547 memmove(path, ptr, strlen(ptr)+1);
2551 strcpy(conn->protostr, "file"); /* store protocol string lowercase */
2553 else {
2554 /* clear path */
2555 path[0]=0;
2557 if (2 > sscanf(data->change.url,
2558 "%15[^\n:]://%[^\n/]%[^\n]",
2559 conn->protostr,
2560 conn->host.name, path)) {
2563 * The URL was badly formatted, let's try the browser-style _without_
2564 * protocol specified like 'http://'.
2566 if((1 > sscanf(data->change.url, "%[^\n/]%[^\n]",
2567 conn->host.name, path)) ) {
2569 * We couldn't even get this format.
2571 failf(data, "<url> malformed");
2572 return CURLE_URL_MALFORMAT;
2576 * Since there was no protocol part specified, we guess what protocol it
2577 * is based on the first letters of the server name.
2580 /* Note: if you add a new protocol, please update the list in
2581 * lib/version.c too! */
2583 if(checkprefix("FTP.", conn->host.name))
2584 strcpy(conn->protostr, "ftp");
2585 else if (checkprefix("DICT.", conn->host.name))
2586 strcpy(conn->protostr, "DICT");
2587 else if (checkprefix("LDAP.", conn->host.name))
2588 strcpy(conn->protostr, "LDAP");
2589 else {
2590 strcpy(conn->protostr, "http");
2593 conn->protocol |= PROT_MISSING; /* not given in URL */
2597 /* We search for '?' in the host name (but only on the right side of a
2598 * @-letter to allow ?-letters in username and password) to handle things
2599 * like http://example.com?param= (notice the missing '/').
2601 at = strchr(conn->host.name, '@');
2602 if(at)
2603 tmp = strchr(at+1, '?');
2604 else
2605 tmp = strchr(conn->host.name, '?');
2607 if(tmp) {
2608 /* We must insert a slash before the '?'-letter in the URL. If the URL had
2609 a slash after the '?', that is where the path currently begins and the
2610 '?string' is still part of the host name.
2612 We must move the trailing part from the host name and put it first in
2613 the path. And have it all prefixed with a slash.
2616 size_t hostlen = strlen(tmp);
2617 size_t pathlen = strlen(path);
2619 /* move the existing path plus the zero byte forward, to make room for
2620 the host-name part */
2621 memmove(path+hostlen+1, path, pathlen+1);
2623 /* now copy the trailing host part in front of the existing path */
2624 memcpy(path+1, tmp, hostlen);
2626 path[0]='/'; /* prepend the missing slash */
2628 *tmp=0; /* now cut off the hostname at the ? */
2630 else if(!path[0]) {
2631 /* if there's no path set, use a single slash */
2632 strcpy(path, "/");
2635 /* If the URL is malformatted (missing a '/' after hostname before path) we
2636 * insert a slash here. The only letter except '/' we accept to start a path
2637 * is '?'.
2639 if(path[0] == '?') {
2640 /* We need this function to deal with overlapping memory areas. We know
2641 that the memory area 'path' points to is 'urllen' bytes big and that
2642 is bigger than the path. Use +1 to move the zero byte too. */
2643 memmove(&path[1], path, strlen(path)+1);
2644 path[0] = '/';
2648 * So if the URL was A://B/C,
2649 * conn->protostr is A
2650 * conn->host.name is B
2651 * data->reqdata.path is /C
2654 return CURLE_OK;
2657 static void llist_dtor(void *user, void *element)
2659 (void)user;
2660 (void)element;
2661 /* Do nothing */
2666 * CreateConnection() sets up a new connectdata struct, or re-uses an already
2667 * existing one, and resolves host name.
2669 * if this function returns CURLE_OK and *async is set to TRUE, the resolve
2670 * response will be coming asynchronously. If *async is FALSE, the name is
2671 * already resolved.
2673 * @param data The sessionhandle pointer
2674 * @param in_connect is set to the next connection data pointer
2675 * @param addr is set to the new dns entry for this connection. If this
2676 * connection is re-used it will be NULL.
2677 * @param async is set TRUE/FALSE depending on the nature of this lookup
2678 * @return CURLcode
2679 * @see SetupConnection()
2681 * *NOTE* this function assigns the conn->data pointer!
2684 static CURLcode CreateConnection(struct SessionHandle *data,
2685 struct connectdata **in_connect,
2686 struct Curl_dns_entry **addr,
2687 bool *async)
2690 char *tmp;
2691 CURLcode result=CURLE_OK;
2692 struct connectdata *conn;
2693 struct connectdata *conn_temp = NULL;
2694 size_t urllen;
2695 struct Curl_dns_entry *hostaddr;
2696 #if defined(HAVE_ALARM) && !defined(USE_ARES)
2697 unsigned int prev_alarm=0;
2698 #endif
2699 char endbracket;
2700 char user[MAX_CURL_USER_LENGTH];
2701 char passwd[MAX_CURL_PASSWORD_LENGTH];
2702 int rc;
2703 bool reuse;
2704 char *proxy;
2705 bool proxy_alloc = FALSE;
2707 #ifndef USE_ARES
2708 #ifdef SIGALRM
2709 #ifdef HAVE_SIGACTION
2710 struct sigaction keep_sigact; /* store the old struct here */
2711 bool keep_copysig=FALSE; /* did copy it? */
2712 #else
2713 #ifdef HAVE_SIGNAL
2714 void (*keep_sigact)(int); /* store the old handler here */
2715 #endif /* HAVE_SIGNAL */
2716 #endif /* HAVE_SIGACTION */
2717 #endif /* SIGALRM */
2718 #endif /* USE_ARES */
2720 *addr = NULL; /* nothing yet */
2721 *async = FALSE;
2723 /*************************************************************
2724 * Check input data
2725 *************************************************************/
2727 if(!data->change.url)
2728 return CURLE_URL_MALFORMAT;
2730 /* First, split up the current URL in parts so that we can use the
2731 parts for checking against the already present connections. In order
2732 to not have to modify everything at once, we allocate a temporary
2733 connection data struct and fill in for comparison purposes. */
2735 conn = (struct connectdata *)calloc(sizeof(struct connectdata), 1);
2736 if(!conn) {
2737 *in_connect = NULL; /* clear the pointer */
2738 return CURLE_OUT_OF_MEMORY;
2740 /* We must set the return variable as soon as possible, so that our
2741 parent can cleanup any possible allocs we may have done before
2742 any failure */
2743 *in_connect = conn;
2745 /* and we setup a few fields in case we end up actually using this struct */
2747 conn->data = data; /* Setup the association between this connection
2748 and the SessionHandle */
2750 conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
2751 conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
2752 conn->connectindex = -1; /* no index */
2754 conn->bits.httpproxy = (bool)(data->set.proxy /* http proxy or not */
2755 && *data->set.proxy
2756 && (data->set.proxytype == CURLPROXY_HTTP));
2757 proxy = data->set.proxy; /* if global proxy is set, this is it */
2759 /* Default protocol-independent behavior doesn't support persistent
2760 connections, so we set this to force-close. Protocols that support
2761 this need to set this to FALSE in their "curl_do" functions. */
2762 conn->bits.close = TRUE;
2764 conn->readchannel_inuse = FALSE;
2765 conn->writechannel_inuse = FALSE;
2767 conn->read_pos = 0;
2768 conn->buf_len = 0;
2770 /* Initialize the pipeline lists */
2771 conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
2772 conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
2774 /* Store creation time to help future close decision making */
2775 conn->created = Curl_tvnow();
2777 /* range status */
2778 data->reqdata.use_range = (bool)(NULL != data->set.set_range);
2780 data->reqdata.range = data->set.set_range; /* clone the range setting */
2781 data->reqdata.resume_from = data->set.set_resume_from;
2783 conn->bits.user_passwd = (bool)(NULL != data->set.userpwd);
2784 conn->bits.proxy_user_passwd = (bool)(NULL != data->set.proxyuserpwd);
2785 conn->bits.no_body = data->set.opt_no_body;
2786 conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy;
2787 conn->bits.ftp_use_epsv = data->set.ftp_use_epsv;
2788 conn->bits.ftp_use_eprt = data->set.ftp_use_eprt;
2790 /* This initing continues below, see the comment "Continue connectdata
2791 * initialization here" */
2793 /***********************************************************
2794 * We need to allocate memory to store the path in. We get the size of the
2795 * full URL to be sure, and we need to make it at least 256 bytes since
2796 * other parts of the code will rely on this fact
2797 ***********************************************************/
2798 #define LEAST_PATH_ALLOC 256
2799 urllen=strlen(data->change.url);
2800 if(urllen < LEAST_PATH_ALLOC)
2801 urllen=LEAST_PATH_ALLOC;
2803 if (!data->set.source_url /* 3rd party FTP */
2804 && data->reqdata.pathbuffer) {
2805 /* Free the old buffer */
2806 free(data->reqdata.pathbuffer);
2810 * We malloc() the buffers below urllen+2 to make room for to possibilities:
2811 * 1 - an extra terminating zero
2812 * 2 - an extra slash (in case a syntax like "www.host.com?moo" is used)
2815 data->reqdata.pathbuffer=(char *)malloc(urllen+2);
2816 if(NULL == data->reqdata.pathbuffer)
2817 return CURLE_OUT_OF_MEMORY; /* really bad error */
2818 data->reqdata.path = data->reqdata.pathbuffer;
2820 conn->host.rawalloc=(char *)malloc(urllen+2);
2821 if(NULL == conn->host.rawalloc)
2822 return CURLE_OUT_OF_MEMORY;
2824 conn->host.name = conn->host.rawalloc;
2825 conn->host.name[0] = 0;
2827 result = ParseURLAndFillConnection(data, conn);
2828 if (result != CURLE_OK) {
2829 return result;
2832 /*************************************************************
2833 * Take care of proxy authentication stuff
2834 *************************************************************/
2835 if(conn->bits.proxy_user_passwd) {
2836 char proxyuser[MAX_CURL_USER_LENGTH]="";
2837 char proxypasswd[MAX_CURL_PASSWORD_LENGTH]="";
2839 sscanf(data->set.proxyuserpwd,
2840 "%" MAX_CURL_USER_LENGTH_TXT "[^:]:"
2841 "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]",
2842 proxyuser, proxypasswd);
2844 conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
2845 if(!conn->proxyuser)
2846 return CURLE_OUT_OF_MEMORY;
2848 conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL);
2849 if(!conn->proxypasswd)
2850 return CURLE_OUT_OF_MEMORY;
2853 #ifndef CURL_DISABLE_HTTP
2854 /*************************************************************
2855 * Detect what (if any) proxy to use
2856 *************************************************************/
2857 if(!conn->bits.httpproxy) {
2858 /* If proxy was not specified, we check for default proxy environment
2859 * variables, to enable i.e Lynx compliance:
2861 * http_proxy=http://some.server.dom:port/
2862 * https_proxy=http://some.server.dom:port/
2863 * ftp_proxy=http://some.server.dom:port/
2864 * no_proxy=domain1.dom,host.domain2.dom
2865 * (a comma-separated list of hosts which should
2866 * not be proxied, or an asterisk to override
2867 * all proxy variables)
2868 * all_proxy=http://some.server.dom:port/
2869 * (seems to exist for the CERN www lib. Probably
2870 * the first to check for.)
2872 * For compatibility, the all-uppercase versions of these variables are
2873 * checked if the lowercase versions don't exist.
2875 char *no_proxy=NULL;
2876 char *no_proxy_tok_buf;
2877 char proxy_env[128];
2879 no_proxy=curl_getenv("no_proxy");
2880 if(!no_proxy)
2881 no_proxy=curl_getenv("NO_PROXY");
2883 if(!no_proxy || !strequal("*", no_proxy)) {
2884 /* NO_PROXY wasn't specified or it wasn't just an asterisk */
2885 char *nope;
2887 nope=no_proxy?strtok_r(no_proxy, ", ", &no_proxy_tok_buf):NULL;
2888 while(nope) {
2889 size_t namelen;
2890 char *endptr = strchr(conn->host.name, ':');
2891 if(endptr)
2892 namelen=endptr-conn->host.name;
2893 else
2894 namelen=strlen(conn->host.name);
2896 if(strlen(nope) <= namelen) {
2897 char *checkn=
2898 conn->host.name + namelen - strlen(nope);
2899 if(checkprefix(nope, checkn)) {
2900 /* no proxy for this host! */
2901 break;
2904 nope=strtok_r(NULL, ", ", &no_proxy_tok_buf);
2906 if(!nope) {
2907 /* It was not listed as without proxy */
2908 char *protop = conn->protostr;
2909 char *envp = proxy_env;
2910 char *prox;
2912 /* Now, build <protocol>_proxy and check for such a one to use */
2913 while(*protop)
2914 *envp++ = (char)tolower((int)*protop++);
2916 /* append _proxy */
2917 strcpy(envp, "_proxy");
2919 /* read the protocol proxy: */
2920 prox=curl_getenv(proxy_env);
2923 * We don't try the uppercase version of HTTP_PROXY because of
2924 * security reasons:
2926 * When curl is used in a webserver application
2927 * environment (cgi or php), this environment variable can
2928 * be controlled by the web server user by setting the
2929 * http header 'Proxy:' to some value.
2931 * This can cause 'internal' http/ftp requests to be
2932 * arbitrarily redirected by any external attacker.
2934 if(!prox && !strequal("http_proxy", proxy_env)) {
2935 /* There was no lowercase variable, try the uppercase version: */
2936 for(envp = proxy_env; *envp; envp++)
2937 *envp = (char)toupper((int)*envp);
2938 prox=curl_getenv(proxy_env);
2941 if(prox && *prox) { /* don't count "" strings */
2942 proxy = prox; /* use this */
2944 else {
2945 proxy = curl_getenv("all_proxy"); /* default proxy to use */
2946 if(!proxy)
2947 proxy=curl_getenv("ALL_PROXY");
2950 if(proxy && *proxy) {
2951 long bits = conn->protocol & (PROT_HTTPS|PROT_SSL|PROT_MISSING);
2952 /* force this to become HTTP */
2953 conn->protocol = PROT_HTTP | bits;
2955 proxy_alloc=TRUE; /* this needs to be freed later */
2956 conn->bits.httpproxy = TRUE;
2958 } /* if (!nope) - it wasn't specified non-proxy */
2959 } /* NO_PROXY wasn't specified or '*' */
2960 if(no_proxy)
2961 free(no_proxy);
2962 } /* if not using proxy */
2963 #endif /* CURL_DISABLE_HTTP */
2965 /*************************************************************
2966 * No protocol part in URL was used, add it!
2967 *************************************************************/
2968 if(conn->protocol&PROT_MISSING) {
2969 /* We're guessing prefixes here and if we're told to use a proxy or if
2970 we're gonna follow a Location: later or... then we need the protocol
2971 part added so that we have a valid URL. */
2972 char *reurl;
2974 reurl = aprintf("%s://%s", conn->protostr, data->change.url);
2976 if(!reurl)
2977 return CURLE_OUT_OF_MEMORY;
2979 data->change.url = reurl;
2980 data->change.url_alloc = TRUE; /* free this later */
2981 conn->protocol &= ~PROT_MISSING; /* switch that one off again */
2984 #ifndef CURL_DISABLE_HTTP
2985 /************************************************************
2986 * RESUME on a HTTP page is a tricky business. First, let's just check that
2987 * 'range' isn't used, then set the range parameter and leave the resume as
2988 * it is to inform about this situation for later use. We will then
2989 * "attempt" to resume, and if we're talking to a HTTP/1.1 (or later)
2990 * server, we will get the document resumed. If we talk to a HTTP/1.0
2991 * server, we just fail since we can't rewind the file writing from within
2992 * this function.
2993 ***********************************************************/
2994 if(data->reqdata.resume_from) {
2995 if(!data->reqdata.use_range) {
2996 /* if it already was in use, we just skip this */
2997 data->reqdata.range = aprintf("%" FORMAT_OFF_T "-", data->reqdata.resume_from);
2998 if(!data->reqdata.range)
2999 return CURLE_OUT_OF_MEMORY;
3000 data->reqdata.rangestringalloc = TRUE; /* mark as allocated */
3001 data->reqdata.use_range = 1; /* switch on range usage */
3004 #endif
3005 /*************************************************************
3006 * Setup internals depending on protocol
3007 *************************************************************/
3009 conn->socktype = SOCK_STREAM; /* most of them are TCP streams */
3011 if (strequal(conn->protostr, "HTTP")) {
3012 #ifndef CURL_DISABLE_HTTP
3013 conn->port = PORT_HTTP;
3014 conn->remote_port = PORT_HTTP;
3015 conn->protocol |= PROT_HTTP;
3016 conn->curl_do = Curl_http;
3017 conn->curl_do_more = (Curl_do_more_func)ZERO_NULL;
3018 conn->curl_done = Curl_http_done;
3019 conn->curl_connect = Curl_http_connect;
3020 #else
3021 failf(data, LIBCURL_NAME
3022 " was built with HTTP disabled, http: not supported!");
3023 return CURLE_UNSUPPORTED_PROTOCOL;
3024 #endif
3026 else if (strequal(conn->protostr, "HTTPS")) {
3027 #if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)
3029 conn->port = PORT_HTTPS;
3030 conn->remote_port = PORT_HTTPS;
3031 conn->protocol |= PROT_HTTP|PROT_HTTPS|PROT_SSL;
3033 conn->curl_do = Curl_http;
3034 conn->curl_do_more = (Curl_do_more_func)ZERO_NULL;
3035 conn->curl_done = Curl_http_done;
3036 conn->curl_connect = Curl_http_connect;
3037 conn->curl_connecting = Curl_https_connecting;
3038 conn->curl_proto_getsock = Curl_https_getsock;
3040 #else /* USE_SSL */
3041 failf(data, LIBCURL_NAME
3042 " was built with SSL disabled, https: not supported!");
3043 return CURLE_UNSUPPORTED_PROTOCOL;
3044 #endif /* !USE_SSL */
3046 else if(strequal(conn->protostr, "FTP") ||
3047 strequal(conn->protostr, "FTPS")) {
3049 #ifndef CURL_DISABLE_FTP
3050 char *type;
3051 int port = PORT_FTP;
3053 if(strequal(conn->protostr, "FTPS")) {
3054 #ifdef USE_SSL
3055 conn->protocol |= PROT_FTPS|PROT_SSL;
3056 conn->ssl[SECONDARYSOCKET].use = TRUE; /* send data securely */
3057 port = PORT_FTPS;
3058 #else
3059 failf(data, LIBCURL_NAME
3060 " was built with SSL disabled, ftps: not supported!");
3061 return CURLE_UNSUPPORTED_PROTOCOL;
3062 #endif /* !USE_SSL */
3065 conn->port = port;
3066 conn->remote_port = (unsigned short)port;
3067 conn->protocol |= PROT_FTP;
3069 if(proxy && *proxy && !data->set.tunnel_thru_httpproxy) {
3070 /* Unless we have asked to tunnel ftp operations through the proxy, we
3071 switch and use HTTP operations only */
3072 #ifndef CURL_DISABLE_HTTP
3073 conn->curl_do = Curl_http;
3074 conn->curl_done = Curl_http_done;
3075 conn->protocol = PROT_HTTP; /* switch to HTTP */
3076 #else
3077 failf(data, "FTP over http proxy requires HTTP support built-in!");
3078 return CURLE_UNSUPPORTED_PROTOCOL;
3079 #endif
3081 else {
3082 conn->curl_do = Curl_ftp;
3083 conn->curl_do_more = Curl_ftp_nextconnect;
3084 conn->curl_done = Curl_ftp_done;
3085 conn->curl_connect = Curl_ftp_connect;
3086 conn->curl_connecting = Curl_ftp_multi_statemach;
3087 conn->curl_doing = Curl_ftp_doing;
3088 conn->curl_proto_getsock = Curl_ftp_getsock;
3089 conn->curl_doing_getsock = Curl_ftp_getsock;
3090 conn->curl_disconnect = Curl_ftp_disconnect;
3093 data->reqdata.path++; /* don't include the initial slash */
3095 /* FTP URLs support an extension like ";type=<typecode>" that
3096 * we'll try to get now! */
3097 type=strstr(data->reqdata.path, ";type=");
3098 if(!type) {
3099 type=strstr(conn->host.rawalloc, ";type=");
3101 if(type) {
3102 char command;
3103 *type=0; /* it was in the middle of the hostname */
3104 command = (char)toupper((int)type[6]);
3105 switch(command) {
3106 case 'A': /* ASCII mode */
3107 data->set.prefer_ascii = TRUE;
3108 break;
3109 case 'D': /* directory mode */
3110 data->set.ftp_list_only = TRUE;
3111 break;
3112 case 'I': /* binary mode */
3113 default:
3114 /* switch off ASCII */
3115 data->set.prefer_ascii = FALSE;
3116 break;
3119 #else /* CURL_DISABLE_FTP */
3120 failf(data, LIBCURL_NAME
3121 " was built with FTP disabled, ftp/ftps: not supported!");
3122 return CURLE_UNSUPPORTED_PROTOCOL;
3123 #endif
3125 else if(strequal(conn->protostr, "TELNET")) {
3126 #ifndef CURL_DISABLE_TELNET
3127 /* telnet testing factory */
3128 conn->protocol |= PROT_TELNET;
3130 conn->port = PORT_TELNET;
3131 conn->remote_port = PORT_TELNET;
3132 conn->curl_do = Curl_telnet;
3133 conn->curl_done = Curl_telnet_done;
3134 #else
3135 failf(data, LIBCURL_NAME
3136 " was built with TELNET disabled!");
3137 #endif
3139 else if (strequal(conn->protostr, "DICT")) {
3140 #ifndef CURL_DISABLE_DICT
3141 conn->protocol |= PROT_DICT;
3142 conn->port = PORT_DICT;
3143 conn->remote_port = PORT_DICT;
3144 conn->curl_do = Curl_dict;
3145 /* no DICT-specific done */
3146 conn->curl_done = (Curl_done_func)ZERO_NULL;
3147 #else
3148 failf(data, LIBCURL_NAME
3149 " was built with DICT disabled!");
3150 #endif
3152 else if (strequal(conn->protostr, "LDAP")) {
3153 #ifndef CURL_DISABLE_LDAP
3154 conn->protocol |= PROT_LDAP;
3155 conn->port = PORT_LDAP;
3156 conn->remote_port = PORT_LDAP;
3157 conn->curl_do = Curl_ldap;
3158 /* no LDAP-specific done */
3159 conn->curl_done = (Curl_done_func)ZERO_NULL;
3160 #else
3161 failf(data, LIBCURL_NAME
3162 " was built with LDAP disabled!");
3163 #endif
3165 else if (strequal(conn->protostr, "FILE")) {
3166 #ifndef CURL_DISABLE_FILE
3167 conn->protocol |= PROT_FILE;
3169 conn->curl_do = Curl_file;
3170 conn->curl_done = Curl_file_done;
3172 /* anyway, this is supposed to be the connect function so we better
3173 at least check that the file is present here! */
3174 result = Curl_file_connect(conn);
3176 /* Setup a "faked" transfer that'll do nothing */
3177 if(CURLE_OK == result) {
3178 conn->data = data;
3179 conn->bits.tcpconnect = TRUE; /* we are "connected */
3180 ConnectionStore(data, conn);
3182 result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */
3183 -1, NULL); /* no upload */
3186 return result;
3187 #else
3188 failf(data, LIBCURL_NAME
3189 " was built with FILE disabled!");
3190 #endif
3192 else if (strequal(conn->protostr, "TFTP")) {
3193 #ifndef CURL_DISABLE_TFTP
3194 char *type;
3195 conn->socktype = SOCK_DGRAM; /* UDP datagram based */
3196 conn->protocol |= PROT_TFTP;
3197 conn->port = PORT_TFTP;
3198 conn->remote_port = PORT_TFTP;
3199 conn->curl_connect = Curl_tftp_connect;
3200 conn->curl_do = Curl_tftp;
3201 conn->curl_done = Curl_tftp_done;
3202 /* TFTP URLs support an extension like ";mode=<typecode>" that
3203 * we'll try to get now! */
3204 type=strstr(data->reqdata.path, ";mode=");
3205 if(!type) {
3206 type=strstr(conn->host.rawalloc, ";mode=");
3208 if(type) {
3209 char command;
3210 *type=0; /* it was in the middle of the hostname */
3211 command = (char)toupper((int)type[6]);
3212 switch(command) {
3213 case 'A': /* ASCII mode */
3214 case 'N': /* NETASCII mode */
3215 data->set.prefer_ascii = TRUE;
3216 break;
3217 case 'O': /* octet mode */
3218 case 'I': /* binary mode */
3219 default:
3220 /* switch off ASCII */
3221 data->set.prefer_ascii = FALSE;
3222 break;
3225 #else
3226 failf(data, LIBCURL_NAME
3227 " was built with TFTP disabled!");
3228 #endif
3230 else if (strequal(conn->protostr, "SCP")) {
3231 #ifdef USE_LIBSSH2
3232 conn->port = PORT_SSH;
3233 conn->remote_port = PORT_SSH;
3234 conn->protocol = PROT_SCP;
3235 conn->curl_connect = Curl_ssh_connect; /* ssh_connect? */
3236 conn->curl_do = Curl_scp_do;
3237 conn->curl_done = Curl_scp_done;
3238 conn->curl_do_more = (Curl_do_more_func)ZERO_NULL;
3239 #else
3240 failf(data, LIBCURL_NAME
3241 " was built without LIBSSH2, scp: not supported!");
3242 return CURLE_UNSUPPORTED_PROTOCOL;
3243 #endif
3245 else if (strequal(conn->protostr, "SFTP")) {
3246 #ifdef USE_LIBSSH2
3247 conn->port = PORT_SSH;
3248 conn->remote_port = PORT_SSH;
3249 conn->protocol = PROT_SFTP;
3250 conn->curl_connect = Curl_ssh_connect; /* ssh_connect? */
3251 conn->curl_do = Curl_sftp_do;
3252 conn->curl_done = Curl_sftp_done;
3253 conn->curl_do_more = (Curl_do_more_func)NULL;
3254 #else
3255 failf(data, LIBCURL_NAME
3256 " was built without LIBSSH2, scp: not supported!");
3257 return CURLE_UNSUPPORTED_PROTOCOL;
3258 #endif
3260 else {
3261 /* We fell through all checks and thus we don't support the specified
3262 protocol */
3263 failf(data, "Unsupported protocol: %s", conn->protostr);
3264 return CURLE_UNSUPPORTED_PROTOCOL;
3267 if(proxy && *proxy) {
3268 /* If this is supposed to use a proxy, we need to figure out the proxy
3269 host name name, so that we can re-use an existing connection
3270 that may exist registered to the same proxy host. */
3272 char *prox_portno;
3273 char *endofprot;
3275 /* We need to make a duplicate of the proxy so that we can modify the
3276 string safely. If 'proxy_alloc' is TRUE, the string is already
3277 allocated and we can treat it as duplicated. */
3278 char *proxydup=proxy_alloc?proxy:strdup(proxy);
3280 /* We use 'proxyptr' to point to the proxy name from now on... */
3281 char *proxyptr=proxydup;
3282 char *portptr;
3283 char *atsign;
3285 if(NULL == proxydup) {
3286 failf(data, "memory shortage");
3287 return CURLE_OUT_OF_MEMORY;
3290 /* We do the proxy host string parsing here. We want the host name and the
3291 * port name. Accept a protocol:// prefix, even though it should just be
3292 * ignored.
3295 /* Skip the protocol part if present */
3296 endofprot=strstr(proxyptr, "://");
3297 if(endofprot)
3298 proxyptr = endofprot+3;
3300 /* Is there a username and password given in this proxy url? */
3301 atsign = strchr(proxyptr, '@');
3302 if(atsign) {
3303 char proxyuser[MAX_CURL_USER_LENGTH];
3304 char proxypasswd[MAX_CURL_PASSWORD_LENGTH];
3305 proxypasswd[0] = 0;
3307 if(1 <= sscanf(proxyptr,
3308 "%" MAX_CURL_USER_LENGTH_TXT"[^:]:"
3309 "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]",
3310 proxyuser, proxypasswd)) {
3311 CURLcode res = CURLE_OK;
3313 /* found user and password, rip them out. note that we are
3314 unescaping them, as there is otherwise no way to have a
3315 username or password with reserved characters like ':' in
3316 them. */
3317 Curl_safefree(conn->proxyuser);
3318 conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
3320 if(!conn->proxyuser)
3321 res = CURLE_OUT_OF_MEMORY;
3322 else {
3323 Curl_safefree(conn->proxypasswd);
3324 conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL);
3326 if(!conn->proxypasswd)
3327 res = CURLE_OUT_OF_MEMORY;
3330 if(CURLE_OK == res) {
3331 conn->bits.proxy_user_passwd = TRUE; /* enable it */
3332 atsign = strdup(atsign+1); /* the right side of the @-letter */
3334 if(atsign) {
3335 free(proxydup); /* free the former proxy string */
3336 proxydup = proxyptr = atsign; /* now use this instead */
3338 else
3339 res = CURLE_OUT_OF_MEMORY;
3342 if(res) {
3343 free(proxydup); /* free the allocated proxy string */
3344 return res;
3349 /* start scanning for port number at this point */
3350 portptr = proxyptr;
3352 /* detect and extract RFC2732-style IPv6-addresses */
3353 if(*proxyptr == '[') {
3354 char *ptr = ++proxyptr; /* advance beyond the initial bracket */
3355 while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':')))
3356 ptr++;
3357 if(*ptr == ']') {
3358 /* yeps, it ended nicely with a bracket as well */
3359 *ptr = 0;
3360 portptr = ptr+1;
3362 /* Note that if this didn't end with a bracket, we still advanced the
3363 * proxyptr first, but I can't see anything wrong with that as no host
3364 * name nor a numeric can legally start with a bracket.
3368 /* Get port number off proxy.server.com:1080 */
3369 prox_portno = strchr(portptr, ':');
3370 if (prox_portno) {
3371 *prox_portno = 0x0; /* cut off number from host name */
3372 prox_portno ++;
3373 /* now set the local port number */
3374 conn->port = atoi(prox_portno);
3376 else if(data->set.proxyport) {
3377 /* None given in the proxy string, then get the default one if it is
3378 given */
3379 conn->port = data->set.proxyport;
3382 /* now, clone the cleaned proxy host name */
3383 conn->proxy.rawalloc = strdup(proxyptr);
3384 conn->proxy.name = conn->proxy.rawalloc;
3386 free(proxydup); /* free the duplicate pointer and not the modified */
3387 proxy = NULL; /* this may have just been freed */
3388 if(!conn->proxy.rawalloc)
3389 return CURLE_OUT_OF_MEMORY;
3392 /*************************************************************
3393 * If the protocol is using SSL and HTTP proxy is used, we set
3394 * the tunnel_proxy bit.
3395 *************************************************************/
3396 if((conn->protocol&PROT_SSL) && conn->bits.httpproxy)
3397 conn->bits.tunnel_proxy = TRUE;
3399 /*************************************************************
3400 * Take care of user and password authentication stuff
3401 *************************************************************/
3404 * Inputs: data->set.userpwd (CURLOPT_USERPWD)
3405 * data->set.fpasswd (CURLOPT_PASSWDFUNCTION)
3406 * data->set.use_netrc (CURLOPT_NETRC)
3407 * conn->host.name
3408 * netrc file
3409 * hard-coded defaults
3411 * Outputs: (almost :- all currently undefined)
3412 * conn->bits.user_passwd - non-zero if non-default passwords exist
3413 * conn->user - non-zero length if defined
3414 * conn->passwd - ditto
3415 * conn->host.name - remove user name and password
3418 /* At this point, we're hoping all the other special cases have
3419 * been taken care of, so conn->host.name is at most
3420 * [user[:password]]@]hostname
3422 * We need somewhere to put the embedded details, so do that first.
3425 user[0] =0; /* to make everything well-defined */
3426 passwd[0]=0;
3428 if (conn->protocol & (PROT_FTP|PROT_HTTP|PROT_SCP|PROT_SFTP)) {
3429 /* This is a FTP, HTTP, SCP or SFTP URL, we will now try to extract the
3430 * possible user+password pair in a string like:
3431 * ftp://user:password@ftp.my.site:8021/README */
3432 char *ptr=strchr(conn->host.name, '@');
3433 char *userpass = conn->host.name;
3434 if(ptr != NULL) {
3435 /* there's a user+password given here, to the left of the @ */
3437 conn->host.name = ++ptr;
3439 /* So the hostname is sane. Only bother interpreting the
3440 * results if we could care. It could still be wasted
3441 * work because it might be overtaken by the programmatically
3442 * set user/passwd, but doing that first adds more cases here :-(
3445 if (data->set.use_netrc != CURL_NETRC_REQUIRED) {
3446 /* We could use the one in the URL */
3448 conn->bits.user_passwd = 1; /* enable user+password */
3450 if(*userpass != ':') {
3451 /* the name is given, get user+password */
3452 sscanf(userpass, "%" MAX_CURL_USER_LENGTH_TXT "[^:@]:"
3453 "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]",
3454 user, passwd);
3456 else
3457 /* no name given, get the password only */
3458 sscanf(userpass, ":%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", passwd);
3460 if(user[0]) {
3461 char *newname=curl_easy_unescape(data, user, 0, NULL);
3462 if(!newname)
3463 return CURLE_OUT_OF_MEMORY;
3464 if(strlen(newname) < sizeof(user))
3465 strcpy(user, newname);
3467 /* if the new name is longer than accepted, then just use
3468 the unconverted name, it'll be wrong but what the heck */
3469 free(newname);
3471 if (passwd[0]) {
3472 /* we have a password found in the URL, decode it! */
3473 char *newpasswd=curl_easy_unescape(data, passwd, 0, NULL);
3474 if(!newpasswd)
3475 return CURLE_OUT_OF_MEMORY;
3476 if(strlen(newpasswd) < sizeof(passwd))
3477 strcpy(passwd, newpasswd);
3479 free(newpasswd);
3485 /*************************************************************
3486 * Figure out the remote port number
3488 * No matter if we use a proxy or not, we have to figure out the remote
3489 * port number of various reasons.
3491 * To be able to detect port number flawlessly, we must not confuse them
3492 * IPv6-specified addresses in the [0::1] style. (RFC2732)
3494 * The conn->host.name is currently [user:passwd@]host[:port] where host
3495 * could be a hostname, IPv4 address or IPv6 address.
3496 *************************************************************/
3497 if((1 == sscanf(conn->host.name, "[%*39[0-9a-fA-F:.]%c", &endbracket)) &&
3498 (']' == endbracket)) {
3499 /* this is a RFC2732-style specified IP-address */
3500 conn->bits.ipv6_ip = TRUE;
3502 conn->host.name++; /* pass the starting bracket */
3503 tmp = strchr(conn->host.name, ']');
3504 *tmp = 0; /* zero terminate */
3505 tmp++; /* pass the ending bracket */
3506 if(':' != *tmp)
3507 tmp = NULL; /* no port number available */
3509 else
3510 tmp = strrchr(conn->host.name, ':');
3512 if(data->set.use_port && data->state.allow_port) {
3513 /* if set, we use this and ignore the port possibly given in the URL */
3514 conn->remote_port = (unsigned short)data->set.use_port;
3515 if(tmp)
3516 *tmp = '\0'; /* cut off the name there anyway - if there was a port
3517 number - since the port number is to be ignored! */
3518 if(conn->bits.httpproxy) {
3519 /* we need to create new URL with the new port number */
3520 char *url;
3522 url = aprintf("http://%s:%d%s", conn->host.name, conn->remote_port,
3523 data->reqdata.path);
3524 if(!url)
3525 return CURLE_OUT_OF_MEMORY;
3527 if(data->change.url_alloc)
3528 free(data->change.url);
3530 data->change.url = url;
3531 data->change.url_alloc = TRUE;
3534 else if (tmp) {
3535 /* no CURLOPT_PORT given, extract the one from the URL */
3537 char *rest;
3538 unsigned long port;
3540 port=strtoul(tmp+1, &rest, 10); /* Port number must be decimal */
3542 if (rest != (tmp+1) && *rest == '\0') {
3543 /* The colon really did have only digits after it,
3544 * so it is either a port number or a mistake */
3546 if (port > 0xffff) { /* Single unix standard says port numbers are
3547 * 16 bits long */
3548 failf(data, "Port number too large: %lu", port);
3549 return CURLE_URL_MALFORMAT;
3552 *tmp = '\0'; /* cut off the name there */
3553 conn->remote_port = (unsigned short)port;
3557 /* Programmatically set password:
3558 * - always applies, if available
3559 * - takes precedence over the values we just set above
3560 * so scribble it over the top.
3561 * User-supplied passwords are assumed not to need unescaping.
3563 * user_password is set in "inherit initial knowledge' above,
3564 * so it doesn't have to be set in this block
3566 if (data->set.userpwd != NULL) {
3567 /* the name is given, get user+password */
3568 sscanf(data->set.userpwd,
3569 "%" MAX_CURL_USER_LENGTH_TXT "[^:]:"
3570 "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]",
3571 user, passwd);
3574 conn->bits.netrc = FALSE;
3575 if (data->set.use_netrc != CURL_NETRC_IGNORED) {
3576 if(Curl_parsenetrc(conn->host.name,
3577 user, passwd,
3578 data->set.netrc_file)) {
3579 infof(data, "Couldn't find host %s in the " DOT_CHAR
3580 "netrc file, using defaults\n",
3581 conn->host.name);
3583 else {
3584 /* set bits.netrc TRUE to remember that we got the name from a .netrc
3585 file, so that it is safe to use even if we followed a Location: to a
3586 different host or similar. */
3587 conn->bits.netrc = TRUE;
3589 conn->bits.user_passwd = 1; /* enable user+password */
3593 /* If our protocol needs a password and we have none, use the defaults */
3594 if ( (conn->protocol & PROT_FTP) &&
3595 !conn->bits.user_passwd) {
3597 conn->user = strdup(CURL_DEFAULT_USER);
3598 conn->passwd = strdup(CURL_DEFAULT_PASSWORD);
3599 /* This is the default password, so DON'T set conn->bits.user_passwd */
3601 else {
3602 /* store user + password, zero-length if not set */
3603 conn->user = strdup(user);
3604 conn->passwd = strdup(passwd);
3606 if(!conn->user || !conn->passwd)
3607 return CURLE_OUT_OF_MEMORY;
3609 /*************************************************************
3610 * Check the current list of connections to see if we can
3611 * re-use an already existing one or if we have to create a
3612 * new one.
3613 *************************************************************/
3615 /* get a cloned copy of the SSL config situation stored in the
3616 connection struct */
3617 if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config))
3618 return CURLE_OUT_OF_MEMORY;
3620 /* reuse_fresh is TRUE if we are told to use a new connection by force, but
3621 we only acknowledge this option if this is not a re-used connection
3622 already (which happens due to follow-location or during a HTTP
3623 authentication phase). */
3624 if(data->set.reuse_fresh && !data->state.this_is_a_follow)
3625 reuse = FALSE;
3626 else
3627 reuse = ConnectionExists(data, conn, &conn_temp);
3629 if(reuse) {
3631 * We already have a connection for this, we got the former connection
3632 * in the conn_temp variable and thus we need to cleanup the one we
3633 * just allocated before we can move along and use the previously
3634 * existing one.
3636 struct connectdata *old_conn = conn;
3638 if(old_conn->proxy.rawalloc)
3639 free(old_conn->proxy.rawalloc);
3641 /* free the SSL config struct from this connection struct as this was
3642 allocated in vain and is targeted for destruction */
3643 Curl_free_ssl_config(&conn->ssl_config);
3645 conn = conn_temp; /* use this connection from now on */
3647 conn->data = old_conn->data;
3649 /* get the user+password information from the old_conn struct since it may
3650 * be new for this request even when we re-use an existing connection */
3651 conn->bits.user_passwd = old_conn->bits.user_passwd;
3652 if (conn->bits.user_passwd) {
3653 /* use the new user namd and password though */
3654 Curl_safefree(conn->user);
3655 Curl_safefree(conn->passwd);
3656 conn->user = old_conn->user;
3657 conn->passwd = old_conn->passwd;
3658 old_conn->user = NULL;
3659 old_conn->passwd = NULL;
3662 conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd;
3663 if (conn->bits.proxy_user_passwd) {
3664 /* use the new proxy user name and proxy password though */
3665 Curl_safefree(conn->proxyuser);
3666 Curl_safefree(conn->proxypasswd);
3667 conn->proxyuser = old_conn->proxyuser;
3668 conn->proxypasswd = old_conn->proxypasswd;
3669 old_conn->proxyuser = NULL;
3670 old_conn->proxypasswd = NULL;
3673 /* host can change, when doing keepalive with a proxy ! */
3674 if (conn->bits.httpproxy) {
3675 free(conn->host.rawalloc);
3676 conn->host=old_conn->host;
3679 /* get the newly set value, not the old one */
3680 conn->bits.no_body = old_conn->bits.no_body;
3682 if (!conn->bits.httpproxy)
3683 free(old_conn->host.rawalloc); /* free the newly allocated name buffer */
3685 /* re-use init */
3686 conn->bits.reuse = TRUE; /* yes, we're re-using here */
3687 conn->bits.chunk = FALSE; /* always assume not chunked unless told
3688 otherwise */
3690 Curl_safefree(old_conn->user);
3691 Curl_safefree(old_conn->passwd);
3692 Curl_safefree(old_conn->proxyuser);
3693 Curl_safefree(old_conn->proxypasswd);
3694 Curl_llist_destroy(old_conn->send_pipe, NULL);
3695 Curl_llist_destroy(old_conn->recv_pipe, NULL);
3697 free(old_conn); /* we don't need this anymore */
3700 * If we're doing a resumed transfer, we need to setup our stuff
3701 * properly.
3703 data->reqdata.resume_from = data->set.set_resume_from;
3704 if (data->reqdata.resume_from) {
3705 if (data->reqdata.rangestringalloc == TRUE)
3706 free(data->reqdata.range);
3707 data->reqdata.range = aprintf("%" FORMAT_OFF_T "-",
3708 data->reqdata.resume_from);
3709 if(!data->reqdata.range)
3710 return CURLE_OUT_OF_MEMORY;
3712 /* tell ourselves to fetch this range */
3713 data->reqdata.use_range = TRUE; /* enable range download */
3714 data->reqdata.rangestringalloc = TRUE; /* mark range string allocated */
3716 else if (data->set.set_range) {
3717 /* There is a range, but is not a resume, useful for random ftp access */
3718 data->reqdata.range = strdup(data->set.set_range);
3719 if(!data->reqdata.range)
3720 return CURLE_OUT_OF_MEMORY;
3721 data->reqdata.rangestringalloc = TRUE; /* mark range string allocated */
3722 data->reqdata.use_range = TRUE; /* enable range download */
3724 else
3725 data->reqdata.use_range = FALSE; /* disable range download */
3727 *in_connect = conn; /* return this instead! */
3729 infof(data, "Re-using existing connection! (#%ld) with host %s\n",
3730 conn->connectindex,
3731 conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname);
3733 else {
3735 * This is a brand new connection, so let's store it in the connection
3736 * cache of ours!
3738 ConnectionStore(data, conn);
3741 /* Continue connectdata initialization here. */
3745 * Inherit the proper values from the urldata struct AFTER we have arranged
3746 * the persistent connection stuff */
3747 conn->fread = data->set.fread;
3748 conn->fread_in = data->set.in;
3750 if ((conn->protocol&PROT_HTTP) &&
3751 data->set.upload &&
3752 (data->set.infilesize == -1) &&
3753 (data->set.httpversion != CURL_HTTP_VERSION_1_0)) {
3754 /* HTTP, upload, unknown file size and not HTTP 1.0 */
3755 conn->bits.upload_chunky = TRUE;
3757 else {
3758 /* else, no chunky upload */
3759 conn->bits.upload_chunky = FALSE;
3762 #ifndef USE_ARES
3763 /*************************************************************
3764 * Set timeout if that is being used, and we're not using an asynchronous
3765 * name resolve.
3766 *************************************************************/
3767 if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) {
3768 /*************************************************************
3769 * Set signal handler to catch SIGALRM
3770 * Store the old value to be able to set it back later!
3771 *************************************************************/
3773 #ifdef SIGALRM
3774 #ifdef HAVE_ALARM
3775 long shortest;
3776 #endif
3777 #ifdef HAVE_SIGACTION
3778 struct sigaction sigact;
3779 sigaction(SIGALRM, NULL, &sigact);
3780 keep_sigact = sigact;
3781 keep_copysig = TRUE; /* yes, we have a copy */
3782 sigact.sa_handler = alarmfunc;
3783 #ifdef SA_RESTART
3784 /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */
3785 sigact.sa_flags &= ~SA_RESTART;
3786 #endif
3787 /* now set the new struct */
3788 sigaction(SIGALRM, &sigact, NULL);
3789 #else /* HAVE_SIGACTION */
3790 /* no sigaction(), revert to the much lamer signal() */
3791 #ifdef HAVE_SIGNAL
3792 keep_sigact = signal(SIGALRM, alarmfunc);
3793 #endif
3794 #endif /* HAVE_SIGACTION */
3796 /* We set the timeout on the name resolving phase first, separately from
3797 * the download/upload part to allow a maximum time on everything. This is
3798 * a signal-based timeout, why it won't work and shouldn't be used in
3799 * multi-threaded environments. */
3801 #ifdef HAVE_ALARM
3802 shortest = data->set.timeout; /* default to this timeout value */
3803 if(shortest && data->set.connecttimeout &&
3804 (data->set.connecttimeout < shortest))
3805 /* if both are set, pick the shortest */
3806 shortest = data->set.connecttimeout;
3807 else if(!shortest)
3808 /* if timeout is not set, use the connect timeout */
3809 shortest = data->set.connecttimeout;
3811 /* alarm() makes a signal get sent when the timeout fires off, and that
3812 will abort system calls */
3813 prev_alarm = alarm((unsigned int) shortest);
3814 /* We can expect the conn->created time to be "now", as that was just
3815 recently set in the beginning of this function and nothing slow
3816 has been done since then until now. */
3817 #endif
3818 #endif /* SIGALRM */
3820 #endif /* USE_ARES */
3822 /*************************************************************
3823 * Resolve the name of the server or proxy
3824 *************************************************************/
3825 if(conn->bits.reuse) {
3826 /* re-used connection, no resolving is necessary */
3827 hostaddr = NULL;
3828 /* we'll need to clear conn->dns_entry later in Curl_disconnect() */
3830 if (conn->bits.httpproxy)
3831 fix_hostname(data, conn, &conn->host);
3833 else {
3834 /* this is a fresh connect */
3836 /* set a pointer to the hostname we display */
3837 fix_hostname(data, conn, &conn->host);
3839 if(!conn->proxy.name || !*conn->proxy.name) {
3840 /* If not connecting via a proxy, extract the port from the URL, if it is
3841 * there, thus overriding any defaults that might have been set above. */
3842 conn->port = conn->remote_port; /* it is the same port */
3844 /* Resolve target host right on */
3845 rc = Curl_resolv(conn, conn->host.name, (int)conn->port, &hostaddr);
3846 if(rc == CURLRESOLV_PENDING)
3847 *async = TRUE;
3849 else if(!hostaddr) {
3850 failf(data, "Couldn't resolve host '%s'", conn->host.dispname);
3851 result = CURLE_COULDNT_RESOLVE_HOST;
3852 /* don't return yet, we need to clean up the timeout first */
3855 else {
3856 /* This is a proxy that hasn't been resolved yet. */
3858 /* IDN-fix the proxy name */
3859 fix_hostname(data, conn, &conn->proxy);
3861 /* resolve proxy */
3862 rc = Curl_resolv(conn, conn->proxy.name, (int)conn->port, &hostaddr);
3864 if(rc == CURLRESOLV_PENDING)
3865 *async = TRUE;
3867 else if(!hostaddr) {
3868 failf(data, "Couldn't resolve proxy '%s'", conn->proxy.dispname);
3869 result = CURLE_COULDNT_RESOLVE_PROXY;
3870 /* don't return yet, we need to clean up the timeout first */
3874 *addr = hostaddr;
3876 #if defined(HAVE_ALARM) && defined(SIGALRM) && !defined(USE_ARES)
3877 if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) {
3878 #ifdef HAVE_SIGACTION
3879 if(keep_copysig) {
3880 /* we got a struct as it looked before, now put that one back nice
3881 and clean */
3882 sigaction(SIGALRM, &keep_sigact, NULL); /* put it back */
3884 #else
3885 #ifdef HAVE_SIGNAL
3886 /* restore the previous SIGALRM handler */
3887 signal(SIGALRM, keep_sigact);
3888 #endif
3889 #endif /* HAVE_SIGACTION */
3891 /* switch back the alarm() to either zero or to what it was before minus
3892 the time we spent until now! */
3893 if(prev_alarm) {
3894 /* there was an alarm() set before us, now put it back */
3895 unsigned long elapsed_ms = Curl_tvdiff(Curl_tvnow(), conn->created);
3896 unsigned long alarm_set;
3898 /* the alarm period is counted in even number of seconds */
3899 alarm_set = prev_alarm - elapsed_ms/1000;
3901 if(!alarm_set ||
3902 ((alarm_set >= 0x80000000) && (prev_alarm < 0x80000000)) ) {
3903 /* if the alarm time-left reached zero or turned "negative" (counted
3904 with unsigned values), we should fire off a SIGALRM here, but we
3905 won't, and zero would be to switch it off so we never set it to
3906 less than 1! */
3907 alarm(1);
3908 result = CURLE_OPERATION_TIMEOUTED;
3909 failf(data, "Previous alarm fired off!");
3911 else
3912 alarm((unsigned int)alarm_set);
3914 else
3915 alarm(0); /* just shut it off */
3917 #endif
3919 return result;
3922 /* SetupConnection() is called after the name resolve initiated in
3923 * CreateConnection() is all done.
3925 * NOTE: the argument 'hostaddr' is NULL when this function is called for a
3926 * re-used connection.
3928 * conn->data MUST already have been setup fine (in CreateConnection)
3931 static CURLcode SetupConnection(struct connectdata *conn,
3932 struct Curl_dns_entry *hostaddr,
3933 bool *protocol_done)
3935 CURLcode result=CURLE_OK;
3936 struct SessionHandle *data = conn->data;
3938 Curl_pgrsTime(data, TIMER_NAMELOOKUP);
3940 if(conn->protocol & PROT_FILE) {
3941 /* There's nothing in this function to setup if we're only doing
3942 a file:// transfer */
3943 *protocol_done = TRUE;
3944 return result;
3946 *protocol_done = FALSE; /* default to not done */
3948 /*************************************************************
3949 * Send user-agent to HTTP proxies even if the target protocol
3950 * isn't HTTP.
3951 *************************************************************/
3952 if((conn->protocol&PROT_HTTP) || conn->bits.httpproxy) {
3953 if(data->set.useragent) {
3954 Curl_safefree(conn->allocptr.uagent);
3955 conn->allocptr.uagent =
3956 aprintf("User-Agent: %s\r\n", data->set.useragent);
3957 if(!conn->allocptr.uagent)
3958 return CURLE_OUT_OF_MEMORY;
3962 conn->headerbytecount = 0;
3964 #ifdef CURL_DO_LINEEND_CONV
3965 data->state.crlf_conversions = 0; /* reset CRLF conversion counter */
3966 #endif /* CURL_DO_LINEEND_CONV */
3968 for(;;) {
3969 /* loop for CURL_SERVER_CLOSED_CONNECTION */
3971 if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
3972 bool connected = FALSE;
3974 /* Connect only if not already connected! */
3975 result = ConnectPlease(data, conn, hostaddr, &connected);
3977 if(connected) {
3978 result = Curl_protocol_connect(conn, protocol_done);
3979 if(CURLE_OK == result)
3980 conn->bits.tcpconnect = TRUE;
3982 else
3983 conn->bits.tcpconnect = FALSE;
3985 /* if the connection was closed by the server while exchanging
3986 authentication informations, retry with the new set
3987 authentication information */
3988 if(conn->bits.proxy_connect_closed) {
3989 /* reset the error buffer */
3990 if (data->set.errorbuffer)
3991 data->set.errorbuffer[0] = '\0';
3992 data->state.errorbuf = FALSE;
3993 continue;
3996 if(CURLE_OK != result)
3997 return result;
3999 else {
4000 Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */
4001 conn->bits.tcpconnect = TRUE;
4002 *protocol_done = TRUE;
4003 if(data->set.verbose)
4004 verboseconnect(conn);
4006 /* Stop the loop now */
4007 break;
4010 conn->now = Curl_tvnow(); /* time this *after* the connect is done, we
4011 set this here perhaps a second time */
4013 #ifdef __EMX__
4014 /* 20000330 mgs
4015 * the check is quite a hack...
4016 * we're calling _fsetmode to fix the problem with fwrite converting newline
4017 * characters (you get mangled text files, and corrupted binary files when
4018 * you download to stdout and redirect it to a file). */
4020 if ((data->set.out)->_handle == NULL) {
4021 _fsetmode(stdout, "b");
4023 #endif
4025 return CURLE_OK;
4028 CURLcode Curl_connect(struct SessionHandle *data,
4029 struct connectdata **in_connect,
4030 bool *asyncp,
4031 bool *protocol_done)
4033 CURLcode code;
4034 struct Curl_dns_entry *dns;
4036 *asyncp = FALSE; /* assume synchronous resolves by default */
4038 /* call the stuff that needs to be called */
4039 code = CreateConnection(data, in_connect, &dns, asyncp);
4041 if(CURLE_OK == code) {
4042 /* no error */
4043 if(dns || !*asyncp)
4044 /* If an address is available it means that we already have the name
4045 resolved, OR it isn't async. if this is a re-used connection 'dns'
4046 will be NULL here. Continue connecting from here */
4047 code = SetupConnection(*in_connect, dns, protocol_done);
4048 /* else
4049 response will be received and treated async wise */
4052 if(CURLE_OK != code) {
4053 /* We're not allowed to return failure with memory left allocated
4054 in the connectdata struct, free those here */
4055 if(*in_connect) {
4056 Curl_disconnect(*in_connect); /* close the connection */
4057 *in_connect = NULL; /* return a NULL */
4060 else {
4061 if ((*in_connect)->is_in_pipeline)
4062 data->state.is_in_pipeline = TRUE;
4065 return code;
4068 /* Call this function after Curl_connect() has returned async=TRUE and
4069 then a successful name resolve has been received.
4071 Note: this function disconnects and frees the conn data in case of
4072 resolve failure */
4073 CURLcode Curl_async_resolved(struct connectdata *conn,
4074 bool *protocol_done)
4076 #if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \
4077 defined(USE_THREADING_GETADDRINFO)
4078 CURLcode code = SetupConnection(conn, conn->async.dns, protocol_done);
4080 if(code)
4081 /* We're not allowed to return failure with memory left allocated
4082 in the connectdata struct, free those here */
4083 Curl_disconnect(conn); /* close the connection */
4085 return code;
4086 #else
4087 (void)conn;
4088 (void)protocol_done;
4089 return CURLE_OK;
4090 #endif
4094 CURLcode Curl_done(struct connectdata **connp,
4095 CURLcode status, bool premature) /* an error if this is called after an
4096 error was detected */
4098 CURLcode result;
4099 struct connectdata *conn = *connp;
4100 struct SessionHandle *data = conn->data;
4102 Curl_expire(data, 0); /* stop timer */
4104 if(conn->bits.done)
4105 return CURLE_OK; /* Curl_done() has already been called */
4107 conn->bits.done = TRUE; /* called just now! */
4109 if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) &&
4110 conn->readchannel_inuse)
4111 conn->readchannel_inuse = FALSE;
4112 if(Curl_removeHandleFromPipeline(data, conn->send_pipe) &&
4113 conn->writechannel_inuse)
4114 conn->writechannel_inuse = FALSE;
4116 /* cleanups done even if the connection is re-used */
4117 if(data->reqdata.rangestringalloc) {
4118 free(data->reqdata.range);
4119 data->reqdata.rangestringalloc = FALSE;
4122 /* Cleanup possible redirect junk */
4123 if(data->reqdata.newurl) {
4124 free(data->reqdata.newurl);
4125 data->reqdata.newurl = NULL;
4128 if(conn->dns_entry) {
4129 Curl_resolv_unlock(data, conn->dns_entry); /* done with this */
4130 conn->dns_entry = NULL;
4133 /* this calls the protocol-specific function pointer previously set */
4134 if(conn->curl_done)
4135 result = conn->curl_done(conn, status, premature);
4136 else
4137 result = CURLE_OK;
4139 Curl_pgrsDone(conn); /* done with the operation */
4141 /* for ares-using, make sure all possible outstanding requests are properly
4142 cancelled before we proceed */
4143 ares_cancel(data->state.areschannel);
4145 /* if data->set.reuse_forbid is TRUE, it means the libcurl client has
4146 forced us to close this no matter what we think.
4148 if conn->bits.close is TRUE, it means that the connection should be
4149 closed in spite of all our efforts to be nice, due to protocol
4150 restrictions in our or the server's end */
4151 if(data->set.reuse_forbid || conn->bits.close) {
4152 CURLcode res2 = Curl_disconnect(conn); /* close the connection */
4154 *connp = NULL; /* to make the caller of this function better detect that
4155 this was actually killed here */
4157 /* If we had an error already, make sure we return that one. But
4158 if we got a new error, return that. */
4159 if(!result && res2)
4160 result = res2;
4162 else {
4163 ConnectionDone(conn); /* the connection is no longer in use */
4165 /* remember the most recently used connection */
4166 data->state.lastconnect = conn->connectindex;
4168 infof(data, "Connection #%ld to host %s left intact\n",
4169 conn->connectindex,
4170 conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname);
4173 return result;
4176 CURLcode Curl_do(struct connectdata **connp, bool *done)
4178 CURLcode result=CURLE_OK;
4179 struct connectdata *conn = *connp;
4180 struct SessionHandle *data = conn->data;
4182 conn->bits.done = FALSE; /* Curl_done() is not called yet */
4183 conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */
4185 if(conn->curl_do) {
4186 /* generic protocol-specific function pointer set in curl_connect() */
4187 result = conn->curl_do(conn, done);
4189 /* This was formerly done in transfer.c, but we better do it here */
4191 if((CURLE_SEND_ERROR == result) && conn->bits.reuse) {
4192 /* This was a re-use of a connection and we got a write error in the
4193 * DO-phase. Then we DISCONNECT this connection and have another attempt
4194 * to CONNECT and then DO again! The retry cannot possibly find another
4195 * connection to re-use, since we only keep one possible connection for
4196 * each. */
4198 infof(data, "Re-used connection seems dead, get a new one\n");
4200 conn->bits.close = TRUE; /* enforce close of this connection */
4201 result = Curl_done(&conn, result, FALSE); /* we are so done with this */
4203 /* conn may no longer be a good pointer */
4206 * According to bug report #1330310. We need to check for
4207 * CURLE_SEND_ERROR here as well. I figure this could happen when the
4208 * request failed on a FTP connection and thus Curl_done() itself tried
4209 * to use the connection (again). Slight Lack of feedback in the report,
4210 * but I don't think this extra check can do much harm.
4212 if((CURLE_OK == result) || (CURLE_SEND_ERROR == result)) {
4213 bool async;
4214 bool protocol_done = TRUE;
4216 /* Now, redo the connect and get a new connection */
4217 result = Curl_connect(data, connp, &async, &protocol_done);
4218 if(CURLE_OK == result) {
4219 /* We have connected or sent away a name resolve query fine */
4221 conn = *connp; /* setup conn to again point to something nice */
4222 if(async) {
4223 /* Now, if async is TRUE here, we need to wait for the name
4224 to resolve */
4225 result = Curl_wait_for_resolv(conn, NULL);
4226 if(result)
4227 return result;
4229 /* Resolved, continue with the connection */
4230 result = Curl_async_resolved(conn, &protocol_done);
4231 if(result)
4232 return result;
4235 /* ... finally back to actually retry the DO phase */
4236 result = conn->curl_do(conn, done);
4241 return result;
4244 CURLcode Curl_do_more(struct connectdata *conn)
4246 CURLcode result=CURLE_OK;
4248 if(conn->curl_do_more)
4249 result = conn->curl_do_more(conn);
4251 return result;