1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2005, 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.
22 ***************************************************************************/
24 /* -- WIN32 approved -- */
33 #ifdef HAVE_SYS_TYPES_H
34 #include <sys/types.h>
36 #ifdef HAVE_SYS_STAT_H
41 #if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
45 #ifdef HAVE_SYS_SOCKET_H
46 #include <sys/socket.h>
48 #include <netinet/in.h>
54 #ifdef HAVE_ARPA_INET_H
55 #include <arpa/inet.h>
60 #include <sys/ioctl.h>
63 #ifdef HAVE_SYS_PARAM_H
64 #include <sys/param.h>
77 #error "We can't compile without socket() support!"
86 #include <stringprep.h>
87 #ifdef HAVE_IDN_FREE_H
90 void idn_free (void *ptr); /* prototype from idn-free.h, not provided by
91 libidn 0.4.5's make install! */
94 /* if idn_free() was not found in this version of libidn, use plain free()
96 #define idn_free(x) (free)(x)
103 #include "formdata.h"
107 #include "transfer.h"
109 #include "progress.h"
111 #include "strequal.h"
112 #include "strerror.h"
116 #include "content_encoding.h"
117 #include "http_digest.h"
118 #include "http_negotiate.h"
122 /* And now for the protocols */
131 #include "inet_ntop.h"
132 #include "http_ntlm.h"
133 #include <ca-bundle.h>
135 #if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
136 #include "inet_ntoa_r.h"
139 #define _MPRINTF_REPLACE /* use our functions only */
140 #include <curl/mprintf.h>
147 /* The last #include file should be: */
148 #include "memdebug.h"
150 /* Local static prototypes */
151 static long ConnectionKillOne(struct SessionHandle *data);
152 static bool ConnectionExists(struct SessionHandle *data,
153 struct connectdata *needle,
154 struct connectdata **usethis);
155 static long ConnectionStore(struct SessionHandle *data,
156 struct connectdata *conn);
157 static bool safe_strequal(char* str1, char* str2);
160 /* not for Win32, unless it is cygwin
161 not for ares builds */
162 #if !defined(WIN32) || defined(__CYGWIN32__)
165 #define RETSIGTYPE void
167 #ifdef HAVE_SIGSETJMP
168 extern sigjmp_buf curl_jmpenv;
171 RETSIGTYPE alarmfunc(int sig)
173 /* this is for "-ansi -Wall -pedantic" to stop complaining! (rabe) */
175 #ifdef HAVE_SIGSETJMP
176 siglongjmp(curl_jmpenv, 1);
181 #endif /* USE_ARES */
183 void Curl_safefree(void *ptr)
190 * This is the internal function curl_easy_cleanup() calls. This should
191 * cleanup and free all resources associated with this sessionhandle.
193 * NOTE: if we ever add something that attempts to write to a socket or
194 * similar here, we must ignore SIGPIPE first. It is currently only done
195 * when curl_easy_perform() is invoked.
198 CURLcode Curl_close(struct SessionHandle *data)
201 /* this handle is still part of a multi handle, take care of this first */
202 Curl_multi_rmeasy(data->multi, data);
204 /* Loop through all open connections and kill them one by one */
205 while(-1 != ConnectionKillOne(data))
208 if ( ! (data->share && data->share->hostcache) ) {
209 if ( !Curl_global_host_cache_use(data)) {
210 Curl_hash_destroy(data->hostcache);
215 /* Close down all open SSL info and sessions */
216 Curl_SSL_Close_All(data);
219 Curl_safefree(data->state.first_host);
220 Curl_safefree(data->state.scratch);
222 if(data->change.proxy_alloc)
223 free(data->change.proxy);
225 if(data->change.referer_alloc)
226 free(data->change.referer);
228 if(data->change.url_alloc)
229 free(data->change.url);
231 Curl_safefree(data->state.headerbuff);
233 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
234 if(data->change.cookielist) /* clean up list if any */
235 curl_slist_free_all(data->change.cookielist);
237 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
238 if(data->set.cookiejar) {
239 /* we have a "destination" for all the cookies to get dumped to */
240 if(Curl_cookie_output(data->cookies, data->set.cookiejar))
241 infof(data, "WARNING: failed to save cookies in %s\n",
242 data->set.cookiejar);
245 if( !data->share || (data->cookies != data->share->cookies) ) {
246 Curl_cookie_cleanup(data->cookies);
248 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
251 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
252 Curl_digest_cleanup(data);
255 /* free the connection cache */
256 free(data->state.connects);
258 Curl_safefree(data->info.contenttype);
261 /* this destroys the channel and we cannot use it anymore after this */
262 ares_destroy(data->state.areschannel);
265 /* No longer a dirty share, if it exists */
267 data->share->dirty--;
276 * @param curl is a pointer to a sessionhandle pointer that gets set by this
281 CURLcode Curl_open(struct SessionHandle **curl)
283 CURLcode res = CURLE_OK;
284 struct SessionHandle *data;
285 /* Very simple start-up: alloc the struct, init it with zeroes and return */
286 data = (struct SessionHandle *)calloc(1, sizeof(struct SessionHandle));
288 /* this is a very serious error */
289 return CURLE_OUT_OF_MEMORY;
292 if(ARES_SUCCESS != ares_init(&data->state.areschannel)) {
294 return CURLE_FAILED_INIT;
296 /* make sure that all other returns from this function should destroy the
297 ares channel before returning error! */
300 /* We do some initial setup here, all those fields that can't be just 0 */
302 data->state.headerbuff=(char*)malloc(HEADERSIZE);
303 if(!data->state.headerbuff)
304 res = CURLE_OUT_OF_MEMORY;
306 data->state.headersize=HEADERSIZE;
308 data->set.out = stdout; /* default output to stdout */
309 data->set.in = stdin; /* default input from stdin */
310 data->set.err = stderr; /* default stderr to stderr */
312 /* use fwrite as default function to store output */
313 data->set.fwrite = (curl_write_callback)fwrite;
315 /* use fread as default function to read input */
316 data->set.fread = (curl_read_callback)fread;
318 data->set.infilesize = -1; /* we don't know any size */
319 data->set.postfieldsize = -1;
321 data->state.current_speed = -1; /* init to negative == impossible */
323 data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */
324 data->set.ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */
325 data->set.ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */
326 data->set.ftp_use_lprt = TRUE; /* FTP defaults to EPRT operations */
328 data->set.dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
330 /* make libcurl quiet by default: */
331 data->set.hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */
332 data->progress.flags |= PGRS_HIDE;
334 /* Set the default size of the SSL session ID cache */
335 data->set.ssl.numsessions = 5;
337 data->set.proxyport = 1080;
338 data->set.proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
339 data->set.httpauth = CURLAUTH_BASIC; /* defaults to basic */
340 data->set.proxyauth = CURLAUTH_BASIC; /* defaults to basic */
342 /* create an array with connection data struct pointers */
343 data->state.numconnects = 5; /* hard-coded right now */
344 data->state.connects = (struct connectdata **)
345 malloc(sizeof(struct connectdata *) * data->state.numconnects);
347 if(!data->state.connects)
348 res = CURLE_OUT_OF_MEMORY;
350 memset(data->state.connects, 0,
351 sizeof(struct connectdata *)*data->state.numconnects);
354 * libcurl 7.10 introduced SSL verification *by default*! This needs to be
355 * switched off unless wanted.
357 data->set.ssl.verifypeer = TRUE;
358 data->set.ssl.verifyhost = 2;
359 #ifdef CURL_CA_BUNDLE
360 /* This is our prefered CA cert bundle since install time */
361 data->set.ssl.CAfile = (char *)CURL_CA_BUNDLE;
367 ares_destroy(data->state.areschannel);
369 if(data->state.headerbuff)
370 free(data->state.headerbuff);
379 CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
383 CURLcode result = CURLE_OK;
385 va_start(param, option);
388 case CURLOPT_DNS_CACHE_TIMEOUT:
389 data->set.dns_cache_timeout = va_arg(param, int);
391 case CURLOPT_DNS_USE_GLOBAL_CACHE:
393 int use_cache = va_arg(param, int);
395 Curl_global_host_cache_init();
398 data->set.global_dns_cache = use_cache;
401 case CURLOPT_SSL_CIPHER_LIST:
402 /* set a list of cipher we want to use in the SSL connection */
403 data->set.ssl.cipher_list = va_arg(param, char *);
406 case CURLOPT_RANDOM_FILE:
408 * This is the path name to a file that contains random data to seed
409 * the random SSL stuff with. The file is only used for reading.
411 data->set.ssl.random_file = va_arg(param, char *);
413 case CURLOPT_EGDSOCKET:
415 * The Entropy Gathering Daemon socket pathname
417 data->set.ssl.egdsocket = va_arg(param, char *);
419 case CURLOPT_MAXCONNECTS:
421 * Set the absolute number of maximum simultaneous alive connection that
422 * libcurl is allowed to have.
425 long newconnects= va_arg(param, long);
426 struct connectdata **newptr;
429 if(newconnects < data->state.numconnects) {
430 /* Since this number is *decreased* from the existing number, we must
431 close the possibly open connections that live on the indexes that
432 are being removed! */
433 for(i=newconnects; i< data->state.numconnects; i++)
434 Curl_disconnect(data->state.connects[i]);
437 newptr= (struct connectdata **)
438 realloc(data->state.connects,
439 sizeof(struct connectdata *) * newconnects);
441 /* we closed a few connections in vain, but so what? */
442 return CURLE_OUT_OF_MEMORY;
444 /* nullify the newly added pointers */
445 for(i=data->state.numconnects; i<newconnects; i++) {
449 data->state.connects = newptr;
450 data->state.numconnects = newconnects;
453 /* zero makes NO cache at all */
454 if(data->state.connects)
455 free(data->state.connects);
456 data->state.connects=NULL;
457 data->state.numconnects=0;
461 case CURLOPT_FORBID_REUSE:
463 * When this transfer is done, it must not be left to be reused by a
464 * subsequent transfer but shall be closed immediately.
466 data->set.reuse_forbid = va_arg(param, long)?TRUE:FALSE;
468 case CURLOPT_FRESH_CONNECT:
470 * This transfer shall not use a previously cached connection but
471 * should be made with a fresh new connect!
473 data->set.reuse_fresh = va_arg(param, long)?TRUE:FALSE;
475 case CURLOPT_VERBOSE:
477 * Verbose means infof() calls that give a lot of information about
478 * the connection and transfer procedures as well as internal choices.
480 data->set.verbose = va_arg(param, long)?TRUE:FALSE;
484 * Set to include the header in the general data output stream.
486 data->set.include_header = va_arg(param, long)?TRUE:FALSE;
488 case CURLOPT_NOPROGRESS:
490 * Shut off the internal supported progress meter
492 data->set.hide_progress = va_arg(param, long)?TRUE:FALSE;
493 if(data->set.hide_progress)
494 data->progress.flags |= PGRS_HIDE;
496 data->progress.flags &= ~PGRS_HIDE;
500 * Do not include the body part in the output data stream.
502 data->set.opt_no_body = va_arg(param, long)?TRUE:FALSE;
503 if(data->set.opt_no_body)
504 /* in HTTP lingo, this means using the HEAD request */
505 data->set.httpreq = HTTPREQ_HEAD;
507 case CURLOPT_FAILONERROR:
509 * Don't output the >=300 error code HTML-page, but instead only
512 data->set.http_fail_on_error = va_arg(param, long)?TRUE:FALSE;
517 * We want to sent data to the remote host. If this is HTTP, that equals
518 * using the PUT request.
520 data->set.upload = va_arg(param, long)?TRUE:FALSE;
522 /* If this is HTTP, PUT is what's needed to "upload" */
523 data->set.httpreq = HTTPREQ_PUT;
525 case CURLOPT_FILETIME:
527 * Try to get the file time of the remote document. The time will
528 * later (possibly) become available using curl_easy_getinfo().
530 data->set.get_filetime = va_arg(param, long)?TRUE:FALSE;
532 case CURLOPT_FTP_CREATE_MISSING_DIRS:
534 * An FTP option that modifies an upload to create missing directories on
537 data->set.ftp_create_missing_dirs = va_arg( param , long )?TRUE:FALSE;
539 case CURLOPT_FTP_RESPONSE_TIMEOUT:
541 * An FTP option that specifies how quickly an FTP response must be
542 * obtained before it is considered failure.
544 data->set.ftp_response_timeout = va_arg( param , long );
546 case CURLOPT_FTPLISTONLY:
548 * An FTP option that changes the command to one that asks for a list
549 * only, no file info details.
551 data->set.ftp_list_only = va_arg(param, long)?TRUE:FALSE;
553 case CURLOPT_FTPAPPEND:
555 * We want to upload and append to an existing (FTP) file.
557 data->set.ftp_append = va_arg(param, long)?TRUE:FALSE;
561 * Parse the $HOME/.netrc file
563 data->set.use_netrc = (enum CURL_NETRC_OPTION)va_arg(param, long);
565 case CURLOPT_NETRC_FILE:
567 * Use this file instead of the $HOME/.netrc file
569 data->set.netrc_file = va_arg(param, char *);
571 case CURLOPT_TRANSFERTEXT:
573 * This option was previously named 'FTPASCII'. Renamed to work with
574 * more protocols than merely FTP.
576 * Transfer using ASCII (instead of BINARY).
578 data->set.ftp_ascii = va_arg(param, long)?TRUE:FALSE;
580 case CURLOPT_TIMECONDITION:
582 * Set HTTP time condition. This must be one of the defines in the
583 * curl/curl.h header file.
585 data->set.timecondition = (curl_TimeCond)va_arg(param, long);
587 case CURLOPT_TIMEVALUE:
589 * This is the value to compare with the remote document with the
590 * method set with CURLOPT_TIMECONDITION
592 data->set.timevalue = (time_t)va_arg(param, long);
594 case CURLOPT_SSLVERSION:
596 * Set explicit SSL version to try to connect with, as some SSL
597 * implementations are lame.
599 data->set.ssl.version = va_arg(param, long);
602 #ifndef CURL_DISABLE_HTTP
603 case CURLOPT_AUTOREFERER:
605 * Switch on automatic referer that gets set if curl follows locations.
607 data->set.http_auto_referer = va_arg(param, long)?1:0;
610 case CURLOPT_ENCODING:
612 * String to use at the value of Accept-Encoding header.
614 * If the encoding is set to "" we use an Accept-Encoding header that
615 * encompasses all the encodings we support.
616 * If the encoding is set to NULL we don't send an Accept-Encoding header
617 * and ignore an received Content-Encoding header.
620 data->set.encoding = va_arg(param, char *);
621 if(data->set.encoding && !*data->set.encoding)
622 data->set.encoding = (char*)ALL_CONTENT_ENCODINGS;
625 case CURLOPT_FOLLOWLOCATION:
627 * Follow Location: header hints on a HTTP-server.
629 data->set.http_follow_location = va_arg(param, long)?TRUE:FALSE;
632 case CURLOPT_UNRESTRICTED_AUTH:
634 * Send authentication (user+password) when following locations, even when
637 data->set.http_disable_hostname_check_before_authentication =
638 va_arg(param, long)?TRUE:FALSE;
641 case CURLOPT_MAXREDIRS:
643 * The maximum amount of hops you allow curl to follow Location:
644 * headers. This should mostly be used to detect never-ending loops.
646 data->set.maxredirs = va_arg(param, long);
650 /* Does this option serve a purpose anymore? Yes it does, when
651 CURLOPT_POSTFIELDS isn't used and the POST data is read off the
653 if(va_arg(param, long))
654 data->set.httpreq = HTTPREQ_POST;
656 data->set.httpreq = HTTPREQ_GET;
659 case CURLOPT_POSTFIELDS:
661 * A string with POST data. Makes curl HTTP POST. Even if it is NULL.
663 data->set.postfields = va_arg(param, char *);
664 data->set.httpreq = HTTPREQ_POST;
667 case CURLOPT_POSTFIELDSIZE:
669 * The size of the POSTFIELD data to prevent libcurl to do strlen() to
670 * figure it out. Enables binary posts.
672 data->set.postfieldsize = va_arg(param, long);
675 case CURLOPT_POSTFIELDSIZE_LARGE:
677 * The size of the POSTFIELD data to prevent libcurl to do strlen() to
678 * figure it out. Enables binary posts.
680 data->set.postfieldsize = va_arg(param, curl_off_t);
683 case CURLOPT_HTTPPOST:
685 * Set to make us do HTTP POST
687 data->set.httppost = va_arg(param, struct curl_httppost *);
688 data->set.httpreq = HTTPREQ_POST_FORM;
691 case CURLOPT_REFERER:
693 * String to set in the HTTP Referer: field.
695 if(data->change.referer_alloc) {
696 free(data->change.referer);
697 data->change.referer_alloc = FALSE;
699 data->set.set_referer = va_arg(param, char *);
700 data->change.referer = data->set.set_referer;
703 case CURLOPT_USERAGENT:
705 * String to use in the HTTP User-Agent field
707 data->set.useragent = va_arg(param, char *);
710 case CURLOPT_HTTPHEADER:
712 * Set a list with HTTP headers to use (or replace internals with)
714 data->set.headers = va_arg(param, struct curl_slist *);
717 case CURLOPT_HTTP200ALIASES:
719 * Set a list of aliases for HTTP 200 in response header
721 data->set.http200aliases = va_arg(param, struct curl_slist *);
724 #if !defined(CURL_DISABLE_COOKIES)
727 * Cookie string to send to the remote server in the request.
729 data->set.cookie = va_arg(param, char *);
732 case CURLOPT_COOKIEFILE:
734 * Set cookie file to read and parse. Can be used multiple times.
736 argptr = (char *)va_arg(param, void *);
738 struct curl_slist *cl;
739 /* append the cookie file name to the list of file names, and deal with
741 cl = curl_slist_append(data->change.cookielist, argptr);
744 return CURLE_OUT_OF_MEMORY;
746 data->change.cookielist = cl;
750 case CURLOPT_COOKIEJAR:
752 * Set cookie file name to dump all cookies to when we're done.
754 data->set.cookiejar = (char *)va_arg(param, void *);
757 * Activate the cookie parser. This may or may not already
760 data->cookies = Curl_cookie_init(data, NULL, data->cookies,
761 data->set.cookiesession);
764 case CURLOPT_COOKIESESSION:
766 * Set this option to TRUE to start a new "cookie session". It will
767 * prevent the forthcoming read-cookies-from-file actions to accept
768 * cookies that are marked as being session cookies, as they belong to a
771 * In the original Netscape cookie spec, "session cookies" are cookies
772 * with no expire date set. RFC2109 describes the same action if no
773 * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds
774 * a 'Discard' action that can enforce the discard even for cookies that
777 * We run mostly with the original cookie spec, as hardly anyone implements
780 data->set.cookiesession = (bool)va_arg(param, long);
782 #endif /* CURL_DISABLE_COOKIES */
784 case CURLOPT_HTTPGET:
786 * Set to force us do HTTP GET
788 if(va_arg(param, long)) {
789 data->set.httpreq = HTTPREQ_GET;
790 data->set.upload = FALSE; /* switch off upload */
794 case CURLOPT_HTTP_VERSION:
796 * This sets a requested HTTP version to be used. The value is one of
797 * the listed enums in curl/curl.h.
799 data->set.httpversion = va_arg(param, long);
802 case CURLOPT_HTTPPROXYTUNNEL:
804 * Tunnel operations through the proxy instead of normal proxy use
806 data->set.tunnel_thru_httpproxy = va_arg(param, long)?TRUE:FALSE;
809 case CURLOPT_CUSTOMREQUEST:
811 * Set a custom string to use as request
813 data->set.customrequest = va_arg(param, char *);
816 data->set.httpreq = HTTPREQ_CUSTOM;
817 here, we continue as if we were using the already set type
818 and this just changes the actual request keyword */
821 case CURLOPT_PROXYPORT:
823 * Explicitly set HTTP proxy port number.
825 data->set.proxyport = va_arg(param, long);
828 case CURLOPT_HTTPAUTH:
830 * Set HTTP Authentication type BITMASK.
833 long auth = va_arg(param, long);
834 /* switch off bits we can't support */
835 #if ! defined(USE_SSLEAY) && !defined(USE_WINDOWS_SSPI)
836 auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
839 auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */
842 return CURLE_FAILED_INIT; /* no supported types left! */
844 data->set.httpauth = auth;
848 case CURLOPT_PROXYAUTH:
850 * Set HTTP Authentication type BITMASK.
853 long auth = va_arg(param, long);
854 /* switch off bits we can't support */
856 auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
859 auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */
862 return CURLE_FAILED_INIT; /* no supported types left! */
864 data->set.proxyauth = auth;
867 #endif /* CURL_DISABLE_HTTP */
871 * Set proxy server:port to use as HTTP proxy.
873 * If the proxy is set to "" we explicitly say that we don't want to use a
874 * proxy (even though there might be environment variables saying so).
876 * Setting it to NULL, means no proxy but allows the environment variables
879 if(data->change.proxy_alloc) {
881 * The already set string is allocated, free that first
883 data->change.proxy_alloc=FALSE;;
884 free(data->change.proxy);
886 data->set.set_proxy = va_arg(param, char *);
887 data->change.proxy = data->set.set_proxy;
890 case CURLOPT_WRITEHEADER:
892 * Custom pointer to pass the header write callback function
894 data->set.writeheader = (void *)va_arg(param, void *);
896 case CURLOPT_ERRORBUFFER:
898 * Error buffer provided by the caller to get the human readable
901 data->set.errorbuffer = va_arg(param, char *);
905 * FILE pointer to write to or include in the data write callback
907 data->set.out = va_arg(param, FILE *);
909 case CURLOPT_FTPPORT:
911 * Use FTP PORT, this also specifies which IP address to use
913 data->set.ftpport = va_arg(param, char *);
914 data->set.ftp_use_port = data->set.ftpport?1:0;
917 case CURLOPT_FTP_USE_EPRT:
918 data->set.ftp_use_eprt = va_arg(param, long)?TRUE:FALSE;
919 data->set.ftp_use_lprt = data->set.ftp_use_eprt;
922 case CURLOPT_FTP_USE_EPSV:
923 data->set.ftp_use_epsv = va_arg(param, long)?TRUE:FALSE;
928 * FILE pointer to read the file to be uploaded from. Or possibly
929 * used as argument to the read callback.
931 data->set.in = va_arg(param, FILE *);
933 case CURLOPT_INFILESIZE:
935 * If known, this should inform curl about the file size of the
936 * to-be-uploaded file.
938 data->set.infilesize = va_arg(param, long);
940 case CURLOPT_INFILESIZE_LARGE:
942 * If known, this should inform curl about the file size of the
943 * to-be-uploaded file.
945 data->set.infilesize = va_arg(param, curl_off_t);
947 case CURLOPT_LOW_SPEED_LIMIT:
949 * The low speed limit that if transfers are below this for
950 * CURLOPT_LOW_SPEED_TIME, the transfer is aborted.
952 data->set.low_speed_limit=va_arg(param, long);
954 case CURLOPT_LOW_SPEED_TIME:
956 * The low speed time that if transfers are below the set
957 * CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted.
959 data->set.low_speed_time=va_arg(param, long);
965 if(data->change.url_alloc) {
966 /* the already set URL is allocated, free it first! */
967 free(data->change.url);
968 data->change.url_alloc=FALSE;
970 data->set.set_url = va_arg(param, char *);
971 data->change.url = data->set.set_url;
972 data->change.url_changed = TRUE;
976 * The port number to use when getting the URL
978 data->set.use_port = va_arg(param, long);
980 case CURLOPT_TIMEOUT:
982 * The maximum time you allow curl to use for a single transfer
985 data->set.timeout = va_arg(param, long);
987 case CURLOPT_CONNECTTIMEOUT:
989 * The maximum time you allow curl to use to connect.
991 data->set.connecttimeout = va_arg(param, long);
994 case CURLOPT_USERPWD:
996 * user:password to use in the operation
998 data->set.userpwd = va_arg(param, char *);
1000 case CURLOPT_POSTQUOTE:
1002 * List of RAW FTP commands to use after a transfer
1004 data->set.postquote = va_arg(param, struct curl_slist *);
1006 case CURLOPT_PREQUOTE:
1008 * List of RAW FTP commands to use prior to RETR (Wesley Laxton)
1010 data->set.prequote = va_arg(param, struct curl_slist *);
1014 * List of RAW FTP commands to use before a transfer
1016 data->set.quote = va_arg(param, struct curl_slist *);
1018 case CURLOPT_PROGRESSFUNCTION:
1020 * Progress callback function
1022 data->set.fprogress = va_arg(param, curl_progress_callback);
1023 if(data->set.fprogress)
1024 data->progress.callback = TRUE; /* no longer internal */
1026 data->progress.callback = FALSE; /* NULL enforces internal */
1029 case CURLOPT_PROGRESSDATA:
1031 * Custom client data to pass to the progress callback
1033 data->set.progress_client = va_arg(param, void *);
1035 case CURLOPT_PROXYUSERPWD:
1037 * user:password needed to use the proxy
1039 data->set.proxyuserpwd = va_arg(param, char *);
1043 * What range of the file you want to transfer
1045 data->set.set_range = va_arg(param, char *);
1047 case CURLOPT_RESUME_FROM:
1049 * Resume transfer at the give file position
1051 data->set.set_resume_from = va_arg(param, long);
1053 case CURLOPT_RESUME_FROM_LARGE:
1055 * Resume transfer at the give file position
1057 data->set.set_resume_from = va_arg(param, curl_off_t);
1059 case CURLOPT_DEBUGFUNCTION:
1061 * stderr write callback.
1063 data->set.fdebug = va_arg(param, curl_debug_callback);
1065 * if the callback provided is NULL, it'll use the default callback
1068 case CURLOPT_DEBUGDATA:
1070 * Set to a void * that should receive all error writes. This
1071 * defaults to CURLOPT_STDERR for normal operations.
1073 data->set.debugdata = va_arg(param, void *);
1075 case CURLOPT_STDERR:
1077 * Set to a FILE * that should receive all error writes. This
1078 * defaults to stderr for normal operations.
1080 data->set.err = va_arg(param, FILE *);
1082 data->set.err = stderr;
1084 case CURLOPT_HEADERFUNCTION:
1086 * Set header write callback
1088 data->set.fwrite_header = va_arg(param, curl_write_callback);
1090 case CURLOPT_WRITEFUNCTION:
1092 * Set data write callback
1094 data->set.fwrite = va_arg(param, curl_write_callback);
1095 if(!data->set.fwrite)
1096 /* When set to NULL, reset to our internal default function */
1097 data->set.fwrite = (curl_write_callback)fwrite;
1099 case CURLOPT_READFUNCTION:
1101 * Read data callback
1103 data->set.fread = va_arg(param, curl_read_callback);
1104 if(!data->set.fread)
1105 /* When set to NULL, reset to our internal default function */
1106 data->set.fread = (curl_read_callback)fread;
1108 case CURLOPT_IOCTLFUNCTION:
1110 * I/O control callback. Might be NULL.
1112 data->set.ioctl = va_arg(param, curl_ioctl_callback);
1114 case CURLOPT_IOCTLDATA:
1116 * I/O control data pointer. Might be NULL.
1118 data->set.ioctl_client = va_arg(param, void *);
1120 case CURLOPT_SSLCERT:
1122 * String that holds file name of the SSL certificate to use
1124 data->set.cert = va_arg(param, char *);
1126 case CURLOPT_SSLCERTTYPE:
1128 * String that holds file type of the SSL certificate to use
1130 data->set.cert_type = va_arg(param, char *);
1132 case CURLOPT_SSLKEY:
1134 * String that holds file name of the SSL certificate to use
1136 data->set.key = va_arg(param, char *);
1138 case CURLOPT_SSLKEYTYPE:
1140 * String that holds file type of the SSL certificate to use
1142 data->set.key_type = va_arg(param, char *);
1144 case CURLOPT_SSLKEYPASSWD:
1146 * String that holds the SSL private key password.
1148 data->set.key_passwd = va_arg(param, char *);
1150 case CURLOPT_SSLENGINE:
1152 * String that holds the SSL crypto engine.
1154 argptr = va_arg(param, char *);
1155 if (argptr && argptr[0])
1156 result = Curl_SSL_set_engine(data, argptr);
1159 case CURLOPT_SSLENGINE_DEFAULT:
1161 * flag to set engine as default.
1163 result = Curl_SSL_set_engine_default(data);
1167 * Kludgy option to enable CRLF convertions. Subject for removal.
1169 data->set.crlf = va_arg(param, long)?TRUE:FALSE;
1171 case CURLOPT_INTERFACE:
1173 * Set what interface to bind to when performing an operation and thus
1174 * what from-IP your connection will use.
1176 data->set.device = va_arg(param, char *);
1178 case CURLOPT_KRB4LEVEL:
1180 * A string that defines the krb4 security level.
1182 data->set.krb4_level = va_arg(param, char *);
1183 data->set.krb4=data->set.krb4_level?TRUE:FALSE;
1185 case CURLOPT_SSL_VERIFYPEER:
1187 * Enable peer SSL verifying.
1189 data->set.ssl.verifypeer = va_arg(param, long);
1191 case CURLOPT_SSL_VERIFYHOST:
1193 * Enable verification of the CN contained in the peer certificate
1195 data->set.ssl.verifyhost = va_arg(param, long);
1197 case CURLOPT_SSL_CTX_FUNCTION:
1199 * Set a SSL_CTX callback
1201 data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback);
1203 case CURLOPT_SSL_CTX_DATA:
1205 * Set a SSL_CTX callback parameter pointer
1207 data->set.ssl.fsslctxp = va_arg(param, void *);
1209 case CURLOPT_CAINFO:
1211 * Set CA info for SSL connection. Specify file name of the CA certificate
1213 data->set.ssl.CAfile = va_arg(param, char *);
1215 case CURLOPT_CAPATH:
1217 * Set CA path info for SSL connection. Specify directory name of the CA
1218 * certificates which have been prepared using openssl c_rehash utility.
1220 /* This does not work on windows. */
1221 data->set.ssl.CApath = va_arg(param, char *);
1223 case CURLOPT_TELNETOPTIONS:
1225 * Set a linked list of telnet options
1227 data->set.telnet_options = va_arg(param, struct curl_slist *);
1230 case CURLOPT_BUFFERSIZE:
1232 * The application kindly asks for a differently sized receive buffer.
1233 * If it seems reasonable, we'll use it.
1235 data->set.buffer_size = va_arg(param, long);
1237 if((data->set.buffer_size> (BUFSIZE -1 )) ||
1238 (data->set.buffer_size < 1))
1239 data->set.buffer_size = 0; /* huge internal default */
1243 case CURLOPT_NOSIGNAL:
1245 * The application asks not to set any signal() or alarm() handlers,
1246 * even when using a timeout.
1248 data->set.no_signal = va_arg(param, long) ? TRUE : FALSE;
1253 struct Curl_share *set;
1254 set = va_arg(param, struct Curl_share *);
1256 /* disconnect from old share, if any */
1258 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
1260 if(data->share->hostcache == data->hostcache)
1261 data->hostcache = NULL;
1263 if(data->share->cookies == data->cookies)
1264 data->cookies = NULL;
1266 data->share->dirty--;
1268 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
1272 /* use new share if it set */
1276 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
1278 data->share->dirty++;
1280 if(data->share->hostcache) {
1281 /* use shared host cache, first free own one if any */
1283 Curl_hash_destroy(data->hostcache);
1285 data->hostcache = data->share->hostcache;
1287 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
1288 if(data->share->cookies) {
1289 /* use shared cookie list, first free own one if any */
1291 Curl_cookie_cleanup(data->cookies);
1292 data->cookies = data->share->cookies;
1294 #endif /* CURL_DISABLE_HTTP */
1295 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
1298 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
1299 /* check cookie list is set */
1301 data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE );
1302 #endif /* CURL_DISABLE_HTTP */
1303 /* check for host cache not needed,
1304 * it will be done by curl_easy_perform */
1308 case CURLOPT_PROXYTYPE:
1310 * Set proxy type. HTTP/SOCKS4/SOCKS5
1312 data->set.proxytype = (curl_proxytype)va_arg(param, long);
1315 case CURLOPT_PRIVATE:
1317 * Set private data pointer.
1319 data->set.private_data = va_arg(param, char *);
1322 case CURLOPT_MAXFILESIZE:
1324 * Set the maximum size of a file to download.
1326 data->set.max_filesize = va_arg(param, long);
1329 case CURLOPT_FTP_SSL:
1331 * Make FTP transfers attempt to use SSL/TLS.
1333 data->set.ftp_ssl = (curl_ftpssl)va_arg(param, long);
1336 case CURLOPT_FTPSSLAUTH:
1338 * Set a specific auth for FTP-SSL transfers.
1340 data->set.ftpsslauth = (curl_ftpauth)va_arg(param, long);
1343 case CURLOPT_IPRESOLVE:
1344 data->set.ip_version = va_arg(param, long);
1347 case CURLOPT_MAXFILESIZE_LARGE:
1349 * Set the maximum size of a file to download.
1351 data->set.max_filesize = va_arg(param, curl_off_t);
1354 case CURLOPT_TCP_NODELAY:
1356 * Enable or disable TCP_NODELAY, which will disable/enable the Nagle
1359 data->set.tcp_nodelay = (bool)va_arg(param, long);
1362 /*********** 3rd party transfer options ***********/
1363 case CURLOPT_SOURCE_URL:
1367 data->set.source_url = va_arg(param, char *);
1368 data->set.printhost = (data->set.source_url != NULL);
1371 case CURLOPT_SOURCE_USERPWD:
1373 * Use SOURCE USER[:PASSWORD]
1375 data->set.source_userpwd = va_arg(param, char *);
1378 case CURLOPT_SOURCE_QUOTE:
1380 * List of RAW FTP commands to use after a connect
1382 data->set.source_quote = va_arg(param, struct curl_slist *);
1385 case CURLOPT_SOURCE_PREQUOTE:
1387 * List of RAW FTP commands to use before a transfer on the source host
1389 data->set.source_prequote = va_arg(param, struct curl_slist *);
1392 case CURLOPT_SOURCE_POSTQUOTE:
1394 * List of RAW FTP commands to use after a transfer on the source host
1396 data->set.source_postquote = va_arg(param, struct curl_slist *);
1399 case CURLOPT_FTP_ACCOUNT:
1400 data->set.ftp_account = va_arg(param, char *);
1404 /* unknown tag and its companion, just ignore: */
1405 result = CURLE_FAILED_INIT; /* correct this */
1412 CURLcode Curl_disconnect(struct connectdata *conn)
1414 struct SessionHandle *data;
1416 return CURLE_OK; /* this is closed and fine already */
1420 #if defined(CURLDEBUG) && defined(AGGRESIVE_TEST)
1421 /* scan for DNS cache entries still marked as in use */
1422 Curl_hash_apply(data->hostcache,
1423 NULL, Curl_scan_cache_used);
1426 Curl_hostcache_prune(data); /* kill old DNS cache entries */
1429 * The range string is usually freed in curl_done(), but we might
1430 * get here *instead* if we fail prematurely. Thus we need to be able
1431 * to free this resource here as well.
1433 if(conn->bits.rangestringalloc) {
1435 conn->bits.rangestringalloc = FALSE;
1438 if((conn->ntlm.state != NTLMSTATE_NONE) ||
1439 (conn->proxyntlm.state != NTLMSTATE_NONE)) {
1440 /* Authentication data is a mix of connection-related and sessionhandle-
1441 related stuff. NTLM is connection-related so when we close the shop
1443 data->state.authhost.done = FALSE;
1444 data->state.authhost.picked =
1445 data->state.authhost.want;
1447 data->state.authproxy.done = FALSE;
1448 data->state.authproxy.picked =
1449 data->state.authhost.want;
1451 data->state.authproblem = FALSE;
1453 #if defined(USE_SSLEAY) || defined(USE_WINDOWS_SSPI)
1454 Curl_ntlm_cleanup(conn);
1458 if(conn->curl_disconnect)
1459 /* This is set if protocol-specific cleanups should be made */
1460 conn->curl_disconnect(conn);
1462 if(-1 != conn->connectindex) {
1463 /* unlink ourselves! */
1464 infof(data, "Closing connection #%ld\n", conn->connectindex);
1465 data->state.connects[conn->connectindex] = NULL;
1468 Curl_safefree(conn->proto.generic);
1469 Curl_safefree(conn->newurl);
1470 Curl_safefree(conn->pathbuffer); /* the URL path buffer */
1472 Curl_safefree(conn->host.rawalloc); /* host name buffer */
1473 Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */
1475 if(conn->host.encalloc)
1476 idn_free(conn->host.encalloc); /* encoded host name buffer, must be freed
1477 with idn_free() since this was allocated
1479 if(conn->proxy.encalloc)
1480 idn_free(conn->proxy.encalloc); /* encoded proxy name buffer, must be
1481 freed with idn_free() since this was
1482 allocated by libidn */
1484 Curl_SSL_Close(conn);
1486 /* close possibly still open sockets */
1487 if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
1488 sclose(conn->sock[SECONDARYSOCKET]);
1489 if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET])
1490 sclose(conn->sock[FIRSTSOCKET]);
1492 Curl_safefree(conn->user);
1493 Curl_safefree(conn->passwd);
1494 Curl_safefree(conn->proxyuser);
1495 Curl_safefree(conn->proxypasswd);
1496 Curl_safefree(conn->allocptr.proxyuserpwd);
1497 Curl_safefree(conn->allocptr.uagent);
1498 Curl_safefree(conn->allocptr.userpwd);
1499 Curl_safefree(conn->allocptr.accept_encoding);
1500 Curl_safefree(conn->allocptr.rangeline);
1501 Curl_safefree(conn->allocptr.ref);
1502 Curl_safefree(conn->allocptr.host);
1503 Curl_safefree(conn->allocptr.cookiehost);
1504 Curl_safefree(conn->ip_addr_str);
1506 #if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \
1507 defined(USE_THREADING_GETADDRINFO)
1508 /* possible left-overs from the async name resolve */
1509 Curl_safefree(conn->async.hostname);
1510 Curl_safefree(conn->async.os_specific);
1513 Curl_free_ssl_config(&conn->ssl_config);
1515 free(conn); /* free all the connection oriented data */
1521 * This function should return TRUE if the socket is to be assumed to
1522 * be dead. Most commonly this happens when the server has closed the
1523 * connection due to inactivity.
1525 static bool SocketIsDead(curl_socket_t sock)
1528 bool ret_val = TRUE;
1530 sval = Curl_select(sock, CURL_SOCKET_BAD, 0);
1539 * Given one filled in connection struct (named needle), this function should
1540 * detect if there already is one that have all the significant details
1541 * exactly the same and thus should be used instead.
1544 ConnectionExists(struct SessionHandle *data,
1545 struct connectdata *needle,
1546 struct connectdata **usethis)
1549 struct connectdata *check;
1551 for(i=0; i< data->state.numconnects; i++) {
1554 * Note that if we use a HTTP proxy, we check connections to that
1555 * proxy and not to the actual remote server.
1557 check = data->state.connects[i];
1559 /* NULL pointer means not filled-in entry */
1562 if((needle->protocol&PROT_SSL) != (check->protocol&PROT_SSL))
1563 /* don't do mixed SSL and non-SSL connections */
1566 if(!needle->bits.httpproxy || needle->protocol&PROT_SSL) {
1567 /* The requested connection does not use a HTTP proxy or it
1570 if(!(needle->protocol&PROT_SSL) && check->bits.httpproxy)
1571 /* we don't do SSL but the cached connection has a proxy,
1572 then don't match this */
1575 if(strequal(needle->protostr, check->protostr) &&
1576 strequal(needle->host.name, check->host.name) &&
1577 (needle->remote_port == check->remote_port) ) {
1578 if(needle->protocol & PROT_SSL) {
1579 /* This is SSL, verify that we're using the same
1580 ssl options as well */
1581 if(!Curl_ssl_config_matches(&needle->ssl_config,
1582 &check->ssl_config)) {
1586 if((needle->protocol & PROT_FTP) ||
1587 ((needle->protocol & PROT_HTTP) &&
1588 (needle->data->state.authhost.want==CURLAUTH_NTLM))) {
1589 /* This is FTP or HTTP+NTLM, verify that we're using the same name
1590 and password as well */
1591 if(!strequal(needle->user, check->user) ||
1592 !strequal(needle->passwd, check->passwd)) {
1593 /* one of them was different */
1600 else { /* The requested needle connection is using a proxy,
1601 is the checked one using the same? */
1602 if(check->bits.httpproxy &&
1603 strequal(needle->proxy.name, check->proxy.name) &&
1604 needle->port == check->port) {
1605 /* This is the same proxy connection, use it! */
1611 bool dead = SocketIsDead(check->sock[FIRSTSOCKET]);
1615 infof(data, "Connection %d seems to be dead!\n", i);
1616 Curl_disconnect(check); /* disconnect resources */
1617 data->state.connects[i]=NULL; /* nothing here */
1619 /* There's no need to continue searching, because we only store
1620 one connection for each unique set of identifiers */
1625 return TRUE; /* yes, we found one to use! */
1628 return FALSE; /* no matching connecting exists */
1632 * This function frees/closes a connection in the connection cache. This
1633 * should take the previously set policy into account when deciding which
1634 * of the connections to kill.
1637 ConnectionKillOne(struct SessionHandle *data)
1640 struct connectdata *conn;
1648 for(i=0; i< data->state.numconnects; i++) {
1649 conn = data->state.connects[i];
1655 * By using the set policy, we score each connection.
1657 switch(data->set.closepolicy) {
1658 case CURLCLOSEPOLICY_LEAST_RECENTLY_USED:
1661 * Set higher score for the age passed since the connection
1664 score = Curl_tvdiff(now, conn->now);
1666 case CURLCLOSEPOLICY_OLDEST:
1668 * Set higher score for the age passed since the connection
1671 score = Curl_tvdiff(now, conn->created);
1675 if(score > highscore) {
1680 if(connindex >= 0) {
1682 /* the winner gets the honour of being disconnected */
1683 (void) Curl_disconnect(data->state.connects[connindex]);
1685 /* clean the array entry */
1686 data->state.connects[connindex] = NULL;
1689 return connindex; /* return the available index or -1 */
1693 * The given input connection struct pointer is to be stored. If the "cache"
1694 * is already full, we must clean out the most suitable using the previously
1697 * The given connection should be unique. That must've been checked prior to
1701 ConnectionStore(struct SessionHandle *data,
1702 struct connectdata *conn)
1705 for(i=0; i< data->state.numconnects; i++) {
1706 if(!data->state.connects[i])
1709 if(i == data->state.numconnects) {
1710 /* there was no room available, kill one */
1711 i = ConnectionKillOne(data);
1712 infof(data, "Connection (#%d) was killed to make room\n", i);
1716 /* only do this if a true index was returned, if -1 was returned there
1717 is no room in the cache for an unknown reason and we cannot store
1719 data->state.connects[i] = conn; /* fill in this */
1720 conn->connectindex = i; /* make the child know where the pointer to this
1721 particular data is stored */
1727 * This function logs in to a SOCKS5 proxy and sends the specifies the final
1728 * desitination server.
1730 static int handleSock5Proxy(const char *proxy_name,
1731 const char *proxy_password,
1732 struct connectdata *conn)
1735 According to the RFC1928, section "6. Replies". This is what a SOCK5
1738 +----+-----+-------+------+----------+----------+
1739 |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
1740 +----+-----+-------+------+----------+----------+
1741 | 1 | 1 | X'00' | 1 | Variable | 2 |
1742 +----+-----+-------+------+----------+----------+
1746 o VER protocol version: X'05'
1751 unsigned char socksreq[600]; /* room for large user/pw (255 max each) */
1756 int sock = conn->sock[FIRSTSOCKET];
1758 Curl_nonblock(sock, FALSE);
1760 socksreq[0] = 5; /* version */
1761 socksreq[1] = (char)(proxy_name ? 2 : 1); /* number of methods (below) */
1762 socksreq[2] = 0; /* no authentication */
1763 socksreq[3] = 2; /* username/password */
1765 code = Curl_write(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]),
1767 if ((code != CURLE_OK) || (written != (2 + (int)socksreq[1]))) {
1768 failf(conn->data, "Unable to send initial SOCKS5 request.");
1772 result=Curl_read(conn, sock, (char *)socksreq, 2, &actualread);
1773 if ((result != CURLE_OK) || (actualread != 2)) {
1774 failf(conn->data, "Unable to receive initial SOCKS5 response.");
1778 if (socksreq[0] != 5) {
1779 failf(conn->data, "Received invalid version in initial SOCKS5 response.");
1782 if (socksreq[1] == 0) {
1783 /* Nothing to do, no authentication needed */
1786 else if (socksreq[1] == 2) {
1787 /* Needs user name and password */
1788 int userlen, pwlen, len;
1790 userlen = (int)strlen(proxy_name);
1791 pwlen = proxy_password?(int)strlen(proxy_password):0;
1793 /* username/password request looks like
1794 * +----+------+----------+------+----------+
1795 * |VER | ULEN | UNAME | PLEN | PASSWD |
1796 * +----+------+----------+------+----------+
1797 * | 1 | 1 | 1 to 255 | 1 | 1 to 255 |
1798 * +----+------+----------+------+----------+
1801 socksreq[len++] = 1; /* username/pw subnegotiation version */
1802 socksreq[len++] = (char) userlen;
1803 memcpy(socksreq + len, proxy_name, (int) userlen);
1805 socksreq[len++] = (char) pwlen;
1806 memcpy(socksreq + len, proxy_password, (int) pwlen);
1809 code = Curl_write(conn, sock, (char *)socksreq, len, &written);
1810 if ((code != CURLE_OK) || (len != written)) {
1811 failf(conn->data, "Failed to send SOCKS5 sub-negotiation request.");
1815 result=Curl_read(conn, sock, (char *)socksreq, 2, &actualread);
1816 if ((result != CURLE_OK) || (actualread != 2)) {
1817 failf(conn->data, "Unable to receive SOCKS5 sub-negotiation response.");
1821 /* ignore the first (VER) byte */
1822 if (socksreq[1] != 0) { /* status */
1823 failf(conn->data, "User was rejected by the SOCKS5 server (%d %d).",
1824 socksreq[0], socksreq[1]);
1828 /* Everything is good so far, user was authenticated! */
1832 if (socksreq[1] == 1) {
1834 "SOCKS5 GSSAPI per-message authentication is not supported.");
1837 else if (socksreq[1] == 255) {
1838 if (!proxy_name || !*proxy_name) {
1840 "No authentication method was acceptable. (It is quite likely"
1841 " that the SOCKS5 server wanted a username/password, since none"
1842 " was supplied to the server on this connection.)");
1845 failf(conn->data, "No authentication method was acceptable.");
1851 "Undocumented SOCKS5 mode attempted to be used by server.");
1856 /* Authentication is complete, now specify destination to the proxy */
1857 socksreq[0] = 5; /* version (SOCKS5) */
1858 socksreq[1] = 1; /* connect */
1859 socksreq[2] = 0; /* must be zero */
1860 socksreq[3] = 1; /* IPv4 = 1 */
1863 struct Curl_dns_entry *dns;
1864 Curl_addrinfo *hp=NULL;
1865 int rc = Curl_resolv(conn, conn->host.name, (int)conn->remote_port, &dns);
1867 if(rc == CURLRESOLV_ERROR)
1870 if(rc == CURLRESOLV_PENDING)
1871 /* this requires that we're in "wait for resolve" state */
1872 rc = Curl_wait_for_resolv(conn, &dns);
1875 * We cannot use 'hostent' as a struct that Curl_resolv() returns. It
1876 * returns a Curl_addrinfo pointer that may not always look the same.
1882 unsigned short ip[4];
1883 Curl_printable_address(hp, buf, sizeof(buf));
1885 if(4 == sscanf( buf, "%hu.%hu.%hu.%hu",
1886 &ip[0], &ip[1], &ip[2], &ip[3])) {
1887 socksreq[4] = (unsigned char)ip[0];
1888 socksreq[5] = (unsigned char)ip[1];
1889 socksreq[6] = (unsigned char)ip[2];
1890 socksreq[7] = (unsigned char)ip[3];
1893 hp = NULL; /* fail! */
1895 Curl_resolv_unlock(conn->data, dns); /* not used anymore from now on */
1898 failf(conn->data, "Failed to resolve \"%s\" for SOCKS5 connect.",
1904 *((unsigned short*)&socksreq[8]) = htons(conn->remote_port);
1907 const int packetsize = 10;
1909 code = Curl_write(conn, sock, (char *)socksreq, packetsize, &written);
1910 if ((code != CURLE_OK) || (written != packetsize)) {
1911 failf(conn->data, "Failed to send SOCKS5 connect request.");
1915 result = Curl_read(conn, sock, (char *)socksreq, packetsize, &actualread);
1916 if ((result != CURLE_OK) || (actualread != packetsize)) {
1917 failf(conn->data, "Failed to receive SOCKS5 connect request ack.");
1921 if (socksreq[0] != 5) { /* version */
1923 "SOCKS5 reply has wrong version, version should be 5.");
1926 if (socksreq[1] != 0) { /* Anything besides 0 is an error */
1928 "Can't complete SOCKS5 connection to %d.%d.%d.%d:%d. (%d)",
1929 (unsigned char)socksreq[4], (unsigned char)socksreq[5],
1930 (unsigned char)socksreq[6], (unsigned char)socksreq[7],
1931 (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])),
1937 Curl_nonblock(sock, TRUE);
1938 return 0; /* Proxy was successful! */
1941 static CURLcode ConnectPlease(struct connectdata *conn,
1942 struct Curl_dns_entry *hostaddr,
1946 Curl_addrinfo *addr;
1947 struct SessionHandle *data = conn->data;
1948 char *hostname = data->change.proxy?conn->proxy.name:conn->host.name;
1950 infof(data, "About to connect() to %s port %d\n",
1951 hostname, conn->port);
1953 /*************************************************************
1954 * Connect to server/proxy
1955 *************************************************************/
1956 result= Curl_connecthost(conn,
1958 &conn->sock[FIRSTSOCKET],
1961 if(CURLE_OK == result) {
1962 /* All is cool, then we store the current information */
1963 conn->dns_entry = hostaddr;
1964 conn->ip_addr = addr;
1966 Curl_store_ip_addr(conn);
1968 if (conn->data->set.proxytype == CURLPROXY_SOCKS5) {
1969 return handleSock5Proxy(conn->proxyuser,
1972 CURLE_COULDNT_CONNECT : CURLE_OK;
1974 else if (conn->data->set.proxytype == CURLPROXY_HTTP) {
1975 /* do nothing here. handled later. */
1978 failf(conn->data, "unknown proxytype option given");
1979 return CURLE_COULDNT_CONNECT;
1987 * verboseconnect() displays verbose information after a connect
1989 static void verboseconnect(struct connectdata *conn)
1991 infof(conn->data, "Connected to %s (%s) port %d\n",
1992 conn->bits.httpproxy ? conn->proxy.dispname : conn->host.dispname,
1993 conn->ip_addr_str, conn->port);
1996 CURLcode Curl_protocol_fdset(struct connectdata *conn,
1997 fd_set *read_fd_set,
1998 fd_set *write_fd_set,
2001 CURLcode res = CURLE_OK;
2002 if(conn->curl_proto_fdset)
2003 res = conn->curl_proto_fdset(conn, read_fd_set, write_fd_set, max_fdp);
2007 CURLcode Curl_doing_fdset(struct connectdata *conn,
2008 fd_set *read_fd_set,
2009 fd_set *write_fd_set,
2012 CURLcode res = CURLE_OK;
2013 if(conn && conn->curl_doing_fdset)
2014 res = conn->curl_doing_fdset(conn, read_fd_set, write_fd_set, max_fdp);
2019 * We are doing protocol-specific connecting and this is being called over and
2020 * over from the multi interface until the connection phase is done on
2024 CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done)
2026 CURLcode result=CURLE_OK;
2028 if(conn && conn->curl_connecting) {
2030 result = conn->curl_connecting(conn, done);
2039 * We are DOING this is being called over and over from the multi interface
2040 * until the DOING phase is done on protocol layer.
2043 CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done)
2045 CURLcode result=CURLE_OK;
2047 if(conn && conn->curl_doing) {
2049 result = conn->curl_doing(conn, done);
2058 * We have discovered that the TCP connection has been successful, we can now
2059 * proceed with some action.
2062 CURLcode Curl_protocol_connect(struct connectdata *conn, bool *protocol_done)
2064 struct SessionHandle *data = conn->data;
2065 CURLcode result=CURLE_OK;
2067 *protocol_done = FALSE;
2069 if(conn->bits.tcpconnect && conn->bits.protoconnstart) {
2070 /* We already are connected, get back. This may happen when the connect
2071 worked fine in the first call, like when we connect to a local server
2072 or proxy. Note that we don't know if the protocol is actually done.
2074 Unless this protocol doesn't have any protocol-connect callback, as
2075 then we know we're done. */
2076 if(!conn->curl_connecting)
2077 *protocol_done = TRUE;
2082 if(!conn->bits.tcpconnect) {
2084 Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
2086 if(data->set.verbose)
2087 verboseconnect(conn);
2090 if(!conn->bits.protoconnstart) {
2091 if(conn->curl_connect) {
2092 /* is there a protocol-specific connect() procedure? */
2094 /* Set start time here for timeout purposes in the connect procedure, it
2095 is later set again for the progress meter purpose */
2096 conn->now = Curl_tvnow();
2098 /* Call the protocol-specific connect function */
2099 result = conn->curl_connect(conn, protocol_done);
2102 *protocol_done = TRUE;
2104 /* it has started, possibly even completed but that knowledge isn't stored
2106 conn->bits.protoconnstart = TRUE;
2109 return result; /* pass back status */
2113 * Helpers for IDNA convertions.
2116 static bool is_ASCII_name (const char *hostname)
2118 const unsigned char *ch = (const unsigned char*)hostname;
2128 * Check if characters in hostname is allowed in Top Level Domain.
2130 static bool tld_check_name (struct SessionHandle *data,
2131 const char *ace_hostname)
2134 char *uc_name = NULL;
2137 /* Convert (and downcase) ACE-name back into locale's character set */
2138 rc = idna_to_unicode_lzlz(ace_hostname, &uc_name, 0);
2139 if (rc != IDNA_SUCCESS)
2142 rc = tld_check_lz(uc_name, &err_pos, NULL);
2143 if (rc == TLD_INVALID)
2144 infof(data, "WARNING: %s; pos %u = `%c'/0x%02X\n",
2145 #ifdef HAVE_TLD_STRERROR
2150 err_pos, uc_name[err_pos],
2151 uc_name[err_pos] & 255);
2152 else if (rc != TLD_SUCCESS)
2153 infof(data, "WARNING: TLD check for %s failed; %s\n",
2155 #ifdef HAVE_TLD_STRERROR
2163 return (rc == TLD_SUCCESS);
2167 static void fix_hostname(struct connectdata *conn, struct hostname *host)
2169 /* set the name we use to display the host name */
2170 host->dispname = host->name;
2173 /*************************************************************
2174 * Check name for non-ASCII and convert hostname to ACE form.
2175 *************************************************************/
2176 if (!is_ASCII_name(host->name) &&
2177 stringprep_check_version(LIBIDN_REQUIRED_VERSION)) {
2178 char *ace_hostname = NULL;
2179 struct SessionHandle *data = conn->data;
2180 int rc = idna_to_ascii_lz(host->name, &ace_hostname, 0);
2181 infof (data, "Input domain encoded as `%s'\n",
2182 stringprep_locale_charset ());
2183 if (rc != IDNA_SUCCESS)
2184 infof(data, "Failed to convert %s to ACE; %s\n",
2185 host->name, Curl_idn_strerror(conn,rc));
2187 tld_check_name(data, ace_hostname);
2189 host->encalloc = ace_hostname;
2190 /* change the name pointer to point to the encoded hostname */
2191 host->name = host->encalloc;
2195 (void)conn; /* never used */
2201 * CreateConnection() sets up a new connectdata struct, or re-uses an already
2202 * existing one, and resolves host name.
2204 * if this function returns CURLE_OK and *async is set to TRUE, the resolve
2205 * response will be coming asynchronously. If *async is FALSE, the name is
2208 * @param data The sessionhandle pointer
2209 * @param in_connect is set to the next connection data pointer
2210 * @param addr is set to the new dns entry for this connection
2211 * @param async is set TRUE/FALSE depending on the nature of this lookup
2213 * @see SetupConnection()
2216 static CURLcode CreateConnection(struct SessionHandle *data,
2217 struct connectdata **in_connect,
2218 struct Curl_dns_entry **addr,
2223 CURLcode result=CURLE_OK;
2224 struct connectdata *conn;
2225 struct connectdata *conn_temp;
2227 struct Curl_dns_entry *hostaddr;
2228 #if defined(HAVE_ALARM) && !defined(USE_ARES)
2229 unsigned int prev_alarm=0;
2232 char user[MAX_CURL_USER_LENGTH];
2233 char passwd[MAX_CURL_PASSWORD_LENGTH];
2239 #ifdef HAVE_SIGACTION
2240 struct sigaction keep_sigact; /* store the old struct here */
2241 bool keep_copysig=FALSE; /* did copy it? */
2244 void *keep_sigact; /* store the old handler here */
2245 #endif /* HAVE_SIGNAL */
2246 #endif /* HAVE_SIGACTION */
2247 #endif /* SIGALRM */
2248 #endif /* USE_ARES */
2250 *addr = NULL; /* nothing yet */
2253 /*************************************************************
2255 *************************************************************/
2257 if(!data->change.url)
2258 return CURLE_URL_MALFORMAT;
2260 /* First, split up the current URL in parts so that we can use the
2261 parts for checking against the already present connections. In order
2262 to not have to modify everything at once, we allocate a temporary
2263 connection data struct and fill in for comparison purposes. */
2265 conn = (struct connectdata *)calloc(sizeof(struct connectdata), 1);
2267 *in_connect = NULL; /* clear the pointer */
2268 return CURLE_OUT_OF_MEMORY;
2270 /* We must set the return variable as soon as possible, so that our
2271 parent can cleanup any possible allocs we may have done before
2275 /* and we setup a few fields in case we end up actually using this struct */
2276 conn->data = data; /* remember our daddy */
2277 conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
2278 conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
2279 conn->connectindex = -1; /* no index */
2280 conn->bits.httpproxy = (data->change.proxy && *data->change.proxy &&
2281 (data->set.proxytype == CURLPROXY_HTTP))?
2282 TRUE:FALSE; /* http proxy or not */
2284 /* Default protocol-independent behavior doesn't support persistant
2285 connections, so we set this to force-close. Protocols that support
2286 this need to set this to FALSE in their "curl_do" functions. */
2287 conn->bits.close = TRUE;
2289 /* maxdownload must be -1 on init, as 0 is a valid value! */
2290 conn->maxdownload = -1; /* might have been used previously! */
2292 /* Store creation time to help future close decision making */
2293 conn->created = Curl_tvnow();
2295 conn->bits.use_range = data->set.set_range?TRUE:FALSE; /* range status */
2296 conn->range = data->set.set_range; /* clone the range setting */
2297 conn->resume_from = data->set.set_resume_from; /* inherite resume_from */
2299 conn->bits.user_passwd = data->set.userpwd?1:0;
2300 conn->bits.proxy_user_passwd = data->set.proxyuserpwd?1:0;
2301 conn->bits.no_body = data->set.opt_no_body;
2302 conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy;
2303 conn->bits.ftp_use_epsv = data->set.ftp_use_epsv;
2304 conn->bits.ftp_use_eprt = data->set.ftp_use_eprt;
2305 conn->bits.ftp_use_lprt = data->set.ftp_use_lprt;
2307 /* This initing continues below, see the comment "Continue connectdata
2308 * initialization here" */
2310 /***********************************************************
2311 * We need to allocate memory to store the path in. We get the size of the
2312 * full URL to be sure, and we need to make it at least 256 bytes since
2313 * other parts of the code will rely on this fact
2314 ***********************************************************/
2315 #define LEAST_PATH_ALLOC 256
2316 urllen=strlen(data->change.url);
2317 if(urllen < LEAST_PATH_ALLOC)
2318 urllen=LEAST_PATH_ALLOC;
2320 conn->pathbuffer=(char *)malloc(urllen);
2321 if(NULL == conn->pathbuffer)
2322 return CURLE_OUT_OF_MEMORY; /* really bad error */
2323 conn->path = conn->pathbuffer;
2325 conn->host.rawalloc=(char *)malloc(urllen);
2326 if(NULL == conn->host.rawalloc)
2327 return CURLE_OUT_OF_MEMORY;
2328 conn->host.name = conn->host.rawalloc;
2329 conn->host.name[0] = 0;
2331 /*************************************************************
2334 * We need to parse the url even when using the proxy, because we will need
2335 * the hostname and port in case we are trying to SSL connect through the
2336 * proxy -- and we don't know if we will need to use SSL until we parse the
2338 ************************************************************/
2339 if((2 == sscanf(data->change.url, "%15[^:]:%[^\n]",
2341 conn->path)) && strequal(conn->protostr, "file")) {
2342 if(conn->path[0] == '/' && conn->path[1] == '/') {
2343 /* Allow omitted hostname (e.g. file:/<path>). This is not strictly
2344 * speaking a valid file: URL by RFC 1738, but treating file:/<path> as
2345 * file://localhost/<path> is similar to how other schemes treat missing
2346 * hostnames. See RFC 1808. */
2348 /* This cannot be done with strcpy() in a portable manner, since the
2349 memory areas overlap! */
2350 memmove(conn->path, conn->path + 2, strlen(conn->path + 2)+1);
2353 * we deal with file://<host>/<path> differently since it supports no
2354 * hostname other than "localhost" and "127.0.0.1", which is unique among
2355 * the URL protocols specified in RFC 1738
2357 if(conn->path[0] != '/') {
2358 /* the URL included a host name, we ignore host names in file:// URLs
2359 as the standards don't define what to do with them */
2360 char *ptr=strchr(conn->path, '/');
2362 /* there was a slash present
2364 RFC1738 (section 3.1, page 5) says:
2366 The rest of the locator consists of data specific to the scheme,
2367 and is known as the "url-path". It supplies the details of how the
2368 specified resource can be accessed. Note that the "/" between the
2369 host (or port) and the url-path is NOT part of the url-path.
2371 As most agents use file://localhost/foo to get '/foo' although the
2372 slash preceeding foo is a separator and not a slash for the path,
2373 a URL as file://localhost//foo must be valid as well, to refer to
2374 the same file with an absolute path.
2377 if(ptr[1] && ('/' == ptr[1]))
2378 /* if there was two slashes, we skip the first one as that is then
2379 used truly as a separator */
2382 /* This cannot be made with strcpy, as the memory chunks overlap! */
2383 memmove(conn->path, ptr, strlen(ptr)+1);
2387 strcpy(conn->protostr, "file"); /* store protocol string lowercase */
2390 /* Set default path */
2391 strcpy(conn->path, "/");
2393 if (2 > sscanf(data->change.url,
2394 "%15[^\n:]://%[^\n/]%[^\n]",
2396 conn->host.name, conn->path)) {
2399 * The URL was badly formatted, let's try the browser-style _without_
2400 * protocol specified like 'http://'.
2402 if((1 > sscanf(data->change.url, "%[^\n/]%[^\n]",
2403 conn->host.name, conn->path)) ) {
2405 * We couldn't even get this format.
2407 failf(data, "<url> malformed");
2408 return CURLE_URL_MALFORMAT;
2412 * Since there was no protocol part specified, we guess what protocol it
2413 * is based on the first letters of the server name.
2416 /* Note: if you add a new protocol, please update the list in
2417 * lib/version.c too! */
2419 if(checkprefix("GOPHER.", conn->host.name))
2420 strcpy(conn->protostr, "gopher");
2422 else if(checkprefix("FTPS", conn->host.name))
2423 strcpy(conn->protostr, "ftps");
2424 #endif /* USE_SSLEAY */
2425 else if(checkprefix("FTP.", conn->host.name))
2426 strcpy(conn->protostr, "ftp");
2427 else if(checkprefix("TELNET.", conn->host.name))
2428 strcpy(conn->protostr, "telnet");
2429 else if (checkprefix("DICT.", conn->host.name))
2430 strcpy(conn->protostr, "DICT");
2431 else if (checkprefix("LDAP.", conn->host.name))
2432 strcpy(conn->protostr, "LDAP");
2434 strcpy(conn->protostr, "http");
2437 conn->protocol |= PROT_MISSING; /* not given in URL */
2441 /* We search for '?' in the host name (but only on the right side of a
2442 * @-letter to allow ?-letters in username and password) to handle things
2443 * like http://example.com?param= (notice the missing '/').
2445 at = strchr(conn->host.name, '@');
2447 tmp = strchr(at+1, '?');
2449 tmp = strchr(conn->host.name, '?');
2452 /* The right part of the ?-letter needs to be moved to prefix
2453 the current path buffer! */
2454 size_t len = strlen(tmp);
2455 /* move the existing path plus the zero byte */
2456 memmove(conn->path+len+1, conn->path, strlen(conn->path)+1);
2457 conn->path[0]='/'; /* prepend the missing slash */
2458 memcpy(conn->path+1, tmp, len); /* now copy the prefix part */
2459 *tmp=0; /* now cut off the hostname at the ? */
2462 /* If the URL is malformatted (missing a '/' after hostname before path) we
2463 * insert a slash here. The only letter except '/' we accept to start a path
2466 if(conn->path[0] == '?') {
2467 /* We need this function to deal with overlapping memory areas. We know
2468 that the memory area 'path' points to is 'urllen' bytes big and that
2469 is bigger than the path. Use +1 to move the zero byte too. */
2470 memmove(&conn->path[1], conn->path, strlen(conn->path)+1);
2471 conn->path[0] = '/';
2475 * So if the URL was A://B/C,
2476 * conn->protostr is A
2477 * conn->host.name is B
2481 /*************************************************************
2482 * Take care of proxy authentication stuff
2483 *************************************************************/
2484 if(conn->bits.proxy_user_passwd) {
2485 char proxyuser[MAX_CURL_USER_LENGTH]="";
2486 char proxypasswd[MAX_CURL_PASSWORD_LENGTH]="";
2488 sscanf(data->set.proxyuserpwd,
2489 "%" MAX_CURL_USER_LENGTH_TXT "[^:]:"
2490 "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]",
2491 proxyuser, proxypasswd);
2493 conn->proxyuser = strdup(proxyuser);
2494 if(!conn->proxyuser)
2495 return CURLE_OUT_OF_MEMORY;
2497 conn->proxypasswd = strdup(proxypasswd);
2498 if(!conn->proxypasswd)
2499 return CURLE_OUT_OF_MEMORY;
2502 #ifndef CURL_DISABLE_HTTP
2503 /*************************************************************
2504 * Detect what (if any) proxy to use
2505 *************************************************************/
2506 if(!data->change.proxy) {
2507 /* If proxy was not specified, we check for default proxy environment
2508 * variables, to enable i.e Lynx compliance:
2510 * http_proxy=http://some.server.dom:port/
2511 * https_proxy=http://some.server.dom:port/
2512 * ftp_proxy=http://some.server.dom:port/
2513 * gopher_proxy=http://some.server.dom:port/
2514 * no_proxy=domain1.dom,host.domain2.dom
2515 * (a comma-separated list of hosts which should
2516 * not be proxied, or an asterisk to override
2517 * all proxy variables)
2518 * all_proxy=http://some.server.dom:port/
2519 * (seems to exist for the CERN www lib. Probably
2520 * the first to check for.)
2522 * For compatibility, the all-uppercase versions of these variables are
2523 * checked if the lowercase versions don't exist.
2525 char *no_proxy=NULL;
2526 char *no_proxy_tok_buf;
2528 char proxy_env[128];
2530 no_proxy=curl_getenv("no_proxy");
2532 no_proxy=curl_getenv("NO_PROXY");
2534 if(!no_proxy || !strequal("*", no_proxy)) {
2535 /* NO_PROXY wasn't specified or it wasn't just an asterisk */
2538 nope=no_proxy?strtok_r(no_proxy, ", ", &no_proxy_tok_buf):NULL;
2541 char *endptr = strchr(conn->host.name, ':');
2543 namelen=endptr-conn->host.name;
2545 namelen=strlen(conn->host.name);
2547 if(strlen(nope) <= namelen) {
2549 conn->host.name + namelen - strlen(nope);
2550 if(checkprefix(nope, checkn)) {
2551 /* no proxy for this host! */
2555 nope=strtok_r(NULL, ", ", &no_proxy_tok_buf);
2558 /* It was not listed as without proxy */
2559 char *protop = conn->protostr;
2560 char *envp = proxy_env;
2563 /* Now, build <protocol>_proxy and check for such a one to use */
2565 *envp++ = tolower((int)*protop++);
2568 strcpy(envp, "_proxy");
2570 /* read the protocol proxy: */
2571 prox=curl_getenv(proxy_env);
2574 * We don't try the uppercase version of HTTP_PROXY because of
2577 * When curl is used in a webserver application
2578 * environment (cgi or php), this environment variable can
2579 * be controlled by the web server user by setting the
2580 * http header 'Proxy:' to some value.
2582 * This can cause 'internal' http/ftp requests to be
2583 * arbitrarily redirected by any external attacker.
2585 if(!prox && !strequal("http_proxy", proxy_env)) {
2586 /* There was no lowercase variable, try the uppercase version: */
2587 for(envp = proxy_env; *envp; envp++)
2588 *envp = toupper((int)*envp);
2589 prox=curl_getenv(proxy_env);
2592 if(prox && *prox) { /* don't count "" strings */
2593 proxy = prox; /* use this */
2596 proxy = curl_getenv("all_proxy"); /* default proxy to use */
2598 proxy=curl_getenv("ALL_PROXY");
2601 if(proxy && *proxy) {
2602 /* we have a proxy here to set */
2604 char proxyuser[MAX_CURL_USER_LENGTH];
2605 char proxypasswd[MAX_CURL_PASSWORD_LENGTH];
2609 /* skip the possible protocol piece */
2610 ptr=strstr(proxy, "://");
2618 /* check for an @-letter */
2619 ptr = strchr(ptr, '@');
2620 if(ptr && (2 == sscanf(fineptr,
2621 "%" MAX_CURL_USER_LENGTH_TXT"[^:]:"
2622 "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]",
2623 proxyuser, proxypasswd))) {
2624 CURLcode res = CURLE_OK;
2626 /* found user and password, rip them out */
2627 Curl_safefree(conn->proxyuser);
2628 conn->proxyuser = strdup(proxyuser);
2630 if(!conn->proxyuser)
2631 res = CURLE_OUT_OF_MEMORY;
2633 Curl_safefree(conn->proxypasswd);
2634 conn->proxypasswd = strdup(proxypasswd);
2636 if(!conn->proxypasswd)
2637 res = CURLE_OUT_OF_MEMORY;
2640 if(CURLE_OK == res) {
2641 conn->bits.proxy_user_passwd = TRUE; /* enable it */
2642 ptr = strdup(ptr+1); /* the right side of the @-letter */
2645 free(proxy); /* free the former proxy string */
2646 proxy = ptr; /* now use this instead */
2649 res = CURLE_OUT_OF_MEMORY;
2653 free(proxy); /* free the allocated proxy string */
2658 data->change.proxy = proxy;
2659 data->change.proxy_alloc=TRUE; /* this needs to be freed later */
2660 conn->bits.httpproxy = TRUE;
2662 } /* if (!nope) - it wasn't specified non-proxy */
2663 } /* NO_PROXY wasn't specified or '*' */
2666 } /* if not using proxy */
2667 #endif /* CURL_DISABLE_HTTP */
2669 /*************************************************************
2670 * No protocol part in URL was used, add it!
2671 *************************************************************/
2672 if(conn->protocol&PROT_MISSING) {
2673 /* We're guessing prefixes here and if we're told to use a proxy or if
2674 we're gonna follow a Location: later or... then we need the protocol
2675 part added so that we have a valid URL. */
2678 reurl = aprintf("%s://%s", conn->protostr, data->change.url);
2681 return CURLE_OUT_OF_MEMORY;
2683 data->change.url = reurl;
2684 data->change.url_alloc = TRUE; /* free this later */
2685 conn->protocol &= ~PROT_MISSING; /* switch that one off again */
2688 #ifndef CURL_DISABLE_HTTP
2689 /************************************************************
2690 * RESUME on a HTTP page is a tricky business. First, let's just check that
2691 * 'range' isn't used, then set the range parameter and leave the resume as
2692 * it is to inform about this situation for later use. We will then
2693 * "attempt" to resume, and if we're talking to a HTTP/1.1 (or later)
2694 * server, we will get the document resumed. If we talk to a HTTP/1.0
2695 * server, we just fail since we can't rewind the file writing from within
2697 ***********************************************************/
2698 if(conn->resume_from) {
2699 if(!conn->bits.use_range) {
2700 /* if it already was in use, we just skip this */
2701 conn->range = aprintf("%" FORMAT_OFF_T "-", conn->resume_from);
2703 return CURLE_OUT_OF_MEMORY;
2704 conn->bits.rangestringalloc = TRUE; /* mark as allocated */
2705 conn->bits.use_range = 1; /* switch on range usage */
2709 /*************************************************************
2710 * Setup internals depending on protocol
2711 *************************************************************/
2713 if (strequal(conn->protostr, "HTTP")) {
2714 #ifndef CURL_DISABLE_HTTP
2715 conn->port = (data->set.use_port && data->state.allow_port)?
2716 data->set.use_port:PORT_HTTP;
2717 conn->remote_port = PORT_HTTP;
2718 conn->protocol |= PROT_HTTP;
2719 conn->curl_do = Curl_http;
2720 conn->curl_do_more = NULL;
2721 conn->curl_done = Curl_http_done;
2722 conn->curl_connect = Curl_http_connect;
2724 failf(data, LIBCURL_NAME
2725 " was built with HTTP disabled, http: not supported!");
2726 return CURLE_UNSUPPORTED_PROTOCOL;
2729 else if (strequal(conn->protostr, "HTTPS")) {
2730 #if defined(USE_SSLEAY) && !defined(CURL_DISABLE_HTTP)
2732 conn->port = (data->set.use_port && data->state.allow_port)?
2733 data->set.use_port:PORT_HTTPS;
2734 conn->remote_port = PORT_HTTPS;
2735 conn->protocol |= PROT_HTTP|PROT_HTTPS|PROT_SSL;
2737 conn->curl_do = Curl_http;
2738 conn->curl_do_more = NULL;
2739 conn->curl_done = Curl_http_done;
2740 conn->curl_connect = Curl_http_connect;
2742 #else /* USE_SSLEAY */
2743 failf(data, LIBCURL_NAME
2744 " was built with SSL disabled, https: not supported!");
2745 return CURLE_UNSUPPORTED_PROTOCOL;
2746 #endif /* !USE_SSLEAY */
2748 else if (strequal(conn->protostr, "GOPHER")) {
2749 #ifndef CURL_DISABLE_GOPHER
2750 conn->port = (data->set.use_port && data->state.allow_port)?
2751 data->set.use_port:PORT_GOPHER;
2752 conn->remote_port = PORT_GOPHER;
2753 /* Skip /<item-type>/ in path if present */
2754 if (isdigit((int)conn->path[1])) {
2755 conn->path = strchr(&conn->path[1], '/');
2756 if (conn->path == NULL)
2757 conn->path = conn->pathbuffer;
2759 conn->protocol |= PROT_GOPHER;
2760 conn->curl_do = Curl_http;
2761 conn->curl_do_more = NULL;
2762 conn->curl_done = Curl_http_done;
2764 failf(data, LIBCURL_NAME
2765 " was built with GOPHER disabled, gopher: not supported!");
2768 else if(strequal(conn->protostr, "FTP") ||
2769 strequal(conn->protostr, "FTPS")) {
2771 #ifndef CURL_DISABLE_FTP
2773 int port = PORT_FTP;
2775 if(strequal(conn->protostr, "FTPS")) {
2777 conn->protocol |= PROT_FTPS|PROT_SSL;
2778 conn->ssl[SECONDARYSOCKET].use = TRUE; /* send data securely */
2781 failf(data, LIBCURL_NAME
2782 " was built with SSL disabled, ftps: not supported!");
2783 return CURLE_UNSUPPORTED_PROTOCOL;
2784 #endif /* !USE_SSLEAY */
2787 conn->port = (data->set.use_port && data->state.allow_port)?
2788 data->set.use_port:port;
2789 conn->remote_port = port;
2790 conn->protocol |= PROT_FTP;
2792 if(data->change.proxy &&
2793 *data->change.proxy &&
2794 !data->set.tunnel_thru_httpproxy) {
2795 /* Unless we have asked to tunnel ftp operations through the proxy, we
2796 switch and use HTTP operations only */
2797 if(conn->protocol & PROT_FTPS) {
2798 /* FTPS is a hacked protocol and does not work through your
2799 ordinary http proxy! */
2800 failf(data, "ftps does not work through http proxy!");
2801 return CURLE_UNSUPPORTED_PROTOCOL;
2803 #ifndef CURL_DISABLE_HTTP
2804 conn->curl_do = Curl_http;
2805 conn->curl_done = Curl_http_done;
2807 failf(data, "FTP over http proxy requires HTTP support built-in!");
2808 return CURLE_UNSUPPORTED_PROTOCOL;
2812 conn->curl_do = Curl_ftp;
2813 conn->curl_do_more = Curl_ftp_nextconnect;
2814 conn->curl_done = Curl_ftp_done;
2815 conn->curl_connect = Curl_ftp_connect;
2816 conn->curl_connecting = Curl_ftp_multi_statemach;
2817 conn->curl_doing = Curl_ftp_doing;
2818 conn->curl_proto_fdset = Curl_ftp_fdset;
2819 conn->curl_doing_fdset = Curl_ftp_fdset;
2820 conn->curl_disconnect = Curl_ftp_disconnect;
2823 conn->path++; /* don't include the initial slash */
2825 /* FTP URLs support an extension like ";type=<typecode>" that
2826 * we'll try to get now! */
2827 type=strstr(conn->path, ";type=");
2829 type=strstr(conn->host.rawalloc, ";type=");
2833 *type=0; /* it was in the middle of the hostname */
2834 command = toupper((int)type[6]);
2836 case 'A': /* ASCII mode */
2837 data->set.ftp_ascii = 1;
2839 case 'D': /* directory mode */
2840 data->set.ftp_list_only = 1;
2842 case 'I': /* binary mode */
2844 /* switch off ASCII */
2845 data->set.ftp_ascii = 0;
2849 #else /* CURL_DISABLE_FTP */
2850 failf(data, LIBCURL_NAME
2851 " was built with FTP disabled, ftp/ftps: not supported!");
2852 return CURLE_UNSUPPORTED_PROTOCOL;
2855 else if(strequal(conn->protostr, "TELNET")) {
2856 #ifndef CURL_DISABLE_TELNET
2857 /* telnet testing factory */
2858 conn->protocol |= PROT_TELNET;
2860 conn->port = (data->set.use_port && data->state.allow_port)?
2861 data->set.use_port: PORT_TELNET;
2862 conn->remote_port = PORT_TELNET;
2863 conn->curl_do = Curl_telnet;
2864 conn->curl_done = Curl_telnet_done;
2866 failf(data, LIBCURL_NAME
2867 " was built with TELNET disabled!");
2870 else if (strequal(conn->protostr, "DICT")) {
2871 #ifndef CURL_DISABLE_DICT
2872 conn->protocol |= PROT_DICT;
2873 conn->port = (data->set.use_port && data->state.allow_port)?
2874 data->set.use_port:PORT_DICT;
2875 conn->remote_port = PORT_DICT;
2876 conn->curl_do = Curl_dict;
2877 conn->curl_done = NULL; /* no DICT-specific done */
2879 failf(data, LIBCURL_NAME
2880 " was built with DICT disabled!");
2883 else if (strequal(conn->protostr, "LDAP")) {
2884 #ifndef CURL_DISABLE_LDAP
2885 conn->protocol |= PROT_LDAP;
2886 conn->port = (data->set.use_port && data->state.allow_port)?
2887 data->set.use_port:PORT_LDAP;
2888 conn->remote_port = PORT_LDAP;
2889 conn->curl_do = Curl_ldap;
2890 conn->curl_done = NULL; /* no LDAP-specific done */
2892 failf(data, LIBCURL_NAME
2893 " was built with LDAP disabled!");
2896 else if (strequal(conn->protostr, "FILE")) {
2897 #ifndef CURL_DISABLE_FILE
2898 conn->protocol |= PROT_FILE;
2900 conn->curl_do = Curl_file;
2901 conn->curl_done = Curl_file_done;
2903 /* anyway, this is supposed to be the connect function so we better
2904 at least check that the file is present here! */
2905 result = Curl_file_connect(conn);
2907 /* Setup a "faked" transfer that'll do nothing */
2908 if(CURLE_OK == result) {
2909 conn->bits.tcpconnect = TRUE; /* we are "connected */
2910 result = Curl_Transfer(conn, -1, -1, FALSE, NULL, /* no download */
2911 -1, NULL); /* no upload */
2916 failf(data, LIBCURL_NAME
2917 " was built with FILE disabled!");
2921 /* We fell through all checks and thus we don't support the specified
2923 failf(data, "Unsupported protocol: %s", conn->protostr);
2924 return CURLE_UNSUPPORTED_PROTOCOL;
2927 if(data->change.proxy && *data->change.proxy) {
2928 /* If this is supposed to use a proxy, we need to figure out the proxy
2929 host name name, so that we can re-use an existing connection
2930 that may exist registered to the same proxy host. */
2935 /* We need to make a duplicate of the proxy so that we can modify the
2937 char *proxydup=strdup(data->change.proxy);
2939 /* We use 'proxyptr' to point to the proxy name from now on... */
2940 char *proxyptr=proxydup;
2942 if(NULL == proxydup) {
2943 failf(data, "memory shortage");
2944 return CURLE_OUT_OF_MEMORY;
2947 /* Daniel Dec 10, 1998:
2948 We do the proxy host string parsing here. We want the host name and the
2949 port name. Accept a protocol:// prefix, even though it should just be
2952 /* 1. skip the protocol part if present */
2953 endofprot=strstr(proxyptr, "://");
2955 proxyptr = endofprot+3;
2958 /* allow user to specify proxy.server.com:1080 if desired */
2959 prox_portno = strchr (proxyptr, ':');
2961 *prox_portno = 0x0; /* cut off number from host name */
2963 /* now set the local port number */
2964 conn->port = atoi(prox_portno);
2966 else if(data->set.proxyport) {
2967 /* None given in the proxy string, then get the default one if it is
2969 conn->port = data->set.proxyport;
2972 /* now, clone the cleaned proxy host name */
2973 conn->proxy.rawalloc = strdup(proxyptr);
2974 conn->proxy.name = conn->proxy.rawalloc;
2976 free(proxydup); /* free the duplicate pointer and not the modified */
2977 if(!conn->proxy.rawalloc)
2978 return CURLE_OUT_OF_MEMORY;
2981 /*************************************************************
2982 * If the protcol is using SSL and HTTP proxy is used, we set
2983 * the tunnel_proxy bit.
2984 *************************************************************/
2985 if((conn->protocol&PROT_SSL) && conn->bits.httpproxy)
2986 conn->bits.tunnel_proxy = TRUE;
2988 /*************************************************************
2989 * Take care of user and password authentication stuff
2990 *************************************************************/
2993 * Inputs: data->set.userpwd (CURLOPT_USERPWD)
2994 * data->set.fpasswd (CURLOPT_PASSWDFUNCTION)
2995 * data->set.use_netrc (CURLOPT_NETRC)
2998 * hard-coded defaults
3000 * Outputs: (almost :- all currently undefined)
3001 * conn->bits.user_passwd - non-zero if non-default passwords exist
3002 * conn->user - non-zero length if defined
3003 * conn->passwd - ditto
3004 * conn->host.name - remove user name and password
3007 /* At this point, we're hoping all the other special cases have
3008 * been taken care of, so conn->host.name is at most
3009 * [user[:password]]@]hostname
3011 * We need somewhere to put the embedded details, so do that first.
3014 user[0] =0; /* to make everything well-defined */
3017 if (conn->protocol & (PROT_FTP|PROT_HTTP)) {
3018 /* This is a FTP or HTTP URL, we will now try to extract the possible
3019 * user+password pair in a string like:
3020 * ftp://user:password@ftp.my.site:8021/README */
3021 char *ptr=strchr(conn->host.name, '@');
3022 char *userpass = conn->host.name;
3024 /* there's a user+password given here, to the left of the @ */
3026 conn->host.name = ++ptr;
3028 /* So the hostname is sane. Only bother interpreting the
3029 * results if we could care. It could still be wasted
3030 * work because it might be overtaken by the programmatically
3031 * set user/passwd, but doing that first adds more cases here :-(
3034 if (data->set.use_netrc != CURL_NETRC_REQUIRED) {
3035 /* We could use the one in the URL */
3037 conn->bits.user_passwd = 1; /* enable user+password */
3039 if(*userpass != ':') {
3040 /* the name is given, get user+password */
3041 sscanf(userpass, "%127[^:@]:%127[^@]",
3045 /* no name given, get the password only */
3046 sscanf(userpass, ":%127[^@]", passwd);
3049 char *newname=curl_unescape(user, 0);
3051 return CURLE_OUT_OF_MEMORY;
3052 if(strlen(newname) < sizeof(user))
3053 strcpy(user, newname);
3055 /* if the new name is longer than accepted, then just use
3056 the unconverted name, it'll be wrong but what the heck */
3060 /* we have a password found in the URL, decode it! */
3061 char *newpasswd=curl_unescape(passwd, 0);
3063 return CURLE_OUT_OF_MEMORY;
3064 if(strlen(newpasswd) < sizeof(passwd))
3065 strcpy(passwd, newpasswd);
3073 /*************************************************************
3074 * Figure out the remote port number
3076 * No matter if we use a proxy or not, we have to figure out the remote
3077 * port number of various reasons.
3079 * To be able to detect port number flawlessly, we must not confuse them
3080 * IPv6-specified addresses in the [0::1] style. (RFC2732)
3082 * The conn->host.name is currently [user:passwd@]host[:port] where host
3083 * could be a hostname, IPv4 address or IPv6 address.
3084 *************************************************************/
3085 if((1 == sscanf(conn->host.name, "[%*39[0-9a-fA-F:.]%c", &endbracket)) &&
3086 (']' == endbracket)) {
3087 /* this is a RFC2732-style specified IP-address */
3088 conn->bits.ipv6_ip = TRUE;
3090 conn->host.name++; /* pass the starting bracket */
3091 tmp = strchr(conn->host.name, ']');
3092 *tmp = 0; /* zero terminate */
3093 tmp++; /* pass the ending bracket */
3095 tmp = NULL; /* no port number available */
3098 tmp = strrchr(conn->host.name, ':');
3104 port=strtoul(tmp+1, &rest, 10); /* Port number must be decimal */
3106 if (rest != (tmp+1) && *rest == '\0') {
3107 /* The colon really did have only digits after it,
3108 * so it is either a port number or a mistake */
3110 if (port > 0xffff) { /* Single unix standard says port numbers are
3112 failf(data, "Port number too large: %lu", port);
3113 return CURLE_URL_MALFORMAT;
3116 *tmp = '\0'; /* cut off the name there */
3117 conn->remote_port = (unsigned short)port;
3121 /* Programmatically set password:
3122 * - always applies, if available
3123 * - takes precedence over the values we just set above
3124 * so scribble it over the top.
3125 * User-supplied passwords are assumed not to need unescaping.
3127 * user_password is set in "inherite initial knowledge' above,
3128 * so it doesn't have to be set in this block
3130 if (data->set.userpwd != NULL) {
3131 /* the name is given, get user+password */
3132 sscanf(data->set.userpwd,
3133 "%" MAX_CURL_USER_LENGTH_TXT "[^:]:"
3134 "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]",
3138 if (data->set.use_netrc != CURL_NETRC_IGNORED) {
3139 if(Curl_parsenetrc(conn->host.name,
3141 data->set.netrc_file)) {
3142 infof(data, "Couldn't find host %s in the " DOT_CHAR "netrc file, using defaults\n",
3146 conn->bits.user_passwd = 1; /* enable user+password */
3149 /* If our protocol needs a password and we have none, use the defaults */
3150 if ( (conn->protocol & PROT_FTP) &&
3151 !conn->bits.user_passwd) {
3153 conn->user = strdup(CURL_DEFAULT_USER);
3154 conn->passwd = strdup(CURL_DEFAULT_PASSWORD);
3155 /* This is the default password, so DON'T set conn->bits.user_passwd */
3158 /* store user + password, zero-length if not set */
3159 conn->user = strdup(user);
3160 conn->passwd = strdup(passwd);
3162 if(!conn->user || !conn->passwd)
3163 return CURLE_OUT_OF_MEMORY;
3165 /*************************************************************
3166 * Check the current list of connections to see if we can
3167 * re-use an already existing one or if we have to create a
3169 *************************************************************/
3171 /* get a cloned copy of the SSL config situation stored in the
3172 connection struct */
3173 if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config))
3174 return CURLE_OUT_OF_MEMORY;
3176 /* reuse_fresh is TRUE if we are told to use a new connection by force, but
3177 we only acknowledge this option if this is not a re-used connection
3178 already (which happens due to follow-location or during a HTTP
3179 authentication phase). */
3180 if(data->set.reuse_fresh && !data->state.this_is_a_follow)
3183 reuse = ConnectionExists(data, conn, &conn_temp);
3187 * We already have a connection for this, we got the former connection
3188 * in the conn_temp variable and thus we need to cleanup the one we
3189 * just allocated before we can move along and use the previously
3192 struct connectdata *old_conn = conn;
3194 if(old_conn->proxy.rawalloc)
3195 free(old_conn->proxy.rawalloc);
3197 /* free the SSL config struct from this connection struct as this was
3198 allocated in vain and is targeted for destruction */
3199 Curl_free_ssl_config(&conn->ssl_config);
3201 conn = conn_temp; /* use this connection from now on */
3203 /* get the user+password information from the old_conn struct since it may
3204 * be new for this request even when we re-use an existing connection */
3205 conn->bits.user_passwd = old_conn->bits.user_passwd;
3206 if (conn->bits.user_passwd) {
3207 /* use the new user namd and password though */
3208 Curl_safefree(conn->user);
3209 Curl_safefree(conn->passwd);
3210 conn->user = old_conn->user;
3211 conn->passwd = old_conn->passwd;
3212 old_conn->user = NULL;
3213 old_conn->passwd = NULL;
3216 conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd;
3217 if (conn->bits.proxy_user_passwd) {
3218 /* use the new proxy user name and proxy password though */
3219 Curl_safefree(conn->proxyuser);
3220 Curl_safefree(conn->proxypasswd);
3221 conn->proxyuser = old_conn->proxyuser;
3222 conn->proxypasswd = old_conn->proxypasswd;
3223 old_conn->proxyuser = NULL;
3224 old_conn->proxypasswd = NULL;
3227 /* host can change, when doing keepalive with a proxy ! */
3228 if (conn->bits.httpproxy) {
3229 free(conn->host.rawalloc);
3230 conn->host=old_conn->host;
3233 /* get the newly set value, not the old one */
3234 conn->bits.no_body = old_conn->bits.no_body;
3236 if (!conn->bits.httpproxy)
3237 free(old_conn->host.rawalloc); /* free the newly allocated name buffer */
3239 free(conn->pathbuffer); /* free the newly allocated path pointer */
3240 conn->pathbuffer = old_conn->pathbuffer; /* use the old one */
3241 conn->path = old_conn->path;
3244 conn->bits.reuse = TRUE; /* yes, we're re-using here */
3245 conn->bits.chunk = FALSE; /* always assume not chunked unless told
3247 conn->maxdownload = -1; /* might have been used previously! */
3249 Curl_safefree(old_conn->user);
3250 Curl_safefree(old_conn->passwd);
3251 Curl_safefree(old_conn->proxyuser);
3252 Curl_safefree(old_conn->proxypasswd);
3254 if(old_conn->bits.rangestringalloc)
3255 free(old_conn->range);
3257 free(old_conn); /* we don't need this anymore */
3260 * If we're doing a resumed transfer, we need to setup our stuff
3263 conn->resume_from = data->set.set_resume_from;
3264 if (conn->resume_from) {
3265 if (conn->bits.rangestringalloc == TRUE)
3267 conn->range = aprintf("%" FORMAT_OFF_T "-", conn->resume_from);
3269 return CURLE_OUT_OF_MEMORY;
3271 /* tell ourselves to fetch this range */
3272 conn->bits.use_range = TRUE; /* enable range download */
3273 conn->bits.rangestringalloc = TRUE; /* mark range string allocated */
3275 else if (data->set.set_range) {
3276 /* There is a range, but is not a resume, useful for random ftp access */
3277 conn->range = strdup(data->set.set_range);
3279 return CURLE_OUT_OF_MEMORY;
3280 conn->bits.rangestringalloc = TRUE; /* mark range string allocated */
3281 conn->bits.use_range = TRUE; /* enable range download */
3284 conn->bits.use_range = FALSE; /* disable range download */
3286 *in_connect = conn; /* return this instead! */
3288 infof(data, "Re-using existing connection! (#%ld) with host %s\n",
3290 conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname);
3294 * This is a brand new connection, so let's store it in the connection
3297 ConnectionStore(data, conn);
3300 /* Continue connectdata initialization here.
3302 * Inherit the proper values from the urldata struct AFTER we have arranged
3303 * the persistant conncetion stuff */
3304 conn->fread = data->set.fread;
3305 conn->fread_in = data->set.in;
3307 conn->bits.upload_chunky =
3308 ((conn->protocol&PROT_HTTP) &&
3310 (data->set.infilesize == -1) &&
3311 (data->set.httpversion != CURL_HTTP_VERSION_1_0))?
3312 /* HTTP, upload, unknown file size and not HTTP 1.0 */
3314 /* else, no chunky upload */
3318 /*************************************************************
3319 * Set timeout if that is being used, and we're not using an asynchronous
3321 *************************************************************/
3322 if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) {
3323 /*************************************************************
3324 * Set signal handler to catch SIGALRM
3325 * Store the old value to be able to set it back later!
3326 *************************************************************/
3329 #ifdef HAVE_SIGACTION
3330 struct sigaction sigact;
3331 sigaction(SIGALRM, NULL, &sigact);
3332 keep_sigact = sigact;
3333 keep_copysig = TRUE; /* yes, we have a copy */
3334 sigact.sa_handler = alarmfunc;
3336 /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */
3337 sigact.sa_flags &= ~SA_RESTART;
3339 /* now set the new struct */
3340 sigaction(SIGALRM, &sigact, NULL);
3341 #else /* HAVE_SIGACTION */
3342 /* no sigaction(), revert to the much lamer signal() */
3344 keep_sigact = signal(SIGALRM, alarmfunc);
3346 #endif /* HAVE_SIGACTION */
3348 /* We set the timeout on the name resolving phase first, separately from
3349 * the download/upload part to allow a maximum time on everything. This is
3350 * a signal-based timeout, why it won't work and shouldn't be used in
3351 * multi-threaded environments. */
3354 /* alarm() makes a signal get sent when the timeout fires off, and that
3355 will abort system calls */
3356 prev_alarm = alarm(data->set.connecttimeout?
3357 data->set.connecttimeout:
3359 /* We can expect the conn->created time to be "now", as that was just
3360 recently set in the beginning of this function and nothing slow
3361 has been done since then until now. */
3363 #endif /* SIGALRM */
3365 #endif /* USE_ARES */
3367 /*************************************************************
3368 * Resolve the name of the server or proxy
3369 *************************************************************/
3370 if(conn->bits.reuse) {
3371 /* re-used connection, no resolving is necessary */
3373 /* we'll need to clear conn->dns_entry later in Curl_disconnect() */
3375 if (conn->bits.httpproxy)
3376 fix_hostname(conn, &conn->host);
3379 /* this is a fresh connect */
3381 /* set a pointer to the hostname we display */
3382 fix_hostname(conn, &conn->host);
3384 if(!data->change.proxy || !*data->change.proxy) {
3385 /* If not connecting via a proxy, extract the port from the URL, if it is
3386 * there, thus overriding any defaults that might have been set above. */
3387 conn->port = conn->remote_port; /* it is the same port */
3389 /* Resolve target host right on */
3390 rc = Curl_resolv(conn, conn->host.name, (int)conn->port, &hostaddr);
3391 if(rc == CURLRESOLV_PENDING)
3394 else if(!hostaddr) {
3395 failf(data, "Couldn't resolve host '%s'", conn->host.dispname);
3396 result = CURLE_COULDNT_RESOLVE_HOST;
3397 /* don't return yet, we need to clean up the timeout first */
3401 /* This is a proxy that hasn't been resolved yet. */
3403 /* IDN-fix the proxy name */
3404 fix_hostname(conn, &conn->proxy);
3407 rc = Curl_resolv(conn, conn->proxy.name, (int)conn->port, &hostaddr);
3409 if(rc == CURLRESOLV_PENDING)
3412 else if(!hostaddr) {
3413 failf(data, "Couldn't resolve proxy '%s'", conn->proxy.dispname);
3414 result = CURLE_COULDNT_RESOLVE_PROXY;
3415 /* don't return yet, we need to clean up the timeout first */
3421 #if defined(HAVE_ALARM) && defined(SIGALRM) && !defined(USE_ARES)
3422 if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) {
3423 #ifdef HAVE_SIGACTION
3425 /* we got a struct as it looked before, now put that one back nice
3427 sigaction(SIGALRM, &keep_sigact, NULL); /* put it back */
3431 /* restore the previous SIGALRM handler */
3432 signal(SIGALRM, keep_sigact);
3434 #endif /* HAVE_SIGACTION */
3436 /* switch back the alarm() to either zero or to what it was before minus
3437 the time we spent until now! */
3439 /* there was an alarm() set before us, now put it back */
3440 unsigned long elapsed_ms = Curl_tvdiff(Curl_tvnow(), conn->created);
3441 unsigned long alarm_set;
3443 /* the alarm period is counted in even number of seconds */
3444 alarm_set = prev_alarm - elapsed_ms/1000;
3447 ((alarm_set >= 0x80000000) && (prev_alarm < 0x80000000)) ) {
3448 /* if the alarm time-left reached zero or turned "negative" (counted
3449 with unsigned values), we should fire off a SIGALRM here, but we
3450 won't, and zero would be to switch it off so we never set it to
3453 result = CURLE_OPERATION_TIMEOUTED;
3454 failf(data, "Previous alarm fired off!");
3457 alarm((unsigned int)alarm_set);
3460 alarm(0); /* just shut it off */
3467 /* SetupConnection() should be called after the name resolve initiated in
3468 * CreateConnection() is all done.
3471 static CURLcode SetupConnection(struct connectdata *conn,
3472 struct Curl_dns_entry *hostaddr,
3473 bool *protocol_done)
3475 struct SessionHandle *data = conn->data;
3476 CURLcode result=CURLE_OK;
3478 Curl_pgrsTime(data, TIMER_NAMELOOKUP);
3480 if(conn->protocol & PROT_FILE) {
3481 /* There's nothing in this function to setup if we're only doing
3482 a file:// transfer */
3483 *protocol_done = TRUE;
3486 *protocol_done = FALSE; /* default to not done */
3488 /*************************************************************
3489 * Send user-agent to HTTP proxies even if the target protocol
3491 *************************************************************/
3492 if((conn->protocol&PROT_HTTP) ||
3493 (data->change.proxy && *data->change.proxy)) {
3494 if(data->set.useragent) {
3495 Curl_safefree(conn->allocptr.uagent);
3496 conn->allocptr.uagent =
3497 aprintf("User-Agent: %s\015\012", data->set.useragent);
3498 if(!conn->allocptr.uagent)
3499 return CURLE_OUT_OF_MEMORY;
3503 conn->bytecount = 0;
3504 conn->headerbytecount = 0;
3506 if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
3507 bool connected = FALSE;
3509 /* Connect only if not already connected! */
3510 result = ConnectPlease(conn, hostaddr, &connected);
3513 result = Curl_protocol_connect(conn, protocol_done);
3514 if(CURLE_OK == result)
3515 conn->bits.tcpconnect = TRUE;
3518 conn->bits.tcpconnect = FALSE;
3521 if(CURLE_OK != result)
3525 Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */
3526 conn->bits.tcpconnect = TRUE;
3527 *protocol_done = TRUE;
3528 if(data->set.verbose)
3529 verboseconnect(conn);
3532 conn->now = Curl_tvnow(); /* time this *after* the connect is done, we
3533 set this here perhaps a second time */
3537 * the check is quite a hack...
3538 * we're calling _fsetmode to fix the problem with fwrite converting newline
3539 * characters (you get mangled text files, and corrupted binary files when
3540 * you download to stdout and redirect it to a file). */
3542 if ((data->set.out)->_handle == NULL) {
3543 _fsetmode(stdout, "b");
3550 CURLcode Curl_connect(struct SessionHandle *data,
3551 struct connectdata **in_connect,
3553 bool *protocol_done)
3556 struct Curl_dns_entry *dns;
3558 *asyncp = FALSE; /* assume synchronous resolves by default */
3560 /* call the stuff that needs to be called */
3561 code = CreateConnection(data, in_connect, &dns, asyncp);
3563 if(CURLE_OK == code) {
3566 /* If an address is available it means that we already have the name
3567 resolved, OR it isn't async.
3568 If so => continue connecting from here */
3569 code = SetupConnection(*in_connect, dns, protocol_done);
3571 response will be received and treated async wise */
3574 if(CURLE_OK != code) {
3575 /* We're not allowed to return failure with memory left allocated
3576 in the connectdata struct, free those here */
3578 Curl_disconnect(*in_connect); /* close the connection */
3579 *in_connect = NULL; /* return a NULL */
3586 /* Call this function after Curl_connect() has returned async=TRUE and
3587 then a successful name resolve has been received.
3589 Note: this function disconnects and frees the conn data in case of
3591 CURLcode Curl_async_resolved(struct connectdata *conn,
3592 bool *protocol_done)
3594 #if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \
3595 defined(USE_THREADING_GETADDRINFO)
3596 CURLcode code = SetupConnection(conn, conn->async.dns, protocol_done);
3599 /* We're not allowed to return failure with memory left allocated
3600 in the connectdata struct, free those here */
3601 Curl_disconnect(conn); /* close the connection */
3606 (void)protocol_done;
3612 CURLcode Curl_done(struct connectdata **connp,
3613 CURLcode status) /* an error if this is called after an
3614 error was detected */
3617 struct connectdata *conn = *connp;
3618 struct SessionHandle *data=conn->data;
3620 /* cleanups done even if the connection is re-used */
3621 if(conn->bits.rangestringalloc) {
3623 conn->bits.rangestringalloc = FALSE;
3626 if(conn->dns_entry) {
3627 Curl_resolv_unlock(data, conn->dns_entry); /* done with this */
3628 conn->dns_entry = NULL;
3631 /* Cleanup possible redirect junk */
3634 conn->newurl = NULL;
3637 /* this calls the protocol-specific function pointer previously set */
3639 result = conn->curl_done(conn, status);
3643 Curl_pgrsDone(conn); /* done with the operation */
3645 /* if data->set.reuse_forbid is TRUE, it means the libcurl client has
3646 forced us to close this no matter what we think.
3648 if conn->bits.close is TRUE, it means that the connection should be
3649 closed in spite of all our efforts to be nice, due to protocol
3650 restrictions in our or the server's end */
3651 if(data->set.reuse_forbid || conn->bits.close) {
3653 res2 = Curl_disconnect(conn); /* close the connection */
3655 *connp = NULL; /* to make the caller of this function better detect that
3656 this was actually killed here */
3658 /* If we had an error already, make sure we return that one. But
3659 if we got a new error, return that. */
3664 infof(data, "Connection #%ld to host %s left intact\n",
3666 conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname);
3671 CURLcode Curl_do(struct connectdata **connp, bool *done)
3673 CURLcode result=CURLE_OK;
3674 struct connectdata *conn = *connp;
3675 struct SessionHandle *data=conn->data;
3677 conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */
3680 /* generic protocol-specific function pointer set in curl_connect() */
3681 result = conn->curl_do(conn, done);
3683 /* This was formerly done in transfer.c, but we better do it here */
3685 if((CURLE_SEND_ERROR == result) && conn->bits.reuse) {
3686 /* This was a re-use of a connection and we got a write error in the
3687 * DO-phase. Then we DISCONNECT this connection and have another attempt
3688 * to CONNECT and then DO again! The retry cannot possibly find another
3689 * connection to re-use, since we only keep one possible connection for
3692 infof(data, "Re-used connection seems dead, get a new one\n");
3694 conn->bits.close = TRUE; /* enforce close of this connection */
3695 result = Curl_done(&conn, result); /* we are so done with this */
3697 /* conn may no longer be a good pointer */
3699 if(CURLE_OK == result) {
3701 bool protocol_done = TRUE;
3703 /* Now, redo the connect and get a new connection */
3704 result = Curl_connect(data, connp, &async, &protocol_done);
3705 if(CURLE_OK == result) {
3706 /* We have connected or sent away a name resolve query fine */
3708 conn = *connp; /* setup conn to again point to something nice */
3710 /* Now, if async is TRUE here, we need to wait for the name
3712 result = Curl_wait_for_resolv(conn, NULL);
3716 /* Resolved, continue with the connection */
3717 result = Curl_async_resolved(conn, &protocol_done);
3722 /* ... finally back to actually retry the DO phase */
3723 result = conn->curl_do(conn, done);
3731 CURLcode Curl_do_more(struct connectdata *conn)
3733 CURLcode result=CURLE_OK;
3735 if(conn->curl_do_more)
3736 result = conn->curl_do_more(conn);
3741 static bool safe_strequal(char* str1, char* str2)
3744 /* both pointers point to something then compare them */
3745 return strequal(str1, str2);
3747 /* if both pointers are NULL then treat them as equal */
3748 return (!str1 && !str2);
3752 Curl_ssl_config_matches(struct ssl_config_data* data,
3753 struct ssl_config_data* needle)
3755 if((data->version == needle->version) &&
3756 (data->verifypeer == needle->verifypeer) &&
3757 (data->verifyhost == needle->verifyhost) &&
3758 safe_strequal(data->CApath, needle->CApath) &&
3759 safe_strequal(data->CAfile, needle->CAfile) &&
3760 safe_strequal(data->random_file, needle->random_file) &&
3761 safe_strequal(data->egdsocket, needle->egdsocket) &&
3762 safe_strequal(data->cipher_list, needle->cipher_list))
3769 Curl_clone_ssl_config(struct ssl_config_data *source,
3770 struct ssl_config_data *dest)
3772 dest->verifyhost = source->verifyhost;
3773 dest->verifypeer = source->verifypeer;
3774 dest->version = source->version;
3776 if(source->CAfile) {
3777 dest->CAfile = strdup(source->CAfile);
3782 if(source->CApath) {
3783 dest->CApath = strdup(source->CApath);
3788 if(source->cipher_list) {
3789 dest->cipher_list = strdup(source->cipher_list);
3790 if(!dest->cipher_list)
3794 if(source->egdsocket) {
3795 dest->egdsocket = strdup(source->egdsocket);
3796 if(!dest->egdsocket)
3800 if(source->random_file) {
3801 dest->random_file = strdup(source->random_file);
3802 if(!dest->random_file)
3809 void Curl_free_ssl_config(struct ssl_config_data* sslc)
3817 if(sslc->cipher_list)
3818 free(sslc->cipher_list);
3821 free(sslc->egdsocket);
3823 if(sslc->random_file)
3824 free(sslc->random_file);