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"
108 #include "transfer.h"
110 #include "progress.h"
112 #include "strequal.h"
113 #include "strerror.h"
117 #include "content_encoding.h"
118 #include "http_digest.h"
119 #include "http_negotiate.h"
123 /* And now for the protocols */
132 #include "inet_ntop.h"
133 #include "http_ntlm.h"
134 #include <ca-bundle.h>
136 #if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
137 #include "inet_ntoa_r.h"
140 #define _MPRINTF_REPLACE /* use our functions only */
141 #include <curl/mprintf.h>
148 /* The last #include file should be: */
149 #include "memdebug.h"
151 /* Local static prototypes */
152 static long ConnectionKillOne(struct SessionHandle *data);
153 static bool ConnectionExists(struct SessionHandle *data,
154 struct connectdata *needle,
155 struct connectdata **usethis);
156 static long ConnectionStore(struct SessionHandle *data,
157 struct connectdata *conn);
158 static bool safe_strequal(char* str1, char* str2);
161 /* not for Win32, unless it is cygwin
162 not for ares builds */
163 #if !defined(WIN32) || defined(__CYGWIN32__)
166 #define RETSIGTYPE void
168 #ifdef HAVE_SIGSETJMP
169 extern sigjmp_buf curl_jmpenv;
172 RETSIGTYPE alarmfunc(int sig)
174 /* this is for "-ansi -Wall -pedantic" to stop complaining! (rabe) */
176 #ifdef HAVE_SIGSETJMP
177 siglongjmp(curl_jmpenv, 1);
182 #endif /* USE_ARES */
184 void Curl_safefree(void *ptr)
191 * This is the internal function curl_easy_cleanup() calls. This should
192 * cleanup and free all resources associated with this sessionhandle.
194 * NOTE: if we ever add something that attempts to write to a socket or
195 * similar here, we must ignore SIGPIPE first. It is currently only done
196 * when curl_easy_perform() is invoked.
199 CURLcode Curl_close(struct SessionHandle *data)
202 /* this handle is still part of a multi handle, take care of this first */
203 Curl_multi_rmeasy(data->multi, data);
205 /* Loop through all open connections and kill them one by one */
206 while(-1 != ConnectionKillOne(data))
209 if ( ! (data->share && data->share->hostcache) ) {
210 if ( !Curl_global_host_cache_use(data)) {
211 Curl_hash_destroy(data->hostcache);
216 /* Close down all open SSL info and sessions */
217 Curl_SSL_Close_All(data);
220 Curl_safefree(data->state.first_host);
221 Curl_safefree(data->state.scratch);
223 if(data->change.proxy_alloc)
224 free(data->change.proxy);
226 if(data->change.referer_alloc)
227 free(data->change.referer);
229 if(data->change.url_alloc)
230 free(data->change.url);
232 Curl_safefree(data->state.headerbuff);
234 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
235 if(data->change.cookielist) /* clean up list if any */
236 curl_slist_free_all(data->change.cookielist);
238 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
239 if(data->set.cookiejar) {
240 /* we have a "destination" for all the cookies to get dumped to */
241 if(Curl_cookie_output(data->cookies, data->set.cookiejar))
242 infof(data, "WARNING: failed to save cookies in %s\n",
243 data->set.cookiejar);
246 if( !data->share || (data->cookies != data->share->cookies) ) {
247 Curl_cookie_cleanup(data->cookies);
249 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
252 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
253 Curl_digest_cleanup(data);
256 /* free the connection cache */
257 free(data->state.connects);
259 Curl_safefree(data->info.contenttype);
262 /* this destroys the channel and we cannot use it anymore after this */
263 ares_destroy(data->state.areschannel);
266 /* No longer a dirty share, if it exists */
268 data->share->dirty--;
277 * @param curl is a pointer to a sessionhandle pointer that gets set by this
282 CURLcode Curl_open(struct SessionHandle **curl)
284 CURLcode res = CURLE_OK;
285 struct SessionHandle *data;
286 /* Very simple start-up: alloc the struct, init it with zeroes and return */
287 data = (struct SessionHandle *)calloc(1, sizeof(struct SessionHandle));
289 /* this is a very serious error */
290 return CURLE_OUT_OF_MEMORY;
293 if(ARES_SUCCESS != ares_init(&data->state.areschannel)) {
295 return CURLE_FAILED_INIT;
297 /* make sure that all other returns from this function should destroy the
298 ares channel before returning error! */
301 /* We do some initial setup here, all those fields that can't be just 0 */
303 data->state.headerbuff=(char*)malloc(HEADERSIZE);
304 if(!data->state.headerbuff)
305 res = CURLE_OUT_OF_MEMORY;
307 data->state.headersize=HEADERSIZE;
309 data->set.out = stdout; /* default output to stdout */
310 data->set.in = stdin; /* default input from stdin */
311 data->set.err = stderr; /* default stderr to stderr */
313 /* use fwrite as default function to store output */
314 data->set.fwrite = (curl_write_callback)fwrite;
316 /* use fread as default function to read input */
317 data->set.fread = (curl_read_callback)fread;
319 data->set.infilesize = -1; /* we don't know any size */
320 data->set.postfieldsize = -1;
322 data->state.current_speed = -1; /* init to negative == impossible */
324 data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */
325 data->set.ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */
326 data->set.ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */
327 data->set.ftp_use_lprt = TRUE; /* FTP defaults to EPRT operations */
329 data->set.dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
331 /* make libcurl quiet by default: */
332 data->set.hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */
333 data->progress.flags |= PGRS_HIDE;
335 /* Set the default size of the SSL session ID cache */
336 data->set.ssl.numsessions = 5;
338 data->set.proxyport = 1080;
339 data->set.proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
340 data->set.httpauth = CURLAUTH_BASIC; /* defaults to basic */
341 data->set.proxyauth = CURLAUTH_BASIC; /* defaults to basic */
343 /* create an array with connection data struct pointers */
344 data->state.numconnects = 5; /* hard-coded right now */
345 data->state.connects = (struct connectdata **)
346 malloc(sizeof(struct connectdata *) * data->state.numconnects);
348 if(!data->state.connects)
349 res = CURLE_OUT_OF_MEMORY;
351 memset(data->state.connects, 0,
352 sizeof(struct connectdata *)*data->state.numconnects);
355 * libcurl 7.10 introduced SSL verification *by default*! This needs to be
356 * switched off unless wanted.
358 data->set.ssl.verifypeer = TRUE;
359 data->set.ssl.verifyhost = 2;
360 #ifdef CURL_CA_BUNDLE
361 /* This is our prefered CA cert bundle since install time */
362 data->set.ssl.CAfile = (char *)CURL_CA_BUNDLE;
368 ares_destroy(data->state.areschannel);
370 if(data->state.headerbuff)
371 free(data->state.headerbuff);
380 CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
384 CURLcode result = CURLE_OK;
386 va_start(param, option);
389 case CURLOPT_DNS_CACHE_TIMEOUT:
390 data->set.dns_cache_timeout = va_arg(param, int);
392 case CURLOPT_DNS_USE_GLOBAL_CACHE:
394 int use_cache = va_arg(param, int);
396 Curl_global_host_cache_init();
399 data->set.global_dns_cache = use_cache;
402 case CURLOPT_SSL_CIPHER_LIST:
403 /* set a list of cipher we want to use in the SSL connection */
404 data->set.ssl.cipher_list = va_arg(param, char *);
407 case CURLOPT_RANDOM_FILE:
409 * This is the path name to a file that contains random data to seed
410 * the random SSL stuff with. The file is only used for reading.
412 data->set.ssl.random_file = va_arg(param, char *);
414 case CURLOPT_EGDSOCKET:
416 * The Entropy Gathering Daemon socket pathname
418 data->set.ssl.egdsocket = va_arg(param, char *);
420 case CURLOPT_MAXCONNECTS:
422 * Set the absolute number of maximum simultaneous alive connection that
423 * libcurl is allowed to have.
426 long newconnects= va_arg(param, long);
427 struct connectdata **newptr;
430 if(newconnects < data->state.numconnects) {
431 /* Since this number is *decreased* from the existing number, we must
432 close the possibly open connections that live on the indexes that
433 are being removed! */
434 for(i=newconnects; i< data->state.numconnects; i++)
435 Curl_disconnect(data->state.connects[i]);
438 newptr= (struct connectdata **)
439 realloc(data->state.connects,
440 sizeof(struct connectdata *) * newconnects);
442 /* we closed a few connections in vain, but so what? */
443 return CURLE_OUT_OF_MEMORY;
445 /* nullify the newly added pointers */
446 for(i=data->state.numconnects; i<newconnects; i++) {
450 data->state.connects = newptr;
451 data->state.numconnects = newconnects;
454 /* zero makes NO cache at all */
455 if(data->state.connects)
456 free(data->state.connects);
457 data->state.connects=NULL;
458 data->state.numconnects=0;
462 case CURLOPT_FORBID_REUSE:
464 * When this transfer is done, it must not be left to be reused by a
465 * subsequent transfer but shall be closed immediately.
467 data->set.reuse_forbid = va_arg(param, long)?TRUE:FALSE;
469 case CURLOPT_FRESH_CONNECT:
471 * This transfer shall not use a previously cached connection but
472 * should be made with a fresh new connect!
474 data->set.reuse_fresh = va_arg(param, long)?TRUE:FALSE;
476 case CURLOPT_VERBOSE:
478 * Verbose means infof() calls that give a lot of information about
479 * the connection and transfer procedures as well as internal choices.
481 data->set.verbose = va_arg(param, long)?TRUE:FALSE;
485 * Set to include the header in the general data output stream.
487 data->set.include_header = va_arg(param, long)?TRUE:FALSE;
489 case CURLOPT_NOPROGRESS:
491 * Shut off the internal supported progress meter
493 data->set.hide_progress = va_arg(param, long)?TRUE:FALSE;
494 if(data->set.hide_progress)
495 data->progress.flags |= PGRS_HIDE;
497 data->progress.flags &= ~PGRS_HIDE;
501 * Do not include the body part in the output data stream.
503 data->set.opt_no_body = va_arg(param, long)?TRUE:FALSE;
504 if(data->set.opt_no_body)
505 /* in HTTP lingo, this means using the HEAD request */
506 data->set.httpreq = HTTPREQ_HEAD;
508 case CURLOPT_FAILONERROR:
510 * Don't output the >=300 error code HTML-page, but instead only
513 data->set.http_fail_on_error = va_arg(param, long)?TRUE:FALSE;
518 * We want to sent data to the remote host. If this is HTTP, that equals
519 * using the PUT request.
521 data->set.upload = va_arg(param, long)?TRUE:FALSE;
523 /* If this is HTTP, PUT is what's needed to "upload" */
524 data->set.httpreq = HTTPREQ_PUT;
526 case CURLOPT_FILETIME:
528 * Try to get the file time of the remote document. The time will
529 * later (possibly) become available using curl_easy_getinfo().
531 data->set.get_filetime = va_arg(param, long)?TRUE:FALSE;
533 case CURLOPT_FTP_CREATE_MISSING_DIRS:
535 * An FTP option that modifies an upload to create missing directories on
538 data->set.ftp_create_missing_dirs = va_arg( param , long )?TRUE:FALSE;
540 case CURLOPT_FTP_RESPONSE_TIMEOUT:
542 * An FTP option that specifies how quickly an FTP response must be
543 * obtained before it is considered failure.
545 data->set.ftp_response_timeout = va_arg( param , long );
547 case CURLOPT_FTPLISTONLY:
549 * An FTP option that changes the command to one that asks for a list
550 * only, no file info details.
552 data->set.ftp_list_only = va_arg(param, long)?TRUE:FALSE;
554 case CURLOPT_FTPAPPEND:
556 * We want to upload and append to an existing (FTP) file.
558 data->set.ftp_append = va_arg(param, long)?TRUE:FALSE;
562 * Parse the $HOME/.netrc file
564 data->set.use_netrc = (enum CURL_NETRC_OPTION)va_arg(param, long);
566 case CURLOPT_NETRC_FILE:
568 * Use this file instead of the $HOME/.netrc file
570 data->set.netrc_file = va_arg(param, char *);
572 case CURLOPT_TRANSFERTEXT:
574 * This option was previously named 'FTPASCII'. Renamed to work with
575 * more protocols than merely FTP.
577 * Transfer using ASCII (instead of BINARY).
579 data->set.ftp_ascii = va_arg(param, long)?TRUE:FALSE;
581 case CURLOPT_TIMECONDITION:
583 * Set HTTP time condition. This must be one of the defines in the
584 * curl/curl.h header file.
586 data->set.timecondition = (curl_TimeCond)va_arg(param, long);
588 case CURLOPT_TIMEVALUE:
590 * This is the value to compare with the remote document with the
591 * method set with CURLOPT_TIMECONDITION
593 data->set.timevalue = (time_t)va_arg(param, long);
595 case CURLOPT_SSLVERSION:
597 * Set explicit SSL version to try to connect with, as some SSL
598 * implementations are lame.
600 data->set.ssl.version = va_arg(param, long);
603 #ifndef CURL_DISABLE_HTTP
604 case CURLOPT_AUTOREFERER:
606 * Switch on automatic referer that gets set if curl follows locations.
608 data->set.http_auto_referer = va_arg(param, long)?1:0;
611 case CURLOPT_ENCODING:
613 * String to use at the value of Accept-Encoding header.
615 * If the encoding is set to "" we use an Accept-Encoding header that
616 * encompasses all the encodings we support.
617 * If the encoding is set to NULL we don't send an Accept-Encoding header
618 * and ignore an received Content-Encoding header.
621 data->set.encoding = va_arg(param, char *);
622 if(data->set.encoding && !*data->set.encoding)
623 data->set.encoding = (char*)ALL_CONTENT_ENCODINGS;
626 case CURLOPT_FOLLOWLOCATION:
628 * Follow Location: header hints on a HTTP-server.
630 data->set.http_follow_location = va_arg(param, long)?TRUE:FALSE;
633 case CURLOPT_UNRESTRICTED_AUTH:
635 * Send authentication (user+password) when following locations, even when
638 data->set.http_disable_hostname_check_before_authentication =
639 va_arg(param, long)?TRUE:FALSE;
642 case CURLOPT_MAXREDIRS:
644 * The maximum amount of hops you allow curl to follow Location:
645 * headers. This should mostly be used to detect never-ending loops.
647 data->set.maxredirs = va_arg(param, long);
651 /* Does this option serve a purpose anymore? Yes it does, when
652 CURLOPT_POSTFIELDS isn't used and the POST data is read off the
654 if(va_arg(param, long))
655 data->set.httpreq = HTTPREQ_POST;
657 data->set.httpreq = HTTPREQ_GET;
660 case CURLOPT_POSTFIELDS:
662 * A string with POST data. Makes curl HTTP POST. Even if it is NULL.
664 data->set.postfields = va_arg(param, char *);
665 data->set.httpreq = HTTPREQ_POST;
668 case CURLOPT_POSTFIELDSIZE:
670 * The size of the POSTFIELD data to prevent libcurl to do strlen() to
671 * figure it out. Enables binary posts.
673 data->set.postfieldsize = va_arg(param, long);
676 case CURLOPT_POSTFIELDSIZE_LARGE:
678 * The size of the POSTFIELD data to prevent libcurl to do strlen() to
679 * figure it out. Enables binary posts.
681 data->set.postfieldsize = va_arg(param, curl_off_t);
684 case CURLOPT_HTTPPOST:
686 * Set to make us do HTTP POST
688 data->set.httppost = va_arg(param, struct curl_httppost *);
689 data->set.httpreq = HTTPREQ_POST_FORM;
692 case CURLOPT_REFERER:
694 * String to set in the HTTP Referer: field.
696 if(data->change.referer_alloc) {
697 free(data->change.referer);
698 data->change.referer_alloc = FALSE;
700 data->set.set_referer = va_arg(param, char *);
701 data->change.referer = data->set.set_referer;
704 case CURLOPT_USERAGENT:
706 * String to use in the HTTP User-Agent field
708 data->set.useragent = va_arg(param, char *);
711 case CURLOPT_HTTPHEADER:
713 * Set a list with HTTP headers to use (or replace internals with)
715 data->set.headers = va_arg(param, struct curl_slist *);
718 case CURLOPT_HTTP200ALIASES:
720 * Set a list of aliases for HTTP 200 in response header
722 data->set.http200aliases = va_arg(param, struct curl_slist *);
725 #if !defined(CURL_DISABLE_COOKIES)
728 * Cookie string to send to the remote server in the request.
730 data->set.cookie = va_arg(param, char *);
733 case CURLOPT_COOKIEFILE:
735 * Set cookie file to read and parse. Can be used multiple times.
737 argptr = (char *)va_arg(param, void *);
739 struct curl_slist *cl;
740 /* append the cookie file name to the list of file names, and deal with
742 cl = curl_slist_append(data->change.cookielist, argptr);
745 return CURLE_OUT_OF_MEMORY;
747 data->change.cookielist = cl;
751 case CURLOPT_COOKIEJAR:
753 * Set cookie file name to dump all cookies to when we're done.
755 data->set.cookiejar = (char *)va_arg(param, void *);
758 * Activate the cookie parser. This may or may not already
761 data->cookies = Curl_cookie_init(data, NULL, data->cookies,
762 data->set.cookiesession);
765 case CURLOPT_COOKIESESSION:
767 * Set this option to TRUE to start a new "cookie session". It will
768 * prevent the forthcoming read-cookies-from-file actions to accept
769 * cookies that are marked as being session cookies, as they belong to a
772 * In the original Netscape cookie spec, "session cookies" are cookies
773 * with no expire date set. RFC2109 describes the same action if no
774 * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds
775 * a 'Discard' action that can enforce the discard even for cookies that
778 * We run mostly with the original cookie spec, as hardly anyone implements
781 data->set.cookiesession = (bool)va_arg(param, long);
783 #endif /* CURL_DISABLE_COOKIES */
785 case CURLOPT_HTTPGET:
787 * Set to force us do HTTP GET
789 if(va_arg(param, long)) {
790 data->set.httpreq = HTTPREQ_GET;
791 data->set.upload = FALSE; /* switch off upload */
795 case CURLOPT_HTTP_VERSION:
797 * This sets a requested HTTP version to be used. The value is one of
798 * the listed enums in curl/curl.h.
800 data->set.httpversion = va_arg(param, long);
803 case CURLOPT_HTTPPROXYTUNNEL:
805 * Tunnel operations through the proxy instead of normal proxy use
807 data->set.tunnel_thru_httpproxy = va_arg(param, long)?TRUE:FALSE;
810 case CURLOPT_CUSTOMREQUEST:
812 * Set a custom string to use as request
814 data->set.customrequest = va_arg(param, char *);
817 data->set.httpreq = HTTPREQ_CUSTOM;
818 here, we continue as if we were using the already set type
819 and this just changes the actual request keyword */
822 case CURLOPT_PROXYPORT:
824 * Explicitly set HTTP proxy port number.
826 data->set.proxyport = va_arg(param, long);
829 case CURLOPT_HTTPAUTH:
831 * Set HTTP Authentication type BITMASK.
834 long auth = va_arg(param, long);
835 /* switch off bits we can't support */
836 #if ! defined(USE_SSLEAY) && !defined(USE_WINDOWS_SSPI)
837 auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
840 auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */
843 return CURLE_FAILED_INIT; /* no supported types left! */
845 data->set.httpauth = auth;
849 case CURLOPT_PROXYAUTH:
851 * Set HTTP Authentication type BITMASK.
854 long auth = va_arg(param, long);
855 /* switch off bits we can't support */
857 auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
860 auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */
863 return CURLE_FAILED_INIT; /* no supported types left! */
865 data->set.proxyauth = auth;
868 #endif /* CURL_DISABLE_HTTP */
872 * Set proxy server:port to use as HTTP proxy.
874 * If the proxy is set to "" we explicitly say that we don't want to use a
875 * proxy (even though there might be environment variables saying so).
877 * Setting it to NULL, means no proxy but allows the environment variables
880 if(data->change.proxy_alloc) {
882 * The already set string is allocated, free that first
884 data->change.proxy_alloc=FALSE;;
885 free(data->change.proxy);
887 data->set.set_proxy = va_arg(param, char *);
888 data->change.proxy = data->set.set_proxy;
891 case CURLOPT_WRITEHEADER:
893 * Custom pointer to pass the header write callback function
895 data->set.writeheader = (void *)va_arg(param, void *);
897 case CURLOPT_ERRORBUFFER:
899 * Error buffer provided by the caller to get the human readable
902 data->set.errorbuffer = va_arg(param, char *);
906 * FILE pointer to write to or include in the data write callback
908 data->set.out = va_arg(param, FILE *);
910 case CURLOPT_FTPPORT:
912 * Use FTP PORT, this also specifies which IP address to use
914 data->set.ftpport = va_arg(param, char *);
915 data->set.ftp_use_port = data->set.ftpport?1:0;
918 case CURLOPT_FTP_USE_EPRT:
919 data->set.ftp_use_eprt = va_arg(param, long)?TRUE:FALSE;
920 data->set.ftp_use_lprt = data->set.ftp_use_eprt;
923 case CURLOPT_FTP_USE_EPSV:
924 data->set.ftp_use_epsv = va_arg(param, long)?TRUE:FALSE;
929 * FILE pointer to read the file to be uploaded from. Or possibly
930 * used as argument to the read callback.
932 data->set.in = va_arg(param, FILE *);
934 case CURLOPT_INFILESIZE:
936 * If known, this should inform curl about the file size of the
937 * to-be-uploaded file.
939 data->set.infilesize = va_arg(param, long);
941 case CURLOPT_INFILESIZE_LARGE:
943 * If known, this should inform curl about the file size of the
944 * to-be-uploaded file.
946 data->set.infilesize = va_arg(param, curl_off_t);
948 case CURLOPT_LOW_SPEED_LIMIT:
950 * The low speed limit that if transfers are below this for
951 * CURLOPT_LOW_SPEED_TIME, the transfer is aborted.
953 data->set.low_speed_limit=va_arg(param, long);
955 case CURLOPT_LOW_SPEED_TIME:
957 * The low speed time that if transfers are below the set
958 * CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted.
960 data->set.low_speed_time=va_arg(param, long);
966 if(data->change.url_alloc) {
967 /* the already set URL is allocated, free it first! */
968 free(data->change.url);
969 data->change.url_alloc=FALSE;
971 data->set.set_url = va_arg(param, char *);
972 data->change.url = data->set.set_url;
973 data->change.url_changed = TRUE;
977 * The port number to use when getting the URL
979 data->set.use_port = va_arg(param, long);
981 case CURLOPT_TIMEOUT:
983 * The maximum time you allow curl to use for a single transfer
986 data->set.timeout = va_arg(param, long);
988 case CURLOPT_CONNECTTIMEOUT:
990 * The maximum time you allow curl to use to connect.
992 data->set.connecttimeout = va_arg(param, long);
995 case CURLOPT_USERPWD:
997 * user:password to use in the operation
999 data->set.userpwd = va_arg(param, char *);
1001 case CURLOPT_POSTQUOTE:
1003 * List of RAW FTP commands to use after a transfer
1005 data->set.postquote = va_arg(param, struct curl_slist *);
1007 case CURLOPT_PREQUOTE:
1009 * List of RAW FTP commands to use prior to RETR (Wesley Laxton)
1011 data->set.prequote = va_arg(param, struct curl_slist *);
1015 * List of RAW FTP commands to use before a transfer
1017 data->set.quote = va_arg(param, struct curl_slist *);
1019 case CURLOPT_PROGRESSFUNCTION:
1021 * Progress callback function
1023 data->set.fprogress = va_arg(param, curl_progress_callback);
1024 if(data->set.fprogress)
1025 data->progress.callback = TRUE; /* no longer internal */
1027 data->progress.callback = FALSE; /* NULL enforces internal */
1030 case CURLOPT_PROGRESSDATA:
1032 * Custom client data to pass to the progress callback
1034 data->set.progress_client = va_arg(param, void *);
1036 case CURLOPT_PROXYUSERPWD:
1038 * user:password needed to use the proxy
1040 data->set.proxyuserpwd = va_arg(param, char *);
1044 * What range of the file you want to transfer
1046 data->set.set_range = va_arg(param, char *);
1048 case CURLOPT_RESUME_FROM:
1050 * Resume transfer at the give file position
1052 data->set.set_resume_from = va_arg(param, long);
1054 case CURLOPT_RESUME_FROM_LARGE:
1056 * Resume transfer at the give file position
1058 data->set.set_resume_from = va_arg(param, curl_off_t);
1060 case CURLOPT_DEBUGFUNCTION:
1062 * stderr write callback.
1064 data->set.fdebug = va_arg(param, curl_debug_callback);
1066 * if the callback provided is NULL, it'll use the default callback
1069 case CURLOPT_DEBUGDATA:
1071 * Set to a void * that should receive all error writes. This
1072 * defaults to CURLOPT_STDERR for normal operations.
1074 data->set.debugdata = va_arg(param, void *);
1076 case CURLOPT_STDERR:
1078 * Set to a FILE * that should receive all error writes. This
1079 * defaults to stderr for normal operations.
1081 data->set.err = va_arg(param, FILE *);
1083 data->set.err = stderr;
1085 case CURLOPT_HEADERFUNCTION:
1087 * Set header write callback
1089 data->set.fwrite_header = va_arg(param, curl_write_callback);
1091 case CURLOPT_WRITEFUNCTION:
1093 * Set data write callback
1095 data->set.fwrite = va_arg(param, curl_write_callback);
1096 if(!data->set.fwrite)
1097 /* When set to NULL, reset to our internal default function */
1098 data->set.fwrite = (curl_write_callback)fwrite;
1100 case CURLOPT_READFUNCTION:
1102 * Read data callback
1104 data->set.fread = va_arg(param, curl_read_callback);
1105 if(!data->set.fread)
1106 /* When set to NULL, reset to our internal default function */
1107 data->set.fread = (curl_read_callback)fread;
1109 case CURLOPT_IOCTLFUNCTION:
1111 * I/O control callback. Might be NULL.
1113 data->set.ioctl = va_arg(param, curl_ioctl_callback);
1115 case CURLOPT_IOCTLDATA:
1117 * I/O control data pointer. Might be NULL.
1119 data->set.ioctl_client = va_arg(param, void *);
1121 case CURLOPT_SSLCERT:
1123 * String that holds file name of the SSL certificate to use
1125 data->set.cert = va_arg(param, char *);
1127 case CURLOPT_SSLCERTTYPE:
1129 * String that holds file type of the SSL certificate to use
1131 data->set.cert_type = va_arg(param, char *);
1133 case CURLOPT_SSLKEY:
1135 * String that holds file name of the SSL certificate to use
1137 data->set.key = va_arg(param, char *);
1139 case CURLOPT_SSLKEYTYPE:
1141 * String that holds file type of the SSL certificate to use
1143 data->set.key_type = va_arg(param, char *);
1145 case CURLOPT_SSLKEYPASSWD:
1147 * String that holds the SSL private key password.
1149 data->set.key_passwd = va_arg(param, char *);
1151 case CURLOPT_SSLENGINE:
1153 * String that holds the SSL crypto engine.
1155 argptr = va_arg(param, char *);
1156 if (argptr && argptr[0])
1157 result = Curl_SSL_set_engine(data, argptr);
1160 case CURLOPT_SSLENGINE_DEFAULT:
1162 * flag to set engine as default.
1164 result = Curl_SSL_set_engine_default(data);
1168 * Kludgy option to enable CRLF convertions. Subject for removal.
1170 data->set.crlf = va_arg(param, long)?TRUE:FALSE;
1172 case CURLOPT_INTERFACE:
1174 * Set what interface to bind to when performing an operation and thus
1175 * what from-IP your connection will use.
1177 data->set.device = va_arg(param, char *);
1179 case CURLOPT_KRB4LEVEL:
1181 * A string that defines the krb4 security level.
1183 data->set.krb4_level = va_arg(param, char *);
1184 data->set.krb4=data->set.krb4_level?TRUE:FALSE;
1186 case CURLOPT_SSL_VERIFYPEER:
1188 * Enable peer SSL verifying.
1190 data->set.ssl.verifypeer = va_arg(param, long);
1192 case CURLOPT_SSL_VERIFYHOST:
1194 * Enable verification of the CN contained in the peer certificate
1196 data->set.ssl.verifyhost = va_arg(param, long);
1198 case CURLOPT_SSL_CTX_FUNCTION:
1200 * Set a SSL_CTX callback
1202 data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback);
1204 case CURLOPT_SSL_CTX_DATA:
1206 * Set a SSL_CTX callback parameter pointer
1208 data->set.ssl.fsslctxp = va_arg(param, void *);
1210 case CURLOPT_CAINFO:
1212 * Set CA info for SSL connection. Specify file name of the CA certificate
1214 data->set.ssl.CAfile = va_arg(param, char *);
1216 case CURLOPT_CAPATH:
1218 * Set CA path info for SSL connection. Specify directory name of the CA
1219 * certificates which have been prepared using openssl c_rehash utility.
1221 /* This does not work on windows. */
1222 data->set.ssl.CApath = va_arg(param, char *);
1224 case CURLOPT_TELNETOPTIONS:
1226 * Set a linked list of telnet options
1228 data->set.telnet_options = va_arg(param, struct curl_slist *);
1231 case CURLOPT_BUFFERSIZE:
1233 * The application kindly asks for a differently sized receive buffer.
1234 * If it seems reasonable, we'll use it.
1236 data->set.buffer_size = va_arg(param, long);
1238 if((data->set.buffer_size> (BUFSIZE -1 )) ||
1239 (data->set.buffer_size < 1))
1240 data->set.buffer_size = 0; /* huge internal default */
1244 case CURLOPT_NOSIGNAL:
1246 * The application asks not to set any signal() or alarm() handlers,
1247 * even when using a timeout.
1249 data->set.no_signal = va_arg(param, long) ? TRUE : FALSE;
1254 struct Curl_share *set;
1255 set = va_arg(param, struct Curl_share *);
1257 /* disconnect from old share, if any */
1259 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
1261 if(data->share->hostcache == data->hostcache)
1262 data->hostcache = NULL;
1264 if(data->share->cookies == data->cookies)
1265 data->cookies = NULL;
1267 data->share->dirty--;
1269 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
1273 /* use new share if it set */
1277 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
1279 data->share->dirty++;
1281 if(data->share->hostcache) {
1282 /* use shared host cache, first free own one if any */
1284 Curl_hash_destroy(data->hostcache);
1286 data->hostcache = data->share->hostcache;
1288 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
1289 if(data->share->cookies) {
1290 /* use shared cookie list, first free own one if any */
1292 Curl_cookie_cleanup(data->cookies);
1293 data->cookies = data->share->cookies;
1295 #endif /* CURL_DISABLE_HTTP */
1296 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
1299 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
1300 /* check cookie list is set */
1302 data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE );
1303 #endif /* CURL_DISABLE_HTTP */
1304 /* check for host cache not needed,
1305 * it will be done by curl_easy_perform */
1309 case CURLOPT_PROXYTYPE:
1311 * Set proxy type. HTTP/SOCKS4/SOCKS5
1313 data->set.proxytype = (curl_proxytype)va_arg(param, long);
1316 case CURLOPT_PRIVATE:
1318 * Set private data pointer.
1320 data->set.private_data = va_arg(param, char *);
1323 case CURLOPT_MAXFILESIZE:
1325 * Set the maximum size of a file to download.
1327 data->set.max_filesize = va_arg(param, long);
1330 case CURLOPT_FTP_SSL:
1332 * Make FTP transfers attempt to use SSL/TLS.
1334 data->set.ftp_ssl = (curl_ftpssl)va_arg(param, long);
1337 case CURLOPT_FTPSSLAUTH:
1339 * Set a specific auth for FTP-SSL transfers.
1341 data->set.ftpsslauth = (curl_ftpauth)va_arg(param, long);
1344 case CURLOPT_IPRESOLVE:
1345 data->set.ip_version = va_arg(param, long);
1348 case CURLOPT_MAXFILESIZE_LARGE:
1350 * Set the maximum size of a file to download.
1352 data->set.max_filesize = va_arg(param, curl_off_t);
1355 case CURLOPT_TCP_NODELAY:
1357 * Enable or disable TCP_NODELAY, which will disable/enable the Nagle
1360 data->set.tcp_nodelay = (bool)va_arg(param, long);
1363 /*********** 3rd party transfer options ***********/
1364 case CURLOPT_SOURCE_URL:
1368 data->set.source_url = va_arg(param, char *);
1369 data->set.printhost = (data->set.source_url != NULL);
1372 case CURLOPT_SOURCE_USERPWD:
1374 * Use SOURCE USER[:PASSWORD]
1376 data->set.source_userpwd = va_arg(param, char *);
1379 case CURLOPT_SOURCE_QUOTE:
1381 * List of RAW FTP commands to use after a connect
1383 data->set.source_quote = va_arg(param, struct curl_slist *);
1386 case CURLOPT_SOURCE_PREQUOTE:
1388 * List of RAW FTP commands to use before a transfer on the source host
1390 data->set.source_prequote = va_arg(param, struct curl_slist *);
1393 case CURLOPT_SOURCE_POSTQUOTE:
1395 * List of RAW FTP commands to use after a transfer on the source host
1397 data->set.source_postquote = va_arg(param, struct curl_slist *);
1400 case CURLOPT_FTP_ACCOUNT:
1401 data->set.ftp_account = va_arg(param, char *);
1405 /* unknown tag and its companion, just ignore: */
1406 result = CURLE_FAILED_INIT; /* correct this */
1413 CURLcode Curl_disconnect(struct connectdata *conn)
1415 struct SessionHandle *data;
1417 return CURLE_OK; /* this is closed and fine already */
1421 #if defined(CURLDEBUG) && defined(AGGRESIVE_TEST)
1422 /* scan for DNS cache entries still marked as in use */
1423 Curl_hash_apply(data->hostcache,
1424 NULL, Curl_scan_cache_used);
1427 Curl_hostcache_prune(data); /* kill old DNS cache entries */
1430 * The range string is usually freed in curl_done(), but we might
1431 * get here *instead* if we fail prematurely. Thus we need to be able
1432 * to free this resource here as well.
1434 if(conn->bits.rangestringalloc) {
1436 conn->bits.rangestringalloc = FALSE;
1439 if((conn->ntlm.state != NTLMSTATE_NONE) ||
1440 (conn->proxyntlm.state != NTLMSTATE_NONE)) {
1441 /* Authentication data is a mix of connection-related and sessionhandle-
1442 related stuff. NTLM is connection-related so when we close the shop
1444 data->state.authhost.done = FALSE;
1445 data->state.authhost.picked =
1446 data->state.authhost.want;
1448 data->state.authproxy.done = FALSE;
1449 data->state.authproxy.picked =
1450 data->state.authhost.want;
1452 data->state.authproblem = FALSE;
1454 #if defined(USE_SSLEAY) || defined(USE_WINDOWS_SSPI)
1455 Curl_ntlm_cleanup(conn);
1459 if(conn->curl_disconnect)
1460 /* This is set if protocol-specific cleanups should be made */
1461 conn->curl_disconnect(conn);
1463 if(-1 != conn->connectindex) {
1464 /* unlink ourselves! */
1465 infof(data, "Closing connection #%ld\n", conn->connectindex);
1466 data->state.connects[conn->connectindex] = NULL;
1469 Curl_safefree(conn->proto.generic);
1470 Curl_safefree(conn->newurl);
1471 Curl_safefree(conn->pathbuffer); /* the URL path buffer */
1473 Curl_safefree(conn->host.rawalloc); /* host name buffer */
1474 Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */
1476 if(conn->host.encalloc)
1477 idn_free(conn->host.encalloc); /* encoded host name buffer, must be freed
1478 with idn_free() since this was allocated
1480 if(conn->proxy.encalloc)
1481 idn_free(conn->proxy.encalloc); /* encoded proxy name buffer, must be
1482 freed with idn_free() since this was
1483 allocated by libidn */
1485 Curl_SSL_Close(conn);
1487 /* close possibly still open sockets */
1488 if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
1489 sclose(conn->sock[SECONDARYSOCKET]);
1490 if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET])
1491 sclose(conn->sock[FIRSTSOCKET]);
1493 Curl_safefree(conn->user);
1494 Curl_safefree(conn->passwd);
1495 Curl_safefree(conn->proxyuser);
1496 Curl_safefree(conn->proxypasswd);
1497 Curl_safefree(conn->allocptr.proxyuserpwd);
1498 Curl_safefree(conn->allocptr.uagent);
1499 Curl_safefree(conn->allocptr.userpwd);
1500 Curl_safefree(conn->allocptr.accept_encoding);
1501 Curl_safefree(conn->allocptr.rangeline);
1502 Curl_safefree(conn->allocptr.ref);
1503 Curl_safefree(conn->allocptr.host);
1504 Curl_safefree(conn->allocptr.cookiehost);
1505 Curl_safefree(conn->ip_addr_str);
1507 #if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \
1508 defined(USE_THREADING_GETADDRINFO)
1509 /* possible left-overs from the async name resolve */
1510 Curl_safefree(conn->async.hostname);
1511 Curl_safefree(conn->async.os_specific);
1514 Curl_free_ssl_config(&conn->ssl_config);
1516 free(conn); /* free all the connection oriented data */
1522 * This function should return TRUE if the socket is to be assumed to
1523 * be dead. Most commonly this happens when the server has closed the
1524 * connection due to inactivity.
1526 static bool SocketIsDead(curl_socket_t sock)
1529 bool ret_val = TRUE;
1531 sval = Curl_select(sock, CURL_SOCKET_BAD, 0);
1540 * Given one filled in connection struct (named needle), this function should
1541 * detect if there already is one that have all the significant details
1542 * exactly the same and thus should be used instead.
1545 ConnectionExists(struct SessionHandle *data,
1546 struct connectdata *needle,
1547 struct connectdata **usethis)
1550 struct connectdata *check;
1552 for(i=0; i< data->state.numconnects; i++) {
1555 * Note that if we use a HTTP proxy, we check connections to that
1556 * proxy and not to the actual remote server.
1558 check = data->state.connects[i];
1560 /* NULL pointer means not filled-in entry */
1563 if((needle->protocol&PROT_SSL) != (check->protocol&PROT_SSL))
1564 /* don't do mixed SSL and non-SSL connections */
1567 if(!needle->bits.httpproxy || needle->protocol&PROT_SSL) {
1568 /* The requested connection does not use a HTTP proxy or it
1571 if(!(needle->protocol&PROT_SSL) && check->bits.httpproxy)
1572 /* we don't do SSL but the cached connection has a proxy,
1573 then don't match this */
1576 if(strequal(needle->protostr, check->protostr) &&
1577 strequal(needle->host.name, check->host.name) &&
1578 (needle->remote_port == check->remote_port) ) {
1579 if(needle->protocol & PROT_SSL) {
1580 /* This is SSL, verify that we're using the same
1581 ssl options as well */
1582 if(!Curl_ssl_config_matches(&needle->ssl_config,
1583 &check->ssl_config)) {
1587 if((needle->protocol & PROT_FTP) ||
1588 ((needle->protocol & PROT_HTTP) &&
1589 (needle->data->state.authhost.want==CURLAUTH_NTLM))) {
1590 /* This is FTP or HTTP+NTLM, verify that we're using the same name
1591 and password as well */
1592 if(!strequal(needle->user, check->user) ||
1593 !strequal(needle->passwd, check->passwd)) {
1594 /* one of them was different */
1601 else { /* The requested needle connection is using a proxy,
1602 is the checked one using the same? */
1603 if(check->bits.httpproxy &&
1604 strequal(needle->proxy.name, check->proxy.name) &&
1605 needle->port == check->port) {
1606 /* This is the same proxy connection, use it! */
1612 bool dead = SocketIsDead(check->sock[FIRSTSOCKET]);
1616 infof(data, "Connection %d seems to be dead!\n", i);
1617 Curl_disconnect(check); /* disconnect resources */
1618 data->state.connects[i]=NULL; /* nothing here */
1620 /* There's no need to continue searching, because we only store
1621 one connection for each unique set of identifiers */
1626 return TRUE; /* yes, we found one to use! */
1629 return FALSE; /* no matching connecting exists */
1633 * This function frees/closes a connection in the connection cache. This
1634 * should take the previously set policy into account when deciding which
1635 * of the connections to kill.
1638 ConnectionKillOne(struct SessionHandle *data)
1641 struct connectdata *conn;
1649 for(i=0; i< data->state.numconnects; i++) {
1650 conn = data->state.connects[i];
1656 * By using the set policy, we score each connection.
1658 switch(data->set.closepolicy) {
1659 case CURLCLOSEPOLICY_LEAST_RECENTLY_USED:
1662 * Set higher score for the age passed since the connection
1665 score = Curl_tvdiff(now, conn->now);
1667 case CURLCLOSEPOLICY_OLDEST:
1669 * Set higher score for the age passed since the connection
1672 score = Curl_tvdiff(now, conn->created);
1676 if(score > highscore) {
1681 if(connindex >= 0) {
1683 /* the winner gets the honour of being disconnected */
1684 (void) Curl_disconnect(data->state.connects[connindex]);
1686 /* clean the array entry */
1687 data->state.connects[connindex] = NULL;
1690 return connindex; /* return the available index or -1 */
1694 * The given input connection struct pointer is to be stored. If the "cache"
1695 * is already full, we must clean out the most suitable using the previously
1698 * The given connection should be unique. That must've been checked prior to
1702 ConnectionStore(struct SessionHandle *data,
1703 struct connectdata *conn)
1706 for(i=0; i< data->state.numconnects; i++) {
1707 if(!data->state.connects[i])
1710 if(i == data->state.numconnects) {
1711 /* there was no room available, kill one */
1712 i = ConnectionKillOne(data);
1713 infof(data, "Connection (#%d) was killed to make room\n", i);
1717 /* only do this if a true index was returned, if -1 was returned there
1718 is no room in the cache for an unknown reason and we cannot store
1720 data->state.connects[i] = conn; /* fill in this */
1721 conn->connectindex = i; /* make the child know where the pointer to this
1722 particular data is stored */
1728 * This function logs in to a SOCKS5 proxy and sends the specifies the final
1729 * desitination server.
1731 static int handleSock5Proxy(const char *proxy_name,
1732 const char *proxy_password,
1733 struct connectdata *conn)
1736 According to the RFC1928, section "6. Replies". This is what a SOCK5
1739 +----+-----+-------+------+----------+----------+
1740 |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
1741 +----+-----+-------+------+----------+----------+
1742 | 1 | 1 | X'00' | 1 | Variable | 2 |
1743 +----+-----+-------+------+----------+----------+
1747 o VER protocol version: X'05'
1752 unsigned char socksreq[600]; /* room for large user/pw (255 max each) */
1757 int sock = conn->sock[FIRSTSOCKET];
1759 Curl_nonblock(sock, FALSE);
1761 socksreq[0] = 5; /* version */
1762 socksreq[1] = (char)(proxy_name ? 2 : 1); /* number of methods (below) */
1763 socksreq[2] = 0; /* no authentication */
1764 socksreq[3] = 2; /* username/password */
1766 code = Curl_write(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]),
1768 if ((code != CURLE_OK) || (written != (2 + (int)socksreq[1]))) {
1769 failf(conn->data, "Unable to send initial SOCKS5 request.");
1773 result=Curl_read(conn, sock, (char *)socksreq, 2, &actualread);
1774 if ((result != CURLE_OK) || (actualread != 2)) {
1775 failf(conn->data, "Unable to receive initial SOCKS5 response.");
1779 if (socksreq[0] != 5) {
1780 failf(conn->data, "Received invalid version in initial SOCKS5 response.");
1783 if (socksreq[1] == 0) {
1784 /* Nothing to do, no authentication needed */
1787 else if (socksreq[1] == 2) {
1788 /* Needs user name and password */
1789 int userlen, pwlen, len;
1791 userlen = (int)strlen(proxy_name);
1792 pwlen = proxy_password?(int)strlen(proxy_password):0;
1794 /* username/password request looks like
1795 * +----+------+----------+------+----------+
1796 * |VER | ULEN | UNAME | PLEN | PASSWD |
1797 * +----+------+----------+------+----------+
1798 * | 1 | 1 | 1 to 255 | 1 | 1 to 255 |
1799 * +----+------+----------+------+----------+
1802 socksreq[len++] = 1; /* username/pw subnegotiation version */
1803 socksreq[len++] = (char) userlen;
1804 memcpy(socksreq + len, proxy_name, (int) userlen);
1806 socksreq[len++] = (char) pwlen;
1807 memcpy(socksreq + len, proxy_password, (int) pwlen);
1810 code = Curl_write(conn, sock, (char *)socksreq, len, &written);
1811 if ((code != CURLE_OK) || (len != written)) {
1812 failf(conn->data, "Failed to send SOCKS5 sub-negotiation request.");
1816 result=Curl_read(conn, sock, (char *)socksreq, 2, &actualread);
1817 if ((result != CURLE_OK) || (actualread != 2)) {
1818 failf(conn->data, "Unable to receive SOCKS5 sub-negotiation response.");
1822 /* ignore the first (VER) byte */
1823 if (socksreq[1] != 0) { /* status */
1824 failf(conn->data, "User was rejected by the SOCKS5 server (%d %d).",
1825 socksreq[0], socksreq[1]);
1829 /* Everything is good so far, user was authenticated! */
1833 if (socksreq[1] == 1) {
1835 "SOCKS5 GSSAPI per-message authentication is not supported.");
1838 else if (socksreq[1] == 255) {
1839 if (!proxy_name || !*proxy_name) {
1841 "No authentication method was acceptable. (It is quite likely"
1842 " that the SOCKS5 server wanted a username/password, since none"
1843 " was supplied to the server on this connection.)");
1846 failf(conn->data, "No authentication method was acceptable.");
1852 "Undocumented SOCKS5 mode attempted to be used by server.");
1857 /* Authentication is complete, now specify destination to the proxy */
1858 socksreq[0] = 5; /* version (SOCKS5) */
1859 socksreq[1] = 1; /* connect */
1860 socksreq[2] = 0; /* must be zero */
1861 socksreq[3] = 1; /* IPv4 = 1 */
1864 struct Curl_dns_entry *dns;
1865 Curl_addrinfo *hp=NULL;
1866 int rc = Curl_resolv(conn, conn->host.name, (int)conn->remote_port, &dns);
1868 if(rc == CURLRESOLV_ERROR)
1871 if(rc == CURLRESOLV_PENDING)
1872 /* this requires that we're in "wait for resolve" state */
1873 rc = Curl_wait_for_resolv(conn, &dns);
1876 * We cannot use 'hostent' as a struct that Curl_resolv() returns. It
1877 * returns a Curl_addrinfo pointer that may not always look the same.
1883 unsigned short ip[4];
1884 Curl_printable_address(hp, buf, sizeof(buf));
1886 if(4 == sscanf( buf, "%hu.%hu.%hu.%hu",
1887 &ip[0], &ip[1], &ip[2], &ip[3])) {
1888 socksreq[4] = (unsigned char)ip[0];
1889 socksreq[5] = (unsigned char)ip[1];
1890 socksreq[6] = (unsigned char)ip[2];
1891 socksreq[7] = (unsigned char)ip[3];
1894 hp = NULL; /* fail! */
1896 Curl_resolv_unlock(conn->data, dns); /* not used anymore from now on */
1899 failf(conn->data, "Failed to resolve \"%s\" for SOCKS5 connect.",
1905 *((unsigned short*)&socksreq[8]) = htons(conn->remote_port);
1908 const int packetsize = 10;
1910 code = Curl_write(conn, sock, (char *)socksreq, packetsize, &written);
1911 if ((code != CURLE_OK) || (written != packetsize)) {
1912 failf(conn->data, "Failed to send SOCKS5 connect request.");
1916 result = Curl_read(conn, sock, (char *)socksreq, packetsize, &actualread);
1917 if ((result != CURLE_OK) || (actualread != packetsize)) {
1918 failf(conn->data, "Failed to receive SOCKS5 connect request ack.");
1922 if (socksreq[0] != 5) { /* version */
1924 "SOCKS5 reply has wrong version, version should be 5.");
1927 if (socksreq[1] != 0) { /* Anything besides 0 is an error */
1929 "Can't complete SOCKS5 connection to %d.%d.%d.%d:%d. (%d)",
1930 (unsigned char)socksreq[4], (unsigned char)socksreq[5],
1931 (unsigned char)socksreq[6], (unsigned char)socksreq[7],
1932 (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])),
1938 Curl_nonblock(sock, TRUE);
1939 return 0; /* Proxy was successful! */
1942 static CURLcode ConnectPlease(struct connectdata *conn,
1943 struct Curl_dns_entry *hostaddr,
1947 Curl_addrinfo *addr;
1948 struct SessionHandle *data = conn->data;
1949 char *hostname = data->change.proxy?conn->proxy.name:conn->host.name;
1951 infof(data, "About to connect() to %s port %d\n",
1952 hostname, conn->port);
1954 /*************************************************************
1955 * Connect to server/proxy
1956 *************************************************************/
1957 result= Curl_connecthost(conn,
1959 &conn->sock[FIRSTSOCKET],
1962 if(CURLE_OK == result) {
1963 /* All is cool, then we store the current information */
1964 conn->dns_entry = hostaddr;
1965 conn->ip_addr = addr;
1967 Curl_store_ip_addr(conn);
1969 if (conn->data->set.proxytype == CURLPROXY_SOCKS5) {
1970 return handleSock5Proxy(conn->proxyuser,
1973 CURLE_COULDNT_CONNECT : CURLE_OK;
1975 else if (conn->data->set.proxytype == CURLPROXY_HTTP) {
1976 /* do nothing here. handled later. */
1979 failf(conn->data, "unknown proxytype option given");
1980 return CURLE_COULDNT_CONNECT;
1988 * verboseconnect() displays verbose information after a connect
1990 static void verboseconnect(struct connectdata *conn)
1992 infof(conn->data, "Connected to %s (%s) port %d\n",
1993 conn->bits.httpproxy ? conn->proxy.dispname : conn->host.dispname,
1994 conn->ip_addr_str, conn->port);
1997 CURLcode Curl_protocol_fdset(struct connectdata *conn,
1998 fd_set *read_fd_set,
1999 fd_set *write_fd_set,
2002 CURLcode res = CURLE_OK;
2003 if(conn->curl_proto_fdset)
2004 res = conn->curl_proto_fdset(conn, read_fd_set, write_fd_set, max_fdp);
2008 CURLcode Curl_doing_fdset(struct connectdata *conn,
2009 fd_set *read_fd_set,
2010 fd_set *write_fd_set,
2013 CURLcode res = CURLE_OK;
2014 if(conn && conn->curl_doing_fdset)
2015 res = conn->curl_doing_fdset(conn, read_fd_set, write_fd_set, max_fdp);
2020 * We are doing protocol-specific connecting and this is being called over and
2021 * over from the multi interface until the connection phase is done on
2025 CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done)
2027 CURLcode result=CURLE_OK;
2029 if(conn && conn->curl_connecting) {
2031 result = conn->curl_connecting(conn, done);
2040 * We are DOING this is being called over and over from the multi interface
2041 * until the DOING phase is done on protocol layer.
2044 CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done)
2046 CURLcode result=CURLE_OK;
2048 if(conn && conn->curl_doing) {
2050 result = conn->curl_doing(conn, done);
2059 * We have discovered that the TCP connection has been successful, we can now
2060 * proceed with some action.
2063 CURLcode Curl_protocol_connect(struct connectdata *conn, bool *protocol_done)
2065 struct SessionHandle *data = conn->data;
2066 CURLcode result=CURLE_OK;
2068 *protocol_done = FALSE;
2070 if(conn->bits.tcpconnect && conn->bits.protoconnstart) {
2071 /* We already are connected, get back. This may happen when the connect
2072 worked fine in the first call, like when we connect to a local server
2073 or proxy. Note that we don't know if the protocol is actually done.
2075 Unless this protocol doesn't have any protocol-connect callback, as
2076 then we know we're done. */
2077 if(!conn->curl_connecting)
2078 *protocol_done = TRUE;
2083 if(!conn->bits.tcpconnect) {
2085 Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
2087 if(data->set.verbose)
2088 verboseconnect(conn);
2091 if(!conn->bits.protoconnstart) {
2092 if(conn->curl_connect) {
2093 /* is there a protocol-specific connect() procedure? */
2095 /* Set start time here for timeout purposes in the connect procedure, it
2096 is later set again for the progress meter purpose */
2097 conn->now = Curl_tvnow();
2099 /* Call the protocol-specific connect function */
2100 result = conn->curl_connect(conn, protocol_done);
2103 *protocol_done = TRUE;
2105 /* it has started, possibly even completed but that knowledge isn't stored
2107 conn->bits.protoconnstart = TRUE;
2110 return result; /* pass back status */
2114 * Helpers for IDNA convertions.
2117 static bool is_ASCII_name (const char *hostname)
2119 const unsigned char *ch = (const unsigned char*)hostname;
2129 * Check if characters in hostname is allowed in Top Level Domain.
2131 static bool tld_check_name (struct SessionHandle *data,
2132 const char *ace_hostname)
2135 char *uc_name = NULL;
2138 /* Convert (and downcase) ACE-name back into locale's character set */
2139 rc = idna_to_unicode_lzlz(ace_hostname, &uc_name, 0);
2140 if (rc != IDNA_SUCCESS)
2143 rc = tld_check_lz(uc_name, &err_pos, NULL);
2144 if (rc == TLD_INVALID)
2145 infof(data, "WARNING: %s; pos %u = `%c'/0x%02X\n",
2146 #ifdef HAVE_TLD_STRERROR
2151 err_pos, uc_name[err_pos],
2152 uc_name[err_pos] & 255);
2153 else if (rc != TLD_SUCCESS)
2154 infof(data, "WARNING: TLD check for %s failed; %s\n",
2156 #ifdef HAVE_TLD_STRERROR
2164 return (rc == TLD_SUCCESS);
2168 static void fix_hostname(struct connectdata *conn, struct hostname *host)
2170 /* set the name we use to display the host name */
2171 host->dispname = host->name;
2174 /*************************************************************
2175 * Check name for non-ASCII and convert hostname to ACE form.
2176 *************************************************************/
2177 if (!is_ASCII_name(host->name) &&
2178 stringprep_check_version(LIBIDN_REQUIRED_VERSION)) {
2179 char *ace_hostname = NULL;
2180 struct SessionHandle *data = conn->data;
2181 int rc = idna_to_ascii_lz(host->name, &ace_hostname, 0);
2182 infof (data, "Input domain encoded as `%s'\n",
2183 stringprep_locale_charset ());
2184 if (rc != IDNA_SUCCESS)
2185 infof(data, "Failed to convert %s to ACE; %s\n",
2186 host->name, Curl_idn_strerror(conn,rc));
2188 tld_check_name(data, ace_hostname);
2190 host->encalloc = ace_hostname;
2191 /* change the name pointer to point to the encoded hostname */
2192 host->name = host->encalloc;
2196 (void)conn; /* never used */
2202 * CreateConnection() sets up a new connectdata struct, or re-uses an already
2203 * existing one, and resolves host name.
2205 * if this function returns CURLE_OK and *async is set to TRUE, the resolve
2206 * response will be coming asynchronously. If *async is FALSE, the name is
2209 * @param data The sessionhandle pointer
2210 * @param in_connect is set to the next connection data pointer
2211 * @param addr is set to the new dns entry for this connection
2212 * @param async is set TRUE/FALSE depending on the nature of this lookup
2214 * @see SetupConnection()
2217 static CURLcode CreateConnection(struct SessionHandle *data,
2218 struct connectdata **in_connect,
2219 struct Curl_dns_entry **addr,
2224 CURLcode result=CURLE_OK;
2225 struct connectdata *conn;
2226 struct connectdata *conn_temp;
2228 struct Curl_dns_entry *hostaddr;
2229 #if defined(HAVE_ALARM) && !defined(USE_ARES)
2230 unsigned int prev_alarm=0;
2233 char user[MAX_CURL_USER_LENGTH];
2234 char passwd[MAX_CURL_PASSWORD_LENGTH];
2240 #ifdef HAVE_SIGACTION
2241 struct sigaction keep_sigact; /* store the old struct here */
2242 bool keep_copysig=FALSE; /* did copy it? */
2245 void *keep_sigact; /* store the old handler here */
2246 #endif /* HAVE_SIGNAL */
2247 #endif /* HAVE_SIGACTION */
2248 #endif /* SIGALRM */
2249 #endif /* USE_ARES */
2251 *addr = NULL; /* nothing yet */
2254 /*************************************************************
2256 *************************************************************/
2258 if(!data->change.url)
2259 return CURLE_URL_MALFORMAT;
2261 /* First, split up the current URL in parts so that we can use the
2262 parts for checking against the already present connections. In order
2263 to not have to modify everything at once, we allocate a temporary
2264 connection data struct and fill in for comparison purposes. */
2266 conn = (struct connectdata *)calloc(sizeof(struct connectdata), 1);
2268 *in_connect = NULL; /* clear the pointer */
2269 return CURLE_OUT_OF_MEMORY;
2271 /* We must set the return variable as soon as possible, so that our
2272 parent can cleanup any possible allocs we may have done before
2276 /* and we setup a few fields in case we end up actually using this struct */
2277 conn->data = data; /* remember our daddy */
2278 conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
2279 conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
2280 conn->connectindex = -1; /* no index */
2281 conn->bits.httpproxy = (data->change.proxy && *data->change.proxy &&
2282 (data->set.proxytype == CURLPROXY_HTTP))?
2283 TRUE:FALSE; /* http proxy or not */
2285 /* Default protocol-independent behavior doesn't support persistant
2286 connections, so we set this to force-close. Protocols that support
2287 this need to set this to FALSE in their "curl_do" functions. */
2288 conn->bits.close = TRUE;
2290 /* maxdownload must be -1 on init, as 0 is a valid value! */
2291 conn->maxdownload = -1; /* might have been used previously! */
2293 /* Store creation time to help future close decision making */
2294 conn->created = Curl_tvnow();
2296 conn->bits.use_range = data->set.set_range?TRUE:FALSE; /* range status */
2297 conn->range = data->set.set_range; /* clone the range setting */
2298 conn->resume_from = data->set.set_resume_from; /* inherite resume_from */
2300 conn->bits.user_passwd = data->set.userpwd?1:0;
2301 conn->bits.proxy_user_passwd = data->set.proxyuserpwd?1:0;
2302 conn->bits.no_body = data->set.opt_no_body;
2303 conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy;
2304 conn->bits.ftp_use_epsv = data->set.ftp_use_epsv;
2305 conn->bits.ftp_use_eprt = data->set.ftp_use_eprt;
2306 conn->bits.ftp_use_lprt = data->set.ftp_use_lprt;
2308 /* This initing continues below, see the comment "Continue connectdata
2309 * initialization here" */
2311 /***********************************************************
2312 * We need to allocate memory to store the path in. We get the size of the
2313 * full URL to be sure, and we need to make it at least 256 bytes since
2314 * other parts of the code will rely on this fact
2315 ***********************************************************/
2316 #define LEAST_PATH_ALLOC 256
2317 urllen=strlen(data->change.url);
2318 if(urllen < LEAST_PATH_ALLOC)
2319 urllen=LEAST_PATH_ALLOC;
2321 conn->pathbuffer=(char *)malloc(urllen);
2322 if(NULL == conn->pathbuffer)
2323 return CURLE_OUT_OF_MEMORY; /* really bad error */
2324 conn->path = conn->pathbuffer;
2326 conn->host.rawalloc=(char *)malloc(urllen);
2327 if(NULL == conn->host.rawalloc)
2328 return CURLE_OUT_OF_MEMORY;
2329 conn->host.name = conn->host.rawalloc;
2330 conn->host.name[0] = 0;
2332 /*************************************************************
2335 * We need to parse the url even when using the proxy, because we will need
2336 * the hostname and port in case we are trying to SSL connect through the
2337 * proxy -- and we don't know if we will need to use SSL until we parse the
2339 ************************************************************/
2340 if((2 == sscanf(data->change.url, "%15[^:]:%[^\n]",
2342 conn->path)) && strequal(conn->protostr, "file")) {
2343 if(conn->path[0] == '/' && conn->path[1] == '/') {
2344 /* Allow omitted hostname (e.g. file:/<path>). This is not strictly
2345 * speaking a valid file: URL by RFC 1738, but treating file:/<path> as
2346 * file://localhost/<path> is similar to how other schemes treat missing
2347 * hostnames. See RFC 1808. */
2349 /* This cannot be done with strcpy() in a portable manner, since the
2350 memory areas overlap! */
2351 memmove(conn->path, conn->path + 2, strlen(conn->path + 2)+1);
2354 * we deal with file://<host>/<path> differently since it supports no
2355 * hostname other than "localhost" and "127.0.0.1", which is unique among
2356 * the URL protocols specified in RFC 1738
2358 if(conn->path[0] != '/') {
2359 /* the URL included a host name, we ignore host names in file:// URLs
2360 as the standards don't define what to do with them */
2361 char *ptr=strchr(conn->path, '/');
2363 /* there was a slash present
2365 RFC1738 (section 3.1, page 5) says:
2367 The rest of the locator consists of data specific to the scheme,
2368 and is known as the "url-path". It supplies the details of how the
2369 specified resource can be accessed. Note that the "/" between the
2370 host (or port) and the url-path is NOT part of the url-path.
2372 As most agents use file://localhost/foo to get '/foo' although the
2373 slash preceeding foo is a separator and not a slash for the path,
2374 a URL as file://localhost//foo must be valid as well, to refer to
2375 the same file with an absolute path.
2378 if(ptr[1] && ('/' == ptr[1]))
2379 /* if there was two slashes, we skip the first one as that is then
2380 used truly as a separator */
2383 /* This cannot be made with strcpy, as the memory chunks overlap! */
2384 memmove(conn->path, ptr, strlen(ptr)+1);
2388 strcpy(conn->protostr, "file"); /* store protocol string lowercase */
2391 /* Set default path */
2392 strcpy(conn->path, "/");
2394 if (2 > sscanf(data->change.url,
2395 "%15[^\n:]://%[^\n/]%[^\n]",
2397 conn->host.name, conn->path)) {
2400 * The URL was badly formatted, let's try the browser-style _without_
2401 * protocol specified like 'http://'.
2403 if((1 > sscanf(data->change.url, "%[^\n/]%[^\n]",
2404 conn->host.name, conn->path)) ) {
2406 * We couldn't even get this format.
2408 failf(data, "<url> malformed");
2409 return CURLE_URL_MALFORMAT;
2413 * Since there was no protocol part specified, we guess what protocol it
2414 * is based on the first letters of the server name.
2417 /* Note: if you add a new protocol, please update the list in
2418 * lib/version.c too! */
2420 if(checkprefix("GOPHER.", conn->host.name))
2421 strcpy(conn->protostr, "gopher");
2423 else if(checkprefix("FTPS", conn->host.name))
2424 strcpy(conn->protostr, "ftps");
2425 #endif /* USE_SSLEAY */
2426 else if(checkprefix("FTP.", conn->host.name))
2427 strcpy(conn->protostr, "ftp");
2428 else if(checkprefix("TELNET.", conn->host.name))
2429 strcpy(conn->protostr, "telnet");
2430 else if (checkprefix("DICT.", conn->host.name))
2431 strcpy(conn->protostr, "DICT");
2432 else if (checkprefix("LDAP.", conn->host.name))
2433 strcpy(conn->protostr, "LDAP");
2435 strcpy(conn->protostr, "http");
2438 conn->protocol |= PROT_MISSING; /* not given in URL */
2442 /* We search for '?' in the host name (but only on the right side of a
2443 * @-letter to allow ?-letters in username and password) to handle things
2444 * like http://example.com?param= (notice the missing '/').
2446 at = strchr(conn->host.name, '@');
2448 tmp = strchr(at+1, '?');
2450 tmp = strchr(conn->host.name, '?');
2453 /* The right part of the ?-letter needs to be moved to prefix
2454 the current path buffer! */
2455 size_t len = strlen(tmp);
2456 /* move the existing path plus the zero byte */
2457 memmove(conn->path+len+1, conn->path, strlen(conn->path)+1);
2458 conn->path[0]='/'; /* prepend the missing slash */
2459 memcpy(conn->path+1, tmp, len); /* now copy the prefix part */
2460 *tmp=0; /* now cut off the hostname at the ? */
2463 /* If the URL is malformatted (missing a '/' after hostname before path) we
2464 * insert a slash here. The only letter except '/' we accept to start a path
2467 if(conn->path[0] == '?') {
2468 /* We need this function to deal with overlapping memory areas. We know
2469 that the memory area 'path' points to is 'urllen' bytes big and that
2470 is bigger than the path. Use +1 to move the zero byte too. */
2471 memmove(&conn->path[1], conn->path, strlen(conn->path)+1);
2472 conn->path[0] = '/';
2476 * So if the URL was A://B/C,
2477 * conn->protostr is A
2478 * conn->host.name is B
2482 /*************************************************************
2483 * Take care of proxy authentication stuff
2484 *************************************************************/
2485 if(conn->bits.proxy_user_passwd) {
2486 char proxyuser[MAX_CURL_USER_LENGTH]="";
2487 char proxypasswd[MAX_CURL_PASSWORD_LENGTH]="";
2489 sscanf(data->set.proxyuserpwd,
2490 "%" MAX_CURL_USER_LENGTH_TXT "[^:]:"
2491 "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]",
2492 proxyuser, proxypasswd);
2494 conn->proxyuser = strdup(proxyuser);
2495 if(!conn->proxyuser)
2496 return CURLE_OUT_OF_MEMORY;
2498 conn->proxypasswd = strdup(proxypasswd);
2499 if(!conn->proxypasswd)
2500 return CURLE_OUT_OF_MEMORY;
2503 #ifndef CURL_DISABLE_HTTP
2504 /*************************************************************
2505 * Detect what (if any) proxy to use
2506 *************************************************************/
2507 if(!data->change.proxy) {
2508 /* If proxy was not specified, we check for default proxy environment
2509 * variables, to enable i.e Lynx compliance:
2511 * http_proxy=http://some.server.dom:port/
2512 * https_proxy=http://some.server.dom:port/
2513 * ftp_proxy=http://some.server.dom:port/
2514 * gopher_proxy=http://some.server.dom:port/
2515 * no_proxy=domain1.dom,host.domain2.dom
2516 * (a comma-separated list of hosts which should
2517 * not be proxied, or an asterisk to override
2518 * all proxy variables)
2519 * all_proxy=http://some.server.dom:port/
2520 * (seems to exist for the CERN www lib. Probably
2521 * the first to check for.)
2523 * For compatibility, the all-uppercase versions of these variables are
2524 * checked if the lowercase versions don't exist.
2526 char *no_proxy=NULL;
2527 char *no_proxy_tok_buf;
2529 char proxy_env[128];
2531 no_proxy=curl_getenv("no_proxy");
2533 no_proxy=curl_getenv("NO_PROXY");
2535 if(!no_proxy || !strequal("*", no_proxy)) {
2536 /* NO_PROXY wasn't specified or it wasn't just an asterisk */
2539 nope=no_proxy?strtok_r(no_proxy, ", ", &no_proxy_tok_buf):NULL;
2542 char *endptr = strchr(conn->host.name, ':');
2544 namelen=endptr-conn->host.name;
2546 namelen=strlen(conn->host.name);
2548 if(strlen(nope) <= namelen) {
2550 conn->host.name + namelen - strlen(nope);
2551 if(checkprefix(nope, checkn)) {
2552 /* no proxy for this host! */
2556 nope=strtok_r(NULL, ", ", &no_proxy_tok_buf);
2559 /* It was not listed as without proxy */
2560 char *protop = conn->protostr;
2561 char *envp = proxy_env;
2564 /* Now, build <protocol>_proxy and check for such a one to use */
2566 *envp++ = tolower((int)*protop++);
2569 strcpy(envp, "_proxy");
2571 /* read the protocol proxy: */
2572 prox=curl_getenv(proxy_env);
2575 * We don't try the uppercase version of HTTP_PROXY because of
2578 * When curl is used in a webserver application
2579 * environment (cgi or php), this environment variable can
2580 * be controlled by the web server user by setting the
2581 * http header 'Proxy:' to some value.
2583 * This can cause 'internal' http/ftp requests to be
2584 * arbitrarily redirected by any external attacker.
2586 if(!prox && !strequal("http_proxy", proxy_env)) {
2587 /* There was no lowercase variable, try the uppercase version: */
2588 for(envp = proxy_env; *envp; envp++)
2589 *envp = toupper((int)*envp);
2590 prox=curl_getenv(proxy_env);
2593 if(prox && *prox) { /* don't count "" strings */
2594 proxy = prox; /* use this */
2597 proxy = curl_getenv("all_proxy"); /* default proxy to use */
2599 proxy=curl_getenv("ALL_PROXY");
2602 if(proxy && *proxy) {
2603 /* we have a proxy here to set */
2605 char proxyuser[MAX_CURL_USER_LENGTH];
2606 char proxypasswd[MAX_CURL_PASSWORD_LENGTH];
2610 /* skip the possible protocol piece */
2611 ptr=strstr(proxy, "://");
2619 /* check for an @-letter */
2620 ptr = strchr(ptr, '@');
2621 if(ptr && (2 == sscanf(fineptr,
2622 "%" MAX_CURL_USER_LENGTH_TXT"[^:]:"
2623 "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]",
2624 proxyuser, proxypasswd))) {
2625 CURLcode res = CURLE_OK;
2627 /* found user and password, rip them out */
2628 Curl_safefree(conn->proxyuser);
2629 conn->proxyuser = strdup(proxyuser);
2631 if(!conn->proxyuser)
2632 res = CURLE_OUT_OF_MEMORY;
2634 Curl_safefree(conn->proxypasswd);
2635 conn->proxypasswd = strdup(proxypasswd);
2637 if(!conn->proxypasswd)
2638 res = CURLE_OUT_OF_MEMORY;
2641 if(CURLE_OK == res) {
2642 conn->bits.proxy_user_passwd = TRUE; /* enable it */
2643 ptr = strdup(ptr+1); /* the right side of the @-letter */
2646 free(proxy); /* free the former proxy string */
2647 proxy = ptr; /* now use this instead */
2650 res = CURLE_OUT_OF_MEMORY;
2654 free(proxy); /* free the allocated proxy string */
2659 data->change.proxy = proxy;
2660 data->change.proxy_alloc=TRUE; /* this needs to be freed later */
2661 conn->bits.httpproxy = TRUE;
2663 } /* if (!nope) - it wasn't specified non-proxy */
2664 } /* NO_PROXY wasn't specified or '*' */
2667 } /* if not using proxy */
2668 #endif /* CURL_DISABLE_HTTP */
2670 /*************************************************************
2671 * No protocol part in URL was used, add it!
2672 *************************************************************/
2673 if(conn->protocol&PROT_MISSING) {
2674 /* We're guessing prefixes here and if we're told to use a proxy or if
2675 we're gonna follow a Location: later or... then we need the protocol
2676 part added so that we have a valid URL. */
2679 reurl = aprintf("%s://%s", conn->protostr, data->change.url);
2682 return CURLE_OUT_OF_MEMORY;
2684 data->change.url = reurl;
2685 data->change.url_alloc = TRUE; /* free this later */
2686 conn->protocol &= ~PROT_MISSING; /* switch that one off again */
2689 #ifndef CURL_DISABLE_HTTP
2690 /************************************************************
2691 * RESUME on a HTTP page is a tricky business. First, let's just check that
2692 * 'range' isn't used, then set the range parameter and leave the resume as
2693 * it is to inform about this situation for later use. We will then
2694 * "attempt" to resume, and if we're talking to a HTTP/1.1 (or later)
2695 * server, we will get the document resumed. If we talk to a HTTP/1.0
2696 * server, we just fail since we can't rewind the file writing from within
2698 ***********************************************************/
2699 if(conn->resume_from) {
2700 if(!conn->bits.use_range) {
2701 /* if it already was in use, we just skip this */
2702 conn->range = aprintf("%" FORMAT_OFF_T "-", conn->resume_from);
2704 return CURLE_OUT_OF_MEMORY;
2705 conn->bits.rangestringalloc = TRUE; /* mark as allocated */
2706 conn->bits.use_range = 1; /* switch on range usage */
2710 /*************************************************************
2711 * Setup internals depending on protocol
2712 *************************************************************/
2714 if (strequal(conn->protostr, "HTTP")) {
2715 #ifndef CURL_DISABLE_HTTP
2716 conn->port = (data->set.use_port && data->state.allow_port)?
2717 data->set.use_port:PORT_HTTP;
2718 conn->remote_port = PORT_HTTP;
2719 conn->protocol |= PROT_HTTP;
2720 conn->curl_do = Curl_http;
2721 conn->curl_do_more = NULL;
2722 conn->curl_done = Curl_http_done;
2723 conn->curl_connect = Curl_http_connect;
2725 failf(data, LIBCURL_NAME
2726 " was built with HTTP disabled, http: not supported!");
2727 return CURLE_UNSUPPORTED_PROTOCOL;
2730 else if (strequal(conn->protostr, "HTTPS")) {
2731 #if defined(USE_SSLEAY) && !defined(CURL_DISABLE_HTTP)
2733 conn->port = (data->set.use_port && data->state.allow_port)?
2734 data->set.use_port:PORT_HTTPS;
2735 conn->remote_port = PORT_HTTPS;
2736 conn->protocol |= PROT_HTTP|PROT_HTTPS|PROT_SSL;
2738 conn->curl_do = Curl_http;
2739 conn->curl_do_more = NULL;
2740 conn->curl_done = Curl_http_done;
2741 conn->curl_connect = Curl_http_connect;
2743 #else /* USE_SSLEAY */
2744 failf(data, LIBCURL_NAME
2745 " was built with SSL disabled, https: not supported!");
2746 return CURLE_UNSUPPORTED_PROTOCOL;
2747 #endif /* !USE_SSLEAY */
2749 else if (strequal(conn->protostr, "GOPHER")) {
2750 #ifndef CURL_DISABLE_GOPHER
2751 conn->port = (data->set.use_port && data->state.allow_port)?
2752 data->set.use_port:PORT_GOPHER;
2753 conn->remote_port = PORT_GOPHER;
2754 /* Skip /<item-type>/ in path if present */
2755 if (isdigit((int)conn->path[1])) {
2756 conn->path = strchr(&conn->path[1], '/');
2757 if (conn->path == NULL)
2758 conn->path = conn->pathbuffer;
2760 conn->protocol |= PROT_GOPHER;
2761 conn->curl_do = Curl_http;
2762 conn->curl_do_more = NULL;
2763 conn->curl_done = Curl_http_done;
2765 failf(data, LIBCURL_NAME
2766 " was built with GOPHER disabled, gopher: not supported!");
2769 else if(strequal(conn->protostr, "FTP") ||
2770 strequal(conn->protostr, "FTPS")) {
2772 #ifndef CURL_DISABLE_FTP
2774 int port = PORT_FTP;
2776 if(strequal(conn->protostr, "FTPS")) {
2778 conn->protocol |= PROT_FTPS|PROT_SSL;
2779 conn->ssl[SECONDARYSOCKET].use = TRUE; /* send data securely */
2782 failf(data, LIBCURL_NAME
2783 " was built with SSL disabled, ftps: not supported!");
2784 return CURLE_UNSUPPORTED_PROTOCOL;
2785 #endif /* !USE_SSLEAY */
2788 conn->port = (data->set.use_port && data->state.allow_port)?
2789 data->set.use_port:port;
2790 conn->remote_port = port;
2791 conn->protocol |= PROT_FTP;
2793 if(data->change.proxy &&
2794 *data->change.proxy &&
2795 !data->set.tunnel_thru_httpproxy) {
2796 /* Unless we have asked to tunnel ftp operations through the proxy, we
2797 switch and use HTTP operations only */
2798 if(conn->protocol & PROT_FTPS) {
2799 /* FTPS is a hacked protocol and does not work through your
2800 ordinary http proxy! */
2801 failf(data, "ftps does not work through http proxy!");
2802 return CURLE_UNSUPPORTED_PROTOCOL;
2804 #ifndef CURL_DISABLE_HTTP
2805 conn->curl_do = Curl_http;
2806 conn->curl_done = Curl_http_done;
2808 failf(data, "FTP over http proxy requires HTTP support built-in!");
2809 return CURLE_UNSUPPORTED_PROTOCOL;
2813 conn->curl_do = Curl_ftp;
2814 conn->curl_do_more = Curl_ftp_nextconnect;
2815 conn->curl_done = Curl_ftp_done;
2816 conn->curl_connect = Curl_ftp_connect;
2817 conn->curl_connecting = Curl_ftp_multi_statemach;
2818 conn->curl_doing = Curl_ftp_doing;
2819 conn->curl_proto_fdset = Curl_ftp_fdset;
2820 conn->curl_doing_fdset = Curl_ftp_fdset;
2821 conn->curl_disconnect = Curl_ftp_disconnect;
2824 conn->path++; /* don't include the initial slash */
2826 /* FTP URLs support an extension like ";type=<typecode>" that
2827 * we'll try to get now! */
2828 type=strstr(conn->path, ";type=");
2830 type=strstr(conn->host.rawalloc, ";type=");
2834 *type=0; /* it was in the middle of the hostname */
2835 command = toupper((int)type[6]);
2837 case 'A': /* ASCII mode */
2838 data->set.ftp_ascii = 1;
2840 case 'D': /* directory mode */
2841 data->set.ftp_list_only = 1;
2843 case 'I': /* binary mode */
2845 /* switch off ASCII */
2846 data->set.ftp_ascii = 0;
2850 #else /* CURL_DISABLE_FTP */
2851 failf(data, LIBCURL_NAME
2852 " was built with FTP disabled, ftp/ftps: not supported!");
2853 return CURLE_UNSUPPORTED_PROTOCOL;
2856 else if(strequal(conn->protostr, "TELNET")) {
2857 #ifndef CURL_DISABLE_TELNET
2858 /* telnet testing factory */
2859 conn->protocol |= PROT_TELNET;
2861 conn->port = (data->set.use_port && data->state.allow_port)?
2862 data->set.use_port: PORT_TELNET;
2863 conn->remote_port = PORT_TELNET;
2864 conn->curl_do = Curl_telnet;
2865 conn->curl_done = Curl_telnet_done;
2867 failf(data, LIBCURL_NAME
2868 " was built with TELNET disabled!");
2871 else if (strequal(conn->protostr, "DICT")) {
2872 #ifndef CURL_DISABLE_DICT
2873 conn->protocol |= PROT_DICT;
2874 conn->port = (data->set.use_port && data->state.allow_port)?
2875 data->set.use_port:PORT_DICT;
2876 conn->remote_port = PORT_DICT;
2877 conn->curl_do = Curl_dict;
2878 conn->curl_done = NULL; /* no DICT-specific done */
2880 failf(data, LIBCURL_NAME
2881 " was built with DICT disabled!");
2884 else if (strequal(conn->protostr, "LDAP")) {
2885 #ifndef CURL_DISABLE_LDAP
2886 conn->protocol |= PROT_LDAP;
2887 conn->port = (data->set.use_port && data->state.allow_port)?
2888 data->set.use_port:PORT_LDAP;
2889 conn->remote_port = PORT_LDAP;
2890 conn->curl_do = Curl_ldap;
2891 conn->curl_done = NULL; /* no LDAP-specific done */
2893 failf(data, LIBCURL_NAME
2894 " was built with LDAP disabled!");
2897 else if (strequal(conn->protostr, "FILE")) {
2898 #ifndef CURL_DISABLE_FILE
2899 conn->protocol |= PROT_FILE;
2901 conn->curl_do = Curl_file;
2902 conn->curl_done = Curl_file_done;
2904 /* anyway, this is supposed to be the connect function so we better
2905 at least check that the file is present here! */
2906 result = Curl_file_connect(conn);
2908 /* Setup a "faked" transfer that'll do nothing */
2909 if(CURLE_OK == result) {
2910 conn->bits.tcpconnect = TRUE; /* we are "connected */
2911 result = Curl_Transfer(conn, -1, -1, FALSE, NULL, /* no download */
2912 -1, NULL); /* no upload */
2917 failf(data, LIBCURL_NAME
2918 " was built with FILE disabled!");
2922 /* We fell through all checks and thus we don't support the specified
2924 failf(data, "Unsupported protocol: %s", conn->protostr);
2925 return CURLE_UNSUPPORTED_PROTOCOL;
2928 if(data->change.proxy && *data->change.proxy) {
2929 /* If this is supposed to use a proxy, we need to figure out the proxy
2930 host name name, so that we can re-use an existing connection
2931 that may exist registered to the same proxy host. */
2936 /* We need to make a duplicate of the proxy so that we can modify the
2938 char *proxydup=strdup(data->change.proxy);
2940 /* We use 'proxyptr' to point to the proxy name from now on... */
2941 char *proxyptr=proxydup;
2943 if(NULL == proxydup) {
2944 failf(data, "memory shortage");
2945 return CURLE_OUT_OF_MEMORY;
2948 /* Daniel Dec 10, 1998:
2949 We do the proxy host string parsing here. We want the host name and the
2950 port name. Accept a protocol:// prefix, even though it should just be
2953 /* 1. skip the protocol part if present */
2954 endofprot=strstr(proxyptr, "://");
2956 proxyptr = endofprot+3;
2959 /* allow user to specify proxy.server.com:1080 if desired */
2960 prox_portno = strchr (proxyptr, ':');
2962 *prox_portno = 0x0; /* cut off number from host name */
2964 /* now set the local port number */
2965 conn->port = atoi(prox_portno);
2967 else if(data->set.proxyport) {
2968 /* None given in the proxy string, then get the default one if it is
2970 conn->port = data->set.proxyport;
2973 /* now, clone the cleaned proxy host name */
2974 conn->proxy.rawalloc = strdup(proxyptr);
2975 conn->proxy.name = conn->proxy.rawalloc;
2977 free(proxydup); /* free the duplicate pointer and not the modified */
2978 if(!conn->proxy.rawalloc)
2979 return CURLE_OUT_OF_MEMORY;
2982 /*************************************************************
2983 * If the protcol is using SSL and HTTP proxy is used, we set
2984 * the tunnel_proxy bit.
2985 *************************************************************/
2986 if((conn->protocol&PROT_SSL) && conn->bits.httpproxy)
2987 conn->bits.tunnel_proxy = TRUE;
2989 /*************************************************************
2990 * Take care of user and password authentication stuff
2991 *************************************************************/
2994 * Inputs: data->set.userpwd (CURLOPT_USERPWD)
2995 * data->set.fpasswd (CURLOPT_PASSWDFUNCTION)
2996 * data->set.use_netrc (CURLOPT_NETRC)
2999 * hard-coded defaults
3001 * Outputs: (almost :- all currently undefined)
3002 * conn->bits.user_passwd - non-zero if non-default passwords exist
3003 * conn->user - non-zero length if defined
3004 * conn->passwd - ditto
3005 * conn->host.name - remove user name and password
3008 /* At this point, we're hoping all the other special cases have
3009 * been taken care of, so conn->host.name is at most
3010 * [user[:password]]@]hostname
3012 * We need somewhere to put the embedded details, so do that first.
3015 user[0] =0; /* to make everything well-defined */
3018 if (conn->protocol & (PROT_FTP|PROT_HTTP)) {
3019 /* This is a FTP or HTTP URL, we will now try to extract the possible
3020 * user+password pair in a string like:
3021 * ftp://user:password@ftp.my.site:8021/README */
3022 char *ptr=strchr(conn->host.name, '@');
3023 char *userpass = conn->host.name;
3025 /* there's a user+password given here, to the left of the @ */
3027 conn->host.name = ++ptr;
3029 /* So the hostname is sane. Only bother interpreting the
3030 * results if we could care. It could still be wasted
3031 * work because it might be overtaken by the programmatically
3032 * set user/passwd, but doing that first adds more cases here :-(
3035 if (data->set.use_netrc != CURL_NETRC_REQUIRED) {
3036 /* We could use the one in the URL */
3038 conn->bits.user_passwd = 1; /* enable user+password */
3040 if(*userpass != ':') {
3041 /* the name is given, get user+password */
3042 sscanf(userpass, "%127[^:@]:%127[^@]",
3046 /* no name given, get the password only */
3047 sscanf(userpass, ":%127[^@]", passwd);
3050 char *newname=curl_unescape(user, 0);
3052 return CURLE_OUT_OF_MEMORY;
3053 if(strlen(newname) < sizeof(user))
3054 strcpy(user, newname);
3056 /* if the new name is longer than accepted, then just use
3057 the unconverted name, it'll be wrong but what the heck */
3061 /* we have a password found in the URL, decode it! */
3062 char *newpasswd=curl_unescape(passwd, 0);
3064 return CURLE_OUT_OF_MEMORY;
3065 if(strlen(newpasswd) < sizeof(passwd))
3066 strcpy(passwd, newpasswd);
3074 /*************************************************************
3075 * Figure out the remote port number
3077 * No matter if we use a proxy or not, we have to figure out the remote
3078 * port number of various reasons.
3080 * To be able to detect port number flawlessly, we must not confuse them
3081 * IPv6-specified addresses in the [0::1] style. (RFC2732)
3083 * The conn->host.name is currently [user:passwd@]host[:port] where host
3084 * could be a hostname, IPv4 address or IPv6 address.
3085 *************************************************************/
3086 if((1 == sscanf(conn->host.name, "[%*39[0-9a-fA-F:.]%c", &endbracket)) &&
3087 (']' == endbracket)) {
3088 /* this is a RFC2732-style specified IP-address */
3089 conn->bits.ipv6_ip = TRUE;
3091 conn->host.name++; /* pass the starting bracket */
3092 tmp = strchr(conn->host.name, ']');
3093 *tmp = 0; /* zero terminate */
3094 tmp++; /* pass the ending bracket */
3096 tmp = NULL; /* no port number available */
3099 tmp = strrchr(conn->host.name, ':');
3105 port=strtoul(tmp+1, &rest, 10); /* Port number must be decimal */
3107 if (rest != (tmp+1) && *rest == '\0') {
3108 /* The colon really did have only digits after it,
3109 * so it is either a port number or a mistake */
3111 if (port > 0xffff) { /* Single unix standard says port numbers are
3113 failf(data, "Port number too large: %lu", port);
3114 return CURLE_URL_MALFORMAT;
3117 *tmp = '\0'; /* cut off the name there */
3118 conn->remote_port = (unsigned short)port;
3122 /* Programmatically set password:
3123 * - always applies, if available
3124 * - takes precedence over the values we just set above
3125 * so scribble it over the top.
3126 * User-supplied passwords are assumed not to need unescaping.
3128 * user_password is set in "inherite initial knowledge' above,
3129 * so it doesn't have to be set in this block
3131 if (data->set.userpwd != NULL) {
3132 /* the name is given, get user+password */
3133 sscanf(data->set.userpwd,
3134 "%" MAX_CURL_USER_LENGTH_TXT "[^:]:"
3135 "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]",
3139 if (data->set.use_netrc != CURL_NETRC_IGNORED) {
3140 if(Curl_parsenetrc(conn->host.name,
3142 data->set.netrc_file)) {
3143 infof(data, "Couldn't find host %s in the " DOT_CHAR "netrc file, using defaults\n",
3147 conn->bits.user_passwd = 1; /* enable user+password */
3150 /* If our protocol needs a password and we have none, use the defaults */
3151 if ( (conn->protocol & PROT_FTP) &&
3152 !conn->bits.user_passwd) {
3154 conn->user = strdup(CURL_DEFAULT_USER);
3155 conn->passwd = strdup(CURL_DEFAULT_PASSWORD);
3156 /* This is the default password, so DON'T set conn->bits.user_passwd */
3159 /* store user + password, zero-length if not set */
3160 conn->user = strdup(user);
3161 conn->passwd = strdup(passwd);
3163 if(!conn->user || !conn->passwd)
3164 return CURLE_OUT_OF_MEMORY;
3166 /*************************************************************
3167 * Check the current list of connections to see if we can
3168 * re-use an already existing one or if we have to create a
3170 *************************************************************/
3172 /* get a cloned copy of the SSL config situation stored in the
3173 connection struct */
3174 if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config))
3175 return CURLE_OUT_OF_MEMORY;
3177 /* reuse_fresh is TRUE if we are told to use a new connection by force, but
3178 we only acknowledge this option if this is not a re-used connection
3179 already (which happens due to follow-location or during a HTTP
3180 authentication phase). */
3181 if(data->set.reuse_fresh && !data->state.this_is_a_follow)
3184 reuse = ConnectionExists(data, conn, &conn_temp);
3188 * We already have a connection for this, we got the former connection
3189 * in the conn_temp variable and thus we need to cleanup the one we
3190 * just allocated before we can move along and use the previously
3193 struct connectdata *old_conn = conn;
3195 if(old_conn->proxy.rawalloc)
3196 free(old_conn->proxy.rawalloc);
3198 /* free the SSL config struct from this connection struct as this was
3199 allocated in vain and is targeted for destruction */
3200 Curl_free_ssl_config(&conn->ssl_config);
3202 conn = conn_temp; /* use this connection from now on */
3204 /* get the user+password information from the old_conn struct since it may
3205 * be new for this request even when we re-use an existing connection */
3206 conn->bits.user_passwd = old_conn->bits.user_passwd;
3207 if (conn->bits.user_passwd) {
3208 /* use the new user namd and password though */
3209 Curl_safefree(conn->user);
3210 Curl_safefree(conn->passwd);
3211 conn->user = old_conn->user;
3212 conn->passwd = old_conn->passwd;
3213 old_conn->user = NULL;
3214 old_conn->passwd = NULL;
3217 conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd;
3218 if (conn->bits.proxy_user_passwd) {
3219 /* use the new proxy user name and proxy password though */
3220 Curl_safefree(conn->proxyuser);
3221 Curl_safefree(conn->proxypasswd);
3222 conn->proxyuser = old_conn->proxyuser;
3223 conn->proxypasswd = old_conn->proxypasswd;
3224 old_conn->proxyuser = NULL;
3225 old_conn->proxypasswd = NULL;
3228 /* host can change, when doing keepalive with a proxy ! */
3229 if (conn->bits.httpproxy) {
3230 free(conn->host.rawalloc);
3231 conn->host=old_conn->host;
3234 /* get the newly set value, not the old one */
3235 conn->bits.no_body = old_conn->bits.no_body;
3237 if (!conn->bits.httpproxy)
3238 free(old_conn->host.rawalloc); /* free the newly allocated name buffer */
3240 free(conn->pathbuffer); /* free the newly allocated path pointer */
3241 conn->pathbuffer = old_conn->pathbuffer; /* use the old one */
3242 conn->path = old_conn->path;
3245 conn->bits.reuse = TRUE; /* yes, we're re-using here */
3246 conn->bits.chunk = FALSE; /* always assume not chunked unless told
3248 conn->maxdownload = -1; /* might have been used previously! */
3250 Curl_safefree(old_conn->user);
3251 Curl_safefree(old_conn->passwd);
3252 Curl_safefree(old_conn->proxyuser);
3253 Curl_safefree(old_conn->proxypasswd);
3255 if(old_conn->bits.rangestringalloc)
3256 free(old_conn->range);
3258 free(old_conn); /* we don't need this anymore */
3261 * If we're doing a resumed transfer, we need to setup our stuff
3264 conn->resume_from = data->set.set_resume_from;
3265 if (conn->resume_from) {
3266 if (conn->bits.rangestringalloc == TRUE)
3268 conn->range = aprintf("%" FORMAT_OFF_T "-", conn->resume_from);
3270 return CURLE_OUT_OF_MEMORY;
3272 /* tell ourselves to fetch this range */
3273 conn->bits.use_range = TRUE; /* enable range download */
3274 conn->bits.rangestringalloc = TRUE; /* mark range string allocated */
3276 else if (data->set.set_range) {
3277 /* There is a range, but is not a resume, useful for random ftp access */
3278 conn->range = strdup(data->set.set_range);
3280 return CURLE_OUT_OF_MEMORY;
3281 conn->bits.rangestringalloc = TRUE; /* mark range string allocated */
3282 conn->bits.use_range = TRUE; /* enable range download */
3285 conn->bits.use_range = FALSE; /* disable range download */
3287 *in_connect = conn; /* return this instead! */
3289 infof(data, "Re-using existing connection! (#%ld) with host %s\n",
3291 conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname);
3295 * This is a brand new connection, so let's store it in the connection
3298 ConnectionStore(data, conn);
3301 /* Continue connectdata initialization here.
3303 * Inherit the proper values from the urldata struct AFTER we have arranged
3304 * the persistant conncetion stuff */
3305 conn->fread = data->set.fread;
3306 conn->fread_in = data->set.in;
3308 conn->bits.upload_chunky =
3309 ((conn->protocol&PROT_HTTP) &&
3311 (data->set.infilesize == -1) &&
3312 (data->set.httpversion != CURL_HTTP_VERSION_1_0))?
3313 /* HTTP, upload, unknown file size and not HTTP 1.0 */
3315 /* else, no chunky upload */
3319 /*************************************************************
3320 * Set timeout if that is being used, and we're not using an asynchronous
3322 *************************************************************/
3323 if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) {
3324 /*************************************************************
3325 * Set signal handler to catch SIGALRM
3326 * Store the old value to be able to set it back later!
3327 *************************************************************/
3330 #ifdef HAVE_SIGACTION
3331 struct sigaction sigact;
3332 sigaction(SIGALRM, NULL, &sigact);
3333 keep_sigact = sigact;
3334 keep_copysig = TRUE; /* yes, we have a copy */
3335 sigact.sa_handler = alarmfunc;
3337 /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */
3338 sigact.sa_flags &= ~SA_RESTART;
3340 /* now set the new struct */
3341 sigaction(SIGALRM, &sigact, NULL);
3342 #else /* HAVE_SIGACTION */
3343 /* no sigaction(), revert to the much lamer signal() */
3345 keep_sigact = signal(SIGALRM, alarmfunc);
3347 #endif /* HAVE_SIGACTION */
3349 /* We set the timeout on the name resolving phase first, separately from
3350 * the download/upload part to allow a maximum time on everything. This is
3351 * a signal-based timeout, why it won't work and shouldn't be used in
3352 * multi-threaded environments. */
3355 /* alarm() makes a signal get sent when the timeout fires off, and that
3356 will abort system calls */
3357 prev_alarm = alarm(data->set.connecttimeout?
3358 data->set.connecttimeout:
3360 /* We can expect the conn->created time to be "now", as that was just
3361 recently set in the beginning of this function and nothing slow
3362 has been done since then until now. */
3364 #endif /* SIGALRM */
3366 #endif /* USE_ARES */
3368 /*************************************************************
3369 * Resolve the name of the server or proxy
3370 *************************************************************/
3371 if(conn->bits.reuse) {
3372 /* re-used connection, no resolving is necessary */
3374 /* we'll need to clear conn->dns_entry later in Curl_disconnect() */
3376 if (conn->bits.httpproxy)
3377 fix_hostname(conn, &conn->host);
3380 /* this is a fresh connect */
3382 /* set a pointer to the hostname we display */
3383 fix_hostname(conn, &conn->host);
3385 if(!data->change.proxy || !*data->change.proxy) {
3386 /* If not connecting via a proxy, extract the port from the URL, if it is
3387 * there, thus overriding any defaults that might have been set above. */
3388 conn->port = conn->remote_port; /* it is the same port */
3390 /* Resolve target host right on */
3391 rc = Curl_resolv(conn, conn->host.name, (int)conn->port, &hostaddr);
3392 if(rc == CURLRESOLV_PENDING)
3395 else if(!hostaddr) {
3396 failf(data, "Couldn't resolve host '%s'", conn->host.dispname);
3397 result = CURLE_COULDNT_RESOLVE_HOST;
3398 /* don't return yet, we need to clean up the timeout first */
3402 /* This is a proxy that hasn't been resolved yet. */
3404 /* IDN-fix the proxy name */
3405 fix_hostname(conn, &conn->proxy);
3408 rc = Curl_resolv(conn, conn->proxy.name, (int)conn->port, &hostaddr);
3410 if(rc == CURLRESOLV_PENDING)
3413 else if(!hostaddr) {
3414 failf(data, "Couldn't resolve proxy '%s'", conn->proxy.dispname);
3415 result = CURLE_COULDNT_RESOLVE_PROXY;
3416 /* don't return yet, we need to clean up the timeout first */
3422 #if defined(HAVE_ALARM) && defined(SIGALRM) && !defined(USE_ARES)
3423 if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) {
3424 #ifdef HAVE_SIGACTION
3426 /* we got a struct as it looked before, now put that one back nice
3428 sigaction(SIGALRM, &keep_sigact, NULL); /* put it back */
3432 /* restore the previous SIGALRM handler */
3433 signal(SIGALRM, keep_sigact);
3435 #endif /* HAVE_SIGACTION */
3437 /* switch back the alarm() to either zero or to what it was before minus
3438 the time we spent until now! */
3440 /* there was an alarm() set before us, now put it back */
3441 unsigned long elapsed_ms = Curl_tvdiff(Curl_tvnow(), conn->created);
3442 unsigned long alarm_set;
3444 /* the alarm period is counted in even number of seconds */
3445 alarm_set = prev_alarm - elapsed_ms/1000;
3448 ((alarm_set >= 0x80000000) && (prev_alarm < 0x80000000)) ) {
3449 /* if the alarm time-left reached zero or turned "negative" (counted
3450 with unsigned values), we should fire off a SIGALRM here, but we
3451 won't, and zero would be to switch it off so we never set it to
3454 result = CURLE_OPERATION_TIMEOUTED;
3455 failf(data, "Previous alarm fired off!");
3458 alarm((unsigned int)alarm_set);
3461 alarm(0); /* just shut it off */
3468 /* SetupConnection() should be called after the name resolve initiated in
3469 * CreateConnection() is all done.
3472 static CURLcode SetupConnection(struct connectdata *conn,
3473 struct Curl_dns_entry *hostaddr,
3474 bool *protocol_done)
3476 struct SessionHandle *data = conn->data;
3477 CURLcode result=CURLE_OK;
3479 Curl_pgrsTime(data, TIMER_NAMELOOKUP);
3481 if(conn->protocol & PROT_FILE) {
3482 /* There's nothing in this function to setup if we're only doing
3483 a file:// transfer */
3484 *protocol_done = TRUE;
3487 *protocol_done = FALSE; /* default to not done */
3489 /*************************************************************
3490 * Send user-agent to HTTP proxies even if the target protocol
3492 *************************************************************/
3493 if((conn->protocol&PROT_HTTP) ||
3494 (data->change.proxy && *data->change.proxy)) {
3495 if(data->set.useragent) {
3496 Curl_safefree(conn->allocptr.uagent);
3497 conn->allocptr.uagent =
3498 aprintf("User-Agent: %s\015\012", data->set.useragent);
3499 if(!conn->allocptr.uagent)
3500 return CURLE_OUT_OF_MEMORY;
3504 conn->bytecount = 0;
3505 conn->headerbytecount = 0;
3507 if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
3508 bool connected = FALSE;
3510 /* Connect only if not already connected! */
3511 result = ConnectPlease(conn, hostaddr, &connected);
3514 result = Curl_protocol_connect(conn, protocol_done);
3515 if(CURLE_OK == result)
3516 conn->bits.tcpconnect = TRUE;
3519 conn->bits.tcpconnect = FALSE;
3522 if(CURLE_OK != result)
3526 Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */
3527 conn->bits.tcpconnect = TRUE;
3528 *protocol_done = TRUE;
3529 if(data->set.verbose)
3530 verboseconnect(conn);
3533 conn->now = Curl_tvnow(); /* time this *after* the connect is done, we
3534 set this here perhaps a second time */
3538 * the check is quite a hack...
3539 * we're calling _fsetmode to fix the problem with fwrite converting newline
3540 * characters (you get mangled text files, and corrupted binary files when
3541 * you download to stdout and redirect it to a file). */
3543 if ((data->set.out)->_handle == NULL) {
3544 _fsetmode(stdout, "b");
3551 CURLcode Curl_connect(struct SessionHandle *data,
3552 struct connectdata **in_connect,
3554 bool *protocol_done)
3557 struct Curl_dns_entry *dns;
3559 *asyncp = FALSE; /* assume synchronous resolves by default */
3561 /* call the stuff that needs to be called */
3562 code = CreateConnection(data, in_connect, &dns, asyncp);
3564 if(CURLE_OK == code) {
3567 /* If an address is available it means that we already have the name
3568 resolved, OR it isn't async.
3569 If so => continue connecting from here */
3570 code = SetupConnection(*in_connect, dns, protocol_done);
3572 response will be received and treated async wise */
3575 if(CURLE_OK != code) {
3576 /* We're not allowed to return failure with memory left allocated
3577 in the connectdata struct, free those here */
3579 Curl_disconnect(*in_connect); /* close the connection */
3580 *in_connect = NULL; /* return a NULL */
3587 /* Call this function after Curl_connect() has returned async=TRUE and
3588 then a successful name resolve has been received.
3590 Note: this function disconnects and frees the conn data in case of
3592 CURLcode Curl_async_resolved(struct connectdata *conn,
3593 bool *protocol_done)
3595 #if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \
3596 defined(USE_THREADING_GETADDRINFO)
3597 CURLcode code = SetupConnection(conn, conn->async.dns, protocol_done);
3600 /* We're not allowed to return failure with memory left allocated
3601 in the connectdata struct, free those here */
3602 Curl_disconnect(conn); /* close the connection */
3607 (void)protocol_done;
3613 CURLcode Curl_done(struct connectdata **connp,
3614 CURLcode status) /* an error if this is called after an
3615 error was detected */
3618 struct connectdata *conn = *connp;
3619 struct SessionHandle *data=conn->data;
3621 /* cleanups done even if the connection is re-used */
3622 if(conn->bits.rangestringalloc) {
3624 conn->bits.rangestringalloc = FALSE;
3627 if(conn->dns_entry) {
3628 Curl_resolv_unlock(data, conn->dns_entry); /* done with this */
3629 conn->dns_entry = NULL;
3632 /* Cleanup possible redirect junk */
3635 conn->newurl = NULL;
3638 /* this calls the protocol-specific function pointer previously set */
3640 result = conn->curl_done(conn, status);
3644 Curl_pgrsDone(conn); /* done with the operation */
3646 /* if data->set.reuse_forbid is TRUE, it means the libcurl client has
3647 forced us to close this no matter what we think.
3649 if conn->bits.close is TRUE, it means that the connection should be
3650 closed in spite of all our efforts to be nice, due to protocol
3651 restrictions in our or the server's end */
3652 if(data->set.reuse_forbid || conn->bits.close) {
3654 res2 = Curl_disconnect(conn); /* close the connection */
3656 *connp = NULL; /* to make the caller of this function better detect that
3657 this was actually killed here */
3659 /* If we had an error already, make sure we return that one. But
3660 if we got a new error, return that. */
3665 infof(data, "Connection #%ld to host %s left intact\n",
3667 conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname);
3672 CURLcode Curl_do(struct connectdata **connp, bool *done)
3674 CURLcode result=CURLE_OK;
3675 struct connectdata *conn = *connp;
3676 struct SessionHandle *data=conn->data;
3678 conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */
3681 /* generic protocol-specific function pointer set in curl_connect() */
3682 result = conn->curl_do(conn, done);
3684 /* This was formerly done in transfer.c, but we better do it here */
3686 if((CURLE_SEND_ERROR == result) && conn->bits.reuse) {
3687 /* This was a re-use of a connection and we got a write error in the
3688 * DO-phase. Then we DISCONNECT this connection and have another attempt
3689 * to CONNECT and then DO again! The retry cannot possibly find another
3690 * connection to re-use, since we only keep one possible connection for
3693 infof(data, "Re-used connection seems dead, get a new one\n");
3695 conn->bits.close = TRUE; /* enforce close of this connection */
3696 result = Curl_done(&conn, result); /* we are so done with this */
3698 /* conn may no longer be a good pointer */
3700 if(CURLE_OK == result) {
3702 bool protocol_done = TRUE;
3704 /* Now, redo the connect and get a new connection */
3705 result = Curl_connect(data, connp, &async, &protocol_done);
3706 if(CURLE_OK == result) {
3707 /* We have connected or sent away a name resolve query fine */
3709 conn = *connp; /* setup conn to again point to something nice */
3711 /* Now, if async is TRUE here, we need to wait for the name
3713 result = Curl_wait_for_resolv(conn, NULL);
3717 /* Resolved, continue with the connection */
3718 result = Curl_async_resolved(conn, &protocol_done);
3723 /* ... finally back to actually retry the DO phase */
3724 result = conn->curl_do(conn, done);
3732 CURLcode Curl_do_more(struct connectdata *conn)
3734 CURLcode result=CURLE_OK;
3736 if(conn->curl_do_more)
3737 result = conn->curl_do_more(conn);
3742 static bool safe_strequal(char* str1, char* str2)
3745 /* both pointers point to something then compare them */
3746 return strequal(str1, str2);
3748 /* if both pointers are NULL then treat them as equal */
3749 return (!str1 && !str2);
3753 Curl_ssl_config_matches(struct ssl_config_data* data,
3754 struct ssl_config_data* needle)
3756 if((data->version == needle->version) &&
3757 (data->verifypeer == needle->verifypeer) &&
3758 (data->verifyhost == needle->verifyhost) &&
3759 safe_strequal(data->CApath, needle->CApath) &&
3760 safe_strequal(data->CAfile, needle->CAfile) &&
3761 safe_strequal(data->random_file, needle->random_file) &&
3762 safe_strequal(data->egdsocket, needle->egdsocket) &&
3763 safe_strequal(data->cipher_list, needle->cipher_list))
3770 Curl_clone_ssl_config(struct ssl_config_data *source,
3771 struct ssl_config_data *dest)
3773 dest->verifyhost = source->verifyhost;
3774 dest->verifypeer = source->verifypeer;
3775 dest->version = source->version;
3777 if(source->CAfile) {
3778 dest->CAfile = strdup(source->CAfile);
3783 if(source->CApath) {
3784 dest->CApath = strdup(source->CApath);
3789 if(source->cipher_list) {
3790 dest->cipher_list = strdup(source->cipher_list);
3791 if(!dest->cipher_list)
3795 if(source->egdsocket) {
3796 dest->egdsocket = strdup(source->egdsocket);
3797 if(!dest->egdsocket)
3801 if(source->random_file) {
3802 dest->random_file = strdup(source->random_file);
3803 if(!dest->random_file)
3810 void Curl_free_ssl_config(struct ssl_config_data* sslc)
3818 if(sslc->cipher_list)
3819 free(sslc->cipher_list);
3822 free(sslc->egdsocket);
3824 if(sslc->random_file)
3825 free(sslc->random_file);