1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2004, 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.350 2004/03/12 08:55:51 bagder Exp $
22 ***************************************************************************/
24 /* -- WIN32 approved -- */
33 #include <sys/types.h>
38 #if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
42 #ifdef HAVE_SYS_SOCKET_H
43 #include <sys/socket.h>
45 #include <netinet/in.h>
51 #ifdef HAVE_ARPA_INET_H
52 #include <arpa/inet.h>
57 #include <sys/ioctl.h>
60 #ifdef HAVE_SYS_PARAM_H
61 #include <sys/param.h>
64 #ifdef HAVE_SYS_SELECT_H
65 #include <sys/select.h>
78 #error "We can't compile without select() support!"
81 #error "We can't compile without socket() support!"
87 #ifdef HAVE_OPENSSL_ENGINE_H
88 #include <openssl/engine.h>
100 #include "progress.h"
102 #include "strequal.h"
106 #include "content_encoding.h"
107 #include "http_digest.h"
108 #include "http_negotiate.h"
110 /* And now for the protocols */
119 //#include <ca-bundle.h>
121 #include <curl/types.h>
123 #if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
124 #include "inet_ntoa_r.h"
127 #define _MPRINTF_REPLACE /* use our functions only */
128 #include <curl/mprintf.h>
131 #include "security.h"
134 /* The last #include file should be: */
136 #include "memdebug.h"
139 /* Local static prototypes */
140 static int ConnectionKillOne(struct SessionHandle *data);
141 static bool ConnectionExists(struct SessionHandle *data,
142 struct connectdata *needle,
143 struct connectdata **usethis);
144 static unsigned int ConnectionStore(struct SessionHandle *data,
145 struct connectdata *conn);
146 static bool safe_strequal(char* str1, char* str2);
149 /* not for Win32, unless it is cygwin
150 not for ares builds */
151 #if !defined(WIN32) || defined(__CYGWIN32__)
154 #define RETSIGTYPE void
156 #ifdef HAVE_SIGSETJMP
157 extern sigjmp_buf curl_jmpenv;
160 RETSIGTYPE alarmfunc(int sig)
162 /* this is for "-ansi -Wall -pedantic" to stop complaining! (rabe) */
164 #ifdef HAVE_SIGSETJMP
165 siglongjmp(curl_jmpenv, 1);
170 #endif /* USE_ARES */
172 void Curl_safefree(void *ptr)
179 * This is the internal function curl_easy_cleanup() calls. This should
180 * cleanup and free all resources associated with this sessionhandle.
182 * NOTE: if we ever add something that attempts to write to a socket or
183 * similar here, we must ignore SIGPIPE first. It is currently only done
184 * when curl_easy_perform() is invoked.
187 CURLcode Curl_close(struct SessionHandle *data)
189 /* Loop through all open connections and kill them one by one */
190 while(-1 != ConnectionKillOne(data));
193 /* Close down all open SSL info and sessions */
194 Curl_SSL_Close_All(data);
197 if(data->change.cookielist) /* clean up list if any */
198 curl_slist_free_all(data->change.cookielist);
200 Curl_safefree(data->state.auth_host);
201 Curl_safefree(data->state.scratch);
203 if(data->change.proxy_alloc)
204 free(data->change.proxy);
206 if(data->change.referer_alloc)
207 free(data->change.referer);
209 if(data->change.url_alloc)
210 free(data->change.url);
212 Curl_safefree(data->state.headerbuff);
214 #ifndef CURL_DISABLE_HTTP
215 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
216 if(data->set.cookiejar) {
217 /* we have a "destination" for all the cookies to get dumped to */
218 if(Curl_cookie_output(data->cookies, data->set.cookiejar))
219 infof(data, "WARNING: failed to save cookies in %s\n",
220 data->set.cookiejar);
223 if( !data->share || (data->cookies != data->share->cookies) ) {
224 Curl_cookie_cleanup(data->cookies);
226 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
229 /* free the connection cache */
230 free(data->state.connects);
232 Curl_safefree(data->info.contenttype);
234 Curl_digest_cleanup(data);
237 /* this destroys the channel and we cannot use it anymore after this */
238 ares_destroy(data->state.areschannel);
241 /* No longer a dirty share, if it exists */
243 data->share->dirty--;
249 CURLcode Curl_open(struct SessionHandle **curl)
251 /* We don't yet support specifying the URL at this point */
252 struct SessionHandle *data;
253 /* Very simple start-up: alloc the struct, init it with zeroes and return */
254 data = (struct SessionHandle *)malloc(sizeof(struct SessionHandle));
256 /* this is a very serious error */
257 return CURLE_OUT_OF_MEMORY;
259 memset(data, 0, sizeof(struct SessionHandle));
262 if(ARES_SUCCESS != ares_init(&data->state.areschannel)) {
264 return CURLE_FAILED_INIT;
266 /* make sure that all other returns from this function should destroy the
267 ares channel before returning error! */
270 /* We do some initial setup here, all those fields that can't be just 0 */
272 data->state.headerbuff=(char*)malloc(HEADERSIZE);
273 if(!data->state.headerbuff) {
274 free(data); /* free the memory again */
275 return CURLE_OUT_OF_MEMORY;
278 data->state.headersize=HEADERSIZE;
280 data->set.out = stdout; /* default output to stdout */
281 data->set.in = stdin; /* default input from stdin */
282 data->set.err = stderr; /* default stderr to stderr */
284 /* use fwrite as default function to store output */
285 data->set.fwrite = (curl_write_callback)fwrite;
287 /* use fread as default function to read input */
288 data->set.fread = (curl_read_callback)fread;
290 data->set.infilesize = -1; /* we don't know any size */
292 data->state.current_speed = -1; /* init to negative == impossible */
294 data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */
295 data->set.ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */
296 data->set.ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */
298 data->set.dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
300 /* make libcurl quiet by default: */
301 data->set.hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */
302 data->progress.flags |= PGRS_HIDE;
304 /* Set the default size of the SSL session ID cache */
305 data->set.ssl.numsessions = 5;
307 data->set.proxyport = 1080;
309 data->set.proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
311 data->set.httpauth = CURLAUTH_BASIC; /* defaults to basic authentication */
312 data->set.proxyauth = CURLAUTH_BASIC; /* defaults to basic authentication */
314 /* create an array with connection data struct pointers */
315 data->state.numconnects = 5; /* hard-coded right now */
316 data->state.connects = (struct connectdata **)
317 malloc(sizeof(struct connectdata *) * data->state.numconnects);
319 if(!data->state.connects) {
320 free(data->state.headerbuff);
322 return CURLE_OUT_OF_MEMORY;
326 * libcurl 7.10 introduces SSL verification *by default*! This needs to be
327 * switched off unless wanted.
329 data->set.ssl.verifypeer = TRUE;
330 data->set.ssl.verifyhost = 2;
331 #ifdef CURL_CA_BUNDLE
332 /* This is our prefered CA cert bundle since install time */
333 data->set.ssl.CAfile = (char *)CURL_CA_BUNDLE;
336 memset(data->state.connects, 0,
337 sizeof(struct connectdata *)*data->state.numconnects);
343 CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
348 va_start(param, option);
351 case CURLOPT_DNS_CACHE_TIMEOUT:
352 data->set.dns_cache_timeout = va_arg(param, int);
354 case CURLOPT_DNS_USE_GLOBAL_CACHE:
356 int use_cache = va_arg(param, int);
358 Curl_global_host_cache_init();
361 data->set.global_dns_cache = use_cache;
364 case CURLOPT_SSL_CIPHER_LIST:
365 /* set a list of cipher we want to use in the SSL connection */
366 data->set.ssl.cipher_list = va_arg(param, char *);
369 case CURLOPT_RANDOM_FILE:
371 * This is the path name to a file that contains random data to seed
372 * the random SSL stuff with. The file is only used for reading.
374 data->set.ssl.random_file = va_arg(param, char *);
376 case CURLOPT_EGDSOCKET:
378 * The Entropy Gathering Daemon socket pathname
380 data->set.ssl.egdsocket = va_arg(param, char *);
382 case CURLOPT_MAXCONNECTS:
384 * Set the absolute number of maximum simultaneous alive connection that
385 * libcurl is allowed to have.
388 long newconnects= va_arg(param, long);
389 struct connectdata **newptr;
391 if(newconnects < data->state.numconnects) {
392 /* Since this number is *decreased* from the existing number, we must
393 close the possibly open connections that live on the indexes that
394 are being removed! */
396 for(i=newconnects; i< data->state.numconnects; i++)
397 Curl_disconnect(data->state.connects[i]);
401 newptr= (struct connectdata **)
402 realloc(data->state.connects,
403 sizeof(struct connectdata *) * newconnects);
405 /* we closed a few connections in vain, but so what? */
406 return CURLE_OUT_OF_MEMORY;
408 /* nullify the newly added pointers */
409 for(i=data->state.numconnects; i<newconnects; i++) {
413 data->state.connects = newptr;
414 data->state.numconnects = newconnects;
417 /* zero makes NO cache at all */
418 if(data->state.connects)
419 free(data->state.connects);
420 data->state.connects=NULL;
421 data->state.numconnects=0;
425 case CURLOPT_FORBID_REUSE:
427 * When this transfer is done, it must not be left to be reused by a
428 * subsequent transfer but shall be closed immediately.
430 data->set.reuse_forbid = va_arg(param, long)?TRUE:FALSE;
432 case CURLOPT_FRESH_CONNECT:
434 * This transfer shall not use a previously cached connection but
435 * should be made with a fresh new connect!
437 data->set.reuse_fresh = va_arg(param, long)?TRUE:FALSE;
439 case CURLOPT_VERBOSE:
441 * Verbose means infof() calls that give a lot of information about
442 * the connection and transfer procedures as well as internal choices.
444 data->set.verbose = va_arg(param, long)?TRUE:FALSE;
448 * Set to include the header in the general data output stream.
450 data->set.http_include_header = va_arg(param, long)?TRUE:FALSE;
452 case CURLOPT_NOPROGRESS:
454 * Shut off the internal supported progress meter
456 data->set.hide_progress = va_arg(param, long)?TRUE:FALSE;
457 if(data->set.hide_progress)
458 data->progress.flags |= PGRS_HIDE;
460 data->progress.flags &= ~PGRS_HIDE;
464 * Do not include the body part in the output data stream.
466 data->set.no_body = va_arg(param, long)?TRUE:FALSE;
468 case CURLOPT_FAILONERROR:
470 * Don't output the >=300 error code HTML-page, but instead only
473 data->set.http_fail_on_error = va_arg(param, long)?TRUE:FALSE;
477 * We want to sent data to the remote host
479 data->set.upload = va_arg(param, long)?TRUE:FALSE;
481 /* If this is HTTP, PUT is what's needed to "upload" */
482 data->set.httpreq = HTTPREQ_PUT;
484 case CURLOPT_FILETIME:
486 * Try to get the file time of the remote document. The time will
487 * later (possibly) become available using curl_easy_getinfo().
489 data->set.get_filetime = va_arg(param, long)?TRUE:FALSE;
491 case CURLOPT_FTP_CREATE_MISSING_DIRS:
493 * An FTP option that modifies an upload to create missing directories on
496 data->set.ftp_create_missing_dirs = va_arg( param , long )?TRUE:FALSE;
498 case CURLOPT_FTP_RESPONSE_TIMEOUT:
500 * An FTP option that specifies how quickly an FTP response must be
501 * obtained before it is considered failure.
503 data->set.ftp_response_timeout = va_arg( param , long );
505 case CURLOPT_FTPLISTONLY:
507 * An FTP option that changes the command to one that asks for a list
508 * only, no file info details.
510 data->set.ftp_list_only = va_arg(param, long)?TRUE:FALSE;
512 case CURLOPT_FTPAPPEND:
514 * We want to upload and append to an existing (FTP) file.
516 data->set.ftp_append = va_arg(param, long)?TRUE:FALSE;
520 * Parse the $HOME/.netrc file
522 data->set.use_netrc = (enum CURL_NETRC_OPTION)va_arg(param, long);
524 case CURLOPT_NETRC_FILE:
526 * Use this file instead of the $HOME/.netrc file
528 data->set.netrc_file = va_arg(param, char *);
530 case CURLOPT_FOLLOWLOCATION:
532 * Follow Location: header hints on a HTTP-server.
534 data->set.http_follow_location = va_arg(param, long)?TRUE:FALSE;
536 case CURLOPT_UNRESTRICTED_AUTH:
538 * Send authentication (user+password) when following locations, even when
541 data->set.http_disable_hostname_check_before_authentication =
542 va_arg(param, long)?TRUE:FALSE;
544 case CURLOPT_HTTP_VERSION:
546 * This sets a requested HTTP version to be used. The value is one of
547 * the listed enums in curl/curl.h.
549 data->set.httpversion = va_arg(param, long);
551 case CURLOPT_TRANSFERTEXT:
553 * This option was previously named 'FTPASCII'. Renamed to work with
554 * more protocols than merely FTP.
556 * Transfer using ASCII (instead of BINARY).
558 data->set.ftp_ascii = va_arg(param, long)?TRUE:FALSE;
562 * Use the HTTP PUT request to transfer data if this is TRUE. If this is
563 * FALSE, don't set the httpreq. We can't know what to revert it to!
565 if(va_arg(param, long))
566 data->set.httpreq = HTTPREQ_PUT;
568 case CURLOPT_TIMECONDITION:
570 * Set HTTP time condition. This must be one of the defines in the
571 * curl/curl.h header file.
573 data->set.timecondition = (curl_TimeCond)va_arg(param, long);
575 case CURLOPT_TIMEVALUE:
577 * This is the value to compare with the remote document with the
578 * method set with CURLOPT_TIMECONDITION
580 data->set.timevalue = va_arg(param, long);
582 case CURLOPT_SSLVERSION:
584 * Set explicit SSL version to try to connect with, as some SSL
585 * implementations are lame.
587 data->set.ssl.version = va_arg(param, long);
590 case CURLOPT_COOKIESESSION:
592 * Set this option to TRUE to start a new "cookie session". It will
593 * prevent the forthcoming read-cookies-from-file actions to accept
594 * cookies that are marked as being session cookies, as they belong to a
597 * In the original Netscape cookie spec, "session cookies" are cookies
598 * with no expire date set. RFC2109 describes the same action if no
599 * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds
600 * a 'Discard' action that can enforce the discard even for cookies that
603 * We run mostly with the original cookie spec, as hardly anyone implements
606 data->set.cookiesession = (bool)va_arg(param, long);
609 #ifndef CURL_DISABLE_HTTP
610 case CURLOPT_COOKIEFILE:
612 * Set cookie file to read and parse. Can be used multiple times.
614 cookiefile = (char *)va_arg(param, void *);
616 /* append the cookie file name to the list of file names, and deal with
618 data->change.cookielist =
619 curl_slist_append(data->change.cookielist, cookiefile);
622 case CURLOPT_COOKIEJAR:
624 * Set cookie file name to dump all cookies to when we're done.
626 data->set.cookiejar = (char *)va_arg(param, void *);
629 * Activate the cookie parser. This may or may not already
632 data->cookies = Curl_cookie_init(data, NULL, data->cookies,
633 data->set.cookiesession);
637 case CURLOPT_WRITEHEADER:
639 * Custom pointer to pass the header write callback function
641 data->set.writeheader = (void *)va_arg(param, void *);
645 * Cookie string to send to the remote server in the request.
647 data->set.cookie = va_arg(param, char *);
649 case CURLOPT_ERRORBUFFER:
651 * Error buffer provided by the caller to get the human readable
654 data->set.errorbuffer = va_arg(param, char *);
658 * FILE pointer to write to or include in the data write callback
660 data->set.out = va_arg(param, FILE *);
662 case CURLOPT_FTPPORT:
664 * Use FTP PORT, this also specifies which IP address to use
666 data->set.ftpport = va_arg(param, char *);
667 data->set.ftp_use_port = data->set.ftpport?1:0;
670 case CURLOPT_FTP_USE_EPRT:
671 data->set.ftp_use_eprt = va_arg(param, long)?TRUE:FALSE;
674 case CURLOPT_FTP_USE_EPSV:
675 data->set.ftp_use_epsv = va_arg(param, long)?TRUE:FALSE;
678 case CURLOPT_HTTPHEADER:
680 * Set a list with HTTP headers to use (or replace internals with)
682 data->set.headers = va_arg(param, struct curl_slist *);
684 case CURLOPT_CUSTOMREQUEST:
686 * Set a custom string to use as request
688 data->set.customrequest = va_arg(param, char *);
691 data->set.httpreq = HTTPREQ_CUSTOM;
692 here, we continue as if we were using the already set type
693 and this just changes the actual request keyword */
695 case CURLOPT_HTTPPOST:
697 * Set to make us do HTTP POST
699 data->set.httppost = va_arg(param, struct curl_httppost *);
700 if(data->set.httppost)
701 data->set.httpreq = HTTPREQ_POST_FORM;
704 case CURLOPT_HTTPGET:
706 * Set to force us do HTTP GET
708 if(va_arg(param, long)) {
709 data->set.httpreq = HTTPREQ_GET;
710 data->set.upload = FALSE; /* switch off upload */
716 * FILE pointer to read the file to be uploaded from. Or possibly
717 * used as argument to the read callback.
719 data->set.in = va_arg(param, FILE *);
721 case CURLOPT_INFILESIZE:
723 * If known, this should inform curl about the file size of the
724 * to-be-uploaded file.
726 data->set.infilesize = va_arg(param, long);
728 case CURLOPT_INFILESIZE_LARGE:
730 * If known, this should inform curl about the file size of the
731 * to-be-uploaded file.
733 data->set.infilesize = va_arg(param, curl_off_t);
735 case CURLOPT_LOW_SPEED_LIMIT:
737 * The low speed limit that if transfers are below this for
738 * CURLOPT_LOW_SPEED_TIME, the transfer is aborted.
740 data->set.low_speed_limit=va_arg(param, long);
742 case CURLOPT_LOW_SPEED_TIME:
744 * The low speed time that if transfers are below the set
745 * CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted.
747 data->set.low_speed_time=va_arg(param, long);
753 if(data->change.url_alloc) {
754 /* the already set URL is allocated, free it first! */
755 free(data->change.url);
756 data->change.url_alloc=FALSE;
758 data->set.set_url = va_arg(param, char *);
759 data->change.url = data->set.set_url;
760 data->change.url_changed = TRUE;
764 * The port number to use when getting the URL
766 data->set.use_port = va_arg(param, long);
769 /* Does this option serve a purpose anymore? Yes it does, when
770 CURLOPT_POSTFIELDS isn't used and the POST data is read off the
772 if(va_arg(param, long))
773 data->set.httpreq = HTTPREQ_POST;
775 case CURLOPT_POSTFIELDS:
777 * A string with POST data. Makes curl HTTP POST.
779 data->set.postfields = va_arg(param, char *);
780 if(data->set.postfields)
781 data->set.httpreq = HTTPREQ_POST;
783 case CURLOPT_POSTFIELDSIZE:
785 * The size of the POSTFIELD data to prevent libcurl to do strlen() to
786 * figure it out. Enables binary posts.
788 data->set.postfieldsize = va_arg(param, long);
790 case CURLOPT_POSTFIELDSIZE_LARGE:
792 * The size of the POSTFIELD data to prevent libcurl to do strlen() to
793 * figure it out. Enables binary posts.
795 data->set.postfieldsize = va_arg(param, curl_off_t);
797 case CURLOPT_REFERER:
799 * String to set in the HTTP Referer: field.
801 if(data->change.referer_alloc) {
802 free(data->change.referer);
803 data->change.referer_alloc = FALSE;
805 data->set.set_referer = va_arg(param, char *);
806 data->change.referer = data->set.set_referer;
808 case CURLOPT_AUTOREFERER:
810 * Switch on automatic referer that gets set if curl follows locations.
812 data->set.http_auto_referer = va_arg(param, long)?1:0;
816 * Set proxy server:port to use as HTTP proxy.
818 * If the proxy is set to "" we explicitly say that we don't want to use a
819 * proxy (even though there might be environment variables saying so).
821 * Setting it to NULL, means no proxy but allows the environment variables
824 if(data->change.proxy_alloc) {
826 * The already set string is allocated, free that first
828 data->change.proxy_alloc=FALSE;;
829 free(data->change.proxy);
831 data->set.set_proxy = va_arg(param, char *);
832 data->change.proxy = data->set.set_proxy;
834 case CURLOPT_HTTPPROXYTUNNEL:
836 * Tunnel operations through the proxy instead of normal proxy use
838 data->set.tunnel_thru_httpproxy = va_arg(param, long)?TRUE:FALSE;
840 case CURLOPT_PROXYPORT:
842 * Explicitly set HTTP proxy port number.
844 data->set.proxyport = va_arg(param, long);
846 case CURLOPT_TIMEOUT:
848 * The maximum time you allow curl to use for a single transfer
851 data->set.timeout = va_arg(param, long);
853 case CURLOPT_CONNECTTIMEOUT:
855 * The maximum time you allow curl to use to connect.
857 data->set.connecttimeout = va_arg(param, long);
859 case CURLOPT_MAXREDIRS:
861 * The maximum amount of hops you allow curl to follow Location:
862 * headers. This should mostly be used to detect never-ending loops.
864 data->set.maxredirs = va_arg(param, long);
866 case CURLOPT_USERAGENT:
868 * String to use in the HTTP User-Agent field
870 data->set.useragent = va_arg(param, char *);
872 case CURLOPT_ENCODING:
874 * String to use at the value of Accept-Encoding header. 08/28/02 jhrg
876 * If the encoding is set to "" we use an Accept-Encoding header that
877 * encompasses all the encodings we support.
878 * If the encoding is set to NULL we don't send an Accept-Encoding header
879 * and ignore an received Content-Encoding header.
882 data->set.encoding = va_arg(param, char *);
883 if(data->set.encoding && !*data->set.encoding)
884 data->set.encoding = (char*)ALL_CONTENT_ENCODINGS;
887 case CURLOPT_HTTPAUTH:
889 * Set HTTP Authentication type BITMASK.
892 long auth = va_arg(param, long);
893 /* switch off bits we can't support */
895 auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
898 auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */
901 return CURLE_FAILED_INIT; /* no supported types left! */
903 data->set.httpauth = auth;
907 case CURLOPT_PROXYAUTH:
909 * Set HTTP Authentication type BITMASK.
912 long auth = va_arg(param, long);
913 /* switch off bits we can't support */
915 auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
918 auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */
921 return CURLE_FAILED_INIT; /* no supported types left! */
923 data->set.proxyauth = auth;
927 case CURLOPT_USERPWD:
929 * user:password to use in the operation
931 data->set.userpwd = va_arg(param, char *);
933 case CURLOPT_POSTQUOTE:
935 * List of RAW FTP commands to use after a transfer
937 data->set.postquote = va_arg(param, struct curl_slist *);
939 case CURLOPT_PREQUOTE:
941 * List of RAW FTP commands to use prior to RETR (Wesley Laxton)
943 data->set.prequote = va_arg(param, struct curl_slist *);
947 * List of RAW FTP commands to use before a transfer
949 data->set.quote = va_arg(param, struct curl_slist *);
951 case CURLOPT_PROGRESSFUNCTION:
953 * Progress callback function
955 data->set.fprogress = va_arg(param, curl_progress_callback);
956 if(data->set.fprogress)
957 data->progress.callback = TRUE; /* no longer internal */
959 data->progress.callback = FALSE; /* NULL enforces internal */
962 case CURLOPT_PROGRESSDATA:
964 * Custom client data to pass to the progress callback
966 data->set.progress_client = va_arg(param, void *);
968 case CURLOPT_PROXYUSERPWD:
970 * user:password needed to use the proxy
972 data->set.proxyuserpwd = va_arg(param, char *);
976 * What range of the file you want to transfer
978 data->set.set_range = va_arg(param, char *);
980 case CURLOPT_RESUME_FROM:
982 * Resume transfer at the give file position
984 data->set.set_resume_from = va_arg(param, long);
986 case CURLOPT_RESUME_FROM_LARGE:
988 * Resume transfer at the give file position
990 data->set.set_resume_from = va_arg(param, curl_off_t);
992 case CURLOPT_DEBUGFUNCTION:
994 * stderr write callback.
996 data->set.fdebug = va_arg(param, curl_debug_callback);
998 * if the callback provided is NULL, it'll use the default callback
1001 case CURLOPT_DEBUGDATA:
1003 * Set to a void * that should receive all error writes. This
1004 * defaults to CURLOPT_STDERR for normal operations.
1006 data->set.debugdata = va_arg(param, void *);
1008 case CURLOPT_STDERR:
1010 * Set to a FILE * that should receive all error writes. This
1011 * defaults to stderr for normal operations.
1013 data->set.err = va_arg(param, FILE *);
1015 data->set.err = stderr;
1017 case CURLOPT_HEADERFUNCTION:
1019 * Set header write callback
1021 data->set.fwrite_header = va_arg(param, curl_write_callback);
1023 case CURLOPT_WRITEFUNCTION:
1025 * Set data write callback
1027 data->set.fwrite = va_arg(param, curl_write_callback);
1028 if(!data->set.fwrite)
1029 /* When set to NULL, reset to our internal default function */
1030 data->set.fwrite = (curl_write_callback)fwrite;
1032 case CURLOPT_READFUNCTION:
1034 * Read data callback
1036 data->set.fread = va_arg(param, curl_read_callback);
1037 if(!data->set.fread)
1038 /* When set to NULL, reset to our internal default function */
1039 data->set.fread = (curl_read_callback)fread;
1041 case CURLOPT_SSLCERT:
1043 * String that holds file name of the SSL certificate to use
1045 data->set.cert = va_arg(param, char *);
1047 case CURLOPT_SSLCERTTYPE:
1049 * String that holds file type of the SSL certificate to use
1051 data->set.cert_type = va_arg(param, char *);
1053 case CURLOPT_SSLKEY:
1055 * String that holds file name of the SSL certificate to use
1057 data->set.key = va_arg(param, char *);
1059 case CURLOPT_SSLKEYTYPE:
1061 * String that holds file type of the SSL certificate to use
1063 data->set.key_type = va_arg(param, char *);
1065 case CURLOPT_SSLKEYPASSWD:
1067 * String that holds the SSL private key password.
1069 data->set.key_passwd = va_arg(param, char *);
1071 case CURLOPT_SSLENGINE:
1073 * String that holds the SSL crypto engine.
1075 #ifdef HAVE_OPENSSL_ENGINE_H
1077 const char *cpTemp = va_arg(param, char *);
1079 if (cpTemp && cpTemp[0]) {
1080 e = ENGINE_by_id(cpTemp);
1083 ENGINE_free(data->engine);
1088 failf(data, "SSL Engine '%s' not found", cpTemp);
1089 return CURLE_SSL_ENGINE_NOTFOUND;
1095 return CURLE_SSL_ENGINE_NOTFOUND;
1097 case CURLOPT_SSLENGINE_DEFAULT:
1099 * flag to set engine as default.
1101 #ifdef HAVE_OPENSSL_ENGINE_H
1103 if (ENGINE_set_default(data->engine, ENGINE_METHOD_ALL) > 0) {
1105 fprintf(stderr,"set default crypto engine\n");
1110 failf(data, "set default crypto engine failed");
1112 return CURLE_SSL_ENGINE_SETFAILED;
1119 * Kludgy option to enable CRLF convertions. Subject for removal.
1121 data->set.crlf = va_arg(param, long)?TRUE:FALSE;
1123 case CURLOPT_INTERFACE:
1125 * Set what interface to bind to when performing an operation and thus
1126 * what from-IP your connection will use.
1128 data->set.device = va_arg(param, char *);
1130 case CURLOPT_KRB4LEVEL:
1132 * A string that defines the krb4 security level.
1134 data->set.krb4_level = va_arg(param, char *);
1135 data->set.krb4=data->set.krb4_level?TRUE:FALSE;
1137 case CURLOPT_SSL_VERIFYPEER:
1139 * Enable peer SSL verifying.
1141 data->set.ssl.verifypeer = va_arg(param, long);
1143 case CURLOPT_SSL_VERIFYHOST:
1145 * Enable verification of the CN contained in the peer certificate
1147 data->set.ssl.verifyhost = va_arg(param, long);
1149 case CURLOPT_SSL_CTX_FUNCTION:
1151 * Set a SSL_CTX callback
1153 data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback);
1155 case CURLOPT_SSL_CTX_DATA:
1157 * Set a SSL_CTX callback parameter pointer
1159 data->set.ssl.fsslctxp = va_arg(param, void *);
1161 case CURLOPT_CAINFO:
1163 * Set CA info for SSL connection. Specify file name of the CA certificate
1165 data->set.ssl.CAfile = va_arg(param, char *);
1167 case CURLOPT_CAPATH:
1169 * Set CA path info for SSL connection. Specify directory name of the CA
1170 * certificates which have been prepared using openssl c_rehash utility.
1172 /* This does not work on windows. */
1173 data->set.ssl.CApath = va_arg(param, char *);
1175 case CURLOPT_TELNETOPTIONS:
1177 * Set a linked list of telnet options
1179 data->set.telnet_options = va_arg(param, struct curl_slist *);
1182 case CURLOPT_BUFFERSIZE:
1184 * The application kindly asks for a differently sized receive buffer.
1185 * If it seems reasonable, we'll use it.
1187 data->set.buffer_size = va_arg(param, long);
1189 if((data->set.buffer_size> (BUFSIZE -1 )) ||
1190 (data->set.buffer_size < 1))
1191 data->set.buffer_size = 0; /* huge internal default */
1195 case CURLOPT_NOSIGNAL:
1197 * The application asks not to set any signal() or alarm() handlers,
1198 * even when using a timeout.
1200 data->set.no_signal = va_arg(param, long) ? TRUE : FALSE;
1205 struct Curl_share *set;
1206 set = va_arg(param, struct Curl_share *);
1208 /* disconnect from old share, if any */
1210 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
1212 if(data->share->hostcache == data->hostcache)
1213 data->hostcache = NULL;
1215 if(data->share->cookies == data->cookies)
1216 data->cookies = NULL;
1218 data->share->dirty--;
1220 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
1224 /* use new share if it set */
1228 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
1230 data->share->dirty++;
1232 if(data->share->hostcache) {
1233 /* use shared host cache, first free own one if any */
1235 Curl_hash_destroy(data->hostcache);
1237 data->hostcache = data->share->hostcache;
1240 if(data->share->cookies) {
1241 /* use shared cookie list, first free own one if any */
1243 Curl_cookie_cleanup(data->cookies);
1244 data->cookies = data->share->cookies;
1247 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
1251 /* check cookie list is set */
1253 data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE );
1255 /* check for host cache not needed,
1256 * it will be done by curl_easy_perform */
1260 case CURLOPT_PROXYTYPE:
1262 * Set proxy type. HTTP/SOCKS4/SOCKS5
1264 data->set.proxytype = (curl_proxytype)va_arg(param, long);
1267 case CURLOPT_PRIVATE:
1269 * Set private data pointer.
1271 data->set.private = va_arg(param, char *);
1274 case CURLOPT_HTTP200ALIASES:
1276 * Set a list of aliases for HTTP 200 in response header
1278 data->set.http200aliases = va_arg(param, struct curl_slist *);
1281 case CURLOPT_MAXFILESIZE:
1283 * Set the maximum size of a file to download.
1285 data->set.max_filesize = va_arg(param, long);
1288 case CURLOPT_FTP_SSL:
1290 * Make FTP transfers attempt to use SSL/TLS.
1292 data->set.ftp_ssl = (curl_ftpssl)va_arg(param, long);
1295 case CURLOPT_IPRESOLVE:
1296 data->set.ip_version = va_arg(param, long);
1299 case CURLOPT_MAXFILESIZE_LARGE:
1301 * Set the maximum size of a file to download.
1303 data->set.max_filesize = va_arg(param, curl_off_t);
1307 /* unknown tag and its companion, just ignore: */
1308 return CURLE_FAILED_INIT; /* correct this */
1313 CURLcode Curl_disconnect(struct connectdata *conn)
1316 return CURLE_OK; /* this is closed and fine already */
1319 * The range string is usually freed in curl_done(), but we might
1320 * get here *instead* if we fail prematurely. Thus we need to be able
1321 * to free this resource here as well.
1323 if(conn->bits.rangestringalloc) {
1325 conn->bits.rangestringalloc = FALSE;
1328 if((conn->ntlm.state != NTLMSTATE_NONE) ||
1329 (conn->proxyntlm.state != NTLMSTATE_NONE))
1330 /* Authentication data is a mix of connection-related and sessionhandle-
1331 related stuff. NTLM is connection-related so when we close the shop
1333 conn->data->state.authstage = 0;
1335 if(conn->curl_disconnect)
1336 /* This is set if protocol-specific cleanups should be made */
1337 conn->curl_disconnect(conn);
1339 if(-1 != conn->connectindex) {
1340 /* unlink ourselves! */
1341 infof(conn->data, "Closing connection #%d\n", conn->connectindex);
1342 conn->data->state.connects[conn->connectindex] = NULL;
1345 Curl_safefree(conn->proto.generic);
1346 Curl_safefree(conn->newurl);
1347 Curl_safefree(conn->path); /* the URL path part */
1348 Curl_SSL_Close(conn);
1350 /* close possibly still open sockets */
1351 if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
1352 sclose(conn->sock[SECONDARYSOCKET]);
1353 if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET])
1354 sclose(conn->sock[FIRSTSOCKET]);
1356 Curl_safefree(conn->user);
1357 Curl_safefree(conn->passwd);
1358 Curl_safefree(conn->proxyuser);
1359 Curl_safefree(conn->proxypasswd);
1360 Curl_safefree(conn->allocptr.proxyuserpwd);
1361 Curl_safefree(conn->allocptr.uagent);
1362 Curl_safefree(conn->allocptr.userpwd);
1363 Curl_safefree(conn->allocptr.accept_encoding);
1364 Curl_safefree(conn->allocptr.rangeline);
1365 Curl_safefree(conn->allocptr.ref);
1366 Curl_safefree(conn->allocptr.cookie);
1367 Curl_safefree(conn->allocptr.host);
1368 Curl_safefree(conn->allocptr.cookiehost);
1369 Curl_safefree(conn->proxyhost);
1370 #if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME)
1371 /* possible left-overs from the async name resolve */
1372 Curl_safefree(conn->async.hostname);
1373 Curl_safefree(conn->async.os_specific);
1376 Curl_free_ssl_config(&conn->ssl_config);
1378 free(conn); /* free all the connection oriented data */
1384 * This function should return TRUE if the socket is to be assumed to
1385 * be dead. Most commonly this happens when the server has closed the
1386 * connection due to inactivity.
1388 static bool SocketIsDead(curl_socket_t sock)
1391 bool ret_val = TRUE;
1395 FD_ZERO(&check_set);
1396 FD_SET(sock, &check_set);
1401 sval = select(sock + 1, &check_set, 0, 0, &to);
1410 * Given one filled in connection struct (named needle), this function should
1411 * detect if there already is one that have all the significant details
1412 * exactly the same and thus should be used instead.
1415 ConnectionExists(struct SessionHandle *data,
1416 struct connectdata *needle,
1417 struct connectdata **usethis)
1420 struct connectdata *check;
1422 for(i=0; i< data->state.numconnects; i++) {
1425 * Note that if we use a HTTP proxy, we check connections to that
1426 * proxy and not to the actual remote server.
1428 check = data->state.connects[i];
1430 /* NULL pointer means not filled-in entry */
1433 if((needle->protocol&PROT_SSL) != (check->protocol&PROT_SSL))
1434 /* don't do mixed SSL and non-SSL connections */
1437 if(!needle->bits.httpproxy || needle->protocol&PROT_SSL) {
1438 /* The requested connection does not use a HTTP proxy or it
1441 if(!(needle->protocol&PROT_SSL) && check->bits.httpproxy)
1442 /* we don't do SSL but the cached connection has a proxy,
1443 then don't match this */
1446 if(strequal(needle->protostr, check->protostr) &&
1447 strequal(needle->name, check->name) &&
1448 (needle->remote_port == check->remote_port) ) {
1449 if(needle->protocol & PROT_SSL) {
1450 /* This is SSL, verify that we're using the same
1451 ssl options as well */
1452 if(!Curl_ssl_config_matches(&needle->ssl_config,
1453 &check->ssl_config)) {
1457 if((needle->protocol & PROT_FTP) ||
1458 ((needle->protocol & PROT_HTTP) &&
1459 (needle->data->state.authwant==CURLAUTH_NTLM))) {
1460 /* This is FTP or HTTP+NTLM, verify that we're using the same name
1461 and password as well */
1462 if(!strequal(needle->user, check->user) ||
1463 !strequal(needle->passwd, check->passwd)) {
1464 /* one of them was different */
1471 else { /* The requested needle connection is using a proxy,
1472 is the checked one using the same? */
1473 if(check->bits.httpproxy &&
1474 strequal(needle->proxyhost, check->proxyhost) &&
1475 needle->port == check->port) {
1476 /* This is the same proxy connection, use it! */
1482 bool dead = SocketIsDead(check->sock[FIRSTSOCKET]);
1486 infof(data, "Connection %d seems to be dead!\n", i);
1487 Curl_disconnect(check); /* disconnect resources */
1488 data->state.connects[i]=NULL; /* nothing here */
1490 /* There's no need to continue searching, because we only store
1491 one connection for each unique set of identifiers */
1496 return TRUE; /* yes, we found one to use! */
1499 return FALSE; /* no matching connecting exists */
1503 * This function frees/closes a connection in the connection cache. This
1504 * should take the previously set policy into account when deciding which
1505 * of the connections to kill.
1508 ConnectionKillOne(struct SessionHandle *data)
1511 struct connectdata *conn;
1519 for(i=0; i< data->state.numconnects; i++) {
1520 conn = data->state.connects[i];
1526 * By using the set policy, we score each connection.
1528 switch(data->set.closepolicy) {
1529 case CURLCLOSEPOLICY_LEAST_RECENTLY_USED:
1532 * Set higher score for the age passed since the connection
1535 score = Curl_tvdiff(now, conn->now);
1537 case CURLCLOSEPOLICY_OLDEST:
1539 * Set higher score for the age passed since the connection
1542 score = Curl_tvdiff(now, conn->created);
1546 if(score > highscore) {
1551 if(connindex >= 0) {
1553 /* the winner gets the honour of being disconnected */
1554 (void) Curl_disconnect(data->state.connects[connindex]);
1556 /* clean the array entry */
1557 data->state.connects[connindex] = NULL;
1560 return connindex; /* return the available index or -1 */
1564 * The given input connection struct pointer is to be stored. If the "cache"
1565 * is already full, we must clean out the most suitable using the previously
1568 * The given connection should be unique. That must've been checked prior to
1572 ConnectionStore(struct SessionHandle *data,
1573 struct connectdata *conn)
1576 for(i=0; i< data->state.numconnects; i++) {
1577 if(!data->state.connects[i])
1580 if(i == data->state.numconnects) {
1581 /* there was no room available, kill one */
1582 i = ConnectionKillOne(data);
1583 infof(data, "Connection (#%d) was killed to make room\n", i);
1587 /* only do this if a true index was returned, if -1 was returned there
1588 is no room in the cache for an unknown reason and we cannot store
1590 data->state.connects[i] = conn; /* fill in this */
1591 conn->connectindex = i; /* make the child know where the pointer to this
1592 particular data is stored */
1598 * This function logs in to a SOCKS5 proxy and sends the specifies the final
1599 * desitination server.
1601 static int handleSock5Proxy(const char *proxy_name,
1602 const char *proxy_password,
1603 struct connectdata *conn)
1606 According to the RFC1928, section "6. Replies". This is what a SOCK5
1609 +----+-----+-------+------+----------+----------+
1610 |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
1611 +----+-----+-------+------+----------+----------+
1612 | 1 | 1 | X'00' | 1 | Variable | 2 |
1613 +----+-----+-------+------+----------+----------+
1617 o VER protocol version: X'05'
1622 unsigned char socksreq[600]; /* room for large user/pw (255 max each) */
1627 int sock = conn->sock[FIRSTSOCKET];
1629 Curl_nonblock(sock, FALSE);
1631 socksreq[0] = 5; /* version */
1632 socksreq[1] = (char)(proxy_name ? 2 : 1); /* number of methods (below) */
1633 socksreq[2] = 0; /* no authentication */
1634 socksreq[3] = 2; /* username/password */
1636 code = Curl_write(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]),
1638 if ((code != CURLE_OK) || (written != (2 + (int)socksreq[1]))) {
1639 failf(conn->data, "Unable to send initial SOCKS5 request.");
1643 result=Curl_read(conn, sock, (char *)socksreq, 2, &actualread);
1644 if ((result != CURLE_OK) || (actualread != 2)) {
1645 failf(conn->data, "Unable to receive initial SOCKS5 response.");
1649 if (socksreq[0] != 5) {
1650 failf(conn->data, "Received invalid version in initial SOCKS5 response.");
1653 if (socksreq[1] == 0) {
1654 /* Nothing to do, no authentication needed */
1657 else if (socksreq[1] == 2) {
1658 /* Needs user name and password */
1659 int userlen, pwlen, len;
1661 userlen = strlen(proxy_name);
1662 pwlen = proxy_password?strlen(proxy_password):0;
1664 /* username/password request looks like
1665 * +----+------+----------+------+----------+
1666 * |VER | ULEN | UNAME | PLEN | PASSWD |
1667 * +----+------+----------+------+----------+
1668 * | 1 | 1 | 1 to 255 | 1 | 1 to 255 |
1669 * +----+------+----------+------+----------+
1672 socksreq[len++] = 1; /* username/pw subnegotiation version */
1673 socksreq[len++] = (char) userlen;
1674 memcpy(socksreq + len, proxy_name, (int) userlen);
1676 socksreq[len++] = (char) pwlen;
1677 memcpy(socksreq + len, proxy_password, (int) pwlen);
1680 code = Curl_write(conn, sock, (char *)socksreq, len, &written);
1681 if ((code != CURLE_OK) || (len != written)) {
1682 failf(conn->data, "Failed to send SOCKS5 sub-negotiation request.");
1686 result=Curl_read(conn, sock, (char *)socksreq, 2, &actualread);
1687 if ((result != CURLE_OK) || (actualread != 2)) {
1688 failf(conn->data, "Unable to receive SOCKS5 sub-negotiation response.");
1692 if ((socksreq[0] != 5) || /* version */
1693 (socksreq[1] != 0)) { /* status */
1694 failf(conn->data, "User was rejected by the SOCKS5 server (%d %d).",
1695 socksreq[0], socksreq[1]);
1699 /* Everything is good so far, user was authenticated! */
1703 if (socksreq[1] == 1) {
1705 "SOCKS5 GSSAPI per-message authentication is not supported.");
1708 else if (socksreq[1] == 255) {
1709 if (proxy_name[0] == 0) {
1711 "No authentication method was acceptable. (It is quite likely"
1712 " that the SOCKS5 server wanted a username/password, since none"
1713 " was supplied to the server on this connection.)");
1716 failf(conn->data, "No authentication method was acceptable.");
1722 "Undocumented SOCKS5 mode attempted to be used by server.");
1727 /* Authentication is complete, now specify destination to the proxy */
1728 socksreq[0] = 5; /* version (SOCKS5) */
1729 socksreq[1] = 1; /* connect */
1730 socksreq[2] = 0; /* must be zero */
1731 socksreq[3] = 1; /* IPv4 = 1 */
1735 struct Curl_dns_entry *dns;
1736 Curl_addrinfo *hp=NULL;
1737 int rc = Curl_resolv(conn, conn->hostname, conn->remote_port, &dns);
1743 /* this requires that we're in "wait for resolve" state */
1744 rc = Curl_wait_for_resolv(conn, &dns);
1747 * We cannot use 'hostent' as a struct that Curl_resolv() returns. It
1748 * returns a Curl_addrinfo pointer that may not always look the same.
1752 if (hp && hp->h_addr_list[0]) {
1753 socksreq[4] = ((char*)hp->h_addr_list[0])[0];
1754 socksreq[5] = ((char*)hp->h_addr_list[0])[1];
1755 socksreq[6] = ((char*)hp->h_addr_list[0])[2];
1756 socksreq[7] = ((char*)hp->h_addr_list[0])[3];
1758 Curl_resolv_unlock(conn->data, dns); /* not used anymore from now on */
1761 failf(conn->data, "Failed to resolve \"%s\" for SOCKS5 connect.",
1767 "%s:%d has an internal error an needs to be fixed to work",
1768 __FILE__, __LINE__);
1773 *((unsigned short*)&socksreq[8]) = htons(conn->remote_port);
1776 const int packetsize = 10;
1778 code = Curl_write(conn, sock, (char *)socksreq, packetsize, &written);
1779 if ((code != CURLE_OK) || (written != packetsize)) {
1780 failf(conn->data, "Failed to send SOCKS5 connect request.");
1784 result = Curl_read(conn, sock, (char *)socksreq, packetsize, &actualread);
1785 if ((result != CURLE_OK) || (actualread != packetsize)) {
1786 failf(conn->data, "Failed to receive SOCKS5 connect request ack.");
1790 if (socksreq[0] != 5) { /* version */
1792 "SOCKS5 reply has wrong version, version should be 5.");
1795 if (socksreq[1] != 0) { /* Anything besides 0 is an error */
1797 "Can't complete SOCKS5 connection to %d.%d.%d.%d:%d. (%d)",
1798 (unsigned char)socksreq[4], (unsigned char)socksreq[5],
1799 (unsigned char)socksreq[6], (unsigned char)socksreq[7],
1800 (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])),
1806 Curl_nonblock(sock, TRUE);
1807 return 0; /* Proxy was successful! */
1810 static CURLcode ConnectPlease(struct connectdata *conn,
1811 struct Curl_dns_entry *hostaddr,
1815 Curl_ipconnect *addr;
1817 /*************************************************************
1818 * Connect to server/proxy
1819 *************************************************************/
1820 result= Curl_connecthost(conn,
1823 &conn->sock[FIRSTSOCKET],
1826 if(CURLE_OK == result) {
1827 /* All is cool, then we store the current information from the hostaddr
1828 struct to the serv_addr, as it might be needed later. The address
1829 returned from the function above is crucial here. */
1830 conn->connect_addr = hostaddr;
1833 conn->serv_addr = addr;
1835 memset((char *) &conn->serv_addr, '\0', sizeof(conn->serv_addr));
1836 memcpy((char *)&(conn->serv_addr.sin_addr),
1837 (struct in_addr *)addr, sizeof(struct in_addr));
1838 conn->serv_addr.sin_family = hostaddr->addr->h_addrtype;
1839 conn->serv_addr.sin_port = htons((unsigned short)conn->port);
1842 if (conn->data->set.proxytype == CURLPROXY_SOCKS5) {
1843 return handleSock5Proxy(conn->proxyuser,
1846 CURLE_COULDNT_CONNECT : CURLE_OK;
1848 else if (conn->data->set.proxytype == CURLPROXY_HTTP) {
1849 /* do nothing here. handled later. */
1852 failf(conn->data, "unknown proxytype option given");
1853 return CURLE_COULDNT_CONNECT;
1861 * ALERT! The 'dns' pointer being passed in here might be NULL at times.
1863 static void verboseconnect(struct connectdata *conn,
1864 struct Curl_dns_entry *dns)
1866 struct SessionHandle *data = conn->data;
1868 /* Figure out the ip-number and display the first host name it shows: */
1871 char hbuf[NI_MAXHOST];
1872 #ifdef NI_WITHSCOPEID
1873 #define NIFLAGS NI_NUMERICHOST | NI_WITHSCOPEID
1875 #define NIFLAGS NI_NUMERICHOST
1878 struct addrinfo *ai = dns->addr;
1880 /* Lookup the name of the given address. This should probably be remade
1881 to use the DNS cache instead, as the host name is most likely cached
1883 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0,
1885 snprintf(hbuf, sizeof(hbuf), "unknown");
1888 if (ai->ai_canonname) {
1889 infof(data, "Connected to %s (%s) port %d\n", ai->ai_canonname, hbuf,
1896 snprintf(hbuf, sizeof(hbuf), "same host");
1899 infof(data, "Connected to %s port %d\n", hbuf, conn->port);
1903 #ifdef HAVE_INET_NTOA_R
1906 Curl_addrinfo *hostaddr=dns?dns->addr:NULL;
1908 (void) memcpy(&in.s_addr, &conn->serv_addr.sin_addr, sizeof (in.s_addr));
1909 infof(data, "Connected to %s (%s) port %d\n",
1910 hostaddr?hostaddr->h_name:"",
1911 #if defined(HAVE_INET_NTOA_R)
1912 inet_ntoa_r(in, ntoa_buf, sizeof(ntoa_buf)),
1922 * We have discovered that the TCP connection has been successful, we can now
1923 * proceed with some action.
1925 * If we're using the multi interface, this host address pointer is most
1926 * likely NULL at this point as we can't keep the resolved info around. This
1927 * may call for some reworking, like a reference counter in the struct or
1928 * something. The hostaddr is not used for very much though, we have the
1929 * 'serv_addr' field in the connectdata struct for most of it.
1931 CURLcode Curl_protocol_connect(struct connectdata *conn,
1932 struct Curl_dns_entry *hostaddr)
1934 struct SessionHandle *data = conn->data;
1935 CURLcode result=CURLE_OK;
1937 if(conn->bits.tcpconnect)
1938 /* We already are connected, get back. This may happen when the connect
1939 worked fine in the first call, like when we connect to a local server
1943 Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
1945 if(data->set.verbose)
1946 verboseconnect(conn, hostaddr);
1948 if(conn->curl_connect) {
1949 /* is there a protocol-specific connect() procedure? */
1951 /* set start time here for timeout purposes in the
1952 * connect procedure, it is later set again for the
1953 * progress meter purpose */
1954 conn->now = Curl_tvnow();
1956 /* Call the protocol-specific connect function */
1957 result = conn->curl_connect(conn);
1960 return result; /* pass back status */
1964 * CreateConnection() sets up a new connectdata struct, or re-uses an already
1965 * existing one, and resolves host name.
1967 * if this function returns CURLE_OK and *async is set to TRUE, the resolve
1968 * response will be coming asynchronously. If *async is FALSE, the name is
1972 static CURLcode CreateConnection(struct SessionHandle *data,
1973 struct connectdata **in_connect,
1974 struct Curl_dns_entry **addr,
1978 CURLcode result=CURLE_OK;
1979 char resumerange[40]="";
1980 struct connectdata *conn;
1981 struct connectdata *conn_temp;
1983 struct Curl_dns_entry *hostaddr;
1985 unsigned int prev_alarm=0;
1988 char user[MAX_CURL_USER_LENGTH];
1989 char passwd[MAX_CURL_PASSWORD_LENGTH];
1993 #ifdef HAVE_SIGACTION
1994 struct sigaction keep_sigact; /* store the old struct here */
1995 bool keep_copysig=FALSE; /* did copy it? */
1998 void *keep_sigact; /* store the old handler here */
2002 *addr = NULL; /* nothing yet */
2005 /*************************************************************
2007 *************************************************************/
2009 if(!data->change.url)
2010 return CURLE_URL_MALFORMAT;
2012 /* First, split up the current URL in parts so that we can use the
2013 parts for checking against the already present connections. In order
2014 to not have to modify everything at once, we allocate a temporary
2015 connection data struct and fill in for comparison purposes. */
2017 conn = (struct connectdata *)malloc(sizeof(struct connectdata));
2019 *in_connect = NULL; /* clear the pointer */
2020 return CURLE_OUT_OF_MEMORY;
2022 /* We must set the return variable as soon as possible, so that our
2023 parent can cleanup any possible allocs we may have done before
2027 /* we have to init the struct */
2028 memset(conn, 0, sizeof(struct connectdata));
2030 /* and we setup a few fields in case we end up actually using this struct */
2031 conn->data = data; /* remember our daddy */
2032 conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
2033 conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
2034 conn->connectindex = -1; /* no index */
2035 conn->bits.httpproxy = (data->change.proxy && *data->change.proxy &&
2036 (data->set.proxytype == CURLPROXY_HTTP))?
2037 TRUE:FALSE; /* http proxy or not */
2039 /* Default protocol-independent behavior doesn't support persistant
2040 connections, so we set this to force-close. Protocols that support
2041 this need to set this to FALSE in their "curl_do" functions. */
2042 conn->bits.close = TRUE;
2044 /* maxdownload must be -1 on init, as 0 is a valid value! */
2045 conn->maxdownload = -1; /* might have been used previously! */
2047 /* Store creation time to help future close decision making */
2048 conn->created = Curl_tvnow();
2050 conn->bits.use_range = data->set.set_range?TRUE:FALSE; /* range status */
2051 conn->range = data->set.set_range; /* clone the range setting */
2052 conn->resume_from = data->set.set_resume_from; /* inherite resume_from */
2054 /* Set the start time temporary to this creation time to allow easier
2055 timeout checks before the transfer has started for real. The start time
2056 is later set "for real" using Curl_pgrsStartNow(). */
2057 conn->data->progress.start = conn->created;
2059 conn->bits.user_passwd = data->set.userpwd?1:0;
2060 conn->bits.proxy_user_passwd = data->set.proxyuserpwd?1:0;
2062 /* This initing continues below, see the comment "Continue connectdata
2063 * initialization here" */
2065 /***********************************************************
2066 * We need to allocate memory to store the path in. We get the size of the
2067 * full URL to be sure, and we need to make it at least 256 bytes since
2068 * other parts of the code will rely on this fact
2069 ***********************************************************/
2070 #define LEAST_PATH_ALLOC 256
2071 urllen=strlen(data->change.url);
2072 if(urllen < LEAST_PATH_ALLOC)
2073 urllen=LEAST_PATH_ALLOC;
2075 conn->path=(char *)malloc(urllen);
2076 if(NULL == conn->path)
2077 return CURLE_OUT_OF_MEMORY; /* really bad error */
2079 /*************************************************************
2082 * We need to parse the url even when using the proxy, because we will need
2083 * the hostname and port in case we are trying to SSL connect through the
2084 * proxy -- and we don't know if we will need to use SSL until we parse the
2086 ************************************************************/
2087 if((2 == sscanf(data->change.url, "%64[^:]:%[^\n]",
2089 conn->path)) && strequal(conn->protostr, "file")) {
2090 if(conn->path[0] == '/' && conn->path[1] == '/') {
2091 /* Allow omitted hostname (e.g. file:/<path>). This is not strictly
2092 * speaking a valid file: URL by RFC 1738, but treating file:/<path> as
2093 * file://localhost/<path> is similar to how other schemes treat missing
2094 * hostnames. See RFC 1808. */
2096 /* This cannot be done with strcpy() in a portable manner, since the
2097 memory areas overlap! */
2098 memmove(conn->path, conn->path + 2, strlen(conn->path + 2)+1);
2101 * we deal with file://<host>/<path> differently since it supports no
2102 * hostname other than "localhost" and "127.0.0.1", which is unique among
2103 * the URL protocols specified in RFC 1738
2105 if(conn->path[0] != '/') {
2106 /* the URL included a host name, we ignore host names in file:// URLs
2107 as the standards don't define what to do with them */
2108 char *ptr=strchr(conn->path, '/');
2110 /* there was a slash present
2112 RFC1738 (section 3.1, page 5) says:
2114 The rest of the locator consists of data specific to the scheme,
2115 and is known as the "url-path". It supplies the details of how the
2116 specified resource can be accessed. Note that the "/" between the
2117 host (or port) and the url-path is NOT part of the url-path.
2119 As most agents use file://localhost/foo to get '/foo' although the
2120 slash preceeding foo is a separator and not a slash for the path,
2121 a URL as file://localhost//foo must be valid as well, to refer to
2122 the same file with an absolute path.
2125 if(ptr[1] && ('/' == ptr[1]))
2126 /* if there was two slashes, we skip the first one as that is then
2127 used truly as a separator */
2130 /* This cannot be made with strcpy, as the memory chunks overlap! */
2131 memmove(conn->path, ptr, strlen(ptr)+1);
2135 strcpy(conn->protostr, "file"); /* store protocol string lowercase */
2138 /* Set default host and default path */
2139 strcpy(conn->gname, "curl.haxx.se");
2140 strcpy(conn->path, "/");
2141 /* We need to search for '/' OR '?' - whichever comes first after host
2142 * name but before the path. We need to change that to handle things like
2143 * http://example.com?param= (notice the missing '/'). Later we'll insert
2144 * that missing slash at the beginning of the path.
2146 if (2 > sscanf(data->change.url,
2147 "%64[^\n:]://%512[^\n/?]%[^\n]",
2148 conn->protostr, conn->gname, conn->path)) {
2151 * The URL was badly formatted, let's try the browser-style _without_
2152 * protocol specified like 'http://'.
2154 if((1 > sscanf(data->change.url, "%512[^\n/?]%[^\n]",
2155 conn->gname, conn->path)) ) {
2157 * We couldn't even get this format.
2159 failf(data, "<url> malformed");
2160 return CURLE_URL_MALFORMAT;
2164 * Since there was no protocol part specified, we guess what protocol it
2165 * is based on the first letters of the server name.
2168 /* Note: if you add a new protocol, please update the list in
2169 * lib/version.c too! */
2171 if(checkprefix("GOPHER", conn->gname))
2172 strcpy(conn->protostr, "gopher");
2174 else if(checkprefix("HTTPS", conn->gname))
2175 strcpy(conn->protostr, "https");
2176 else if(checkprefix("FTPS", conn->gname))
2177 strcpy(conn->protostr, "ftps");
2178 #endif /* USE_SSLEAY */
2179 else if(checkprefix("FTP", conn->gname))
2180 strcpy(conn->protostr, "ftp");
2181 else if(checkprefix("TELNET", conn->gname))
2182 strcpy(conn->protostr, "telnet");
2183 else if (checkprefix("DICT", conn->gname))
2184 strcpy(conn->protostr, "DICT");
2185 else if (checkprefix("LDAP", conn->gname))
2186 strcpy(conn->protostr, "LDAP");
2188 strcpy(conn->protostr, "http");
2191 conn->protocol |= PROT_MISSING; /* not given in URL */
2195 /* If the URL is malformatted (missing a '/' after hostname before path) we
2196 * insert a slash here. The only letter except '/' we accept to start a path
2199 if(conn->path[0] == '?') {
2200 /* We need this function to deal with overlapping memory areas. We know
2201 that the memory area 'path' points to is 'urllen' bytes big and that
2202 is bigger than the path. Use +1 to move the zero byte too. */
2203 memmove(&conn->path[1], conn->path, strlen(conn->path)+1);
2204 conn->path[0] = '/';
2208 * So if the URL was A://B/C,
2209 * conn->protostr is A
2214 /*************************************************************
2215 * Take care of proxy authentication stuff
2216 *************************************************************/
2217 if(conn->bits.proxy_user_passwd) {
2218 char proxyuser[MAX_CURL_USER_LENGTH]="";
2219 char proxypasswd[MAX_CURL_PASSWORD_LENGTH]="";
2221 sscanf(data->set.proxyuserpwd,
2222 "%" MAX_CURL_USER_LENGTH_TXT "[^:]:"
2223 "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]",
2224 proxyuser, proxypasswd);
2226 conn->proxyuser = strdup(proxyuser);
2227 if(!conn->proxyuser)
2228 return CURLE_OUT_OF_MEMORY;
2230 conn->proxypasswd = strdup(proxypasswd);
2231 if(!conn->proxypasswd)
2232 return CURLE_OUT_OF_MEMORY;
2235 /*************************************************************
2236 * Set a few convenience pointers
2237 *************************************************************/
2238 conn->name = conn->gname;
2239 conn->ppath = conn->path;
2240 conn->hostname = conn->name;
2242 /*************************************************************
2243 * Detect what (if any) proxy to use
2244 *************************************************************/
2245 if(!data->change.proxy) {
2246 /* If proxy was not specified, we check for default proxy environment
2247 * variables, to enable i.e Lynx compliance:
2249 * http_proxy=http://some.server.dom:port/
2250 * https_proxy=http://some.server.dom:port/
2251 * ftp_proxy=http://some.server.dom:port/
2252 * gopher_proxy=http://some.server.dom:port/
2253 * no_proxy=domain1.dom,host.domain2.dom
2254 * (a comma-separated list of hosts which should
2255 * not be proxied, or an asterisk to override
2256 * all proxy variables)
2257 * all_proxy=http://some.server.dom:port/
2258 * (seems to exist for the CERN www lib. Probably
2259 * the first to check for.)
2261 * For compatibility, the all-uppercase versions of these variables are
2262 * checked if the lowercase versions don't exist.
2264 char *no_proxy=NULL;
2265 char *no_proxy_tok_buf;
2267 char proxy_env[128];
2269 no_proxy=curl_getenv("no_proxy");
2271 no_proxy=curl_getenv("NO_PROXY");
2273 if(!no_proxy || !strequal("*", no_proxy)) {
2274 /* NO_PROXY wasn't specified or it wasn't just an asterisk */
2277 nope=no_proxy?strtok_r(no_proxy, ", ", &no_proxy_tok_buf):NULL;
2279 unsigned int namelen;
2280 char *endptr = strchr(conn->name, ':');
2282 namelen=endptr-conn->name;
2284 namelen=strlen(conn->name);
2286 if(strlen(nope) <= namelen) {
2288 conn->name + namelen - strlen(nope);
2289 if(checkprefix(nope, checkn)) {
2290 /* no proxy for this host! */
2294 nope=strtok_r(NULL, ", ", &no_proxy_tok_buf);
2297 /* It was not listed as without proxy */
2298 char *protop = conn->protostr;
2299 char *envp = proxy_env;
2302 /* Now, build <protocol>_proxy and check for such a one to use */
2304 *envp++ = tolower(*protop++);
2307 strcpy(envp, "_proxy");
2309 /* read the protocol proxy: */
2310 prox=curl_getenv(proxy_env);
2313 * We don't try the uppercase version of HTTP_PROXY because of
2316 * When curl is used in a webserver application
2317 * environment (cgi or php), this environment variable can
2318 * be controlled by the web server user by setting the
2319 * http header 'Proxy:' to some value.
2321 * This can cause 'internal' http/ftp requests to be
2322 * arbitrarily redirected by any external attacker.
2324 if(!prox && !strequal("http_proxy", proxy_env)) {
2325 /* There was no lowercase variable, try the uppercase version: */
2326 for(envp = proxy_env; *envp; envp++)
2327 *envp = toupper(*envp);
2328 prox=curl_getenv(proxy_env);
2331 if(prox && *prox) { /* don't count "" strings */
2332 proxy = prox; /* use this */
2335 proxy = curl_getenv("all_proxy"); /* default proxy to use */
2337 proxy=curl_getenv("ALL_PROXY");
2340 if(proxy && *proxy) {
2341 /* we have a proxy here to set */
2343 char proxyuser[MAX_CURL_USER_LENGTH];
2344 char proxypasswd[MAX_CURL_PASSWORD_LENGTH];
2346 /* skip the possible protocol piece */
2347 ptr=strstr(proxy, "://");
2353 /* check for an @-letter */
2354 ptr = strchr(ptr, '@');
2355 if(ptr && (2 == sscanf(proxy, "%" MAX_CURL_USER_LENGTH_TXT"[^:]:"
2356 "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]",
2357 proxyuser, proxypasswd))) {
2358 /* found user and password, rip them out */
2359 Curl_safefree(conn->proxyuser);
2360 conn->proxyuser = strdup(proxyuser);
2362 if(!conn->proxyuser)
2363 return CURLE_OUT_OF_MEMORY;
2365 Curl_safefree(conn->proxypasswd);
2366 conn->proxypasswd = strdup(proxypasswd);
2368 if(!conn->proxypasswd)
2369 return CURLE_OUT_OF_MEMORY;
2371 conn->bits.proxy_user_passwd = TRUE; /* enable it */
2373 ptr = strdup(ptr+1);
2374 free(proxy); /* free the former data */
2375 proxy = ptr; /* now use this instead */
2379 data->change.proxy = proxy;
2380 data->change.proxy_alloc=TRUE; /* this needs to be freed later */
2381 conn->bits.httpproxy = TRUE;
2383 } /* if (!nope) - it wasn't specified non-proxy */
2384 } /* NO_PROXY wasn't specified or '*' */
2387 } /* if not using proxy */
2389 /*************************************************************
2390 * No protocol part in URL was used, add it!
2391 *************************************************************/
2392 if(conn->protocol&PROT_MISSING) {
2393 /* We're guessing prefixes here and if we're told to use a proxy or if
2394 we're gonna follow a Location: later or... then we need the protocol
2395 part added so that we have a valid URL. */
2398 reurl = aprintf("%s://%s", conn->protostr, data->change.url);
2401 return CURLE_OUT_OF_MEMORY;
2403 data->change.url = reurl;
2404 data->change.url_alloc = TRUE; /* free this later */
2405 conn->protocol &= ~PROT_MISSING; /* switch that one off again */
2408 #ifndef CURL_DISABLE_HTTP
2409 /************************************************************
2410 * RESUME on a HTTP page is a tricky business. First, let's just check that
2411 * 'range' isn't used, then set the range parameter and leave the resume as
2412 * it is to inform about this situation for later use. We will then
2413 * "attempt" to resume, and if we're talking to a HTTP/1.1 (or later)
2414 * server, we will get the document resumed. If we talk to a HTTP/1.0
2415 * server, we just fail since we can't rewind the file writing from within
2417 ***********************************************************/
2418 if(conn->resume_from) {
2419 if(!conn->bits.use_range) {
2420 /* if it already was in use, we just skip this */
2421 snprintf(resumerange, sizeof(resumerange), "%" FORMAT_OFF_T "-",
2423 conn->range=strdup(resumerange); /* tell ourselves to fetch this range */
2424 conn->bits.rangestringalloc = TRUE; /* mark as allocated */
2425 conn->bits.use_range = 1; /* switch on range usage */
2429 /*************************************************************
2430 * Setup internals depending on protocol
2431 *************************************************************/
2433 if (strequal(conn->protostr, "HTTP")) {
2434 #ifndef CURL_DISABLE_HTTP
2435 conn->port = (data->set.use_port && data->state.allow_port)?
2436 data->set.use_port:PORT_HTTP;
2437 conn->remote_port = PORT_HTTP;
2438 conn->protocol |= PROT_HTTP;
2439 conn->curl_do = Curl_http;
2440 conn->curl_do_more = NULL;
2441 conn->curl_done = Curl_http_done;
2442 conn->curl_connect = Curl_http_connect;
2444 failf(data, LIBCURL_NAME
2445 " was built with HTTP disabled, http: not supported!");
2446 return CURLE_UNSUPPORTED_PROTOCOL;
2449 else if (strequal(conn->protostr, "HTTPS")) {
2450 #if defined(USE_SSLEAY) && !defined(CURL_DISABLE_HTTP)
2452 conn->port = (data->set.use_port && data->state.allow_port)?
2453 data->set.use_port:PORT_HTTPS;
2454 conn->remote_port = PORT_HTTPS;
2455 conn->protocol |= PROT_HTTP|PROT_HTTPS|PROT_SSL;
2457 conn->curl_do = Curl_http;
2458 conn->curl_do_more = NULL;
2459 conn->curl_done = Curl_http_done;
2460 conn->curl_connect = Curl_http_connect;
2462 #else /* USE_SSLEAY */
2463 failf(data, LIBCURL_NAME
2464 " was built with SSL disabled, https: not supported!");
2465 return CURLE_UNSUPPORTED_PROTOCOL;
2466 #endif /* !USE_SSLEAY */
2468 else if (strequal(conn->protostr, "GOPHER")) {
2469 #ifndef CURL_DISABLE_GOPHER
2470 conn->port = (data->set.use_port && data->state.allow_port)?
2471 data->set.use_port:PORT_GOPHER;
2472 conn->remote_port = PORT_GOPHER;
2473 /* Skip /<item-type>/ in path if present */
2474 if (isdigit((int)conn->path[1])) {
2475 conn->ppath = strchr(&conn->path[1], '/');
2476 if (conn->ppath == NULL)
2477 conn->ppath = conn->path;
2479 conn->protocol |= PROT_GOPHER;
2480 conn->curl_do = Curl_http;
2481 conn->curl_do_more = NULL;
2482 conn->curl_done = Curl_http_done;
2484 failf(data, LIBCURL_NAME
2485 " was built with GOPHER disabled, gopher: not supported!");
2488 else if(strequal(conn->protostr, "FTP") ||
2489 strequal(conn->protostr, "FTPS")) {
2492 #ifndef CURL_DISABLE_FTP
2494 int port = PORT_FTP;
2496 if(strequal(conn->protostr, "FTPS")) {
2498 conn->protocol |= PROT_FTPS|PROT_SSL;
2499 conn->ssl[SECONDARYSOCKET].use = TRUE; /* send data securely */
2502 failf(data, LIBCURL_NAME
2503 " was built with SSL disabled, ftps: not supported!");
2504 return CURLE_UNSUPPORTED_PROTOCOL;
2505 #endif /* !USE_SSLEAY */
2508 conn->port = (data->set.use_port && data->state.allow_port)?
2509 data->set.use_port:port;
2510 conn->remote_port = port;
2511 conn->protocol |= PROT_FTP;
2513 if(data->change.proxy &&
2514 *data->change.proxy &&
2515 !data->set.tunnel_thru_httpproxy) {
2516 /* Unless we have asked to tunnel ftp operations through the proxy, we
2517 switch and use HTTP operations only */
2518 if(conn->protocol & PROT_FTPS) {
2519 /* FTPS is a hacked protocol and does not work through your
2520 ordinary http proxy! */
2521 failf(data, "ftps does not work through http proxy!");
2522 return CURLE_UNSUPPORTED_PROTOCOL;
2524 #ifndef CURL_DISABLE_HTTP
2525 conn->curl_do = Curl_http;
2526 conn->curl_done = Curl_http_done;
2528 failf(data, "FTP over http proxy requires HTTP support built-in!");
2529 return CURLE_UNSUPPORTED_PROTOCOL;
2533 conn->curl_do = Curl_ftp;
2534 conn->curl_do_more = Curl_ftp_nextconnect;
2535 conn->curl_done = Curl_ftp_done;
2536 conn->curl_connect = Curl_ftp_connect;
2537 conn->curl_disconnect = Curl_ftp_disconnect;
2540 conn->ppath++; /* don't include the initial slash */
2542 /* FTP URLs support an extension like ";type=<typecode>" that
2543 * we'll try to get now! */
2544 type=strstr(conn->ppath, ";type=");
2546 type=strstr(conn->gname, ";type=");
2550 *type=0; /* it was in the middle of the hostname */
2551 command = toupper(type[6]);
2553 case 'A': /* ASCII mode */
2554 data->set.ftp_ascii = 1;
2556 case 'D': /* directory mode */
2557 data->set.ftp_list_only = 1;
2559 case 'I': /* binary mode */
2561 /* switch off ASCII */
2562 data->set.ftp_ascii = 0;
2568 #else /* CURL_DISABLE_FTP */
2569 failf(data, LIBCURL_NAME
2570 " was built with FTP disabled, ftp/ftps: not supported!");
2571 return CURLE_UNSUPPORTED_PROTOCOL;
2574 else if(strequal(conn->protostr, "TELNET")) {
2575 #ifndef CURL_DISABLE_TELNET
2576 /* telnet testing factory */
2577 conn->protocol |= PROT_TELNET;
2579 conn->port = (data->set.use_port && data->state.allow_port)?
2580 data->set.use_port: PORT_TELNET;
2581 conn->remote_port = PORT_TELNET;
2582 conn->curl_do = Curl_telnet;
2583 conn->curl_done = Curl_telnet_done;
2585 failf(data, LIBCURL_NAME
2586 " was built with TELNET disabled!");
2589 else if (strequal(conn->protostr, "DICT")) {
2590 #ifndef CURL_DISABLE_DICT
2591 conn->protocol |= PROT_DICT;
2592 conn->port = (data->set.use_port && data->state.allow_port)?
2593 data->set.use_port:PORT_DICT;
2594 conn->remote_port = PORT_DICT;
2595 conn->curl_do = Curl_dict;
2596 conn->curl_done = NULL; /* no DICT-specific done */
2598 failf(data, LIBCURL_NAME
2599 " was built with DICT disabled!");
2602 else if (strequal(conn->protostr, "LDAP")) {
2603 #ifndef CURL_DISABLE_LDAP
2604 conn->protocol |= PROT_LDAP;
2605 conn->port = (data->set.use_port && data->state.allow_port)?
2606 data->set.use_port:PORT_LDAP;
2607 conn->remote_port = PORT_LDAP;
2608 conn->curl_do = Curl_ldap;
2609 conn->curl_done = NULL; /* no LDAP-specific done */
2611 failf(data, LIBCURL_NAME
2612 " was built with LDAP disabled!");
2615 else if (strequal(conn->protostr, "FILE")) {
2616 #ifndef CURL_DISABLE_FILE
2617 conn->protocol |= PROT_FILE;
2619 conn->curl_do = Curl_file;
2620 /* no done() function */
2622 /* anyway, this is supposed to be the connect function so we better
2623 at least check that the file is present here! */
2624 result = Curl_file_connect(conn);
2626 /* Setup a "faked" transfer that'll do nothing */
2627 if(CURLE_OK == result) {
2628 conn->bits.tcpconnect = TRUE; /* we are "connected */
2629 result = Curl_Transfer(conn, -1, -1, FALSE, NULL, /* no download */
2630 -1, NULL); /* no upload */
2635 failf(data, LIBCURL_NAME
2636 " was built with FILE disabled!");
2640 /* We fell through all checks and thus we don't support the specified
2642 failf(data, "Unsupported protocol: %s", conn->protostr);
2643 return CURLE_UNSUPPORTED_PROTOCOL;
2646 /*************************************************************
2647 * Figure out the remote port number
2649 * No matter if we use a proxy or not, we have to figure out the remote
2650 * port number of various reasons.
2652 * To be able to detect port number flawlessly, we must not confuse them
2653 * IPv6-specified addresses in the [0::1] style. (RFC2732)
2655 * The conn->name is currently [user:passwd@]host[:port] where host could
2656 * be a hostname, IPv4 address or IPv6 address.
2657 *************************************************************/
2658 if((1 == sscanf(conn->name, "[%*39[0-9a-fA-F:.]%c", &endbracket)) &&
2659 (']' == endbracket)) {
2660 /* this is a RFC2732-style specified IP-address */
2661 conn->bits.ipv6_ip = TRUE;
2663 conn->name++; /* pass the starting bracket */
2665 tmp = strchr(conn->name, ']');
2666 *tmp = 0; /* zero terminate */
2667 tmp++; /* pass the ending bracket */
2669 tmp = NULL; /* no port number available */
2672 tmp = strrchr(conn->name, ':');
2678 port=strtoul(tmp+1, &rest, 10); /* Port number must be decimal */
2680 if (rest != (tmp+1) && *rest == '\0') {
2681 /* The colon really did have only digits after it,
2682 * so it is either a port number or a mistake */
2684 if (port > 0xffff) { /* Single unix standard says port numbers are
2686 failf(data, "Port number too large: %lu", port);
2687 return CURLE_URL_MALFORMAT;
2690 *tmp = '\0'; /* cut off the name there */
2691 conn->remote_port = (unsigned short)port;
2695 if(data->change.proxy && *data->change.proxy) {
2696 /* If this is supposed to use a proxy, we need to figure out the proxy
2697 host name name, so that we can re-use an existing connection
2698 that may exist registered to the same proxy host. */
2703 /* We need to make a duplicate of the proxy so that we can modify the
2705 char *proxydup=strdup(data->change.proxy);
2707 /* We use 'proxyptr' to point to the proxy name from now on... */
2708 char *proxyptr=proxydup;
2710 if(NULL == proxydup) {
2711 failf(data, "memory shortage");
2712 return CURLE_OUT_OF_MEMORY;
2715 /* Daniel Dec 10, 1998:
2716 We do the proxy host string parsing here. We want the host name and the
2717 port name. Accept a protocol:// prefix, even though it should just be
2720 /* 1. skip the protocol part if present */
2721 endofprot=strstr(proxyptr, "://");
2723 proxyptr = endofprot+3;
2726 /* allow user to specify proxy.server.com:1080 if desired */
2727 prox_portno = strchr (proxyptr, ':');
2729 *prox_portno = 0x0; /* cut off number from host name */
2731 /* now set the local port number */
2732 conn->port = atoi(prox_portno);
2734 else if(data->set.proxyport) {
2735 /* None given in the proxy string, then get the default one if it is
2737 conn->port = data->set.proxyport;
2740 /* now, clone the cleaned proxy host name */
2741 conn->proxyhost = strdup(proxyptr);
2743 free(proxydup); /* free the duplicate pointer and not the modified */
2746 /*************************************************************
2747 * Take care of user and password authentication stuff
2748 *************************************************************/
2751 * Inputs: data->set.userpwd (CURLOPT_USERPWD)
2752 * data->set.fpasswd (CURLOPT_PASSWDFUNCTION)
2753 * data->set.use_netrc (CURLOPT_NETRC)
2756 * hard-coded defaults
2758 * Outputs: (almost :- all currently undefined)
2759 * conn->bits.user_passwd - non-zero if non-default passwords exist
2760 * conn->user - non-zero length if defined
2761 * conn->passwd - ditto
2762 * conn->hostname - remove user name and password
2765 /* At this point, we're hoping all the other special cases have
2766 * been taken care of, so conn->hostname is at most
2767 * [user[:password]]@]hostname
2769 * We need somewhere to put the embedded details, so do that first.
2772 user[0] =0; /* to make everything well-defined */
2775 if (conn->protocol & (PROT_FTP|PROT_HTTP)) {
2776 /* This is a FTP or HTTP URL, we will now try to extract the possible
2777 * user+password pair in a string like:
2778 * ftp://user:password@ftp.my.site:8021/README */
2779 char *ptr=strchr(conn->name, '@');
2780 char *userpass = conn->name;
2782 /* there's a user+password given here, to the left of the @ */
2784 conn->name = conn->hostname = ++ptr;
2786 /* So the hostname is sane. Only bother interpreting the
2787 * results if we could care. It could still be wasted
2788 * work because it might be overtaken by the programmatically
2789 * set user/passwd, but doing that first adds more cases here :-(
2792 if (data->set.use_netrc != CURL_NETRC_REQUIRED) {
2793 /* We could use the one in the URL */
2795 conn->bits.user_passwd = 1; /* enable user+password */
2797 if(*userpass != ':') {
2798 /* the name is given, get user+password */
2799 sscanf(userpass, "%127[^:@]:%127[^@]",
2803 /* no name given, get the password only */
2804 sscanf(userpass, ":%127[^@]", passwd);
2807 char *newname=curl_unescape(user, 0);
2808 if(strlen(newname) < sizeof(user)) {
2809 strcpy(user, newname);
2811 /* if the new name is longer than accepted, then just use
2812 the unconverted name, it'll be wrong but what the heck */
2816 /* we have a password found in the URL, decode it! */
2817 char *newpasswd=curl_unescape(passwd, 0);
2818 if(strlen(newpasswd) < sizeof(passwd)) {
2819 strcpy(passwd, newpasswd);
2827 /* Programmatically set password:
2828 * - always applies, if available
2829 * - takes precedence over the values we just set above
2830 * so scribble it over the top.
2831 * User-supplied passwords are assumed not to need unescaping.
2833 * user_password is set in "inherite initial knowledge' above,
2834 * so it doesn't have to be set in this block
2836 if (data->set.userpwd != NULL) {
2837 /* the name is given, get user+password */
2838 sscanf(data->set.userpwd,
2839 "%" MAX_CURL_USER_LENGTH_TXT "[^:]:"
2840 "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]",
2844 if (data->set.use_netrc != CURL_NETRC_IGNORED) {
2845 if(Curl_parsenetrc(conn->hostname,
2847 data->set.netrc_file)) {
2848 infof(data, "Couldn't find host %s in the .netrc file, using defaults\n",
2852 conn->bits.user_passwd = 1; /* enable user+password */
2855 /* If our protocol needs a password and we have none, use the defaults */
2856 if ( (conn->protocol & PROT_FTP) &&
2857 !conn->bits.user_passwd) {
2859 conn->user = strdup(CURL_DEFAULT_USER);
2860 conn->passwd = strdup(CURL_DEFAULT_PASSWORD);
2862 /* This is the default password, so DON'T set conn->bits.user_passwd */
2865 /* store user + password, zero-length if not set */
2866 conn->user = strdup(user);
2867 conn->passwd = strdup(passwd);
2870 /*************************************************************
2871 * Check the current list of connections to see if we can
2872 * re-use an already existing one or if we have to create a
2874 *************************************************************/
2876 /* get a cloned copy of the SSL config situation stored in the
2877 connection struct */
2878 if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config))
2879 return CURLE_OUT_OF_MEMORY;
2881 /* reuse_fresh is TRUE if we are told to use a new connection by force, but
2882 we only acknowledge this option if this is not a re-used connection
2883 already (which happens due to follow-location or during a HTTP
2884 authentication phase). */
2885 if(data->set.reuse_fresh && !data->state.this_is_a_follow)
2888 reuse = ConnectionExists(data, conn, &conn_temp);
2892 * We already have a connection for this, we got the former connection
2893 * in the conn_temp variable and thus we need to cleanup the one we
2894 * just allocated before we can move along and use the previously
2897 struct connectdata *old_conn = conn;
2898 char *path = old_conn->path; /* setup the current path pointer properly */
2899 char *ppath = old_conn->ppath; /* this is the modified path pointer */
2900 if(old_conn->proxyhost)
2901 free(old_conn->proxyhost);
2903 /* free the SSL config struct from this connection struct as this was
2904 allocated in vain and is targeted for destruction */
2905 Curl_free_ssl_config(&conn->ssl_config);
2907 conn = conn_temp; /* use this connection from now on */
2909 /* get the user+password information from the old_conn struct since it may
2910 * be new for this request even when we re-use an existing connection */
2911 conn->bits.user_passwd = old_conn->bits.user_passwd;
2912 conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd;
2914 /* If we speak over a proxy, we need to copy the host name too, as it
2915 might be another remote host even when re-using a connection */
2916 strcpy(conn->gname, old_conn->gname); /* safe strcpy() */
2918 /* we need these pointers if we speak over a proxy */
2919 conn->hostname = conn->gname;
2920 conn->name = &conn->gname[old_conn->name - old_conn->gname];
2922 free(conn->path); /* free the previously allocated path pointer */
2924 /* 'path' points to the allocated data, 'ppath' may have been advanced
2925 to point somewhere within the 'path' area. */
2927 conn->ppath = ppath;
2930 conn->bits.reuse = TRUE; /* yes, we're re-using here */
2931 conn->bits.chunk = FALSE; /* always assume not chunked unless told
2933 conn->maxdownload = -1; /* might have been used previously! */
2935 Curl_safefree(old_conn->user);
2936 Curl_safefree(old_conn->passwd);
2937 Curl_safefree(old_conn->proxyuser);
2938 Curl_safefree(old_conn->proxypasswd);
2940 if(old_conn->bits.rangestringalloc)
2941 free(old_conn->range);
2943 free(old_conn); /* we don't need this anymore */
2946 * If we're doing a resumed transfer, we need to setup our stuff
2949 conn->resume_from = data->set.set_resume_from;
2950 if (conn->resume_from) {
2951 snprintf(resumerange, sizeof(resumerange), "%" FORMAT_OFF_T "-",
2953 if (conn->bits.rangestringalloc == TRUE)
2956 /* tell ourselves to fetch this range */
2957 conn->range = strdup(resumerange);
2958 conn->bits.use_range = TRUE; /* enable range download */
2959 conn->bits.rangestringalloc = TRUE; /* mark range string allocated */
2961 else if (data->set.set_range) {
2962 /* There is a range, but is not a resume, useful for random ftp access */
2963 conn->range = strdup(data->set.set_range);
2964 conn->bits.rangestringalloc = TRUE; /* mark range string allocated */
2965 conn->bits.use_range = TRUE; /* enable range download */
2968 conn->bits.use_range = FALSE; /* disable range download */
2970 *in_connect = conn; /* return this instead! */
2972 infof(data, "Re-using existing connection! (#%d)\n", conn->connectindex);
2976 * This is a brand new connection, so let's store it in the connection
2979 ConnectionStore(data, conn);
2982 /* Continue connectdata initialization here.
2984 * Inherit the proper values from the urldata struct AFTER we have arranged
2985 * the persistant conncetion stuff */
2986 conn->fread = data->set.fread;
2987 conn->fread_in = data->set.in;
2989 conn->bits.upload_chunky =
2990 ((conn->protocol&PROT_HTTP) &&
2992 (data->set.infilesize == -1) &&
2993 (data->set.httpversion != CURL_HTTP_VERSION_1_0))?
2994 /* HTTP, upload, unknown file size and not HTTP 1.0 */
2996 /* else, no chunky upload */
3000 /*************************************************************
3001 * Set timeout if that is being used, and we're not using an asynchronous
3003 *************************************************************/
3004 if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) {
3005 /*************************************************************
3006 * Set signal handler to catch SIGALRM
3007 * Store the old value to be able to set it back later!
3008 *************************************************************/
3011 #ifdef HAVE_SIGACTION
3012 struct sigaction sigact;
3013 sigaction(SIGALRM, NULL, &sigact);
3014 keep_sigact = sigact;
3015 keep_copysig = TRUE; /* yes, we have a copy */
3016 sigact.sa_handler = alarmfunc;
3018 /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */
3019 sigact.sa_flags &= ~SA_RESTART;
3021 /* now set the new struct */
3022 sigaction(SIGALRM, &sigact, NULL);
3023 #else /* HAVE_SIGACTION */
3024 /* no sigaction(), revert to the much lamer signal() */
3026 keep_sigact = signal(SIGALRM, alarmfunc);
3028 #endif /* HAVE_SIGACTION */
3030 /* We set the timeout on the name resolving phase first, separately from
3031 * the download/upload part to allow a maximum time on everything. This is
3032 * a signal-based timeout, why it won't work and shouldn't be used in
3033 * multi-threaded environments. */
3036 /* alarm() makes a signal get sent when the timeout fires off, and that
3037 will abort system calls */
3038 prev_alarm = alarm(data->set.connecttimeout?
3039 data->set.connecttimeout:
3041 /* We can expect the conn->created time to be "now", as that was just
3042 recently set in the beginning of this function and nothing slow
3043 has been done since then until now. */
3045 #endif /* SIGALRM */
3047 #endif /* USE_ARES */
3049 /*************************************************************
3050 * Resolve the name of the server or proxy
3051 *************************************************************/
3052 if(conn->bits.reuse) {
3053 /* re-used connection, no resolving is necessary */
3055 conn->connect_addr = NULL; /* we don't connect now so we don't have any
3056 fresh connect_addr struct to point to */
3058 else if(!data->change.proxy || !*data->change.proxy) {
3059 /* If not connecting via a proxy, extract the port from the URL, if it is
3060 * there, thus overriding any defaults that might have been set above. */
3061 conn->port = conn->remote_port; /* it is the same port */
3063 /* Resolve target host right on */
3064 rc = Curl_resolv(conn, conn->name, conn->port, &hostaddr);
3068 else if(!hostaddr) {
3069 failf(data, "Couldn't resolve host '%s'", conn->name);
3070 result = CURLE_COULDNT_RESOLVE_HOST;
3071 /* don't return yet, we need to clean up the timeout first */
3075 /* This is a proxy that hasn't been resolved yet. */
3078 rc = Curl_resolv(conn, conn->proxyhost, conn->port, &hostaddr);
3083 else if(!hostaddr) {
3084 failf(data, "Couldn't resolve proxy '%s'", conn->proxyhost);
3085 result = CURLE_COULDNT_RESOLVE_PROXY;
3086 /* don't return yet, we need to clean up the timeout first */
3091 #if defined(HAVE_ALARM) && defined(SIGALRM)
3092 if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) {
3093 #ifdef HAVE_SIGACTION
3095 /* we got a struct as it looked before, now put that one back nice
3097 sigaction(SIGALRM, &keep_sigact, NULL); /* put it back */
3101 /* restore the previous SIGALRM handler */
3102 signal(SIGALRM, keep_sigact);
3104 #endif /* HAVE_SIGACTION */
3106 /* switch back the alarm() to either zero or to what it was before minus
3107 the time we spent until now! */
3109 /* there was an alarm() set before us, now put it back */
3110 long elapsed_ms = Curl_tvdiff(Curl_tvnow(), conn->created);
3113 /* the alarm period is counted in even number of seconds */
3114 alarm_set = prev_alarm - elapsed_ms/1000;
3117 /* if it turned negative, we should fire off a SIGALRM here, but we
3118 won't, and zero would be to switch it off so we never set it to
3121 result = CURLE_OPERATION_TIMEOUTED;
3122 failf(data, "Previous alarm fired off!");
3128 alarm(0); /* just shut it off */
3135 /* SetupConnection() should be called after the name resolve initiated in
3136 * CreateConnection() is all done.
3139 static CURLcode SetupConnection(struct connectdata *conn,
3140 struct Curl_dns_entry *hostaddr)
3142 struct SessionHandle *data = conn->data;
3143 CURLcode result=CURLE_OK;
3145 Curl_pgrsTime(data, TIMER_NAMELOOKUP);
3147 if(conn->protocol & PROT_FILE)
3148 /* There's nothing in this function to setup if we're only doing
3149 a file:// transfer */
3152 /*************************************************************
3153 * Send user-agent to HTTP proxies even if the target protocol
3155 *************************************************************/
3156 if((conn->protocol&PROT_HTTP) ||
3157 (data->change.proxy && *data->change.proxy)) {
3158 if(data->set.useragent) {
3159 Curl_safefree(conn->allocptr.uagent);
3160 conn->allocptr.uagent =
3161 aprintf("User-Agent: %s\015\012", data->set.useragent);
3165 if(data->set.encoding) {
3166 Curl_safefree(conn->allocptr.accept_encoding);
3167 conn->allocptr.accept_encoding =
3168 aprintf("Accept-Encoding: %s\015\012", data->set.encoding);
3171 conn->bytecount = 0;
3172 conn->headerbytecount = 0;
3174 if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
3177 /* Connect only if not already connected! */
3178 result = ConnectPlease(conn, hostaddr, &connected);
3181 result = Curl_protocol_connect(conn, hostaddr);
3182 if(CURLE_OK == result)
3183 conn->bits.tcpconnect = TRUE;
3186 conn->bits.tcpconnect = FALSE;
3189 if(CURLE_OK != result)
3193 Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */
3194 conn->bits.tcpconnect = TRUE;
3195 if(data->set.verbose)
3196 verboseconnect(conn, hostaddr);
3199 conn->now = Curl_tvnow(); /* time this *after* the connect is done, we
3200 set this here perhaps a second time */
3204 * the check is quite a hack...
3205 * we're calling _fsetmode to fix the problem with fwrite converting newline
3206 * characters (you get mangled text files, and corrupted binary files when
3207 * you download to stdout and redirect it to a file). */
3209 if ((data->set.out)->_handle == NULL) {
3210 _fsetmode(stdout, "b");
3217 CURLcode Curl_connect(struct SessionHandle *data,
3218 struct connectdata **in_connect,
3222 struct Curl_dns_entry *dns;
3224 *asyncp = FALSE; /* assume synchronous resolves by default */
3226 /* call the stuff that needs to be called */
3227 code = CreateConnection(data, in_connect, &dns, asyncp);
3229 if(CURLE_OK == code) {
3232 /* If an address is available it means that we already have the name
3233 resolved, OR it isn't async.
3234 If so => continue connecting from here */
3235 code = SetupConnection(*in_connect, dns);
3237 response will be received and treated async wise */
3240 if(CURLE_OK != code) {
3241 /* We're not allowed to return failure with memory left allocated
3242 in the connectdata struct, free those here */
3244 Curl_disconnect(*in_connect); /* close the connection */
3245 *in_connect = NULL; /* return a NULL */
3252 /* Call this function after Curl_connect() has returned async=TRUE and
3253 then a successful name resolve has been received */
3254 CURLcode Curl_async_resolved(struct connectdata *conn)
3256 #if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME)
3257 CURLcode code = SetupConnection(conn, conn->async.dns);
3260 /* We're not allowed to return failure with memory left allocated
3261 in the connectdata struct, free those here */
3262 Curl_disconnect(conn); /* close the connection */
3272 CURLcode Curl_done(struct connectdata *conn)
3274 struct SessionHandle *data=conn->data;
3277 /* cleanups done even if the connection is re-used */
3279 if(conn->bits.rangestringalloc) {
3281 conn->bits.rangestringalloc = FALSE;
3284 /* Cleanup possible redirect junk */
3287 conn->newurl = NULL;
3290 if(conn->connect_addr)
3291 Curl_resolv_unlock(conn->data, conn->connect_addr); /* done with this */
3293 #if defined(CURLDEBUG) && defined(AGGRESIVE_TEST)
3294 /* scan for DNS cache entries still marked as in use */
3295 Curl_hash_apply(data->hostcache,
3296 NULL, Curl_scan_cache_used);
3299 Curl_hostcache_prune(data); /* kill old DNS cache entries */
3301 /* this calls the protocol-specific function pointer previously set */
3303 result = conn->curl_done(conn);
3307 Curl_pgrsDone(conn); /* done with the operation */
3309 /* if data->set.reuse_forbid is TRUE, it means the libcurl client has
3310 forced us to close this no matter what we think.
3312 if conn->bits.close is TRUE, it means that the connection should be
3313 closed in spite of all our efforts to be nice, due to protocol
3314 restrictions in our or the server's end */
3315 if(data->set.reuse_forbid || conn->bits.close) {
3317 res2 = Curl_disconnect(conn); /* close the connection */
3319 /* If we had an error already, make sure we return that one. But
3320 if we got a new error, return that. */
3325 infof(data, "Connection #%d left intact\n", conn->connectindex);
3330 CURLcode Curl_do(struct connectdata **connp)
3332 CURLcode result=CURLE_OK;
3333 struct connectdata *conn = *connp;
3334 struct SessionHandle *data=conn->data;
3336 conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */
3339 /* generic protocol-specific function pointer set in curl_connect() */
3340 result = conn->curl_do(conn);
3342 /* This was formerly done in transfer.c, but we better do it here */
3344 if((CURLE_SEND_ERROR == result) && conn->bits.reuse) {
3345 /* This was a re-use of a connection and we got a write error in the
3346 * DO-phase. Then we DISCONNECT this connection and have another attempt
3347 * to CONNECT and then DO again! The retry cannot possibly find another
3348 * connection to re-use, since we only keep one possible connection for
3351 infof(data, "Re-used connection seems dead, get a new one\n");
3353 conn->bits.close = TRUE; /* enforce close of this connection */
3354 result = Curl_done(conn); /* we are so done with this */
3356 /* conn is no longer a good pointer */
3358 if(CURLE_OK == result) {
3360 /* Now, redo the connect and get a new connection */
3361 result = Curl_connect(data, connp, &async);
3362 if(CURLE_OK == result) {
3363 /* We have connected or sent away a name resolve query fine */
3365 conn = *connp; /* setup conn to again point to something nice */
3367 /* Now, if async is TRUE here, we need to wait for the name
3369 result = Curl_wait_for_resolv(conn, NULL);
3373 /* Resolved, continue with the connection */
3374 result = Curl_async_resolved(conn);
3379 /* ... finally back to actually retry the DO phase */
3380 result = conn->curl_do(conn);
3388 CURLcode Curl_do_more(struct connectdata *conn)
3390 CURLcode result=CURLE_OK;
3392 if(conn->curl_do_more)
3393 result = conn->curl_do_more(conn);
3398 static bool safe_strequal(char* str1, char* str2)
3401 /* both pointers point to something then compare them */
3402 return strequal(str1, str2);
3404 /* if both pointers are NULL then treat them as equal */
3405 return (!str1 && !str2);
3409 Curl_ssl_config_matches(struct ssl_config_data* data,
3410 struct ssl_config_data* needle)
3412 if((data->version == needle->version) &&
3413 (data->verifypeer == needle->verifypeer) &&
3414 (data->verifyhost == needle->verifyhost) &&
3415 safe_strequal(data->CApath, needle->CApath) &&
3416 safe_strequal(data->CAfile, needle->CAfile) &&
3417 safe_strequal(data->random_file, needle->random_file) &&
3418 safe_strequal(data->egdsocket, needle->egdsocket) &&
3419 safe_strequal(data->cipher_list, needle->cipher_list))
3426 Curl_clone_ssl_config(struct ssl_config_data *source,
3427 struct ssl_config_data *dest)
3429 dest->verifyhost = source->verifyhost;
3430 dest->verifypeer = source->verifypeer;
3431 dest->version = source->version;
3433 if(source->CAfile) {
3434 dest->CAfile = strdup(source->CAfile);
3439 if(source->CApath) {
3440 dest->CApath = strdup(source->CApath);
3445 if(source->cipher_list) {
3446 dest->cipher_list = strdup(source->cipher_list);
3447 if(!dest->cipher_list)
3451 if(source->egdsocket) {
3452 dest->egdsocket = strdup(source->egdsocket);
3453 if(!dest->egdsocket)
3457 if(source->random_file) {
3458 dest->random_file = strdup(source->random_file);
3459 if(!dest->random_file)
3466 void Curl_free_ssl_config(struct ssl_config_data* sslc)
3474 if(sslc->cipher_list)
3475 free(sslc->cipher_list);
3478 free(sslc->egdsocket);
3480 if(sslc->random_file)
3481 free(sslc->random_file);