1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at http://curl.haxx.se/docs/copyright.html.
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ***************************************************************************/
23 #include "curl_setup.h"
25 #ifdef HAVE_NETINET_IN_H
26 #include <netinet/in.h>
31 #ifdef HAVE_ARPA_INET_H
32 #include <arpa/inet.h>
37 #ifdef HAVE_SYS_IOCTL_H
38 #include <sys/ioctl.h>
41 #ifdef HAVE_SYS_PARAM_H
42 #include <sys/param.h>
51 #error "We can't compile without socket() support!"
61 #include <stringprep.h>
62 #ifdef HAVE_IDN_FREE_H
65 /* prototype from idn-free.h, not provided by libidn 0.4.5's make install! */
66 void idn_free (void *ptr);
69 /* if idn_free() was not found in this version of libidn use free() instead */
70 #define idn_free(x) (free)(x)
72 #elif defined(USE_WIN32_IDN)
73 /* prototype for curl_win32_idn_to_ascii() */
74 int curl_win32_idn_to_ascii(const char *in, char **out);
75 #endif /* USE_LIBIDN */
92 #include "content_encoding.h"
93 #include "http_digest.h"
94 #include "http_negotiate.h"
98 #include "speedcheck.h"
100 #include "warnless.h"
101 #include "non-ascii.h"
102 #include "inet_pton.h"
104 /* And now for the protocols */
111 #include "curl_ldap.h"
116 #include "inet_ntop.h"
117 #include "curl_ntlm.h"
118 #include "curl_ntlm_wb.h"
120 #include "curl_rtmp.h"
122 #include "http_proxy.h"
124 #include "conncache.h"
125 #include "multihandle.h"
126 #include "pipeline.h"
129 #define _MPRINTF_REPLACE /* use our functions only */
130 #include <curl/mprintf.h>
132 #include "curl_memory.h"
133 /* The last #include file should be: */
134 #include "memdebug.h"
136 /* Local static prototypes */
137 static struct connectdata *
138 find_oldest_idle_connection(struct SessionHandle *data);
139 static struct connectdata *
140 find_oldest_idle_connection_in_bundle(struct SessionHandle *data,
141 struct connectbundle *bundle);
142 static void conn_free(struct connectdata *conn);
143 static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke);
144 static CURLcode do_init(struct connectdata *conn);
145 static CURLcode parse_url_login(struct SessionHandle *data,
146 struct connectdata *conn,
147 char *user, char *passwd, char *options);
148 static CURLcode parse_login_details(const char *login, const size_t len,
149 char **userptr, char **passwdptr,
151 static void free_connection_internals(struct SessionHandle *data);
156 static const struct Curl_handler * const protocols[] = {
158 #ifndef CURL_DISABLE_HTTP
162 #if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)
166 #ifndef CURL_DISABLE_FTP
170 #if defined(USE_SSL) && !defined(CURL_DISABLE_FTP)
174 #ifndef CURL_DISABLE_TELNET
175 &Curl_handler_telnet,
178 #ifndef CURL_DISABLE_DICT
182 #ifndef CURL_DISABLE_LDAP
184 #if !defined(CURL_DISABLE_LDAPS) && \
185 ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \
186 (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)))
191 #ifndef CURL_DISABLE_FILE
195 #ifndef CURL_DISABLE_TFTP
204 #ifndef CURL_DISABLE_IMAP
211 #ifndef CURL_DISABLE_POP3
218 #ifndef CURL_DISABLE_SMTP
225 #ifndef CURL_DISABLE_RTSP
229 #ifndef CURL_DISABLE_GOPHER
230 &Curl_handler_gopher,
237 &Curl_handler_rtmpte,
239 &Curl_handler_rtmpts,
242 (struct Curl_handler *) NULL
246 * Dummy handler for undefined protocol schemes.
249 static const struct Curl_handler Curl_handler_dummy = {
250 "<no protocol>", /* scheme */
251 ZERO_NULL, /* setup_connection */
252 ZERO_NULL, /* do_it */
253 ZERO_NULL, /* done */
254 ZERO_NULL, /* do_more */
255 ZERO_NULL, /* connect_it */
256 ZERO_NULL, /* connecting */
257 ZERO_NULL, /* doing */
258 ZERO_NULL, /* proto_getsock */
259 ZERO_NULL, /* doing_getsock */
260 ZERO_NULL, /* domore_getsock */
261 ZERO_NULL, /* perform_getsock */
262 ZERO_NULL, /* disconnect */
263 ZERO_NULL, /* readwrite */
266 PROTOPT_NONE /* flags */
269 void Curl_freeset(struct SessionHandle *data)
271 /* Free all dynamic strings stored in the data->set substructure. */
273 for(i=(enum dupstring)0; i < STRING_LAST; i++)
274 Curl_safefree(data->set.str[i]);
276 if(data->change.referer_alloc) {
277 Curl_safefree(data->change.referer);
278 data->change.referer_alloc = FALSE;
280 data->change.referer = NULL;
283 static CURLcode setstropt(char **charp, char *s)
285 /* Release the previous storage at `charp' and replace by a dynamic storage
286 copy of `s'. Return CURLE_OK or CURLE_OUT_OF_MEMORY. */
288 Curl_safefree(*charp);
294 return CURLE_OUT_OF_MEMORY;
302 static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp,
305 CURLcode result = CURLE_OK;
308 char *options = NULL;
310 /* Parse the login details if specified. It not then we treat NULL as a hint
311 to clear the existing data */
313 result = parse_login_details(option, strlen(option),
314 (userp ? &user : NULL),
315 (passwdp ? &passwd : NULL),
316 (optionsp ? &options : NULL));
320 /* Store the username part of option if required */
322 if(!user && option && option[0] == ':') {
323 /* Allocate an empty string instead of returning NULL as user name */
326 result = CURLE_OUT_OF_MEMORY;
329 Curl_safefree(*userp);
333 /* Store the password part of option if required */
335 Curl_safefree(*passwdp);
339 /* Store the options part of option if required */
341 Curl_safefree(*optionsp);
349 CURLcode Curl_dupset(struct SessionHandle *dst, struct SessionHandle *src)
351 CURLcode r = CURLE_OK;
354 /* Copy src->set into dst->set first, then deal with the strings
358 /* clear all string pointers first */
359 memset(dst->set.str, 0, STRING_LAST * sizeof(char *));
361 /* duplicate all strings */
362 for(i=(enum dupstring)0; i< STRING_LAST; i++) {
363 r = setstropt(&dst->set.str[i], src->set.str[i]);
368 /* If a failure occurred, freeing has to be performed externally. */
373 * This is the internal function curl_easy_cleanup() calls. This should
374 * cleanup and free all resources associated with this sessionhandle.
376 * NOTE: if we ever add something that attempts to write to a socket or
377 * similar here, we must ignore SIGPIPE first. It is currently only done
378 * when curl_easy_perform() is invoked.
381 CURLcode Curl_close(struct SessionHandle *data)
383 struct Curl_multi *m;
388 Curl_expire(data, 0); /* shut off timers */
393 /* This handle is still part of a multi handle, take care of this first
394 and detach this handle from there. */
395 curl_multi_remove_handle(data->multi, data);
398 /* when curl_easy_perform() is used, it creates its own multi handle to
399 use and this is the one */
400 curl_multi_cleanup(data->multi_easy);
402 /* Destroy the timeout list that is held in the easy handle. It is
403 /normally/ done by curl_multi_remove_handle() but this is "just in
405 if(data->state.timeoutlist) {
406 Curl_llist_destroy(data->state.timeoutlist, NULL);
407 data->state.timeoutlist = NULL;
410 data->magic = 0; /* force a clear AFTER the possibly enforced removal from
411 the multi handle, since that function uses the magic
414 if(data->state.rangestringalloc)
415 free(data->state.range);
417 /* Free the pathbuffer */
418 Curl_safefree(data->state.pathbuffer);
419 data->state.path = NULL;
421 /* freed here just in case DONE wasn't called */
422 free_connection_internals(data);
424 /* Close down all open SSL info and sessions */
425 Curl_ssl_close_all(data);
426 Curl_safefree(data->state.first_host);
427 Curl_safefree(data->state.scratch);
428 Curl_ssl_free_certinfo(data);
430 if(data->change.referer_alloc) {
431 Curl_safefree(data->change.referer);
432 data->change.referer_alloc = FALSE;
434 data->change.referer = NULL;
436 if(data->change.url_alloc) {
437 Curl_safefree(data->change.url);
438 data->change.url_alloc = FALSE;
440 data->change.url = NULL;
442 Curl_safefree(data->state.headerbuff);
444 Curl_flush_cookies(data, 1);
446 Curl_digest_cleanup(data);
448 Curl_safefree(data->info.contenttype);
449 Curl_safefree(data->info.wouldredirect);
451 /* this destroys the channel and we cannot use it anymore after this */
452 Curl_resolver_cleanup(data->state.resolver);
454 Curl_convert_close(data);
456 /* No longer a dirty share, if it exists */
458 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
459 data->share->dirty--;
460 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
469 * Initialize the UserDefined fields within a SessionHandle.
470 * This may be safely called on a new or existing SessionHandle.
472 CURLcode Curl_init_userdefined(struct UserDefined *set)
474 CURLcode res = CURLE_OK;
476 set->out = stdout; /* default output to stdout */
477 set->in = stdin; /* default input from stdin */
478 set->err = stderr; /* default stderr to stderr */
480 /* use fwrite as default function to store output */
481 set->fwrite_func = (curl_write_callback)fwrite;
483 /* use fread as default function to read input */
484 set->fread_func = (curl_read_callback)fread;
485 set->is_fread_set = 0;
486 set->is_fwrite_set = 0;
488 set->seek_func = ZERO_NULL;
489 set->seek_client = ZERO_NULL;
491 /* conversion callbacks for non-ASCII hosts */
492 set->convfromnetwork = ZERO_NULL;
493 set->convtonetwork = ZERO_NULL;
494 set->convfromutf8 = ZERO_NULL;
496 set->infilesize = -1; /* we don't know any size */
497 set->postfieldsize = -1; /* unknown size */
498 set->maxredirs = -1; /* allow any amount by default */
500 set->httpreq = HTTPREQ_GET; /* Default HTTP request */
501 set->rtspreq = RTSPREQ_OPTIONS; /* Default RTSP request */
502 set->ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */
503 set->ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */
504 set->ftp_use_pret = FALSE; /* mainly useful for drftpd servers */
505 set->ftp_filemethod = FTPFILE_MULTICWD;
507 set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
509 /* Set the default size of the SSL session ID cache */
510 set->ssl.max_ssl_sessions = 5;
512 set->proxyport = CURL_DEFAULT_PROXY_PORT; /* from url.h */
513 set->proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
514 set->httpauth = CURLAUTH_BASIC; /* defaults to basic */
515 set->proxyauth = CURLAUTH_BASIC; /* defaults to basic */
517 /* make libcurl quiet by default: */
518 set->hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */
521 * libcurl 7.10 introduced SSL verification *by default*! This needs to be
522 * switched off unless wanted.
524 set->ssl.verifypeer = TRUE;
525 set->ssl.verifyhost = TRUE;
527 set->ssl.authtype = CURL_TLSAUTH_NONE;
529 set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
531 set->ssl.sessionid = TRUE; /* session ID caching enabled by default */
533 set->new_file_perms = 0644; /* Default permissions */
534 set->new_directory_perms = 0755; /* Default permissions */
536 /* for the *protocols fields we don't use the CURLPROTO_ALL convenience
537 define since we internally only use the lower 16 bits for the passed
538 in bitmask to not conflict with the private bits */
539 set->allowed_protocols = CURLPROTO_ALL;
540 set->redir_protocols =
541 CURLPROTO_ALL & ~(CURLPROTO_FILE|CURLPROTO_SCP); /* not FILE or SCP */
543 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
545 * disallow unprotected protection negotiation NEC reference implementation
546 * seem not to follow rfc1961 section 4.3/4.4
548 set->socks5_gssapi_nec = FALSE;
549 /* set default gssapi service name */
550 res = setstropt(&set->str[STRING_SOCKS5_GSSAPI_SERVICE],
551 (char *) CURL_DEFAULT_SOCKS5_GSSAPI_SERVICE);
556 /* This is our preferred CA cert bundle/path since install time */
557 #if defined(CURL_CA_BUNDLE)
558 res = setstropt(&set->str[STRING_SSL_CAFILE], (char *) CURL_CA_BUNDLE);
559 #elif defined(CURL_CA_PATH)
560 res = setstropt(&set->str[STRING_SSL_CAPATH], (char *) CURL_CA_PATH);
563 set->wildcardmatch = FALSE;
564 set->chunk_bgn = ZERO_NULL;
565 set->chunk_end = ZERO_NULL;
567 /* tcp keepalives are disabled by default, but provide reasonable values for
568 * the interval and idle times.
570 set->tcp_keepalive = FALSE;
571 set->tcp_keepintvl = 60;
572 set->tcp_keepidle = 60;
580 * @param curl is a pointer to a sessionhandle pointer that gets set by this
585 CURLcode Curl_open(struct SessionHandle **curl)
587 CURLcode res = CURLE_OK;
588 struct SessionHandle *data;
591 /* Very simple start-up: alloc the struct, init it with zeroes and return */
592 data = calloc(1, sizeof(struct SessionHandle));
594 /* this is a very serious error */
595 DEBUGF(fprintf(stderr, "Error: calloc of SessionHandle failed\n"));
596 return CURLE_OUT_OF_MEMORY;
599 data->magic = CURLEASY_MAGIC_NUMBER;
601 status = Curl_resolver_init(&data->state.resolver);
603 DEBUGF(fprintf(stderr, "Error: resolver_init failed\n"));
608 /* We do some initial setup here, all those fields that can't be just 0 */
610 data->state.headerbuff = malloc(HEADERSIZE);
611 if(!data->state.headerbuff) {
612 DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n"));
613 res = CURLE_OUT_OF_MEMORY;
616 Curl_easy_initHandleData(data);
617 res = Curl_init_userdefined(&data->set);
619 data->state.headersize=HEADERSIZE;
621 Curl_convert_init(data);
623 /* most recent connection is not yet defined */
624 data->state.lastconnect = NULL;
626 data->progress.flags |= PGRS_HIDE;
627 data->state.current_speed = -1; /* init to negative == impossible */
629 data->wildcard.state = CURLWC_INIT;
630 data->wildcard.filelist = NULL;
631 data->set.fnmatch = ZERO_NULL;
632 data->set.maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */
636 Curl_resolver_cleanup(data->state.resolver);
637 if(data->state.headerbuff)
638 free(data->state.headerbuff);
649 CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
653 CURLcode result = CURLE_OK;
655 #ifndef CURL_DISABLE_HTTP
660 case CURLOPT_DNS_CACHE_TIMEOUT:
661 data->set.dns_cache_timeout = va_arg(param, long);
663 case CURLOPT_DNS_USE_GLOBAL_CACHE:
664 /* remember we want this enabled */
665 arg = va_arg(param, long);
666 data->set.global_dns_cache = (0 != arg)?TRUE:FALSE;
668 case CURLOPT_SSL_CIPHER_LIST:
669 /* set a list of cipher we want to use in the SSL connection */
670 result = setstropt(&data->set.str[STRING_SSL_CIPHER_LIST],
671 va_arg(param, char *));
674 case CURLOPT_RANDOM_FILE:
676 * This is the path name to a file that contains random data to seed
677 * the random SSL stuff with. The file is only used for reading.
679 result = setstropt(&data->set.str[STRING_SSL_RANDOM_FILE],
680 va_arg(param, char *));
682 case CURLOPT_EGDSOCKET:
684 * The Entropy Gathering Daemon socket pathname
686 result = setstropt(&data->set.str[STRING_SSL_EGDSOCKET],
687 va_arg(param, char *));
689 case CURLOPT_MAXCONNECTS:
691 * Set the absolute number of maximum simultaneous alive connection that
692 * libcurl is allowed to have.
694 data->set.maxconnects = va_arg(param, long);
696 case CURLOPT_FORBID_REUSE:
698 * When this transfer is done, it must not be left to be reused by a
699 * subsequent transfer but shall be closed immediately.
701 data->set.reuse_forbid = (0 != va_arg(param, long))?TRUE:FALSE;
703 case CURLOPT_FRESH_CONNECT:
705 * This transfer shall not use a previously cached connection but
706 * should be made with a fresh new connect!
708 data->set.reuse_fresh = (0 != va_arg(param, long))?TRUE:FALSE;
710 case CURLOPT_VERBOSE:
712 * Verbose means infof() calls that give a lot of information about
713 * the connection and transfer procedures as well as internal choices.
715 data->set.verbose = (0 != va_arg(param, long))?TRUE:FALSE;
719 * Set to include the header in the general data output stream.
721 data->set.include_header = (0 != va_arg(param, long))?TRUE:FALSE;
723 case CURLOPT_NOPROGRESS:
725 * Shut off the internal supported progress meter
727 data->set.hide_progress = (0 != va_arg(param, long))?TRUE:FALSE;
728 if(data->set.hide_progress)
729 data->progress.flags |= PGRS_HIDE;
731 data->progress.flags &= ~PGRS_HIDE;
735 * Do not include the body part in the output data stream.
737 data->set.opt_no_body = (0 != va_arg(param, long))?TRUE:FALSE;
739 case CURLOPT_FAILONERROR:
741 * Don't output the >=300 error code HTML-page, but instead only
744 data->set.http_fail_on_error = (0 != va_arg(param, long))?TRUE:FALSE;
749 * We want to sent data to the remote host. If this is HTTP, that equals
750 * using the PUT request.
752 data->set.upload = (0 != va_arg(param, long))?TRUE:FALSE;
753 if(data->set.upload) {
754 /* If this is HTTP, PUT is what's needed to "upload" */
755 data->set.httpreq = HTTPREQ_PUT;
756 data->set.opt_no_body = FALSE; /* this is implied */
759 /* In HTTP, the opposite of upload is GET (unless NOBODY is true as
760 then this can be changed to HEAD later on) */
761 data->set.httpreq = HTTPREQ_GET;
763 case CURLOPT_FILETIME:
765 * Try to get the file time of the remote document. The time will
766 * later (possibly) become available using curl_easy_getinfo().
768 data->set.get_filetime = (0 != va_arg(param, long))?TRUE:FALSE;
770 case CURLOPT_FTP_CREATE_MISSING_DIRS:
772 * An FTP option that modifies an upload to create missing directories on
775 switch(va_arg(param, long)) {
777 data->set.ftp_create_missing_dirs = 0;
780 data->set.ftp_create_missing_dirs = 1;
783 data->set.ftp_create_missing_dirs = 2;
786 /* reserve other values for future use */
787 result = CURLE_UNKNOWN_OPTION;
791 case CURLOPT_SERVER_RESPONSE_TIMEOUT:
793 * Option that specifies how quickly an server response must be obtained
794 * before it is considered failure. For pingpong protocols.
796 data->set.server_response_timeout = va_arg( param , long ) * 1000;
798 case CURLOPT_TFTP_BLKSIZE:
800 * TFTP option that specifies the block size to use for data transmission
802 data->set.tftp_blksize = va_arg(param, long);
804 case CURLOPT_DIRLISTONLY:
806 * An option that changes the command to one that asks for a list
807 * only, no file info details.
809 data->set.ftp_list_only = (0 != va_arg(param, long))?TRUE:FALSE;
813 * We want to upload and append to an existing file.
815 data->set.ftp_append = (0 != va_arg(param, long))?TRUE:FALSE;
817 case CURLOPT_FTP_FILEMETHOD:
819 * How do access files over FTP.
821 data->set.ftp_filemethod = (curl_ftpfile)va_arg(param, long);
825 * Parse the $HOME/.netrc file
827 data->set.use_netrc = (enum CURL_NETRC_OPTION)va_arg(param, long);
829 case CURLOPT_NETRC_FILE:
831 * Use this file instead of the $HOME/.netrc file
833 result = setstropt(&data->set.str[STRING_NETRC_FILE],
834 va_arg(param, char *));
836 case CURLOPT_TRANSFERTEXT:
838 * This option was previously named 'FTPASCII'. Renamed to work with
839 * more protocols than merely FTP.
841 * Transfer using ASCII (instead of BINARY).
843 data->set.prefer_ascii = (0 != va_arg(param, long))?TRUE:FALSE;
845 case CURLOPT_TIMECONDITION:
847 * Set HTTP time condition. This must be one of the defines in the
848 * curl/curl.h header file.
850 data->set.timecondition = (curl_TimeCond)va_arg(param, long);
852 case CURLOPT_TIMEVALUE:
854 * This is the value to compare with the remote document with the
855 * method set with CURLOPT_TIMECONDITION
857 data->set.timevalue = (time_t)va_arg(param, long);
859 case CURLOPT_SSLVERSION:
861 * Set explicit SSL version to try to connect with, as some SSL
862 * implementations are lame.
864 data->set.ssl.version = va_arg(param, long);
867 #ifndef CURL_DISABLE_HTTP
868 case CURLOPT_AUTOREFERER:
870 * Switch on automatic referer that gets set if curl follows locations.
872 data->set.http_auto_referer = (0 != va_arg(param, long))?TRUE:FALSE;
875 case CURLOPT_ACCEPT_ENCODING:
877 * String to use at the value of Accept-Encoding header.
879 * If the encoding is set to "" we use an Accept-Encoding header that
880 * encompasses all the encodings we support.
881 * If the encoding is set to NULL we don't send an Accept-Encoding header
882 * and ignore an received Content-Encoding header.
885 argptr = va_arg(param, char *);
886 result = setstropt(&data->set.str[STRING_ENCODING],
887 (argptr && !*argptr)?
888 (char *) ALL_CONTENT_ENCODINGS: argptr);
891 case CURLOPT_TRANSFER_ENCODING:
892 data->set.http_transfer_encoding = (0 != va_arg(param, long))?TRUE:FALSE;
895 case CURLOPT_FOLLOWLOCATION:
897 * Follow Location: header hints on a HTTP-server.
899 data->set.http_follow_location = (0 != va_arg(param, long))?TRUE:FALSE;
902 case CURLOPT_UNRESTRICTED_AUTH:
904 * Send authentication (user+password) when following locations, even when
907 data->set.http_disable_hostname_check_before_authentication =
908 (0 != va_arg(param, long))?TRUE:FALSE;
911 case CURLOPT_MAXREDIRS:
913 * The maximum amount of hops you allow curl to follow Location:
914 * headers. This should mostly be used to detect never-ending loops.
916 data->set.maxredirs = va_arg(param, long);
919 case CURLOPT_POSTREDIR:
922 * Set the behaviour of POST when redirecting
923 * CURL_REDIR_GET_ALL - POST is changed to GET after 301 and 302
924 * CURL_REDIR_POST_301 - POST is kept as POST after 301
925 * CURL_REDIR_POST_302 - POST is kept as POST after 302
926 * CURL_REDIR_POST_303 - POST is kept as POST after 303
927 * CURL_REDIR_POST_ALL - POST is kept as POST after 301, 302 and 303
928 * other - POST is kept as POST after 301 and 302
930 int postRedir = curlx_sltosi(va_arg(param, long));
931 data->set.keep_post = postRedir & CURL_REDIR_POST_ALL;
936 /* Does this option serve a purpose anymore? Yes it does, when
937 CURLOPT_POSTFIELDS isn't used and the POST data is read off the
939 if(va_arg(param, long)) {
940 data->set.httpreq = HTTPREQ_POST;
941 data->set.opt_no_body = FALSE; /* this is implied */
944 data->set.httpreq = HTTPREQ_GET;
947 case CURLOPT_COPYPOSTFIELDS:
949 * A string with POST data. Makes curl HTTP POST. Even if it is NULL.
950 * If needed, CURLOPT_POSTFIELDSIZE must have been set prior to
951 * CURLOPT_COPYPOSTFIELDS and not altered later.
953 argptr = va_arg(param, char *);
955 if(!argptr || data->set.postfieldsize == -1)
956 result = setstropt(&data->set.str[STRING_COPYPOSTFIELDS], argptr);
959 * Check that requested length does not overflow the size_t type.
962 if((data->set.postfieldsize < 0) ||
963 ((sizeof(curl_off_t) != sizeof(size_t)) &&
964 (data->set.postfieldsize > (curl_off_t)((size_t)-1))))
965 result = CURLE_OUT_OF_MEMORY;
969 (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
971 /* Allocate even when size == 0. This satisfies the need of possible
972 later address compare to detect the COPYPOSTFIELDS mode, and
973 to mark that postfields is used rather than read function or
976 p = malloc((size_t)(data->set.postfieldsize?
977 data->set.postfieldsize:1));
980 result = CURLE_OUT_OF_MEMORY;
982 if(data->set.postfieldsize)
983 memcpy(p, argptr, (size_t)data->set.postfieldsize);
985 data->set.str[STRING_COPYPOSTFIELDS] = p;
990 data->set.postfields = data->set.str[STRING_COPYPOSTFIELDS];
991 data->set.httpreq = HTTPREQ_POST;
994 case CURLOPT_POSTFIELDS:
996 * Like above, but use static data instead of copying it.
998 data->set.postfields = va_arg(param, void *);
999 /* Release old copied data. */
1000 (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1001 data->set.httpreq = HTTPREQ_POST;
1004 case CURLOPT_POSTFIELDSIZE:
1006 * The size of the POSTFIELD data to prevent libcurl to do strlen() to
1007 * figure it out. Enables binary posts.
1009 bigsize = va_arg(param, long);
1011 if(data->set.postfieldsize < bigsize &&
1012 data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
1013 /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */
1014 (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1015 data->set.postfields = NULL;
1018 data->set.postfieldsize = bigsize;
1021 case CURLOPT_POSTFIELDSIZE_LARGE:
1023 * The size of the POSTFIELD data to prevent libcurl to do strlen() to
1024 * figure it out. Enables binary posts.
1026 bigsize = va_arg(param, curl_off_t);
1028 if(data->set.postfieldsize < bigsize &&
1029 data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
1030 /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */
1031 (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1032 data->set.postfields = NULL;
1035 data->set.postfieldsize = bigsize;
1038 case CURLOPT_HTTPPOST:
1040 * Set to make us do HTTP POST
1042 data->set.httppost = va_arg(param, struct curl_httppost *);
1043 data->set.httpreq = HTTPREQ_POST_FORM;
1044 data->set.opt_no_body = FALSE; /* this is implied */
1047 case CURLOPT_REFERER:
1049 * String to set in the HTTP Referer: field.
1051 if(data->change.referer_alloc) {
1052 Curl_safefree(data->change.referer);
1053 data->change.referer_alloc = FALSE;
1055 result = setstropt(&data->set.str[STRING_SET_REFERER],
1056 va_arg(param, char *));
1057 data->change.referer = data->set.str[STRING_SET_REFERER];
1060 case CURLOPT_USERAGENT:
1062 * String to use in the HTTP User-Agent field
1064 result = setstropt(&data->set.str[STRING_USERAGENT],
1065 va_arg(param, char *));
1068 case CURLOPT_HTTPHEADER:
1070 * Set a list with HTTP headers to use (or replace internals with)
1072 data->set.headers = va_arg(param, struct curl_slist *);
1075 case CURLOPT_HTTP200ALIASES:
1077 * Set a list of aliases for HTTP 200 in response header
1079 data->set.http200aliases = va_arg(param, struct curl_slist *);
1082 #if !defined(CURL_DISABLE_COOKIES)
1083 case CURLOPT_COOKIE:
1085 * Cookie string to send to the remote server in the request.
1087 result = setstropt(&data->set.str[STRING_COOKIE],
1088 va_arg(param, char *));
1091 case CURLOPT_COOKIEFILE:
1093 * Set cookie file to read and parse. Can be used multiple times.
1095 argptr = (char *)va_arg(param, void *);
1097 struct curl_slist *cl;
1098 /* append the cookie file name to the list of file names, and deal with
1100 cl = curl_slist_append(data->change.cookielist, argptr);
1102 curl_slist_free_all(data->change.cookielist);
1103 data->change.cookielist = NULL;
1104 return CURLE_OUT_OF_MEMORY;
1106 data->change.cookielist = cl; /* store the list for later use */
1110 case CURLOPT_COOKIEJAR:
1112 * Set cookie file name to dump all cookies to when we're done.
1114 result = setstropt(&data->set.str[STRING_COOKIEJAR],
1115 va_arg(param, char *));
1118 * Activate the cookie parser. This may or may not already
1121 data->cookies = Curl_cookie_init(data, NULL, data->cookies,
1122 data->set.cookiesession);
1125 case CURLOPT_COOKIESESSION:
1127 * Set this option to TRUE to start a new "cookie session". It will
1128 * prevent the forthcoming read-cookies-from-file actions to accept
1129 * cookies that are marked as being session cookies, as they belong to a
1132 * In the original Netscape cookie spec, "session cookies" are cookies
1133 * with no expire date set. RFC2109 describes the same action if no
1134 * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds
1135 * a 'Discard' action that can enforce the discard even for cookies that
1138 * We run mostly with the original cookie spec, as hardly anyone implements
1141 data->set.cookiesession = (0 != va_arg(param, long))?TRUE:FALSE;
1144 case CURLOPT_COOKIELIST:
1145 argptr = va_arg(param, char *);
1150 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
1152 if(Curl_raw_equal(argptr, "ALL")) {
1153 /* clear all cookies */
1154 Curl_cookie_clearall(data->cookies);
1156 else if(Curl_raw_equal(argptr, "SESS")) {
1157 /* clear session cookies */
1158 Curl_cookie_clearsess(data->cookies);
1160 else if(Curl_raw_equal(argptr, "FLUSH")) {
1161 /* flush cookies to file */
1162 Curl_flush_cookies(data, 0);
1166 /* if cookie engine was not running, activate it */
1167 data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE);
1169 argptr = strdup(argptr);
1171 result = CURLE_OUT_OF_MEMORY;
1175 if(checkprefix("Set-Cookie:", argptr))
1176 /* HTTP Header format line */
1177 Curl_cookie_add(data, data->cookies, TRUE, argptr + 11, NULL, NULL);
1180 /* Netscape format line */
1181 Curl_cookie_add(data, data->cookies, FALSE, argptr, NULL, NULL);
1186 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
1189 #endif /* CURL_DISABLE_COOKIES */
1191 case CURLOPT_HTTPGET:
1193 * Set to force us do HTTP GET
1195 if(va_arg(param, long)) {
1196 data->set.httpreq = HTTPREQ_GET;
1197 data->set.upload = FALSE; /* switch off upload */
1198 data->set.opt_no_body = FALSE; /* this is implied */
1202 case CURLOPT_HTTP_VERSION:
1204 * This sets a requested HTTP version to be used. The value is one of
1205 * the listed enums in curl/curl.h.
1207 data->set.httpversion = va_arg(param, long);
1210 case CURLOPT_HTTPAUTH:
1212 * Set HTTP Authentication type BITMASK.
1217 unsigned long auth = va_arg(param, unsigned long);
1219 if(auth == CURLAUTH_NONE) {
1220 data->set.httpauth = auth;
1224 /* the DIGEST_IE bit is only used to set a special marker, for all the
1225 rest we need to handle it as normal DIGEST */
1226 data->state.authhost.iestyle = (auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE;
1228 if(auth & CURLAUTH_DIGEST_IE) {
1229 auth |= CURLAUTH_DIGEST; /* set standard digest bit */
1230 auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */
1233 /* switch off bits we can't support */
1235 auth &= ~CURLAUTH_NTLM; /* no NTLM support */
1236 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
1237 #elif !defined(NTLM_WB_ENABLED)
1238 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
1240 #ifndef USE_HTTP_NEGOTIATE
1241 auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI or
1245 /* check if any auth bit lower than CURLAUTH_ONLY is still set */
1248 while(bitcheck < 31) {
1249 if(auth & (1UL << bitcheck++)) {
1255 return CURLE_NOT_BUILT_IN; /* no supported types left! */
1257 data->set.httpauth = auth;
1261 #endif /* CURL_DISABLE_HTTP */
1263 case CURLOPT_CUSTOMREQUEST:
1265 * Set a custom string to use as request
1267 result = setstropt(&data->set.str[STRING_CUSTOMREQUEST],
1268 va_arg(param, char *));
1271 data->set.httpreq = HTTPREQ_CUSTOM;
1272 here, we continue as if we were using the already set type
1273 and this just changes the actual request keyword */
1276 #ifndef CURL_DISABLE_PROXY
1277 case CURLOPT_HTTPPROXYTUNNEL:
1279 * Tunnel operations through the proxy instead of normal proxy use
1281 data->set.tunnel_thru_httpproxy = (0 != va_arg(param, long))?TRUE:FALSE;
1284 case CURLOPT_PROXYPORT:
1286 * Explicitly set HTTP proxy port number.
1288 data->set.proxyport = va_arg(param, long);
1291 case CURLOPT_PROXYAUTH:
1293 * Set HTTP Authentication type BITMASK.
1298 unsigned long auth = va_arg(param, unsigned long);
1300 if(auth == CURLAUTH_NONE) {
1301 data->set.proxyauth = auth;
1305 /* the DIGEST_IE bit is only used to set a special marker, for all the
1306 rest we need to handle it as normal DIGEST */
1307 data->state.authproxy.iestyle = (auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE;
1309 if(auth & CURLAUTH_DIGEST_IE) {
1310 auth |= CURLAUTH_DIGEST; /* set standard digest bit */
1311 auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */
1313 /* switch off bits we can't support */
1315 auth &= ~CURLAUTH_NTLM; /* no NTLM support */
1316 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
1317 #elif !defined(NTLM_WB_ENABLED)
1318 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
1320 #ifndef USE_HTTP_NEGOTIATE
1321 auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI or
1325 /* check if any auth bit lower than CURLAUTH_ONLY is still set */
1328 while(bitcheck < 31) {
1329 if(auth & (1UL << bitcheck++)) {
1335 return CURLE_NOT_BUILT_IN; /* no supported types left! */
1337 data->set.proxyauth = auth;
1343 * Set proxy server:port to use as HTTP proxy.
1345 * If the proxy is set to "" we explicitly say that we don't want to use a
1346 * proxy (even though there might be environment variables saying so).
1348 * Setting it to NULL, means no proxy but allows the environment variables
1351 result = setstropt(&data->set.str[STRING_PROXY],
1352 va_arg(param, char *));
1355 case CURLOPT_PROXYTYPE:
1357 * Set proxy type. HTTP/HTTP_1_0/SOCKS4/SOCKS4a/SOCKS5/SOCKS5_HOSTNAME
1359 data->set.proxytype = (curl_proxytype)va_arg(param, long);
1362 case CURLOPT_PROXY_TRANSFER_MODE:
1364 * set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy
1366 switch (va_arg(param, long)) {
1368 data->set.proxy_transfer_mode = FALSE;
1371 data->set.proxy_transfer_mode = TRUE;
1374 /* reserve other values for future use */
1375 result = CURLE_UNKNOWN_OPTION;
1379 #endif /* CURL_DISABLE_PROXY */
1381 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
1382 case CURLOPT_SOCKS5_GSSAPI_SERVICE:
1384 * Set gssapi service name
1386 result = setstropt(&data->set.str[STRING_SOCKS5_GSSAPI_SERVICE],
1387 va_arg(param, char *));
1390 case CURLOPT_SOCKS5_GSSAPI_NEC:
1392 * set flag for nec socks5 support
1394 data->set.socks5_gssapi_nec = (0 != va_arg(param, long))?TRUE:FALSE;
1398 case CURLOPT_WRITEHEADER:
1400 * Custom pointer to pass the header write callback function
1402 data->set.writeheader = (void *)va_arg(param, void *);
1404 case CURLOPT_ERRORBUFFER:
1406 * Error buffer provided by the caller to get the human readable
1409 data->set.errorbuffer = va_arg(param, char *);
1413 * FILE pointer to write to. Or possibly
1414 * used as argument to the write callback.
1416 data->set.out = va_arg(param, void *);
1418 case CURLOPT_FTPPORT:
1420 * Use FTP PORT, this also specifies which IP address to use
1422 result = setstropt(&data->set.str[STRING_FTPPORT],
1423 va_arg(param, char *));
1424 data->set.ftp_use_port = (NULL != data->set.str[STRING_FTPPORT]) ?
1428 case CURLOPT_FTP_USE_EPRT:
1429 data->set.ftp_use_eprt = (0 != va_arg(param, long))?TRUE:FALSE;
1432 case CURLOPT_FTP_USE_EPSV:
1433 data->set.ftp_use_epsv = (0 != va_arg(param, long))?TRUE:FALSE;
1436 case CURLOPT_FTP_USE_PRET:
1437 data->set.ftp_use_pret = (0 != va_arg(param, long))?TRUE:FALSE;
1440 case CURLOPT_FTP_SSL_CCC:
1441 data->set.ftp_ccc = (curl_ftpccc)va_arg(param, long);
1444 case CURLOPT_FTP_SKIP_PASV_IP:
1446 * Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the
1447 * bypass of the IP address in PASV responses.
1449 data->set.ftp_skip_ip = (0 != va_arg(param, long))?TRUE:FALSE;
1452 case CURLOPT_INFILE:
1454 * FILE pointer to read the file to be uploaded from. Or possibly
1455 * used as argument to the read callback.
1457 data->set.in = va_arg(param, void *);
1459 case CURLOPT_INFILESIZE:
1461 * If known, this should inform curl about the file size of the
1462 * to-be-uploaded file.
1464 data->set.infilesize = va_arg(param, long);
1466 case CURLOPT_INFILESIZE_LARGE:
1468 * If known, this should inform curl about the file size of the
1469 * to-be-uploaded file.
1471 data->set.infilesize = va_arg(param, curl_off_t);
1473 case CURLOPT_LOW_SPEED_LIMIT:
1475 * The low speed limit that if transfers are below this for
1476 * CURLOPT_LOW_SPEED_TIME, the transfer is aborted.
1478 data->set.low_speed_limit=va_arg(param, long);
1480 case CURLOPT_MAX_SEND_SPEED_LARGE:
1482 * When transfer uploads are faster then CURLOPT_MAX_SEND_SPEED_LARGE
1483 * bytes per second the transfer is throttled..
1485 data->set.max_send_speed=va_arg(param, curl_off_t);
1487 case CURLOPT_MAX_RECV_SPEED_LARGE:
1489 * When receiving data faster than CURLOPT_MAX_RECV_SPEED_LARGE bytes per
1490 * second the transfer is throttled..
1492 data->set.max_recv_speed=va_arg(param, curl_off_t);
1494 case CURLOPT_LOW_SPEED_TIME:
1496 * The low speed time that if transfers are below the set
1497 * CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted.
1499 data->set.low_speed_time=va_arg(param, long);
1505 if(data->change.url_alloc) {
1506 /* the already set URL is allocated, free it first! */
1507 Curl_safefree(data->change.url);
1508 data->change.url_alloc = FALSE;
1510 result = setstropt(&data->set.str[STRING_SET_URL],
1511 va_arg(param, char *));
1512 data->change.url = data->set.str[STRING_SET_URL];
1516 * The port number to use when getting the URL
1518 data->set.use_port = va_arg(param, long);
1520 case CURLOPT_TIMEOUT:
1522 * The maximum time you allow curl to use for a single transfer
1525 data->set.timeout = va_arg(param, long) * 1000L;
1528 case CURLOPT_TIMEOUT_MS:
1529 data->set.timeout = va_arg(param, long);
1532 case CURLOPT_CONNECTTIMEOUT:
1534 * The maximum time you allow curl to use to connect.
1536 data->set.connecttimeout = va_arg(param, long) * 1000L;
1539 case CURLOPT_CONNECTTIMEOUT_MS:
1540 data->set.connecttimeout = va_arg(param, long);
1543 case CURLOPT_ACCEPTTIMEOUT_MS:
1545 * The maximum time you allow curl to wait for server connect
1547 data->set.accepttimeout = va_arg(param, long);
1550 case CURLOPT_USERPWD:
1552 * user:password;options to use in the operation
1554 result = setstropt_userpwd(va_arg(param, char *),
1555 &data->set.str[STRING_USERNAME],
1556 &data->set.str[STRING_PASSWORD],
1557 &data->set.str[STRING_OPTIONS]);
1559 case CURLOPT_USERNAME:
1561 * authentication user name to use in the operation
1563 result = setstropt(&data->set.str[STRING_USERNAME],
1564 va_arg(param, char *));
1566 case CURLOPT_PASSWORD:
1568 * authentication password to use in the operation
1570 result = setstropt(&data->set.str[STRING_PASSWORD],
1571 va_arg(param, char *));
1573 case CURLOPT_POSTQUOTE:
1575 * List of RAW FTP commands to use after a transfer
1577 data->set.postquote = va_arg(param, struct curl_slist *);
1579 case CURLOPT_PREQUOTE:
1581 * List of RAW FTP commands to use prior to RETR (Wesley Laxton)
1583 data->set.prequote = va_arg(param, struct curl_slist *);
1587 * List of RAW FTP commands to use before a transfer
1589 data->set.quote = va_arg(param, struct curl_slist *);
1591 case CURLOPT_RESOLVE:
1593 * List of NAME:[address] names to populate the DNS cache with
1594 * Prefix the NAME with dash (-) to _remove_ the name from the cache.
1596 * Names added with this API will remain in the cache until explicitly
1597 * removed or the handle is cleaned up.
1599 * This API can remove any name from the DNS cache, but only entries
1600 * that aren't actually in use right now will be pruned immediately.
1602 data->set.resolve = va_arg(param, struct curl_slist *);
1603 data->change.resolve = data->set.resolve;
1605 case CURLOPT_PROGRESSFUNCTION:
1607 * Progress callback function
1609 data->set.fprogress = va_arg(param, curl_progress_callback);
1610 if(data->set.fprogress)
1611 data->progress.callback = TRUE; /* no longer internal */
1613 data->progress.callback = FALSE; /* NULL enforces internal */
1616 case CURLOPT_XFERINFOFUNCTION:
1618 * Transfer info callback function
1620 data->set.fxferinfo = va_arg(param, curl_xferinfo_callback);
1621 if(data->set.fxferinfo)
1622 data->progress.callback = TRUE; /* no longer internal */
1624 data->progress.callback = FALSE; /* NULL enforces internal */
1628 case CURLOPT_PROGRESSDATA:
1630 * Custom client data to pass to the progress callback
1632 data->set.progress_client = va_arg(param, void *);
1635 #ifndef CURL_DISABLE_PROXY
1636 case CURLOPT_PROXYUSERPWD:
1638 * user:password needed to use the proxy
1640 result = setstropt_userpwd(va_arg(param, char *),
1641 &data->set.str[STRING_PROXYUSERNAME],
1642 &data->set.str[STRING_PROXYPASSWORD], NULL);
1644 case CURLOPT_PROXYUSERNAME:
1646 * authentication user name to use in the operation
1648 result = setstropt(&data->set.str[STRING_PROXYUSERNAME],
1649 va_arg(param, char *));
1651 case CURLOPT_PROXYPASSWORD:
1653 * authentication password to use in the operation
1655 result = setstropt(&data->set.str[STRING_PROXYPASSWORD],
1656 va_arg(param, char *));
1658 case CURLOPT_NOPROXY:
1660 * proxy exception list
1662 result = setstropt(&data->set.str[STRING_NOPROXY],
1663 va_arg(param, char *));
1669 * What range of the file you want to transfer
1671 result = setstropt(&data->set.str[STRING_SET_RANGE],
1672 va_arg(param, char *));
1674 case CURLOPT_RESUME_FROM:
1676 * Resume transfer at the give file position
1678 data->set.set_resume_from = va_arg(param, long);
1680 case CURLOPT_RESUME_FROM_LARGE:
1682 * Resume transfer at the give file position
1684 data->set.set_resume_from = va_arg(param, curl_off_t);
1686 case CURLOPT_DEBUGFUNCTION:
1688 * stderr write callback.
1690 data->set.fdebug = va_arg(param, curl_debug_callback);
1692 * if the callback provided is NULL, it'll use the default callback
1695 case CURLOPT_DEBUGDATA:
1697 * Set to a void * that should receive all error writes. This
1698 * defaults to CURLOPT_STDERR for normal operations.
1700 data->set.debugdata = va_arg(param, void *);
1702 case CURLOPT_STDERR:
1704 * Set to a FILE * that should receive all error writes. This
1705 * defaults to stderr for normal operations.
1707 data->set.err = va_arg(param, FILE *);
1709 data->set.err = stderr;
1711 case CURLOPT_HEADERFUNCTION:
1713 * Set header write callback
1715 data->set.fwrite_header = va_arg(param, curl_write_callback);
1717 case CURLOPT_WRITEFUNCTION:
1719 * Set data write callback
1721 data->set.fwrite_func = va_arg(param, curl_write_callback);
1722 if(!data->set.fwrite_func) {
1723 data->set.is_fwrite_set = 0;
1724 /* When set to NULL, reset to our internal default function */
1725 data->set.fwrite_func = (curl_write_callback)fwrite;
1728 data->set.is_fwrite_set = 1;
1730 case CURLOPT_READFUNCTION:
1732 * Read data callback
1734 data->set.fread_func = va_arg(param, curl_read_callback);
1735 if(!data->set.fread_func) {
1736 data->set.is_fread_set = 0;
1737 /* When set to NULL, reset to our internal default function */
1738 data->set.fread_func = (curl_read_callback)fread;
1741 data->set.is_fread_set = 1;
1743 case CURLOPT_SEEKFUNCTION:
1745 * Seek callback. Might be NULL.
1747 data->set.seek_func = va_arg(param, curl_seek_callback);
1749 case CURLOPT_SEEKDATA:
1751 * Seek control callback. Might be NULL.
1753 data->set.seek_client = va_arg(param, void *);
1755 case CURLOPT_CONV_FROM_NETWORK_FUNCTION:
1757 * "Convert from network encoding" callback
1759 data->set.convfromnetwork = va_arg(param, curl_conv_callback);
1761 case CURLOPT_CONV_TO_NETWORK_FUNCTION:
1763 * "Convert to network encoding" callback
1765 data->set.convtonetwork = va_arg(param, curl_conv_callback);
1767 case CURLOPT_CONV_FROM_UTF8_FUNCTION:
1769 * "Convert from UTF-8 encoding" callback
1771 data->set.convfromutf8 = va_arg(param, curl_conv_callback);
1773 case CURLOPT_IOCTLFUNCTION:
1775 * I/O control callback. Might be NULL.
1777 data->set.ioctl_func = va_arg(param, curl_ioctl_callback);
1779 case CURLOPT_IOCTLDATA:
1781 * I/O control data pointer. Might be NULL.
1783 data->set.ioctl_client = va_arg(param, void *);
1785 case CURLOPT_SSLCERT:
1787 * String that holds file name of the SSL certificate to use
1789 result = setstropt(&data->set.str[STRING_CERT],
1790 va_arg(param, char *));
1792 case CURLOPT_SSLCERTTYPE:
1794 * String that holds file type of the SSL certificate to use
1796 result = setstropt(&data->set.str[STRING_CERT_TYPE],
1797 va_arg(param, char *));
1799 case CURLOPT_SSLKEY:
1801 * String that holds file name of the SSL key to use
1803 result = setstropt(&data->set.str[STRING_KEY],
1804 va_arg(param, char *));
1806 case CURLOPT_SSLKEYTYPE:
1808 * String that holds file type of the SSL key to use
1810 result = setstropt(&data->set.str[STRING_KEY_TYPE],
1811 va_arg(param, char *));
1813 case CURLOPT_KEYPASSWD:
1815 * String that holds the SSL or SSH private key password.
1817 result = setstropt(&data->set.str[STRING_KEY_PASSWD],
1818 va_arg(param, char *));
1820 case CURLOPT_SSLENGINE:
1822 * String that holds the SSL crypto engine.
1824 argptr = va_arg(param, char *);
1825 if(argptr && argptr[0])
1826 result = Curl_ssl_set_engine(data, argptr);
1829 case CURLOPT_SSLENGINE_DEFAULT:
1831 * flag to set engine as default.
1833 result = Curl_ssl_set_engine_default(data);
1837 * Kludgy option to enable CRLF conversions. Subject for removal.
1839 data->set.crlf = (0 != va_arg(param, long))?TRUE:FALSE;
1842 case CURLOPT_INTERFACE:
1844 * Set what interface or address/hostname to bind the socket to when
1845 * performing an operation and thus what from-IP your connection will use.
1847 result = setstropt(&data->set.str[STRING_DEVICE],
1848 va_arg(param, char *));
1850 case CURLOPT_LOCALPORT:
1852 * Set what local port to bind the socket to when performing an operation.
1854 data->set.localport = curlx_sltous(va_arg(param, long));
1856 case CURLOPT_LOCALPORTRANGE:
1858 * Set number of local ports to try, starting with CURLOPT_LOCALPORT.
1860 data->set.localportrange = curlx_sltosi(va_arg(param, long));
1862 case CURLOPT_KRBLEVEL:
1864 * A string that defines the kerberos security level.
1866 result = setstropt(&data->set.str[STRING_KRB_LEVEL],
1867 va_arg(param, char *));
1868 data->set.krb = (NULL != data->set.str[STRING_KRB_LEVEL])?TRUE:FALSE;
1870 case CURLOPT_GSSAPI_DELEGATION:
1872 * GSSAPI credential delegation
1874 data->set.gssapi_delegation = va_arg(param, long);
1876 case CURLOPT_SSL_VERIFYPEER:
1878 * Enable peer SSL verifying.
1880 data->set.ssl.verifypeer = (0 != va_arg(param, long))?TRUE:FALSE;
1882 case CURLOPT_SSL_VERIFYHOST:
1884 * Enable verification of the host name in the peer certificate
1886 arg = va_arg(param, long);
1888 /* Obviously people are not reading documentation and too many thought
1889 this argument took a boolean when it wasn't and misused it. We thus ban
1890 1 as a sensible input and we warn about its use. Then we only have the
1891 2 action internally stored as TRUE. */
1894 failf(data, "CURLOPT_SSL_VERIFYHOST no longer supports 1 as value!");
1895 return CURLE_BAD_FUNCTION_ARGUMENT;
1898 data->set.ssl.verifyhost = (0 != arg)?TRUE:FALSE;
1901 /* since these two options are only possible to use on an OpenSSL-
1902 powered libcurl we #ifdef them on this condition so that libcurls
1903 built against other SSL libs will return a proper error when trying
1904 to set this option! */
1905 case CURLOPT_SSL_CTX_FUNCTION:
1907 * Set a SSL_CTX callback
1909 data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback);
1911 case CURLOPT_SSL_CTX_DATA:
1913 * Set a SSL_CTX callback parameter pointer
1915 data->set.ssl.fsslctxp = va_arg(param, void *);
1918 #if defined(USE_SSLEAY) || defined(USE_QSOSSL) || defined(USE_GSKIT)
1919 case CURLOPT_CERTINFO:
1920 data->set.ssl.certinfo = (0 != va_arg(param, long))?TRUE:FALSE;
1923 case CURLOPT_CAINFO:
1925 * Set CA info for SSL connection. Specify file name of the CA certificate
1927 result = setstropt(&data->set.str[STRING_SSL_CAFILE],
1928 va_arg(param, char *));
1930 case CURLOPT_CAPATH:
1932 * Set CA path info for SSL connection. Specify directory name of the CA
1933 * certificates which have been prepared using openssl c_rehash utility.
1935 /* This does not work on windows. */
1936 result = setstropt(&data->set.str[STRING_SSL_CAPATH],
1937 va_arg(param, char *));
1939 case CURLOPT_CRLFILE:
1941 * Set CRL file info for SSL connection. Specify file name of the CRL
1942 * to check certificates revocation
1944 result = setstropt(&data->set.str[STRING_SSL_CRLFILE],
1945 va_arg(param, char *));
1947 case CURLOPT_ISSUERCERT:
1949 * Set Issuer certificate file
1950 * to check certificates issuer
1952 result = setstropt(&data->set.str[STRING_SSL_ISSUERCERT],
1953 va_arg(param, char *));
1955 case CURLOPT_TELNETOPTIONS:
1957 * Set a linked list of telnet options
1959 data->set.telnet_options = va_arg(param, struct curl_slist *);
1962 case CURLOPT_BUFFERSIZE:
1964 * The application kindly asks for a differently sized receive buffer.
1965 * If it seems reasonable, we'll use it.
1967 data->set.buffer_size = va_arg(param, long);
1969 if((data->set.buffer_size> (BUFSIZE -1 )) ||
1970 (data->set.buffer_size < 1))
1971 data->set.buffer_size = 0; /* huge internal default */
1975 case CURLOPT_NOSIGNAL:
1977 * The application asks not to set any signal() or alarm() handlers,
1978 * even when using a timeout.
1980 data->set.no_signal = (0 != va_arg(param, long))?TRUE:FALSE;
1985 struct Curl_share *set;
1986 set = va_arg(param, struct Curl_share *);
1988 /* disconnect from old share, if any */
1990 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
1992 if(data->dns.hostcachetype == HCACHE_SHARED) {
1993 data->dns.hostcache = NULL;
1994 data->dns.hostcachetype = HCACHE_NONE;
1997 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
1998 if(data->share->cookies == data->cookies)
1999 data->cookies = NULL;
2002 if(data->share->sslsession == data->state.session)
2003 data->state.session = NULL;
2005 data->share->dirty--;
2007 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
2011 /* use new share if it set */
2015 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
2017 data->share->dirty++;
2019 if(data->share->hostcache) {
2020 /* use shared host cache */
2021 data->dns.hostcache = data->share->hostcache;
2022 data->dns.hostcachetype = HCACHE_SHARED;
2024 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
2025 if(data->share->cookies) {
2026 /* use shared cookie list, first free own one if any */
2028 Curl_cookie_cleanup(data->cookies);
2029 /* enable cookies since we now use a share that uses cookies! */
2030 data->cookies = data->share->cookies;
2032 #endif /* CURL_DISABLE_HTTP */
2033 if(data->share->sslsession) {
2034 data->set.ssl.max_ssl_sessions = data->share->max_ssl_sessions;
2035 data->state.session = data->share->sslsession;
2037 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
2040 /* check for host cache not needed,
2041 * it will be done by curl_easy_perform */
2045 case CURLOPT_PRIVATE:
2047 * Set private data pointer.
2049 data->set.private_data = va_arg(param, void *);
2052 case CURLOPT_MAXFILESIZE:
2054 * Set the maximum size of a file to download.
2056 data->set.max_filesize = va_arg(param, long);
2060 case CURLOPT_USE_SSL:
2062 * Make transfers attempt to use SSL/TLS.
2064 data->set.use_ssl = (curl_usessl)va_arg(param, long);
2067 case CURLOPT_SSL_OPTIONS:
2068 arg = va_arg(param, long);
2069 data->set.ssl_enable_beast = arg&CURLSSLOPT_ALLOW_BEAST?TRUE:FALSE;
2073 case CURLOPT_FTPSSLAUTH:
2075 * Set a specific auth for FTP-SSL transfers.
2077 data->set.ftpsslauth = (curl_ftpauth)va_arg(param, long);
2080 case CURLOPT_IPRESOLVE:
2081 data->set.ipver = va_arg(param, long);
2084 case CURLOPT_MAXFILESIZE_LARGE:
2086 * Set the maximum size of a file to download.
2088 data->set.max_filesize = va_arg(param, curl_off_t);
2091 case CURLOPT_TCP_NODELAY:
2093 * Enable or disable TCP_NODELAY, which will disable/enable the Nagle
2096 data->set.tcp_nodelay = (0 != va_arg(param, long))?TRUE:FALSE;
2099 case CURLOPT_FTP_ACCOUNT:
2100 result = setstropt(&data->set.str[STRING_FTP_ACCOUNT],
2101 va_arg(param, char *));
2104 case CURLOPT_IGNORE_CONTENT_LENGTH:
2105 data->set.ignorecl = (0 != va_arg(param, long))?TRUE:FALSE;
2108 case CURLOPT_CONNECT_ONLY:
2110 * No data transfer, set up connection and let application use the socket
2112 data->set.connect_only = (0 != va_arg(param, long))?TRUE:FALSE;
2115 case CURLOPT_FTP_ALTERNATIVE_TO_USER:
2116 result = setstropt(&data->set.str[STRING_FTP_ALTERNATIVE_TO_USER],
2117 va_arg(param, char *));
2120 case CURLOPT_SOCKOPTFUNCTION:
2122 * socket callback function: called after socket() but before connect()
2124 data->set.fsockopt = va_arg(param, curl_sockopt_callback);
2127 case CURLOPT_SOCKOPTDATA:
2129 * socket callback data pointer. Might be NULL.
2131 data->set.sockopt_client = va_arg(param, void *);
2134 case CURLOPT_OPENSOCKETFUNCTION:
2136 * open/create socket callback function: called instead of socket(),
2139 data->set.fopensocket = va_arg(param, curl_opensocket_callback);
2142 case CURLOPT_OPENSOCKETDATA:
2144 * socket callback data pointer. Might be NULL.
2146 data->set.opensocket_client = va_arg(param, void *);
2149 case CURLOPT_CLOSESOCKETFUNCTION:
2151 * close socket callback function: called instead of close()
2152 * when shutting down a connection
2154 data->set.fclosesocket = va_arg(param, curl_closesocket_callback);
2157 case CURLOPT_CLOSESOCKETDATA:
2159 * socket callback data pointer. Might be NULL.
2161 data->set.closesocket_client = va_arg(param, void *);
2164 case CURLOPT_SSL_SESSIONID_CACHE:
2165 data->set.ssl.sessionid = (0 != va_arg(param, long))?TRUE:FALSE;
2169 /* we only include SSH options if explicitly built to support SSH */
2170 case CURLOPT_SSH_AUTH_TYPES:
2171 data->set.ssh_auth_types = va_arg(param, long);
2174 case CURLOPT_SSH_PUBLIC_KEYFILE:
2176 * Use this file instead of the $HOME/.ssh/id_dsa.pub file
2178 result = setstropt(&data->set.str[STRING_SSH_PUBLIC_KEY],
2179 va_arg(param, char *));
2182 case CURLOPT_SSH_PRIVATE_KEYFILE:
2184 * Use this file instead of the $HOME/.ssh/id_dsa file
2186 result = setstropt(&data->set.str[STRING_SSH_PRIVATE_KEY],
2187 va_arg(param, char *));
2189 case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5:
2191 * Option to allow for the MD5 of the host public key to be checked
2192 * for validation purposes.
2194 result = setstropt(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5],
2195 va_arg(param, char *));
2197 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2198 case CURLOPT_SSH_KNOWNHOSTS:
2200 * Store the file name to read known hosts from.
2202 result = setstropt(&data->set.str[STRING_SSH_KNOWNHOSTS],
2203 va_arg(param, char *));
2206 case CURLOPT_SSH_KEYFUNCTION:
2207 /* setting to NULL is fine since the ssh.c functions themselves will
2208 then rever to use the internal default */
2209 data->set.ssh_keyfunc = va_arg(param, curl_sshkeycallback);
2212 case CURLOPT_SSH_KEYDATA:
2214 * Custom client data to pass to the SSH keyfunc callback
2216 data->set.ssh_keyfunc_userp = va_arg(param, void *);
2218 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2220 #endif /* USE_LIBSSH2 */
2222 case CURLOPT_HTTP_TRANSFER_DECODING:
2224 * disable libcurl transfer encoding is used
2226 data->set.http_te_skip = (0 == va_arg(param, long))?TRUE:FALSE;
2229 case CURLOPT_HTTP_CONTENT_DECODING:
2231 * raw data passed to the application when content encoding is used
2233 data->set.http_ce_skip = (0 == va_arg(param, long))?TRUE:FALSE;
2236 case CURLOPT_NEW_FILE_PERMS:
2238 * Uses these permissions instead of 0644
2240 data->set.new_file_perms = va_arg(param, long);
2243 case CURLOPT_NEW_DIRECTORY_PERMS:
2245 * Uses these permissions instead of 0755
2247 data->set.new_directory_perms = va_arg(param, long);
2250 case CURLOPT_ADDRESS_SCOPE:
2252 * We always get longs when passed plain numericals, but for this value we
2253 * know that an unsigned int will always hold the value so we blindly
2254 * typecast to this type
2256 data->set.scope = curlx_sltoui(va_arg(param, long));
2259 case CURLOPT_PROTOCOLS:
2260 /* set the bitmask for the protocols that are allowed to be used for the
2261 transfer, which thus helps the app which takes URLs from users or other
2262 external inputs and want to restrict what protocol(s) to deal
2263 with. Defaults to CURLPROTO_ALL. */
2264 data->set.allowed_protocols = va_arg(param, long);
2267 case CURLOPT_REDIR_PROTOCOLS:
2268 /* set the bitmask for the protocols that libcurl is allowed to follow to,
2269 as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
2270 to be set in both bitmasks to be allowed to get redirected to. Defaults
2271 to all protocols except FILE and SCP. */
2272 data->set.redir_protocols = va_arg(param, long);
2275 case CURLOPT_MAIL_FROM:
2276 /* Set the SMTP mail originator */
2277 result = setstropt(&data->set.str[STRING_MAIL_FROM],
2278 va_arg(param, char *));
2281 case CURLOPT_MAIL_AUTH:
2282 /* Set the SMTP auth originator */
2283 result = setstropt(&data->set.str[STRING_MAIL_AUTH],
2284 va_arg(param, char *));
2287 case CURLOPT_MAIL_RCPT:
2288 /* Set the list of mail recipients */
2289 data->set.mail_rcpt = va_arg(param, struct curl_slist *);
2292 case CURLOPT_SASL_IR:
2293 /* Enable/disable SASL initial response */
2294 data->set.sasl_ir = (0 != va_arg(param, long)) ? TRUE : FALSE;
2297 case CURLOPT_RTSP_REQUEST:
2300 * Set the RTSP request method (OPTIONS, SETUP, PLAY, etc...)
2301 * Would this be better if the RTSPREQ_* were just moved into here?
2303 long curl_rtspreq = va_arg(param, long);
2304 Curl_RtspReq rtspreq = RTSPREQ_NONE;
2305 switch(curl_rtspreq) {
2306 case CURL_RTSPREQ_OPTIONS:
2307 rtspreq = RTSPREQ_OPTIONS;
2310 case CURL_RTSPREQ_DESCRIBE:
2311 rtspreq = RTSPREQ_DESCRIBE;
2314 case CURL_RTSPREQ_ANNOUNCE:
2315 rtspreq = RTSPREQ_ANNOUNCE;
2318 case CURL_RTSPREQ_SETUP:
2319 rtspreq = RTSPREQ_SETUP;
2322 case CURL_RTSPREQ_PLAY:
2323 rtspreq = RTSPREQ_PLAY;
2326 case CURL_RTSPREQ_PAUSE:
2327 rtspreq = RTSPREQ_PAUSE;
2330 case CURL_RTSPREQ_TEARDOWN:
2331 rtspreq = RTSPREQ_TEARDOWN;
2334 case CURL_RTSPREQ_GET_PARAMETER:
2335 rtspreq = RTSPREQ_GET_PARAMETER;
2338 case CURL_RTSPREQ_SET_PARAMETER:
2339 rtspreq = RTSPREQ_SET_PARAMETER;
2342 case CURL_RTSPREQ_RECORD:
2343 rtspreq = RTSPREQ_RECORD;
2346 case CURL_RTSPREQ_RECEIVE:
2347 rtspreq = RTSPREQ_RECEIVE;
2350 rtspreq = RTSPREQ_NONE;
2353 data->set.rtspreq = rtspreq;
2358 case CURLOPT_RTSP_SESSION_ID:
2360 * Set the RTSP Session ID manually. Useful if the application is
2361 * resuming a previously established RTSP session
2363 result = setstropt(&data->set.str[STRING_RTSP_SESSION_ID],
2364 va_arg(param, char *));
2367 case CURLOPT_RTSP_STREAM_URI:
2369 * Set the Stream URI for the RTSP request. Unless the request is
2370 * for generic server options, the application will need to set this.
2372 result = setstropt(&data->set.str[STRING_RTSP_STREAM_URI],
2373 va_arg(param, char *));
2376 case CURLOPT_RTSP_TRANSPORT:
2378 * The content of the Transport: header for the RTSP request
2380 result = setstropt(&data->set.str[STRING_RTSP_TRANSPORT],
2381 va_arg(param, char *));
2384 case CURLOPT_RTSP_CLIENT_CSEQ:
2386 * Set the CSEQ number to issue for the next RTSP request. Useful if the
2387 * application is resuming a previously broken connection. The CSEQ
2388 * will increment from this new number henceforth.
2390 data->state.rtsp_next_client_CSeq = va_arg(param, long);
2393 case CURLOPT_RTSP_SERVER_CSEQ:
2394 /* Same as the above, but for server-initiated requests */
2395 data->state.rtsp_next_client_CSeq = va_arg(param, long);
2398 case CURLOPT_INTERLEAVEDATA:
2399 data->set.rtp_out = va_arg(param, void *);
2401 case CURLOPT_INTERLEAVEFUNCTION:
2402 /* Set the user defined RTP write function */
2403 data->set.fwrite_rtp = va_arg(param, curl_write_callback);
2406 case CURLOPT_WILDCARDMATCH:
2407 data->set.wildcardmatch = (0 != va_arg(param, long))?TRUE:FALSE;
2409 case CURLOPT_CHUNK_BGN_FUNCTION:
2410 data->set.chunk_bgn = va_arg(param, curl_chunk_bgn_callback);
2412 case CURLOPT_CHUNK_END_FUNCTION:
2413 data->set.chunk_end = va_arg(param, curl_chunk_end_callback);
2415 case CURLOPT_FNMATCH_FUNCTION:
2416 data->set.fnmatch = va_arg(param, curl_fnmatch_callback);
2418 case CURLOPT_CHUNK_DATA:
2419 data->wildcard.customptr = va_arg(param, void *);
2421 case CURLOPT_FNMATCH_DATA:
2422 data->set.fnmatch_data = va_arg(param, void *);
2425 case CURLOPT_TLSAUTH_USERNAME:
2426 result = setstropt(&data->set.str[STRING_TLSAUTH_USERNAME],
2427 va_arg(param, char *));
2428 if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype)
2429 data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
2431 case CURLOPT_TLSAUTH_PASSWORD:
2432 result = setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD],
2433 va_arg(param, char *));
2434 if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype)
2435 data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
2437 case CURLOPT_TLSAUTH_TYPE:
2438 if(strnequal((char *)va_arg(param, char *), "SRP", strlen("SRP")))
2439 data->set.ssl.authtype = CURL_TLSAUTH_SRP;
2441 data->set.ssl.authtype = CURL_TLSAUTH_NONE;
2444 case CURLOPT_DNS_SERVERS:
2445 result = Curl_set_dns_servers(data, va_arg(param, char *));
2448 case CURLOPT_TCP_KEEPALIVE:
2449 data->set.tcp_keepalive = (0 != va_arg(param, long))?TRUE:FALSE;
2451 case CURLOPT_TCP_KEEPIDLE:
2452 data->set.tcp_keepidle = va_arg(param, long);
2454 case CURLOPT_TCP_KEEPINTVL:
2455 data->set.tcp_keepintvl = va_arg(param, long);
2459 /* unknown tag and its companion, just ignore: */
2460 result = CURLE_UNKNOWN_OPTION;
2467 static void conn_free(struct connectdata *conn)
2472 /* possible left-overs from the async name resolvers */
2473 Curl_resolver_cancel(conn);
2475 /* close the SSL stuff before we close any sockets since they will/may
2476 write to the sockets */
2477 Curl_ssl_close(conn, FIRSTSOCKET);
2478 Curl_ssl_close(conn, SECONDARYSOCKET);
2480 /* close possibly still open sockets */
2481 if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
2482 Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
2483 if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET])
2484 Curl_closesocket(conn, conn->sock[FIRSTSOCKET]);
2486 #if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
2487 Curl_ntlm_wb_cleanup(conn);
2490 Curl_safefree(conn->user);
2491 Curl_safefree(conn->passwd);
2492 Curl_safefree(conn->options);
2493 Curl_safefree(conn->proxyuser);
2494 Curl_safefree(conn->proxypasswd);
2495 Curl_safefree(conn->allocptr.proxyuserpwd);
2496 Curl_safefree(conn->allocptr.uagent);
2497 Curl_safefree(conn->allocptr.userpwd);
2498 Curl_safefree(conn->allocptr.accept_encoding);
2499 Curl_safefree(conn->allocptr.te);
2500 Curl_safefree(conn->allocptr.rangeline);
2501 Curl_safefree(conn->allocptr.ref);
2502 Curl_safefree(conn->allocptr.host);
2503 Curl_safefree(conn->allocptr.cookiehost);
2504 Curl_safefree(conn->allocptr.rtsp_transport);
2505 Curl_safefree(conn->trailer);
2506 Curl_safefree(conn->host.rawalloc); /* host name buffer */
2507 Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */
2508 Curl_safefree(conn->master_buffer);
2510 Curl_llist_destroy(conn->send_pipe, NULL);
2511 Curl_llist_destroy(conn->recv_pipe, NULL);
2513 conn->send_pipe = NULL;
2514 conn->recv_pipe = NULL;
2516 Curl_safefree(conn->localdev);
2517 Curl_free_ssl_config(&conn->ssl_config);
2519 free(conn); /* free all the connection oriented data */
2522 CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
2524 struct SessionHandle *data;
2526 return CURLE_OK; /* this is closed and fine already */
2530 DEBUGF(fprintf(stderr, "DISCONNECT without easy handle, ignoring\n"));
2534 if(conn->dns_entry != NULL) {
2535 Curl_resolv_unlock(data, conn->dns_entry);
2536 conn->dns_entry = NULL;
2539 Curl_hostcache_prune(data); /* kill old DNS cache entries */
2542 int has_host_ntlm = (conn->ntlm.state != NTLMSTATE_NONE);
2543 int has_proxy_ntlm = (conn->proxyntlm.state != NTLMSTATE_NONE);
2545 /* Authentication data is a mix of connection-related and sessionhandle-
2546 related stuff. NTLM is connection-related so when we close the shop
2550 data->state.authhost.done = FALSE;
2551 data->state.authhost.picked =
2552 data->state.authhost.want;
2555 if(has_proxy_ntlm) {
2556 data->state.authproxy.done = FALSE;
2557 data->state.authproxy.picked =
2558 data->state.authproxy.want;
2561 if(has_host_ntlm || has_proxy_ntlm)
2562 data->state.authproblem = FALSE;
2565 /* Cleanup NTLM connection-related data */
2566 Curl_http_ntlm_cleanup(conn);
2568 /* Cleanup possible redirect junk */
2569 if(data->req.newurl) {
2570 free(data->req.newurl);
2571 data->req.newurl = NULL;
2574 if(conn->handler->disconnect)
2575 /* This is set if protocol-specific cleanups should be made */
2576 conn->handler->disconnect(conn, dead_connection);
2578 /* unlink ourselves! */
2579 infof(data, "Closing connection %ld\n", conn->connection_id);
2580 Curl_conncache_remove_conn(data->state.conn_cache, conn);
2582 #if defined(USE_LIBIDN)
2583 if(conn->host.encalloc)
2584 idn_free(conn->host.encalloc); /* encoded host name buffer, must be freed
2585 with idn_free() since this was allocated
2587 if(conn->proxy.encalloc)
2588 idn_free(conn->proxy.encalloc); /* encoded proxy name buffer, must be
2589 freed with idn_free() since this was
2590 allocated by libidn */
2591 #elif defined(USE_WIN32_IDN)
2592 free(conn->host.encalloc); /* encoded host name buffer, must be freed with
2593 idn_free() since this was allocated by
2594 curl_win32_idn_to_ascii */
2595 if(conn->proxy.encalloc)
2596 free(conn->proxy.encalloc); /* encoded proxy name buffer, must be freed
2597 with idn_free() since this was allocated by
2598 curl_win32_idn_to_ascii */
2601 Curl_ssl_close(conn, FIRSTSOCKET);
2603 /* Indicate to all handles on the pipe that we're dead */
2604 if(Curl_multi_pipeline_enabled(data->multi)) {
2605 signalPipeClose(conn->send_pipe, TRUE);
2606 signalPipeClose(conn->recv_pipe, TRUE);
2611 Curl_speedinit(data);
2617 * This function should return TRUE if the socket is to be assumed to
2618 * be dead. Most commonly this happens when the server has closed the
2619 * connection due to inactivity.
2621 static bool SocketIsDead(curl_socket_t sock)
2624 bool ret_val = TRUE;
2626 sval = Curl_socket_ready(sock, CURL_SOCKET_BAD, 0);
2634 static bool IsPipeliningPossible(const struct SessionHandle *handle,
2635 const struct connectdata *conn)
2637 if((conn->handler->protocol & CURLPROTO_HTTP) &&
2638 Curl_multi_pipeline_enabled(handle->multi) &&
2639 (handle->set.httpreq == HTTPREQ_GET ||
2640 handle->set.httpreq == HTTPREQ_HEAD) &&
2641 handle->set.httpversion != CURL_HTTP_VERSION_1_0)
2647 bool Curl_isPipeliningEnabled(const struct SessionHandle *handle)
2649 return Curl_multi_pipeline_enabled(handle->multi);
2652 CURLcode Curl_addHandleToPipeline(struct SessionHandle *data,
2653 struct curl_llist *pipeline)
2655 if(!Curl_llist_insert_next(pipeline, pipeline->tail, data))
2656 return CURLE_OUT_OF_MEMORY;
2657 infof(data, "Curl_addHandleToPipeline: length: %d\n", pipeline->size);
2661 int Curl_removeHandleFromPipeline(struct SessionHandle *handle,
2662 struct curl_llist *pipeline)
2664 struct curl_llist_element *curr;
2666 curr = pipeline->head;
2668 if(curr->ptr == handle) {
2669 Curl_llist_remove(pipeline, curr, NULL);
2670 return 1; /* we removed a handle */
2678 #if 0 /* this code is saved here as it is useful for debugging purposes */
2679 static void Curl_printPipeline(struct curl_llist *pipeline)
2681 struct curl_llist_element *curr;
2683 curr = pipeline->head;
2685 struct SessionHandle *data = (struct SessionHandle *) curr->ptr;
2686 infof(data, "Handle in pipeline: %s\n", data->state.path);
2692 static struct SessionHandle* gethandleathead(struct curl_llist *pipeline)
2694 struct curl_llist_element *curr = pipeline->head;
2696 return (struct SessionHandle *) curr->ptr;
2702 /* remove the specified connection from all (possible) pipelines and related
2704 void Curl_getoff_all_pipelines(struct SessionHandle *data,
2705 struct connectdata *conn)
2707 bool recv_head = (conn->readchannel_inuse &&
2708 (gethandleathead(conn->recv_pipe) == data)) ? TRUE : FALSE;
2710 bool send_head = (conn->writechannel_inuse &&
2711 (gethandleathead(conn->send_pipe) == data)) ? TRUE : FALSE;
2713 if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) && recv_head)
2714 conn->readchannel_inuse = FALSE;
2715 if(Curl_removeHandleFromPipeline(data, conn->send_pipe) && send_head)
2716 conn->writechannel_inuse = FALSE;
2719 static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke)
2721 struct curl_llist_element *curr;
2726 curr = pipeline->head;
2728 struct curl_llist_element *next = curr->next;
2729 struct SessionHandle *data = (struct SessionHandle *) curr->ptr;
2731 #ifdef DEBUGBUILD /* debug-only code */
2732 if(data->magic != CURLEASY_MAGIC_NUMBER) {
2734 infof(data, "signalPipeClose() found BAAD easy handle\n");
2739 data->state.pipe_broke = TRUE;
2740 Curl_multi_handlePipeBreak(data);
2741 Curl_llist_remove(pipeline, curr, NULL);
2747 * This function finds the connection in the connection
2748 * cache that has been unused for the longest time.
2750 * Returns the pointer to the oldest idle connection, or NULL if none was
2753 static struct connectdata *
2754 find_oldest_idle_connection(struct SessionHandle *data)
2756 struct conncache *bc = data->state.conn_cache;
2757 struct curl_hash_iterator iter;
2758 struct curl_llist_element *curr;
2759 struct curl_hash_element *he;
2763 struct connectdata *conn_candidate = NULL;
2764 struct connectbundle *bundle;
2768 Curl_hash_start_iterate(bc->hash, &iter);
2770 he = Curl_hash_next_element(&iter);
2772 struct connectdata *conn;
2776 curr = bundle->conn_list->head;
2781 /* Set higher score for the age passed since the connection was used */
2782 score = Curl_tvdiff(now, conn->now);
2784 if(score > highscore) {
2786 conn_candidate = conn;
2792 he = Curl_hash_next_element(&iter);
2795 return conn_candidate;
2799 * This function finds the connection in the connection
2800 * bundle that has been unused for the longest time.
2802 * Returns the pointer to the oldest idle connection, or NULL if none was
2805 static struct connectdata *
2806 find_oldest_idle_connection_in_bundle(struct SessionHandle *data,
2807 struct connectbundle *bundle)
2809 struct curl_llist_element *curr;
2813 struct connectdata *conn_candidate = NULL;
2814 struct connectdata *conn;
2820 curr = bundle->conn_list->head;
2825 /* Set higher score for the age passed since the connection was used */
2826 score = Curl_tvdiff(now, conn->now);
2828 if(score > highscore) {
2830 conn_candidate = conn;
2836 return conn_candidate;
2840 * Given one filled in connection struct (named needle), this function should
2841 * detect if there already is one that has all the significant details
2842 * exactly the same and thus should be used instead.
2844 * If there is a match, this function returns TRUE - and has marked the
2845 * connection as 'in-use'. It must later be called with ConnectionDone() to
2846 * return back to 'idle' (unused) state.
2848 * The force_reuse flag is set if the connection must be used, even if
2849 * the pipelining strategy wants to open a new connection instead of reusing.
2852 ConnectionExists(struct SessionHandle *data,
2853 struct connectdata *needle,
2854 struct connectdata **usethis,
2857 struct connectdata *check;
2858 struct connectdata *chosen = 0;
2859 bool canPipeline = IsPipeliningPossible(data, needle);
2860 bool wantNTLM = (data->state.authhost.want==CURLAUTH_NTLM) ||
2861 (data->state.authhost.want==CURLAUTH_NTLM_WB) ? TRUE : FALSE;
2862 struct connectbundle *bundle;
2864 *force_reuse = FALSE;
2866 /* We can't pipe if the site is blacklisted */
2867 if(canPipeline && Curl_pipeline_site_blacklisted(data, needle)) {
2868 canPipeline = FALSE;
2871 /* Look up the bundle with all the connections to this
2873 bundle = Curl_conncache_find_bundle(data->state.conn_cache,
2876 size_t max_pipe_len = Curl_multi_max_pipeline_length(data->multi);
2877 size_t best_pipe_len = max_pipe_len;
2878 struct curl_llist_element *curr;
2880 infof(data, "Found bundle for host %s: %p\n",
2881 needle->host.name, (void *)bundle);
2883 /* We can't pipe if we don't know anything about the server */
2884 if(canPipeline && !bundle->server_supports_pipelining) {
2885 infof(data, "Server doesn't support pipelining\n");
2886 canPipeline = FALSE;
2889 curr = bundle->conn_list->head;
2892 bool credentialsMatch = FALSE;
2896 * Note that if we use a HTTP proxy, we check connections to that
2897 * proxy and not to the actual remote server.
2902 pipeLen = check->send_pipe->size + check->recv_pipe->size;
2904 if(!pipeLen && !check->inuse) {
2905 /* The check for a dead socket makes sense only if there are no
2906 handles in pipeline and the connection isn't already marked in
2909 if(check->handler->protocol & CURLPROTO_RTSP)
2910 /* RTSP is a special case due to RTP interleaving */
2911 dead = Curl_rtsp_connisdead(check);
2913 dead = SocketIsDead(check->sock[FIRSTSOCKET]);
2917 infof(data, "Connection %ld seems to be dead!\n",
2918 check->connection_id);
2920 /* disconnect resources */
2921 Curl_disconnect(check, /* dead_connection */ TRUE);
2927 /* Make sure the pipe has only GET requests */
2928 struct SessionHandle* sh = gethandleathead(check->send_pipe);
2929 struct SessionHandle* rh = gethandleathead(check->recv_pipe);
2931 if(!IsPipeliningPossible(sh, check))
2935 if(!IsPipeliningPossible(rh, check))
2941 /* can only happen within multi handles, and means that another easy
2942 handle is using this connection */
2946 if(Curl_resolver_asynch()) {
2947 /* ip_addr_str[0] is NUL only if the resolving of the name hasn't
2948 completed yet and until then we don't re-use this connection */
2949 if(!check->ip_addr_str[0]) {
2951 "Connection #%ld is still name resolving, can't reuse\n",
2952 check->connection_id);
2957 if((check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) ||
2958 check->bits.close) {
2959 /* Don't pick a connection that hasn't connected yet or that is going
2961 infof(data, "Connection #%ld isn't open enough, can't reuse\n",
2962 check->connection_id);
2964 if(check->recv_pipe->size > 0) {
2966 "BAD! Unconnected #%ld has a non-empty recv pipeline!\n",
2967 check->connection_id);
2974 if((needle->handler->flags&PROTOPT_SSL) !=
2975 (check->handler->flags&PROTOPT_SSL))
2976 /* don't do mixed SSL and non-SSL connections */
2977 if(!(needle->handler->protocol & check->handler->protocol))
2978 /* except protocols that have been upgraded via TLS */
2981 if(needle->handler->flags&PROTOPT_SSL) {
2982 if((data->set.ssl.verifypeer != check->verifypeer) ||
2983 (data->set.ssl.verifyhost != check->verifyhost))
2987 if(needle->bits.proxy != check->bits.proxy)
2988 /* don't do mixed proxy and non-proxy connections */
2991 if(!canPipeline && check->inuse)
2992 /* this request can't be pipelined but the checked connection is
2993 already in use so we skip it */
2996 if(needle->localdev || needle->localport) {
2997 /* If we are bound to a specific local end (IP+port), we must not
2998 re-use a random other one, although if we didn't ask for a
2999 particular one we can reuse one that was bound.
3001 This comparison is a bit rough and too strict. Since the input
3002 parameters can be specified in numerous ways and still end up the
3003 same it would take a lot of processing to make it really accurate.
3004 Instead, this matching will assume that re-uses of bound connections
3005 will most likely also re-use the exact same binding parameters and
3006 missing out a few edge cases shouldn't hurt anyone very much.
3008 if((check->localport != needle->localport) ||
3009 (check->localportrange != needle->localportrange) ||
3011 !needle->localdev ||
3012 strcmp(check->localdev, needle->localdev))
3016 if((needle->handler->protocol & CURLPROTO_FTP) ||
3017 ((needle->handler->protocol & CURLPROTO_HTTP) && wantNTLM)) {
3018 /* This is FTP or HTTP+NTLM, verify that we're using the same name
3019 and password as well */
3020 if(!strequal(needle->user, check->user) ||
3021 !strequal(needle->passwd, check->passwd)) {
3022 /* one of them was different */
3025 credentialsMatch = TRUE;
3028 if(!needle->bits.httpproxy || needle->handler->flags&PROTOPT_SSL ||
3029 (needle->bits.httpproxy && check->bits.httpproxy &&
3030 needle->bits.tunnel_proxy && check->bits.tunnel_proxy &&
3031 Curl_raw_equal(needle->proxy.name, check->proxy.name) &&
3032 (needle->port == check->port))) {
3033 /* The requested connection does not use a HTTP proxy or it uses SSL or
3034 it is a non-SSL protocol tunneled over the same http proxy name and
3035 port number or it is a non-SSL protocol which is allowed to be
3038 if((Curl_raw_equal(needle->handler->scheme, check->handler->scheme) ||
3039 needle->handler->protocol & check->handler->protocol) &&
3040 Curl_raw_equal(needle->host.name, check->host.name) &&
3041 needle->remote_port == check->remote_port) {
3042 if(needle->handler->flags & PROTOPT_SSL) {
3043 /* This is a SSL connection so verify that we're using the same
3044 SSL options as well */
3045 if(!Curl_ssl_config_matches(&needle->ssl_config,
3046 &check->ssl_config)) {
3048 "Connection #%ld has different SSL parameters, "
3050 check->connection_id));
3053 else if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete) {
3055 "Connection #%ld has not started SSL connect, "
3057 check->connection_id));
3064 else { /* The requested needle connection is using a proxy,
3065 is the checked one using the same host, port and type? */
3066 if(check->bits.proxy &&
3067 (needle->proxytype == check->proxytype) &&
3068 (needle->bits.tunnel_proxy == check->bits.tunnel_proxy) &&
3069 Curl_raw_equal(needle->proxy.name, check->proxy.name) &&
3070 needle->port == check->port) {
3071 /* This is the same proxy connection, use it! */
3077 /* If we are looking for an NTLM connection, check if this is already
3078 authenticating with the right credentials. If not, keep looking so
3079 that we can reuse NTLM connections if possible. (Especially we
3080 must not reuse the same connection if partway through
3083 if(credentialsMatch && check->ntlm.state != NTLMSTATE_NONE) {
3086 /* We must use this connection, no other */
3087 *force_reuse = TRUE;
3095 /* We can pipeline if we want to. Let's continue looking for
3096 the optimal connection to use, i.e the shortest pipe that is not
3100 /* We have the optimal connection. Let's stop looking. */
3105 /* We can't use the connection if the pipe is full */
3106 if(pipeLen >= max_pipe_len)
3109 /* We can't use the connection if the pipe is penalized */
3110 if(Curl_pipeline_penalized(data, check))
3113 if(pipeLen < best_pipe_len) {
3114 /* This connection has a shorter pipe so far. We'll pick this
3115 and continue searching */
3117 best_pipe_len = pipeLen;
3122 /* We have found a connection. Let's stop searching. */
3132 return TRUE; /* yes, we found one to use! */
3135 return FALSE; /* no matching connecting exists */
3138 /* Mark the connection as 'idle', or close it if the cache is full.
3139 Returns TRUE if the connection is kept, or FALSE if it was closed. */
3141 ConnectionDone(struct SessionHandle *data, struct connectdata *conn)
3143 /* data->multi->maxconnects can be negative, deal with it. */
3144 size_t maxconnects =
3145 (data->multi->maxconnects < 0) ? 0 : data->multi->maxconnects;
3146 struct connectdata *conn_candidate = NULL;
3148 /* Mark the current connection as 'unused' */
3149 conn->inuse = FALSE;
3151 if(maxconnects > 0 &&
3152 data->state.conn_cache->num_connections > maxconnects) {
3153 infof(data, "Connection cache is full, closing the oldest one.\n");
3155 conn_candidate = find_oldest_idle_connection(data);
3157 if(conn_candidate) {
3158 /* Set the connection's owner correctly */
3159 conn_candidate->data = data;
3161 /* the winner gets the honour of being disconnected */
3162 (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
3166 return (conn_candidate == conn) ? FALSE : TRUE;
3170 * The given input connection struct pointer is to be stored in the connection
3171 * cache. If the cache is already full, least interesting existing connection
3172 * (if any) gets closed.
3174 * The given connection should be unique. That must've been checked prior to
3177 static CURLcode ConnectionStore(struct SessionHandle *data,
3178 struct connectdata *conn)
3180 static int connection_id_counter = 0;
3184 /* Assign a number to the connection for easier tracking in the log
3186 conn->connection_id = connection_id_counter++;
3188 result = Curl_conncache_add_conn(data->state.conn_cache, conn);
3189 if(result != CURLE_OK)
3190 conn->connection_id = -1;
3195 /* after a TCP connection to the proxy has been verified, this function does
3196 the next magic step.
3198 Note: this function's sub-functions call failf()
3201 CURLcode Curl_connected_proxy(struct connectdata *conn)
3203 if(!conn->bits.proxy)
3206 switch(conn->proxytype) {
3207 #ifndef CURL_DISABLE_PROXY
3208 case CURLPROXY_SOCKS5:
3209 case CURLPROXY_SOCKS5_HOSTNAME:
3210 return Curl_SOCKS5(conn->proxyuser, conn->proxypasswd,
3211 conn->host.name, conn->remote_port,
3214 case CURLPROXY_SOCKS4:
3215 return Curl_SOCKS4(conn->proxyuser, conn->host.name,
3216 conn->remote_port, FIRSTSOCKET, conn, FALSE);
3218 case CURLPROXY_SOCKS4A:
3219 return Curl_SOCKS4(conn->proxyuser, conn->host.name,
3220 conn->remote_port, FIRSTSOCKET, conn, TRUE);
3222 #endif /* CURL_DISABLE_PROXY */
3223 case CURLPROXY_HTTP:
3224 case CURLPROXY_HTTP_1_0:
3225 /* do nothing here. handled later. */
3229 } /* switch proxytype */
3234 static CURLcode ConnectPlease(struct SessionHandle *data,
3235 struct connectdata *conn,
3239 Curl_addrinfo *addr;
3240 #ifndef CURL_DISABLE_VERBOSE_STRINGS
3241 char *hostname = conn->bits.proxy?conn->proxy.name:conn->host.name;
3243 infof(data, "About to connect() to %s%s port %ld (#%ld)\n",
3244 conn->bits.proxy?"proxy ":"",
3245 hostname, conn->port, conn->connection_id);
3250 /*************************************************************
3251 * Connect to server/proxy
3252 *************************************************************/
3253 result= Curl_connecthost(conn,
3255 &conn->sock[FIRSTSOCKET],
3258 if(CURLE_OK == result) {
3259 /* All is cool, we store the current information */
3260 conn->ip_addr = addr;
3263 result = Curl_connected_proxy(conn);
3265 conn->bits.tcpconnect[FIRSTSOCKET] = TRUE;
3266 Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
3272 *connected = FALSE; /* mark it as not connected */
3278 * verboseconnect() displays verbose information after a connect
3280 #ifndef CURL_DISABLE_VERBOSE_STRINGS
3281 void Curl_verboseconnect(struct connectdata *conn)
3283 if(conn->data->set.verbose)
3284 infof(conn->data, "Connected to %s (%s) port %ld (#%ld)\n",
3285 conn->bits.proxy ? conn->proxy.dispname : conn->host.dispname,
3286 conn->ip_addr_str, conn->port, conn->connection_id);
3290 int Curl_protocol_getsock(struct connectdata *conn,
3291 curl_socket_t *socks,
3294 if(conn->handler->proto_getsock)
3295 return conn->handler->proto_getsock(conn, socks, numsocks);
3296 return GETSOCK_BLANK;
3299 int Curl_doing_getsock(struct connectdata *conn,
3300 curl_socket_t *socks,
3303 if(conn && conn->handler->doing_getsock)
3304 return conn->handler->doing_getsock(conn, socks, numsocks);
3305 return GETSOCK_BLANK;
3309 * We are doing protocol-specific connecting and this is being called over and
3310 * over from the multi interface until the connection phase is done on
3314 CURLcode Curl_protocol_connecting(struct connectdata *conn,
3317 CURLcode result=CURLE_OK;
3319 if(conn && conn->handler->connecting) {
3321 result = conn->handler->connecting(conn, done);
3330 * We are DOING this is being called over and over from the multi interface
3331 * until the DOING phase is done on protocol layer.
3334 CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done)
3336 CURLcode result=CURLE_OK;
3338 if(conn && conn->handler->doing) {
3340 result = conn->handler->doing(conn, done);
3349 * We have discovered that the TCP connection has been successful, we can now
3350 * proceed with some action.
3353 CURLcode Curl_protocol_connect(struct connectdata *conn,
3354 bool *protocol_done)
3356 CURLcode result=CURLE_OK;
3358 *protocol_done = FALSE;
3360 if(conn->bits.tcpconnect[FIRSTSOCKET] && conn->bits.protoconnstart) {
3361 /* We already are connected, get back. This may happen when the connect
3362 worked fine in the first call, like when we connect to a local server
3363 or proxy. Note that we don't know if the protocol is actually done.
3365 Unless this protocol doesn't have any protocol-connect callback, as
3366 then we know we're done. */
3367 if(!conn->handler->connecting)
3368 *protocol_done = TRUE;
3373 if(!conn->bits.protoconnstart) {
3375 result = Curl_proxy_connect(conn);
3379 if(conn->bits.tunnel_proxy && conn->bits.httpproxy &&
3380 (conn->tunnel_state[FIRSTSOCKET] != TUNNEL_COMPLETE))
3381 /* when using an HTTP tunnel proxy, await complete tunnel establishment
3382 before proceeding further. Return CURLE_OK so we'll be called again */
3385 if(conn->handler->connect_it) {
3386 /* is there a protocol-specific connect() procedure? */
3388 /* Call the protocol-specific connect function */
3389 result = conn->handler->connect_it(conn, protocol_done);
3392 *protocol_done = TRUE;
3394 /* it has started, possibly even completed but that knowledge isn't stored
3397 conn->bits.protoconnstart = TRUE;
3400 return result; /* pass back status */
3404 * Helpers for IDNA convertions.
3406 static bool is_ASCII_name(const char *hostname)
3408 const unsigned char *ch = (const unsigned char*)hostname;
3419 * Check if characters in hostname is allowed in Top Level Domain.
3421 static bool tld_check_name(struct SessionHandle *data,
3422 const char *ace_hostname)
3425 char *uc_name = NULL;
3427 #ifndef CURL_DISABLE_VERBOSE_STRINGS
3428 const char *tld_errmsg = "<no msg>";
3433 /* Convert (and downcase) ACE-name back into locale's character set */
3434 rc = idna_to_unicode_lzlz(ace_hostname, &uc_name, 0);
3435 if(rc != IDNA_SUCCESS)
3438 rc = tld_check_lz(uc_name, &err_pos, NULL);
3439 #ifndef CURL_DISABLE_VERBOSE_STRINGS
3440 #ifdef HAVE_TLD_STRERROR
3441 if(rc != TLD_SUCCESS)
3442 tld_errmsg = tld_strerror((Tld_rc)rc);
3444 if(rc == TLD_INVALID)
3445 infof(data, "WARNING: %s; pos %u = `%c'/0x%02X\n",
3446 tld_errmsg, err_pos, uc_name[err_pos],
3447 uc_name[err_pos] & 255);
3448 else if(rc != TLD_SUCCESS)
3449 infof(data, "WARNING: TLD check for %s failed; %s\n",
3450 uc_name, tld_errmsg);
3451 #endif /* CURL_DISABLE_VERBOSE_STRINGS */
3454 if(rc != TLD_SUCCESS)
3462 * Perform any necessary IDN conversion of hostname
3464 static void fix_hostname(struct SessionHandle *data,
3465 struct connectdata *conn, struct hostname *host)
3470 #elif defined(CURL_DISABLE_VERBOSE_STRINGS)
3474 /* set the name we use to display the host name */
3475 host->dispname = host->name;
3476 if(!is_ASCII_name(host->name)) {
3478 /*************************************************************
3479 * Check name for non-ASCII and convert hostname to ACE form.
3480 *************************************************************/
3481 if(stringprep_check_version(LIBIDN_REQUIRED_VERSION)) {
3482 char *ace_hostname = NULL;
3483 int rc = idna_to_ascii_lz(host->name, &ace_hostname, 0);
3484 infof (data, "Input domain encoded as `%s'\n",
3485 stringprep_locale_charset ());
3486 if(rc != IDNA_SUCCESS)
3487 infof(data, "Failed to convert %s to ACE; %s\n",
3488 host->name, Curl_idn_strerror(conn,rc));
3490 /* tld_check_name() displays a warning if the host name contains
3491 "illegal" characters for this TLD */
3492 (void)tld_check_name(data, ace_hostname);
3494 host->encalloc = ace_hostname;
3495 /* change the name pointer to point to the encoded hostname */
3496 host->name = host->encalloc;
3499 #elif defined(USE_WIN32_IDN)
3500 /*************************************************************
3501 * Check name for non-ASCII and convert hostname to ACE form.
3502 *************************************************************/
3503 char *ace_hostname = NULL;
3504 int rc = curl_win32_idn_to_ascii(host->name, &ace_hostname);
3506 infof(data, "Failed to convert %s to ACE;\n",
3509 host->encalloc = ace_hostname;
3510 /* change the name pointer to point to the encoded hostname */
3511 host->name = host->encalloc;
3514 infof(data, "IDN support not present, can't parse Unicode domains\n");
3519 static void llist_dtor(void *user, void *element)
3527 * Allocate and initialize a new connectdata object.
3529 static struct connectdata *allocate_conn(struct SessionHandle *data)
3531 struct connectdata *conn = calloc(1, sizeof(struct connectdata));
3535 conn->handler = &Curl_handler_dummy; /* Be sure we have a handler defined
3536 already from start to avoid NULL
3537 situations and checks */
3539 /* and we setup a few fields in case we end up actually using this struct */
3541 conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
3542 conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
3543 conn->connection_id = -1; /* no ID */
3544 conn->port = -1; /* unknown at this point */
3546 /* Default protocol-independent behavior doesn't support persistent
3547 connections, so we set this to force-close. Protocols that support
3548 this need to set this to FALSE in their "curl_do" functions. */
3549 conn->bits.close = TRUE;
3551 /* Store creation time to help future close decision making */
3552 conn->created = Curl_tvnow();
3554 conn->data = data; /* Setup the association between this connection
3555 and the SessionHandle */
3557 conn->proxytype = data->set.proxytype; /* type */
3559 #ifdef CURL_DISABLE_PROXY
3561 conn->bits.proxy = FALSE;
3562 conn->bits.httpproxy = FALSE;
3563 conn->bits.proxy_user_passwd = FALSE;
3564 conn->bits.tunnel_proxy = FALSE;
3566 #else /* CURL_DISABLE_PROXY */
3568 /* note that these two proxy bits are now just on what looks to be
3569 requested, they may be altered down the road */
3570 conn->bits.proxy = (data->set.str[STRING_PROXY] &&
3571 *data->set.str[STRING_PROXY])?TRUE:FALSE;
3572 conn->bits.httpproxy = (conn->bits.proxy &&
3573 (conn->proxytype == CURLPROXY_HTTP ||
3574 conn->proxytype == CURLPROXY_HTTP_1_0))?TRUE:FALSE;
3575 conn->bits.proxy_user_passwd =
3576 (NULL != data->set.str[STRING_PROXYUSERNAME])?TRUE:FALSE;
3577 conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy;
3579 #endif /* CURL_DISABLE_PROXY */
3581 conn->bits.user_passwd = (NULL != data->set.str[STRING_USERNAME])?TRUE:FALSE;
3582 conn->bits.ftp_use_epsv = data->set.ftp_use_epsv;
3583 conn->bits.ftp_use_eprt = data->set.ftp_use_eprt;
3585 conn->verifypeer = data->set.ssl.verifypeer;
3586 conn->verifyhost = data->set.ssl.verifyhost;
3588 conn->ip_version = data->set.ipver;
3590 #if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
3591 conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
3592 conn->ntlm_auth_hlpr_pid = 0;
3593 conn->challenge_header = NULL;
3594 conn->response_header = NULL;
3597 if(Curl_multi_pipeline_enabled(data->multi) &&
3598 !conn->master_buffer) {
3599 /* Allocate master_buffer to be used for pipelining */
3600 conn->master_buffer = calloc(BUFSIZE, sizeof (char));
3601 if(!conn->master_buffer)
3605 /* Initialize the pipeline lists */
3606 conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
3607 conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
3608 if(!conn->send_pipe || !conn->recv_pipe)
3611 #if defined(HAVE_KRB4) || defined(HAVE_GSSAPI)
3612 conn->data_prot = PROT_CLEAR;
3615 /* Store the local bind parameters that will be used for this connection */
3616 if(data->set.str[STRING_DEVICE]) {
3617 conn->localdev = strdup(data->set.str[STRING_DEVICE]);
3621 conn->localportrange = data->set.localportrange;
3622 conn->localport = data->set.localport;
3624 /* the close socket stuff needs to be copied to the connection struct as
3625 it may live on without (this specific) SessionHandle */
3626 conn->fclosesocket = data->set.fclosesocket;
3627 conn->closesocket_client = data->set.closesocket_client;
3632 Curl_llist_destroy(conn->send_pipe, NULL);
3633 Curl_llist_destroy(conn->recv_pipe, NULL);
3635 conn->send_pipe = NULL;
3636 conn->recv_pipe = NULL;
3638 Curl_safefree(conn->master_buffer);
3639 Curl_safefree(conn->localdev);
3640 Curl_safefree(conn);
3644 static CURLcode findprotocol(struct SessionHandle *data,
3645 struct connectdata *conn,
3646 const char *protostr)
3648 const struct Curl_handler * const *pp;
3649 const struct Curl_handler *p;
3651 /* Scan protocol handler table and match against 'protostr' to set a few
3652 variables based on the URL. Now that the handler may be changed later
3653 when the protocol specific setup function is called. */
3654 for(pp = protocols; (p = *pp) != NULL; pp++) {
3655 if(Curl_raw_equal(p->scheme, protostr)) {
3656 /* Protocol found in table. Check if allowed */
3657 if(!(data->set.allowed_protocols & p->protocol))
3661 /* it is allowed for "normal" request, now do an extra check if this is
3662 the result of a redirect */
3663 if(data->state.this_is_a_follow &&
3664 !(data->set.redir_protocols & p->protocol))
3668 /* Perform setup complement if some. */
3669 conn->handler = conn->given = p;
3671 /* 'port' and 'remote_port' are set in setup_connection_internals() */
3677 /* The protocol was not found in the table, but we don't have to assign it
3678 to anything since it is already assigned to a dummy-struct in the
3679 create_conn() function when the connectdata struct is allocated. */
3680 failf(data, "Protocol %s not supported or disabled in " LIBCURL_NAME,
3683 return CURLE_UNSUPPORTED_PROTOCOL;
3687 * Parse URL and fill in the relevant members of the connection struct.
3689 static CURLcode parseurlandfillconn(struct SessionHandle *data,
3690 struct connectdata *conn,
3692 char *user, char *passwd, char *options)
3696 char *path = data->state.path;
3702 bool rebuild_url = FALSE;
3704 *prot_missing = FALSE;
3706 /*************************************************************
3709 * We need to parse the url even when using the proxy, because we will need
3710 * the hostname and port in case we are trying to SSL connect through the
3711 * proxy -- and we don't know if we will need to use SSL until we parse the
3713 ************************************************************/
3714 if((2 == sscanf(data->change.url, "%15[^:]:%[^\n]",
3716 Curl_raw_equal(protobuf, "file")) {
3717 if(path[0] == '/' && path[1] == '/') {
3718 /* Allow omitted hostname (e.g. file:/<path>). This is not strictly
3719 * speaking a valid file: URL by RFC 1738, but treating file:/<path> as
3720 * file://localhost/<path> is similar to how other schemes treat missing
3721 * hostnames. See RFC 1808. */
3723 /* This cannot be done with strcpy() in a portable manner, since the
3724 memory areas overlap! */
3725 memmove(path, path + 2, strlen(path + 2)+1);
3728 * we deal with file://<host>/<path> differently since it supports no
3729 * hostname other than "localhost" and "127.0.0.1", which is unique among
3730 * the URL protocols specified in RFC 1738
3732 if(path[0] != '/') {
3733 /* the URL included a host name, we ignore host names in file:// URLs
3734 as the standards don't define what to do with them */
3735 char *ptr=strchr(path, '/');
3737 /* there was a slash present
3739 RFC1738 (section 3.1, page 5) says:
3741 The rest of the locator consists of data specific to the scheme,
3742 and is known as the "url-path". It supplies the details of how the
3743 specified resource can be accessed. Note that the "/" between the
3744 host (or port) and the url-path is NOT part of the url-path.
3746 As most agents use file://localhost/foo to get '/foo' although the
3747 slash preceding foo is a separator and not a slash for the path,
3748 a URL as file://localhost//foo must be valid as well, to refer to
3749 the same file with an absolute path.
3752 if(ptr[1] && ('/' == ptr[1]))
3753 /* if there was two slashes, we skip the first one as that is then
3754 used truly as a separator */
3757 /* This cannot be made with strcpy, as the memory chunks overlap! */
3758 memmove(path, ptr, strlen(ptr)+1);
3762 protop = "file"; /* protocol string */
3768 if(2 > sscanf(data->change.url,
3769 "%15[^\n:]://%[^\n/?]%[^\n]",
3771 conn->host.name, path)) {
3774 * The URL was badly formatted, let's try the browser-style _without_
3775 * protocol specified like 'http://'.
3777 rc = sscanf(data->change.url, "%[^\n/?]%[^\n]", conn->host.name, path);
3780 * We couldn't even get this format.
3781 * djgpp 2.04 has a sscanf() bug where 'conn->host.name' is
3782 * assigned, but the return value is EOF!
3784 #if defined(__DJGPP__) && (DJGPP_MINOR == 4)
3785 if(!(rc == -1 && *conn->host.name))
3788 failf(data, "<url> malformed");
3789 return CURLE_URL_MALFORMAT;
3794 * Since there was no protocol part specified, we guess what protocol it
3795 * is based on the first letters of the server name.
3798 /* Note: if you add a new protocol, please update the list in
3799 * lib/version.c too! */
3801 if(checkprefix("FTP.", conn->host.name))
3803 else if(checkprefix("DICT.", conn->host.name))
3805 else if(checkprefix("LDAP.", conn->host.name))
3807 else if(checkprefix("IMAP.", conn->host.name))
3809 else if(checkprefix("SMTP.", conn->host.name))
3811 else if(checkprefix("POP3.", conn->host.name))
3817 *prot_missing = TRUE; /* not given in URL */
3823 /* We search for '?' in the host name (but only on the right side of a
3824 * @-letter to allow ?-letters in username and password) to handle things
3825 * like http://example.com?param= (notice the missing '/').
3827 at = strchr(conn->host.name, '@');
3829 query = strchr(at+1, '?');
3831 query = strchr(conn->host.name, '?');
3834 /* We must insert a slash before the '?'-letter in the URL. If the URL had
3835 a slash after the '?', that is where the path currently begins and the
3836 '?string' is still part of the host name.
3838 We must move the trailing part from the host name and put it first in
3839 the path. And have it all prefixed with a slash.
3842 size_t hostlen = strlen(query);
3843 size_t pathlen = strlen(path);
3845 /* move the existing path plus the zero byte forward, to make room for
3846 the host-name part */
3847 memmove(path+hostlen+1, path, pathlen+1);
3849 /* now copy the trailing host part in front of the existing path */
3850 memcpy(path+1, query, hostlen);
3852 path[0]='/'; /* prepend the missing slash */
3855 *query=0; /* now cut off the hostname at the ? */
3858 /* if there's no path set, use a single slash */
3863 /* If the URL is malformatted (missing a '/' after hostname before path) we
3864 * insert a slash here. The only letter except '/' we accept to start a path
3867 if(path[0] == '?') {
3868 /* We need this function to deal with overlapping memory areas. We know
3869 that the memory area 'path' points to is 'urllen' bytes big and that
3870 is bigger than the path. Use +1 to move the zero byte too. */
3871 memmove(&path[1], path, strlen(path)+1);
3876 /* sanitise paths and remove ../ and ./ sequences according to RFC3986 */
3877 char *newp = Curl_dedotdotify(path);
3879 return CURLE_OUT_OF_MEMORY;
3881 if(strcmp(newp, path)) {
3883 free(data->state.pathbuffer);
3884 data->state.pathbuffer = newp;
3885 data->state.path = newp;
3893 * "rebuild_url" means that one or more URL components have been modified so
3894 * we need to generate an updated full version. We need the corrected URL
3895 * when communicating over HTTP proxy and we don't know at this point if
3896 * we're using a proxy or not.
3901 size_t plen = strlen(path); /* new path, should be 1 byte longer than
3903 size_t urllen = strlen(data->change.url); /* original URL length */
3905 size_t prefixlen = strlen(conn->host.name);
3908 prefixlen += strlen(protop) + strlen("://");
3910 reurl = malloc(urllen + 2); /* 2 for zerobyte + slash */
3912 return CURLE_OUT_OF_MEMORY;
3914 /* copy the prefix */
3915 memcpy(reurl, data->change.url, prefixlen);
3917 /* append the trailing piece + zerobyte */
3918 memcpy(&reurl[prefixlen], path, plen + 1);
3920 /* possible free the old one */
3921 if(data->change.url_alloc) {
3922 Curl_safefree(data->change.url);
3923 data->change.url_alloc = FALSE;
3926 infof(data, "Rebuilt URL to: %s\n", reurl);
3928 data->change.url = reurl;
3929 data->change.url_alloc = TRUE; /* free this later */
3933 * Parse the login details from the URL and strip them out of
3936 result = parse_url_login(data, conn, user, passwd, options);
3937 if(result != CURLE_OK)
3940 if(conn->host.name[0] == '[') {
3941 /* This looks like an IPv6 address literal. See if there is an address
3943 char *percent = strstr (conn->host.name, "%25");
3946 unsigned long scope = strtoul (percent + 3, &endp, 10);
3948 /* The address scope was well formed. Knock it out of the
3950 memmove(percent, endp, strlen(endp)+1);
3951 if(!data->state.this_is_a_follow)
3952 /* Don't honour a scope given in a Location: header */
3953 conn->scope = (unsigned int)scope;
3956 infof(data, "Invalid IPv6 address format\n");
3961 /* Override any scope that was set above. */
3962 conn->scope = data->set.scope;
3964 /* Remove the fragment part of the path. Per RFC 2396, this is always the
3965 last part of the URI. We are looking for the first '#' so that we deal
3966 gracefully with non conformant URI such as http://example.com#foo#bar. */
3967 fragment = strchr(path, '#');
3971 /* we know the path part ended with a fragment, so we know the full URL
3972 string does too and we need to cut it off from there so it isn't used
3974 fragment = strchr(data->change.url, '#');
3980 * So if the URL was A://B/C#D,
3982 * conn->host.name is B
3983 * data->state.path is /C
3986 return findprotocol(data, conn, protop);
3990 * If we're doing a resumed transfer, we need to setup our stuff
3993 static CURLcode setup_range(struct SessionHandle *data)
3995 struct UrlState *s = &data->state;
3996 s->resume_from = data->set.set_resume_from;
3997 if(s->resume_from || data->set.str[STRING_SET_RANGE]) {
3998 if(s->rangestringalloc)
4002 s->range = aprintf("%" FORMAT_OFF_TU "-", s->resume_from);
4004 s->range = strdup(data->set.str[STRING_SET_RANGE]);
4006 s->rangestringalloc = (s->range)?TRUE:FALSE;
4009 return CURLE_OUT_OF_MEMORY;
4011 /* tell ourselves to fetch this range */
4012 s->use_range = TRUE; /* enable range download */
4015 s->use_range = FALSE; /* disable range download */
4022 * setup_connection_internals() -
4024 * Setup connection internals specific to the requested protocol in the
4025 * SessionHandle. This is inited and setup before the connection is made but
4026 * is about the particular protocol that is to be used.
4028 * This MUST get called after proxy magic has been figured out.
4030 static CURLcode setup_connection_internals(struct connectdata *conn)
4032 const struct Curl_handler * p;
4035 /* in some case in the multi state-machine, we go back to the CONNECT state
4036 and then a second (or third or...) call to this function will be made
4037 without doing a DISCONNECT or DONE in between (since the connection is
4038 yet in place) and therefore this function needs to first make sure
4039 there's no lingering previous data allocated. */
4040 free_connection_internals(conn->data);
4042 conn->socktype = SOCK_STREAM; /* most of them are TCP streams */
4044 /* Perform setup complement if some. */
4047 if(p->setup_connection) {
4048 result = (*p->setup_connection)(conn);
4050 if(result != CURLE_OK)
4053 p = conn->handler; /* May have changed. */
4057 /* we check for -1 here since if proxy was detected already, this
4058 was very likely already set to the proxy port */
4059 conn->port = p->defport;
4061 /* only if remote_port was not already parsed off the URL we use the
4062 default port number */
4063 if(!conn->remote_port)
4064 conn->remote_port = (unsigned short)conn->given->defport;
4069 static void free_connection_internals(struct SessionHandle *data)
4071 Curl_safefree(data->state.proto.generic);
4075 #ifndef CURL_DISABLE_PROXY
4076 /****************************************************************
4077 * Checks if the host is in the noproxy list. returns true if it matches
4078 * and therefore the proxy should NOT be used.
4079 ****************************************************************/
4080 static bool check_noproxy(const char* name, const char* no_proxy)
4082 /* no_proxy=domain1.dom,host.domain2.dom
4083 * (a comma-separated list of hosts which should
4084 * not be proxied, or an asterisk to override
4085 * all proxy variables)
4089 const char* separator = ", ";
4090 size_t no_proxy_len;
4094 if(no_proxy && no_proxy[0]) {
4095 if(Curl_raw_equal("*", no_proxy)) {
4099 /* NO_PROXY was specified and it wasn't just an asterisk */
4101 no_proxy_len = strlen(no_proxy);
4102 endptr = strchr(name, ':');
4104 namelen = endptr - name;
4106 namelen = strlen(name);
4108 for(tok_start = 0; tok_start < no_proxy_len; tok_start = tok_end + 1) {
4109 while(tok_start < no_proxy_len &&
4110 strchr(separator, no_proxy[tok_start]) != NULL) {
4111 /* Look for the beginning of the token. */
4115 if(tok_start == no_proxy_len)
4116 break; /* It was all trailing separator chars, no more tokens. */
4118 for(tok_end = tok_start; tok_end < no_proxy_len &&
4119 strchr(separator, no_proxy[tok_end]) == NULL; ++tok_end)
4120 /* Look for the end of the token. */
4123 /* To match previous behaviour, where it was necessary to specify
4124 * ".local.com" to prevent matching "notlocal.com", we will leave
4127 if(no_proxy[tok_start] == '.')
4130 if((tok_end - tok_start) <= namelen) {
4131 /* Match the last part of the name to the domain we are checking. */
4132 const char *checkn = name + namelen - (tok_end - tok_start);
4133 if(Curl_raw_nequal(no_proxy + tok_start, checkn,
4134 tok_end - tok_start)) {
4135 if((tok_end - tok_start) == namelen || *(checkn - 1) == '.') {
4136 /* We either have an exact match, or the previous character is a .
4137 * so it is within the same domain, so no proxy for this host.
4142 } /* if((tok_end - tok_start) <= namelen) */
4143 } /* for(tok_start = 0; tok_start < no_proxy_len;
4144 tok_start = tok_end + 1) */
4145 } /* NO_PROXY was specified and it wasn't just an asterisk */
4150 /****************************************************************
4151 * Detect what (if any) proxy to use. Remember that this selects a host
4152 * name and is not limited to HTTP proxies only.
4153 * The returned pointer must be freed by the caller (unless NULL)
4154 ****************************************************************/
4155 static char *detect_proxy(struct connectdata *conn)
4159 #ifndef CURL_DISABLE_HTTP
4160 /* If proxy was not specified, we check for default proxy environment
4161 * variables, to enable i.e Lynx compliance:
4163 * http_proxy=http://some.server.dom:port/
4164 * https_proxy=http://some.server.dom:port/
4165 * ftp_proxy=http://some.server.dom:port/
4166 * no_proxy=domain1.dom,host.domain2.dom
4167 * (a comma-separated list of hosts which should
4168 * not be proxied, or an asterisk to override
4169 * all proxy variables)
4170 * all_proxy=http://some.server.dom:port/
4171 * (seems to exist for the CERN www lib. Probably
4172 * the first to check for.)
4174 * For compatibility, the all-uppercase versions of these variables are
4175 * checked if the lowercase versions don't exist.
4177 char *no_proxy=NULL;
4178 char proxy_env[128];
4180 no_proxy=curl_getenv("no_proxy");
4182 no_proxy=curl_getenv("NO_PROXY");
4184 if(!check_noproxy(conn->host.name, no_proxy)) {
4185 /* It was not listed as without proxy */
4186 const char *protop = conn->handler->scheme;
4187 char *envp = proxy_env;
4190 /* Now, build <protocol>_proxy and check for such a one to use */
4192 *envp++ = (char)tolower((int)*protop++);
4195 strcpy(envp, "_proxy");
4197 /* read the protocol proxy: */
4198 prox=curl_getenv(proxy_env);
4201 * We don't try the uppercase version of HTTP_PROXY because of
4204 * When curl is used in a webserver application
4205 * environment (cgi or php), this environment variable can
4206 * be controlled by the web server user by setting the
4207 * http header 'Proxy:' to some value.
4209 * This can cause 'internal' http/ftp requests to be
4210 * arbitrarily redirected by any external attacker.
4212 if(!prox && !Curl_raw_equal("http_proxy", proxy_env)) {
4213 /* There was no lowercase variable, try the uppercase version: */
4214 Curl_strntoupper(proxy_env, proxy_env, sizeof(proxy_env));
4215 prox=curl_getenv(proxy_env);
4218 if(prox && *prox) { /* don't count "" strings */
4219 proxy = prox; /* use this */
4222 proxy = curl_getenv("all_proxy"); /* default proxy to use */
4224 proxy=curl_getenv("ALL_PROXY");
4226 } /* if(!check_noproxy(conn->host.name, no_proxy)) - it wasn't specified
4231 #else /* !CURL_DISABLE_HTTP */
4234 #endif /* CURL_DISABLE_HTTP */
4240 * If this is supposed to use a proxy, we need to figure out the proxy
4241 * host name, so that we can re-use an existing connection
4242 * that may exist registered to the same proxy host.
4243 * proxy will be freed before this function returns.
4245 static CURLcode parse_proxy(struct SessionHandle *data,
4246 struct connectdata *conn, char *proxy)
4251 /* We use 'proxyptr' to point to the proxy name from now on... */
4256 /* We do the proxy host string parsing here. We want the host name and the
4257 * port name. Accept a protocol:// prefix
4260 /* Parse the protocol part if present */
4261 endofprot = strstr(proxy, "://");
4263 proxyptr = endofprot+3;
4264 if(checkprefix("socks5h", proxy))
4265 conn->proxytype = CURLPROXY_SOCKS5_HOSTNAME;
4266 else if(checkprefix("socks5", proxy))
4267 conn->proxytype = CURLPROXY_SOCKS5;
4268 else if(checkprefix("socks4a", proxy))
4269 conn->proxytype = CURLPROXY_SOCKS4A;
4270 else if(checkprefix("socks4", proxy) || checkprefix("socks", proxy))
4271 conn->proxytype = CURLPROXY_SOCKS4;
4272 /* Any other xxx:// : change to http proxy */
4275 proxyptr = proxy; /* No xxx:// head: It's a HTTP proxy */
4277 /* Is there a username and password given in this proxy url? */
4278 atsign = strchr(proxyptr, '@');
4280 CURLcode res = CURLE_OK;
4281 char *proxyuser = NULL;
4282 char *proxypasswd = NULL;
4284 res = parse_login_details(proxyptr, atsign - proxyptr,
4285 &proxyuser, &proxypasswd, NULL);
4287 /* found user and password, rip them out. note that we are
4288 unescaping them, as there is otherwise no way to have a
4289 username or password with reserved characters like ':' in
4291 Curl_safefree(conn->proxyuser);
4292 if(proxyuser && strlen(proxyuser) < MAX_CURL_USER_LENGTH)
4293 conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
4295 conn->proxyuser = strdup("");
4297 if(!conn->proxyuser)
4298 res = CURLE_OUT_OF_MEMORY;
4300 Curl_safefree(conn->proxypasswd);
4301 if(proxypasswd && strlen(proxypasswd) < MAX_CURL_PASSWORD_LENGTH)
4302 conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL);
4304 conn->proxypasswd = strdup("");
4306 if(!conn->proxypasswd)
4307 res = CURLE_OUT_OF_MEMORY;
4311 conn->bits.proxy_user_passwd = TRUE; /* enable it */
4312 atsign++; /* the right side of the @-letter */
4315 proxyptr = atsign; /* now use this instead */
4317 res = CURLE_OUT_OF_MEMORY;
4321 Curl_safefree(proxyuser);
4322 Curl_safefree(proxypasswd);
4328 /* start scanning for port number at this point */
4331 /* detect and extract RFC2732-style IPv6-addresses */
4332 if(*proxyptr == '[') {
4333 char *ptr = ++proxyptr; /* advance beyond the initial bracket */
4334 while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '%') ||
4338 /* yeps, it ended nicely with a bracket as well */
4341 infof(data, "Invalid IPv6 address format\n");
4343 /* Note that if this didn't end with a bracket, we still advanced the
4344 * proxyptr first, but I can't see anything wrong with that as no host
4345 * name nor a numeric can legally start with a bracket.
4349 /* Get port number off proxy.server.com:1080 */
4350 prox_portno = strchr(portptr, ':');
4352 *prox_portno = 0x0; /* cut off number from host name */
4354 /* now set the local port number */
4355 conn->port = strtol(prox_portno, NULL, 10);
4358 if(proxyptr[0]=='/')
4359 /* If the first character in the proxy string is a slash, fail
4360 immediately. The following code will otherwise clear the string which
4361 will lead to code running as if no proxy was set! */
4362 return CURLE_COULDNT_RESOLVE_PROXY;
4364 /* without a port number after the host name, some people seem to use
4365 a slash so we strip everything from the first slash */
4366 atsign = strchr(proxyptr, '/');
4368 *atsign = 0x0; /* cut off path part from host name */
4370 if(data->set.proxyport)
4371 /* None given in the proxy string, then get the default one if it is
4373 conn->port = data->set.proxyport;
4376 /* now, clone the cleaned proxy host name */
4377 conn->proxy.rawalloc = strdup(proxyptr);
4378 conn->proxy.name = conn->proxy.rawalloc;
4380 if(!conn->proxy.rawalloc)
4381 return CURLE_OUT_OF_MEMORY;
4387 * Extract the user and password from the authentication string
4389 static CURLcode parse_proxy_auth(struct SessionHandle *data,
4390 struct connectdata *conn)
4392 char proxyuser[MAX_CURL_USER_LENGTH]="";
4393 char proxypasswd[MAX_CURL_PASSWORD_LENGTH]="";
4395 if(data->set.str[STRING_PROXYUSERNAME] != NULL) {
4396 strncpy(proxyuser, data->set.str[STRING_PROXYUSERNAME],
4397 MAX_CURL_USER_LENGTH);
4398 proxyuser[MAX_CURL_USER_LENGTH-1] = '\0'; /*To be on safe side*/
4400 if(data->set.str[STRING_PROXYPASSWORD] != NULL) {
4401 strncpy(proxypasswd, data->set.str[STRING_PROXYPASSWORD],
4402 MAX_CURL_PASSWORD_LENGTH);
4403 proxypasswd[MAX_CURL_PASSWORD_LENGTH-1] = '\0'; /*To be on safe side*/
4406 conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
4407 if(!conn->proxyuser)
4408 return CURLE_OUT_OF_MEMORY;
4410 conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL);
4411 if(!conn->proxypasswd)
4412 return CURLE_OUT_OF_MEMORY;
4416 #endif /* CURL_DISABLE_PROXY */
4421 * Parse the login details (user name, password and options) from the URL and
4422 * strip them out of the host name
4424 * Inputs: data->set.use_netrc (CURLOPT_NETRC)
4427 * Outputs: (almost :- all currently undefined)
4428 * conn->bits.user_passwd - non-zero if non-default passwords exist
4429 * user - non-zero length if defined
4430 * passwd - non-zero length if defined
4431 * options - non-zero length if defined
4432 * conn->host.name - remove user name and password
4434 static CURLcode parse_url_login(struct SessionHandle *data,
4435 struct connectdata *conn,
4436 char *user, char *passwd, char *options)
4438 CURLcode result = CURLE_OK;
4440 char *passwdp = NULL;
4441 char *optionsp = NULL;
4443 /* At this point, we're hoping all the other special cases have
4444 * been taken care of, so conn->host.name is at most
4445 * [user[:password][;options]]@]hostname
4447 * We need somewhere to put the embedded details, so do that first.
4450 char *ptr = strchr(conn->host.name, '@');
4451 char *login = conn->host.name;
4453 user[0] = 0; /* to make everything well-defined */
4457 /* We will now try to extract the
4458 * possible login information in a string like:
4459 * ftp://user:password@ftp.my.site:8021/README */
4461 /* There's login information to the left of the @ */
4463 conn->host.name = ++ptr;
4465 /* So the hostname is sane. Only bother interpreting the
4466 * results if we could care. It could still be wasted
4467 * work because it might be overtaken by the programmatically
4468 * set user/passwd, but doing that first adds more cases here :-(
4471 if(data->set.use_netrc != CURL_NETRC_REQUIRED) {
4472 /* We could use the login information in the URL so extract it */
4473 result = parse_login_details(login, ptr - login - 1,
4474 &userp, &passwdp, &optionsp);
4479 /* We have a user in the URL */
4480 conn->bits.userpwd_in_url = TRUE;
4481 conn->bits.user_passwd = TRUE; /* enable user+password */
4483 /* Decode the user */
4484 newname = curl_easy_unescape(data, userp, 0, NULL);
4486 Curl_safefree(userp);
4487 Curl_safefree(passwdp);
4488 Curl_safefree(optionsp);
4489 return CURLE_OUT_OF_MEMORY;
4492 if(strlen(newname) < MAX_CURL_USER_LENGTH)
4493 strcpy(user, newname);
4499 /* We have a password in the URL so decode it */
4500 char *newpasswd = curl_easy_unescape(data, passwdp, 0, NULL);
4502 Curl_safefree(userp);
4503 Curl_safefree(passwdp);
4504 Curl_safefree(optionsp);
4505 return CURLE_OUT_OF_MEMORY;
4508 if(strlen(newpasswd) < MAX_CURL_PASSWORD_LENGTH)
4509 strcpy(passwd, newpasswd);
4515 /* We have an options list in the URL so decode it */
4516 char *newoptions = curl_easy_unescape(data, optionsp, 0, NULL);
4518 Curl_safefree(userp);
4519 Curl_safefree(passwdp);
4520 Curl_safefree(optionsp);
4521 return CURLE_OUT_OF_MEMORY;
4524 if(strlen(newoptions) < MAX_CURL_OPTIONS_LENGTH)
4525 strcpy(options, newoptions);
4531 Curl_safefree(userp);
4532 Curl_safefree(passwdp);
4533 Curl_safefree(optionsp);
4541 * parse_login_details()
4543 * This is used to parse a login string for user name, password and options in
4544 * the following formats:
4548 * user:password;options
4550 * user;options:password
4558 * login [in] - The login string.
4559 * len [in] - The length of the login string.
4560 * userp [in/out] - The address where a pointer to newly allocated memory
4561 * holding the user will be stored upon completion.
4562 * passdwp [in/out] - The address where a pointer to newly allocated memory
4563 * holding the password will be stored upon completion.
4564 * optionsp [in/out] - The address where a pointer to newly allocated memory
4565 * holding the options will be stored upon completion.
4567 * Returns CURLE_OK on success.
4569 static CURLcode parse_login_details(const char *login, const size_t len,
4570 char **userp, char **passwdp,
4573 CURLcode result = CURLE_OK;
4577 const char *psep = NULL;
4578 const char *osep = NULL;
4583 /* Attempt to find the password separator */
4585 psep = strchr(login, ':');
4587 /* Within the constraint of the login string */
4588 if(psep >= login + len)
4592 /* Attempt to find the options separator */
4594 osep = strchr(login, ';');
4596 /* Within the constraint of the login string */
4597 if(osep >= login + len)
4601 /* Calculate the portion lengths */
4603 (size_t)(osep && psep > osep ? osep - login : psep - login) :
4604 (osep ? (size_t)(osep - login) : len));
4606 (osep && osep > psep ? (size_t)(osep - psep) :
4607 (size_t)(login + len - psep)) - 1 : 0);
4609 (psep && psep > osep ? (size_t)(psep - osep) :
4610 (size_t)(login + len - osep)) - 1 : 0);
4612 /* Allocate the user portion buffer */
4614 ubuf = malloc(ulen + 1);
4616 result = CURLE_OUT_OF_MEMORY;
4619 /* Allocate the password portion buffer */
4620 if(!result && passwdp && plen) {
4621 pbuf = malloc(plen + 1);
4623 Curl_safefree(ubuf);
4624 result = CURLE_OUT_OF_MEMORY;
4628 /* Allocate the options portion buffer */
4629 if(!result && optionsp && olen) {
4630 obuf = malloc(olen + 1);
4632 Curl_safefree(pbuf);
4633 Curl_safefree(ubuf);
4634 result = CURLE_OUT_OF_MEMORY;
4639 /* Store the user portion if necessary */
4641 memcpy(ubuf, login, ulen);
4643 Curl_safefree(*userp);
4647 /* Store the password portion if necessary */
4649 memcpy(pbuf, psep + 1, plen);
4651 Curl_safefree(*passwdp);
4655 /* Store the options portion if necessary */
4657 memcpy(obuf, osep + 1, olen);
4659 Curl_safefree(*optionsp);
4667 /*************************************************************
4668 * Figure out the remote port number and fix it in the URL
4670 * No matter if we use a proxy or not, we have to figure out the remote
4671 * port number of various reasons.
4673 * To be able to detect port number flawlessly, we must not confuse them
4674 * IPv6-specified addresses in the [0::1] style. (RFC2732)
4676 * The conn->host.name is currently [user:passwd@]host[:port] where host
4677 * could be a hostname, IPv4 address or IPv6 address.
4679 * The port number embedded in the URL is replaced, if necessary.
4680 *************************************************************/
4681 static CURLcode parse_remote_port(struct SessionHandle *data,
4682 struct connectdata *conn)
4687 /* Note that at this point, the IPv6 address cannot contain any scope
4688 suffix as that has already been removed in the parseurlandfillconn()
4690 if((1 == sscanf(conn->host.name, "[%*45[0123456789abcdefABCDEF:.]%c",
4692 (']' == endbracket)) {
4693 /* this is a RFC2732-style specified IP-address */
4694 conn->bits.ipv6_ip = TRUE;
4696 conn->host.name++; /* skip over the starting bracket */
4697 portptr = strchr(conn->host.name, ']');
4699 *portptr++ = '\0'; /* zero terminate, killing the bracket */
4701 portptr = NULL; /* no port number available */
4706 struct in6_addr in6;
4707 if(Curl_inet_pton(AF_INET6, conn->host.name, &in6) > 0) {
4708 /* This is a numerical IPv6 address, meaning this is a wrongly formatted
4710 failf(data, "IPv6 numerical address used in URL without brackets");
4711 return CURLE_URL_MALFORMAT;
4715 portptr = strrchr(conn->host.name, ':');
4718 if(data->set.use_port && data->state.allow_port) {
4719 /* if set, we use this and ignore the port possibly given in the URL */
4720 conn->remote_port = (unsigned short)data->set.use_port;
4722 *portptr = '\0'; /* cut off the name there anyway - if there was a port
4723 number - since the port number is to be ignored! */
4724 if(conn->bits.httpproxy) {
4725 /* we need to create new URL with the new port number */
4729 if(conn->bits.type_set)
4730 snprintf(type, sizeof(type), ";type=%c",
4731 data->set.prefer_ascii?'A':
4732 (data->set.ftp_list_only?'D':'I'));
4735 * This synthesized URL isn't always right--suffixes like ;type=A are
4736 * stripped off. It would be better to work directly from the original
4737 * URL and simply replace the port part of it.
4739 url = aprintf("%s://%s%s%s:%hu%s%s%s", conn->given->scheme,
4740 conn->bits.ipv6_ip?"[":"", conn->host.name,
4741 conn->bits.ipv6_ip?"]":"", conn->remote_port,
4742 data->state.slash_removed?"/":"", data->state.path,
4745 return CURLE_OUT_OF_MEMORY;
4747 if(data->change.url_alloc) {
4748 Curl_safefree(data->change.url);
4749 data->change.url_alloc = FALSE;
4752 data->change.url = url;
4753 data->change.url_alloc = TRUE;
4757 /* no CURLOPT_PORT given, extract the one from the URL */
4762 port=strtoul(portptr+1, &rest, 10); /* Port number must be decimal */
4764 if(rest != (portptr+1) && *rest == '\0') {
4765 /* The colon really did have only digits after it,
4766 * so it is either a port number or a mistake */
4768 if(port > 0xffff) { /* Single unix standard says port numbers are
4770 failf(data, "Port number too large: %lu", port);
4771 return CURLE_URL_MALFORMAT;
4774 *portptr = '\0'; /* cut off the name there */
4775 conn->remote_port = curlx_ultous(port);
4778 /* Browser behavior adaptation. If there's a colon with no digits after,
4779 just cut off the name there which makes us ignore the colon and just
4780 use the default port. Firefox and Chrome both do that. */
4787 * Override the login details from the URL with that in the CURLOPT_USERPWD
4788 * option or a .netrc file, if applicable.
4790 static void override_login(struct SessionHandle *data,
4791 struct connectdata *conn,
4792 char *user, char *passwd, char *options)
4794 if(data->set.str[STRING_USERNAME]) {
4795 strncpy(user, data->set.str[STRING_USERNAME], MAX_CURL_USER_LENGTH);
4796 user[MAX_CURL_USER_LENGTH - 1] = '\0'; /* To be on safe side */
4799 if(data->set.str[STRING_PASSWORD]) {
4800 strncpy(passwd, data->set.str[STRING_PASSWORD], MAX_CURL_PASSWORD_LENGTH);
4801 passwd[MAX_CURL_PASSWORD_LENGTH - 1] = '\0'; /* To be on safe side */
4804 if(data->set.str[STRING_OPTIONS]) {
4805 strncpy(options, data->set.str[STRING_OPTIONS], MAX_CURL_OPTIONS_LENGTH);
4806 options[MAX_CURL_OPTIONS_LENGTH - 1] = '\0'; /* To be on safe side */
4809 conn->bits.netrc = FALSE;
4810 if(data->set.use_netrc != CURL_NETRC_IGNORED) {
4811 if(Curl_parsenetrc(conn->host.name,
4813 data->set.str[STRING_NETRC_FILE])) {
4814 infof(data, "Couldn't find host %s in the "
4815 DOT_CHAR "netrc file; using defaults\n",
4819 /* set bits.netrc TRUE to remember that we got the name from a .netrc
4820 file, so that it is safe to use even if we followed a Location: to a
4821 different host or similar. */
4822 conn->bits.netrc = TRUE;
4824 conn->bits.user_passwd = TRUE; /* enable user+password */
4830 * Set password so it's available in the connection.
4832 static CURLcode set_login(struct connectdata *conn,
4833 const char *user, const char *passwd,
4834 const char *options)
4836 CURLcode result = CURLE_OK;
4838 /* If our protocol needs a password and we have none, use the defaults */
4839 if((conn->handler->flags & PROTOPT_NEEDSPWD) && !conn->bits.user_passwd) {
4840 /* Store the default user */
4841 conn->user = strdup(CURL_DEFAULT_USER);
4843 /* Store the default password */
4845 conn->passwd = strdup(CURL_DEFAULT_PASSWORD);
4847 conn->passwd = NULL;
4849 /* This is the default password, so DON'T set conn->bits.user_passwd */
4852 /* Store the user, zero-length if not set */
4853 conn->user = strdup(user);
4855 /* Store the password (only if user is present), zero-length if not set */
4857 conn->passwd = strdup(passwd);
4859 conn->passwd = NULL;
4862 if(!conn->user || !conn->passwd)
4863 result = CURLE_OUT_OF_MEMORY;
4865 /* Store the options, null if not set */
4866 if(!result && options[0]) {
4867 conn->options = strdup(options);
4870 result = CURLE_OUT_OF_MEMORY;
4876 /*************************************************************
4877 * Resolve the address of the server or proxy
4878 *************************************************************/
4879 static CURLcode resolve_server(struct SessionHandle *data,
4880 struct connectdata *conn,
4883 CURLcode result=CURLE_OK;
4884 long timeout_ms = Curl_timeleft(data, NULL, TRUE);
4886 /*************************************************************
4887 * Resolve the name of the server or proxy
4888 *************************************************************/
4889 if(conn->bits.reuse)
4890 /* We're reusing the connection - no need to resolve anything, and
4891 fix_hostname() was called already in create_conn() for the re-use
4896 /* this is a fresh connect */
4898 struct Curl_dns_entry *hostaddr;
4900 /* set a pointer to the hostname we display */
4901 fix_hostname(data, conn, &conn->host);
4903 if(!conn->proxy.name || !*conn->proxy.name) {
4904 /* If not connecting via a proxy, extract the port from the URL, if it is
4905 * there, thus overriding any defaults that might have been set above. */
4906 conn->port = conn->remote_port; /* it is the same port */
4908 /* Resolve target host right on */
4909 rc = Curl_resolv_timeout(conn, conn->host.name, (int)conn->port,
4910 &hostaddr, timeout_ms);
4911 if(rc == CURLRESOLV_PENDING)
4914 else if(rc == CURLRESOLV_TIMEDOUT)
4915 result = CURLE_OPERATION_TIMEDOUT;
4917 else if(!hostaddr) {
4918 failf(data, "Couldn't resolve host '%s'", conn->host.dispname);
4919 result = CURLE_COULDNT_RESOLVE_HOST;
4920 /* don't return yet, we need to clean up the timeout first */
4924 /* This is a proxy that hasn't been resolved yet. */
4926 /* IDN-fix the proxy name */
4927 fix_hostname(data, conn, &conn->proxy);
4930 rc = Curl_resolv_timeout(conn, conn->proxy.name, (int)conn->port,
4931 &hostaddr, timeout_ms);
4933 if(rc == CURLRESOLV_PENDING)
4936 else if(rc == CURLRESOLV_TIMEDOUT)
4937 result = CURLE_OPERATION_TIMEDOUT;
4939 else if(!hostaddr) {
4940 failf(data, "Couldn't resolve proxy '%s'", conn->proxy.dispname);
4941 result = CURLE_COULDNT_RESOLVE_PROXY;
4942 /* don't return yet, we need to clean up the timeout first */
4945 DEBUGASSERT(conn->dns_entry == NULL);
4946 conn->dns_entry = hostaddr;
4953 * Cleanup the connection just allocated before we can move along and use the
4954 * previously existing one. All relevant data is copied over and old_conn is
4955 * ready for freeing once this function returns.
4957 static void reuse_conn(struct connectdata *old_conn,
4958 struct connectdata *conn)
4960 if(old_conn->proxy.rawalloc)
4961 free(old_conn->proxy.rawalloc);
4963 /* free the SSL config struct from this connection struct as this was
4964 allocated in vain and is targeted for destruction */
4965 Curl_free_ssl_config(&old_conn->ssl_config);
4967 conn->data = old_conn->data;
4969 /* get the user+password information from the old_conn struct since it may
4970 * be new for this request even when we re-use an existing connection */
4971 conn->bits.user_passwd = old_conn->bits.user_passwd;
4972 if(conn->bits.user_passwd) {
4973 /* use the new user name and password though */
4974 Curl_safefree(conn->user);
4975 Curl_safefree(conn->passwd);
4976 conn->user = old_conn->user;
4977 conn->passwd = old_conn->passwd;
4978 old_conn->user = NULL;
4979 old_conn->passwd = NULL;
4982 conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd;
4983 if(conn->bits.proxy_user_passwd) {
4984 /* use the new proxy user name and proxy password though */
4985 Curl_safefree(conn->proxyuser);
4986 Curl_safefree(conn->proxypasswd);
4987 conn->proxyuser = old_conn->proxyuser;
4988 conn->proxypasswd = old_conn->proxypasswd;
4989 old_conn->proxyuser = NULL;
4990 old_conn->proxypasswd = NULL;
4993 /* host can change, when doing keepalive with a proxy or if the case is
4994 different this time etc */
4995 Curl_safefree(conn->host.rawalloc);
4996 conn->host=old_conn->host;
4998 /* persist connection info in session handle */
4999 Curl_persistconninfo(conn);
5002 conn->bits.reuse = TRUE; /* yes, we're re-using here */
5004 Curl_safefree(old_conn->user);
5005 Curl_safefree(old_conn->passwd);
5006 Curl_safefree(old_conn->proxyuser);
5007 Curl_safefree(old_conn->proxypasswd);
5008 Curl_safefree(old_conn->localdev);
5010 Curl_llist_destroy(old_conn->send_pipe, NULL);
5011 Curl_llist_destroy(old_conn->recv_pipe, NULL);
5013 old_conn->send_pipe = NULL;
5014 old_conn->recv_pipe = NULL;
5016 Curl_safefree(old_conn->master_buffer);
5020 * create_conn() sets up a new connectdata struct, or re-uses an already
5021 * existing one, and resolves host name.
5023 * if this function returns CURLE_OK and *async is set to TRUE, the resolve
5024 * response will be coming asynchronously. If *async is FALSE, the name is
5027 * @param data The sessionhandle pointer
5028 * @param in_connect is set to the next connection data pointer
5029 * @param async is set TRUE when an async DNS resolution is pending
5030 * @see Curl_setup_conn()
5032 * *NOTE* this function assigns the conn->data pointer!
5035 static CURLcode create_conn(struct SessionHandle *data,
5036 struct connectdata **in_connect,
5039 CURLcode result = CURLE_OK;
5040 struct connectdata *conn;
5041 struct connectdata *conn_temp = NULL;
5043 char user[MAX_CURL_USER_LENGTH];
5044 char passwd[MAX_CURL_PASSWORD_LENGTH];
5045 char options[MAX_CURL_OPTIONS_LENGTH];
5048 bool prot_missing = FALSE;
5049 bool no_connections_available = FALSE;
5051 size_t max_host_connections = Curl_multi_max_host_connections(data->multi);
5052 size_t max_total_connections = Curl_multi_max_total_connections(data->multi);
5056 /*************************************************************
5058 *************************************************************/
5060 if(!data->change.url)
5061 return CURLE_URL_MALFORMAT;
5063 /* First, split up the current URL in parts so that we can use the
5064 parts for checking against the already present connections. In order
5065 to not have to modify everything at once, we allocate a temporary
5066 connection data struct and fill in for comparison purposes. */
5067 conn = allocate_conn(data);
5070 return CURLE_OUT_OF_MEMORY;
5072 /* We must set the return variable as soon as possible, so that our
5073 parent can cleanup any possible allocs we may have done before
5077 /* This initing continues below, see the comment "Continue connectdata
5078 * initialization here" */
5080 /***********************************************************
5081 * We need to allocate memory to store the path in. We get the size of the
5082 * full URL to be sure, and we need to make it at least 256 bytes since
5083 * other parts of the code will rely on this fact
5084 ***********************************************************/
5085 #define LEAST_PATH_ALLOC 256
5086 urllen=strlen(data->change.url);
5087 if(urllen < LEAST_PATH_ALLOC)
5088 urllen=LEAST_PATH_ALLOC;
5091 * We malloc() the buffers below urllen+2 to make room for 2 possibilities:
5092 * 1 - an extra terminating zero
5093 * 2 - an extra slash (in case a syntax like "www.host.com?moo" is used)
5096 Curl_safefree(data->state.pathbuffer);
5097 data->state.path = NULL;
5099 data->state.pathbuffer = malloc(urllen+2);
5100 if(NULL == data->state.pathbuffer)
5101 return CURLE_OUT_OF_MEMORY; /* really bad error */
5102 data->state.path = data->state.pathbuffer;
5104 conn->host.rawalloc = malloc(urllen+2);
5105 if(NULL == conn->host.rawalloc) {
5106 Curl_safefree(data->state.pathbuffer);
5107 data->state.path = NULL;
5108 return CURLE_OUT_OF_MEMORY;
5111 conn->host.name = conn->host.rawalloc;
5112 conn->host.name[0] = 0;
5114 result = parseurlandfillconn(data, conn, &prot_missing, user, passwd,
5116 if(result != CURLE_OK)
5119 /*************************************************************
5120 * No protocol part in URL was used, add it!
5121 *************************************************************/
5123 /* We're guessing prefixes here and if we're told to use a proxy or if
5124 we're gonna follow a Location: later or... then we need the protocol
5125 part added so that we have a valid URL. */
5128 reurl = aprintf("%s://%s", conn->handler->scheme, data->change.url);
5131 Curl_safefree(proxy);
5132 return CURLE_OUT_OF_MEMORY;
5135 if(data->change.url_alloc) {
5136 Curl_safefree(data->change.url);
5137 data->change.url_alloc = FALSE;
5140 data->change.url = reurl;
5141 data->change.url_alloc = TRUE; /* free this later */
5144 /*************************************************************
5145 * If the protocol can't handle url query strings, then cut
5146 * of the unhandable part
5147 *************************************************************/
5148 if((conn->given->flags&PROTOPT_NOURLQUERY)) {
5149 char *path_q_sep = strchr(conn->data->state.path, '?');
5151 /* according to rfc3986, allow the query (?foo=bar)
5152 also on protocols that can't handle it.
5154 cut the string-part after '?'
5157 /* terminate the string */
5162 #ifndef CURL_DISABLE_PROXY
5163 /*************************************************************
5164 * Extract the user and password from the authentication string
5165 *************************************************************/
5166 if(conn->bits.proxy_user_passwd) {
5167 result = parse_proxy_auth(data, conn);
5168 if(result != CURLE_OK)
5172 /*************************************************************
5173 * Detect what (if any) proxy to use
5174 *************************************************************/
5175 if(data->set.str[STRING_PROXY]) {
5176 proxy = strdup(data->set.str[STRING_PROXY]);
5177 /* if global proxy is set, this is it */
5179 failf(data, "memory shortage");
5180 return CURLE_OUT_OF_MEMORY;
5184 if(data->set.str[STRING_NOPROXY] &&
5185 check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY])) {
5187 free(proxy); /* proxy is in exception list */
5192 proxy = detect_proxy(conn);
5194 if(proxy && (!*proxy || (conn->handler->flags & PROTOPT_NONETWORK))) {
5195 free(proxy); /* Don't bother with an empty proxy string or if the
5196 protocol doesn't work with network */
5200 /***********************************************************************
5201 * If this is supposed to use a proxy, we need to figure out the proxy host
5202 * name, proxy type and port number, so that we can re-use an existing
5203 * connection that may exist registered to the same proxy host.
5204 ***********************************************************************/
5206 result = parse_proxy(data, conn, proxy);
5208 free(proxy); /* parse_proxy copies the proxy string */
5213 if((conn->proxytype == CURLPROXY_HTTP) ||
5214 (conn->proxytype == CURLPROXY_HTTP_1_0)) {
5215 #ifdef CURL_DISABLE_HTTP
5216 /* asking for a HTTP proxy is a bit funny when HTTP is disabled... */
5217 return CURLE_UNSUPPORTED_PROTOCOL;
5219 /* force this connection's protocol to become HTTP if not already
5220 compatible - if it isn't tunneling through */
5221 if(!(conn->handler->protocol & CURLPROTO_HTTP) &&
5222 !conn->bits.tunnel_proxy)
5223 conn->handler = &Curl_handler_http;
5225 conn->bits.httpproxy = TRUE;
5229 conn->bits.httpproxy = FALSE; /* not a HTTP proxy */
5230 conn->bits.proxy = TRUE;
5233 /* we aren't using the proxy after all... */
5234 conn->bits.proxy = FALSE;
5235 conn->bits.httpproxy = FALSE;
5236 conn->bits.proxy_user_passwd = FALSE;
5237 conn->bits.tunnel_proxy = FALSE;
5240 #endif /* CURL_DISABLE_PROXY */
5242 /*************************************************************
5243 * If the protocol is using SSL and HTTP proxy is used, we set
5244 * the tunnel_proxy bit.
5245 *************************************************************/
5246 if((conn->given->flags&PROTOPT_SSL) && conn->bits.httpproxy)
5247 conn->bits.tunnel_proxy = TRUE;
5249 /*************************************************************
5250 * Figure out the remote port number and fix it in the URL
5251 *************************************************************/
5252 result = parse_remote_port(data, conn);
5253 if(result != CURLE_OK)
5256 /* Check for overridden login details and set them accordingly so they
5257 they are known when protocol->setup_connection is called! */
5258 override_login(data, conn, user, passwd, options);
5259 result = set_login(conn, user, passwd, options);
5260 if(result != CURLE_OK)
5263 /*************************************************************
5264 * Setup internals depending on protocol. Needs to be done after
5265 * we figured out what/if proxy to use.
5266 *************************************************************/
5267 result = setup_connection_internals(conn);
5268 if(result != CURLE_OK) {
5269 Curl_safefree(proxy);
5273 conn->recv[FIRSTSOCKET] = Curl_recv_plain;
5274 conn->send[FIRSTSOCKET] = Curl_send_plain;
5275 conn->recv[SECONDARYSOCKET] = Curl_recv_plain;
5276 conn->send[SECONDARYSOCKET] = Curl_send_plain;
5278 /***********************************************************************
5279 * file: is a special case in that it doesn't need a network connection
5280 ***********************************************************************/
5281 #ifndef CURL_DISABLE_FILE
5282 if(conn->handler->flags & PROTOPT_NONETWORK) {
5284 /* this is supposed to be the connect function so we better at least check
5285 that the file is present here! */
5286 DEBUGASSERT(conn->handler->connect_it);
5287 result = conn->handler->connect_it(conn, &done);
5289 /* Setup a "faked" transfer that'll do nothing */
5290 if(CURLE_OK == result) {
5292 conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; /* we are "connected */
5294 ConnectionStore(data, conn);
5297 * Setup whatever necessary for a resumed transfer
5299 result = setup_range(data);
5301 DEBUGASSERT(conn->handler->done);
5302 /* we ignore the return code for the protocol-specific DONE */
5303 (void)conn->handler->done(conn, result, FALSE);
5307 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */
5308 -1, NULL); /* no upload */
5311 /* since we skip do_init() */
5318 /* Get a cloned copy of the SSL config situation stored in the
5319 connection struct. But to get this going nicely, we must first make
5320 sure that the strings in the master copy are pointing to the correct
5321 strings in the session handle strings array!
5323 Keep in mind that the pointers in the master copy are pointing to strings
5324 that will be freed as part of the SessionHandle struct, but all cloned
5325 copies will be separately allocated.
5327 data->set.ssl.CApath = data->set.str[STRING_SSL_CAPATH];
5328 data->set.ssl.CAfile = data->set.str[STRING_SSL_CAFILE];
5329 data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE];
5330 data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT];
5331 data->set.ssl.random_file = data->set.str[STRING_SSL_RANDOM_FILE];
5332 data->set.ssl.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
5333 data->set.ssl.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST];
5335 data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME];
5336 data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD];
5339 if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config))
5340 return CURLE_OUT_OF_MEMORY;
5342 /*************************************************************
5343 * Check the current list of connections to see if we can
5344 * re-use an already existing one or if we have to create a
5346 *************************************************************/
5348 /* reuse_fresh is TRUE if we are told to use a new connection by force, but
5349 we only acknowledge this option if this is not a re-used connection
5350 already (which happens due to follow-location or during a HTTP
5351 authentication phase). */
5352 if(data->set.reuse_fresh && !data->state.this_is_a_follow)
5355 reuse = ConnectionExists(data, conn, &conn_temp, &force_reuse);
5357 /* If we found a reusable connection, we may still want to
5358 open a new connection if we are pipelining. */
5359 if(reuse && !force_reuse && IsPipeliningPossible(data, conn_temp)) {
5360 size_t pipelen = conn_temp->send_pipe->size + conn_temp->recv_pipe->size;
5362 infof(data, "Found connection %ld, with requests in the pipe (%zu)\n",
5363 conn_temp->connection_id, pipelen);
5365 if(conn_temp->bundle->num_connections < max_host_connections &&
5366 data->state.conn_cache->num_connections < max_total_connections) {
5367 /* We want a new connection anyway */
5370 infof(data, "We can reuse, but we want a new connection anyway\n");
5377 * We already have a connection for this, we got the former connection
5378 * in the conn_temp variable and thus we need to cleanup the one we
5379 * just allocated before we can move along and use the previously
5382 conn_temp->inuse = TRUE; /* mark this as being in use so that no other
5383 handle in a multi stack may nick it */
5384 reuse_conn(conn, conn_temp);
5385 free(conn); /* we don't need this anymore */
5389 /* set a pointer to the hostname we display */
5390 fix_hostname(data, conn, &conn->host);
5392 infof(data, "Re-using existing connection! (#%ld) with host %s\n",
5393 conn->connection_id,
5394 conn->proxy.name?conn->proxy.dispname:conn->host.dispname);
5397 /* We have decided that we want a new connection. However, we may not
5398 be able to do that if we have reached the limit of how many
5399 connections we are allowed to open. */
5400 struct connectbundle *bundle;
5402 bundle = Curl_conncache_find_bundle(data->state.conn_cache,
5404 if(max_host_connections > 0 && bundle &&
5405 (bundle->num_connections >= max_host_connections)) {
5406 struct connectdata *conn_candidate;
5408 /* The bundle is full. Let's see if we can kill a connection. */
5409 conn_candidate = find_oldest_idle_connection_in_bundle(data, bundle);
5411 if(conn_candidate) {
5412 /* Set the connection's owner correctly, then kill it */
5413 conn_candidate->data = data;
5414 (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
5417 no_connections_available = TRUE;
5420 if(max_total_connections > 0 &&
5421 (data->state.conn_cache->num_connections >= max_total_connections)) {
5422 struct connectdata *conn_candidate;
5424 /* The cache is full. Let's see if we can kill a connection. */
5425 conn_candidate = find_oldest_idle_connection(data);
5427 if(conn_candidate) {
5428 /* Set the connection's owner correctly, then kill it */
5429 conn_candidate->data = data;
5430 (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
5433 no_connections_available = TRUE;
5437 if(no_connections_available) {
5438 infof(data, "No connections available.\n");
5443 return CURLE_NO_CONNECTION_AVAILABLE;
5447 * This is a brand new connection, so let's store it in the connection
5450 ConnectionStore(data, conn);
5454 /* Mark the connection as used */
5457 /* Setup and init stuff before DO starts, in preparing for the transfer. */
5461 * Setup whatever necessary for a resumed transfer
5463 result = setup_range(data);
5467 /* Continue connectdata initialization here. */
5470 * Inherit the proper values from the urldata struct AFTER we have arranged
5471 * the persistent connection stuff
5473 conn->fread_func = data->set.fread_func;
5474 conn->fread_in = data->set.in;
5475 conn->seek_func = data->set.seek_func;
5476 conn->seek_client = data->set.seek_client;
5478 /*************************************************************
5479 * Resolve the address of the server or proxy
5480 *************************************************************/
5481 result = resolve_server(data, conn, async);
5486 /* Curl_setup_conn() is called after the name resolve initiated in
5487 * create_conn() is all done.
5489 * Curl_setup_conn() also handles reused connections
5491 * conn->data MUST already have been setup fine (in create_conn)
5494 CURLcode Curl_setup_conn(struct connectdata *conn,
5495 bool *protocol_done)
5497 CURLcode result = CURLE_OK;
5498 struct SessionHandle *data = conn->data;
5500 Curl_pgrsTime(data, TIMER_NAMELOOKUP);
5502 if(conn->handler->flags & PROTOPT_NONETWORK) {
5503 /* nothing to setup when not using a network */
5504 *protocol_done = TRUE;
5507 *protocol_done = FALSE; /* default to not done */
5509 /* set proxy_connect_closed to false unconditionally already here since it
5510 is used strictly to provide extra information to a parent function in the
5511 case of proxy CONNECT failures and we must make sure we don't have it
5512 lingering set from a previous invoke */
5513 conn->bits.proxy_connect_closed = FALSE;
5516 * Set user-agent. Used for HTTP, but since we can attempt to tunnel
5517 * basically anything through a http proxy we can't limit this based on
5520 if(data->set.str[STRING_USERAGENT]) {
5521 Curl_safefree(conn->allocptr.uagent);
5522 conn->allocptr.uagent =
5523 aprintf("User-Agent: %s\r\n", data->set.str[STRING_USERAGENT]);
5524 if(!conn->allocptr.uagent)
5525 return CURLE_OUT_OF_MEMORY;
5528 data->req.headerbytecount = 0;
5530 #ifdef CURL_DO_LINEEND_CONV
5531 data->state.crlf_conversions = 0; /* reset CRLF conversion counter */
5532 #endif /* CURL_DO_LINEEND_CONV */
5534 /* set start time here for timeout purposes in the connect procedure, it
5535 is later set again for the progress meter purpose */
5536 conn->now = Curl_tvnow();
5539 /* loop for CURL_SERVER_CLOSED_CONNECTION */
5541 if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
5542 /* Try to connect only if not already connected */
5543 bool connected = FALSE;
5545 result = ConnectPlease(data, conn, &connected);
5547 if(result && !conn->ip_addr) {
5548 /* transport connection failure not related with authentication */
5549 conn->bits.tcpconnect[FIRSTSOCKET] = FALSE;
5554 result = Curl_protocol_connect(conn, protocol_done);
5555 if(CURLE_OK == result)
5556 conn->bits.tcpconnect[FIRSTSOCKET] = TRUE;
5559 conn->bits.tcpconnect[FIRSTSOCKET] = FALSE;
5561 /* if the connection was closed by the server while exchanging
5562 authentication informations, retry with the new set
5563 authentication information */
5564 if(conn->bits.proxy_connect_closed) {
5565 /* reset the error buffer */
5566 if(data->set.errorbuffer)
5567 data->set.errorbuffer[0] = '\0';
5568 data->state.errorbuf = FALSE;
5572 if(CURLE_OK != result)
5576 Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */
5577 Curl_pgrsTime(data, TIMER_APPCONNECT); /* we're connected already */
5578 conn->bits.tcpconnect[FIRSTSOCKET] = TRUE;
5579 *protocol_done = TRUE;
5580 Curl_verboseconnect(conn);
5581 Curl_updateconninfo(conn, conn->sock[FIRSTSOCKET]);
5583 /* Stop the loop now */
5587 conn->now = Curl_tvnow(); /* time this *after* the connect is done, we
5588 set this here perhaps a second time */
5592 * This check is quite a hack. We're calling _fsetmode to fix the problem
5593 * with fwrite converting newline characters (you get mangled text files,
5594 * and corrupted binary files when you download to stdout and redirect it to
5598 if((data->set.out)->_handle == NULL) {
5599 _fsetmode(stdout, "b");
5606 CURLcode Curl_connect(struct SessionHandle *data,
5607 struct connectdata **in_connect,
5609 bool *protocol_done)
5613 *asyncp = FALSE; /* assume synchronous resolves by default */
5615 /* call the stuff that needs to be called */
5616 code = create_conn(data, in_connect, asyncp);
5618 if(CURLE_OK == code) {
5620 if((*in_connect)->send_pipe->size || (*in_connect)->recv_pipe->size)
5622 *protocol_done = TRUE;
5624 /* DNS resolution is done: that's either because this is a reused
5625 connection, in which case DNS was unnecessary, or because DNS
5626 really did finish already (synch resolver/fast async resolve) */
5627 code = Curl_setup_conn(*in_connect, protocol_done);
5631 if(code == CURLE_NO_CONNECTION_AVAILABLE) {
5636 if(code && *in_connect) {
5637 /* We're not allowed to return failure with memory left allocated
5638 in the connectdata struct, free those here */
5639 Curl_disconnect(*in_connect, FALSE); /* close the connection */
5640 *in_connect = NULL; /* return a NULL */
5646 CURLcode Curl_done(struct connectdata **connp,
5647 CURLcode status, /* an error if this is called after an
5648 error was detected */
5652 struct connectdata *conn;
5653 struct SessionHandle *data;
5655 DEBUGASSERT(*connp);
5661 /* Stop if Curl_done() has already been called */
5664 Curl_getoff_all_pipelines(data, conn);
5666 if((conn->send_pipe->size + conn->recv_pipe->size != 0 &&
5667 !data->set.reuse_forbid &&
5669 /* Stop if pipeline is not empty and we do not have to close
5673 conn->bits.done = TRUE; /* called just now! */
5675 /* Cleanup possible redirect junk */
5676 if(data->req.newurl) {
5677 free(data->req.newurl);
5678 data->req.newurl = NULL;
5680 if(data->req.location) {
5681 free(data->req.location);
5682 data->req.location = NULL;
5685 Curl_resolver_cancel(conn);
5687 if(conn->dns_entry) {
5688 Curl_resolv_unlock(data, conn->dns_entry); /* done with this */
5689 conn->dns_entry = NULL;
5692 if(status == CURLE_ABORTED_BY_CALLBACK)
5693 /* When we're aborted due to a callback return code it basically have to
5694 be counted as premature as there is trouble ahead if we don't. We have
5695 many callbacks and protocols work differently, we could potentially do
5696 this more fine-grained in the future. */
5699 /* this calls the protocol-specific function pointer previously set */
5700 if(conn->handler->done)
5701 result = conn->handler->done(conn, status, premature);
5705 if(Curl_pgrsDone(conn) && !result)
5706 result = CURLE_ABORTED_BY_CALLBACK;
5708 /* if the transfer was completed in a paused state there can be buffered
5709 data left to write and then kill */
5710 if(data->state.tempwrite) {
5711 free(data->state.tempwrite);
5712 data->state.tempwrite = NULL;
5715 /* if data->set.reuse_forbid is TRUE, it means the libcurl client has
5716 forced us to close this no matter what we think.
5718 if conn->bits.close is TRUE, it means that the connection should be
5719 closed in spite of all our efforts to be nice, due to protocol
5720 restrictions in our or the server's end
5722 if premature is TRUE, it means this connection was said to be DONE before
5723 the entire request operation is complete and thus we can't know in what
5724 state it is for re-using, so we're forced to close it. In a perfect world
5725 we can add code that keep track of if we really must close it here or not,
5726 but currently we have no such detail knowledge.
5728 if(data->set.reuse_forbid || conn->bits.close || premature) {
5729 CURLcode res2 = Curl_disconnect(conn, premature); /* close connection */
5731 /* If we had an error already, make sure we return that one. But
5732 if we got a new error, return that. */
5737 /* the connection is no longer in use */
5738 if(ConnectionDone(data, conn)) {
5739 /* remember the most recently used connection */
5740 data->state.lastconnect = conn;
5742 infof(data, "Connection #%ld to host %s left intact\n",
5743 conn->connection_id,
5744 conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname);
5747 data->state.lastconnect = NULL;
5750 *connp = NULL; /* to make the caller of this function better detect that
5751 this was either closed or handed over to the connection
5752 cache here, and therefore cannot be used from this point on
5754 free_connection_internals(data);
5760 * do_init() inits the readwrite session. This is inited each time (in the DO
5761 * function before the protocol-specific DO functions are invoked) for a
5762 * transfer, sometimes multiple times on the same SessionHandle. Make sure
5763 * nothing in here depends on stuff that are setup dynamically for the
5767 static CURLcode do_init(struct connectdata *conn)
5769 struct SessionHandle *data = conn->data;
5770 struct SingleRequest *k = &data->req;
5772 conn->bits.done = FALSE; /* Curl_done() is not called yet */
5773 conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */
5774 data->state.expect100header = FALSE;
5776 if(data->set.opt_no_body)
5777 /* in HTTP lingo, no body means using the HEAD request... */
5778 data->set.httpreq = HTTPREQ_HEAD;
5779 else if(HTTPREQ_HEAD == data->set.httpreq)
5780 /* ... but if unset there really is no perfect method that is the
5781 "opposite" of HEAD but in reality most people probably think GET
5782 then. The important thing is that we can't let it remain HEAD if the
5783 opt_no_body is set FALSE since then we'll behave wrong when getting
5785 data->set.httpreq = HTTPREQ_GET;
5787 /* NB: the content encoding software depends on this initialization */
5788 Curl_easy_initHandleData(data);
5790 k->start = Curl_tvnow(); /* start time */
5791 k->now = k->start; /* current time is now */
5792 k->header = TRUE; /* assume header */
5796 k->buf = data->state.buffer;
5797 k->uploadbuf = data->state.uploadbuffer;
5798 k->hbufp = data->state.headerbuff;
5799 k->ignorebody=FALSE;
5801 Curl_speedinit(data);
5803 Curl_pgrsSetUploadCounter(data, 0);
5804 Curl_pgrsSetDownloadCounter(data, 0);
5810 * do_complete is called when the DO actions are complete.
5812 * We init chunking and trailer bits to their default values here immediately
5813 * before receiving any header data for the current request in the pipeline.
5815 static void do_complete(struct connectdata *conn)
5817 conn->data->req.chunk=FALSE;
5818 conn->data->req.maxfd = (conn->sockfd>conn->writesockfd?
5819 conn->sockfd:conn->writesockfd)+1;
5820 Curl_pgrsTime(conn->data, TIMER_PRETRANSFER);
5823 CURLcode Curl_do(struct connectdata **connp, bool *done)
5825 CURLcode result=CURLE_OK;
5826 struct connectdata *conn = *connp;
5827 struct SessionHandle *data = conn->data;
5829 if(conn->handler->do_it) {
5830 /* generic protocol-specific function pointer set in curl_connect() */
5831 result = conn->handler->do_it(conn, done);
5833 /* This was formerly done in transfer.c, but we better do it here */
5834 if((CURLE_SEND_ERROR == result) && conn->bits.reuse) {
5836 * If the connection is using an easy handle, call reconnect
5837 * to re-establish the connection. Otherwise, let the multi logic
5838 * figure out how to re-establish the connection.
5841 result = Curl_reconnect_request(connp);
5843 if(result == CURLE_OK) {
5844 /* ... finally back to actually retry the DO phase */
5845 conn = *connp; /* re-assign conn since Curl_reconnect_request
5846 creates a new connection */
5847 result = conn->handler->do_it(conn, done);
5854 if((result == CURLE_OK) && *done)
5855 /* do_complete must be called after the protocol-specific DO function */
5862 * Curl_do_more() is called during the DO_MORE multi state. It is basically a
5863 * second stage DO state which (wrongly) was introduced to support FTP's
5864 * second connection.
5866 * TODO: A future libcurl should be able to work away this state.
5868 * 'complete' can return 0 for incomplete, 1 for done and -1 for go back to
5869 * DOING state there's more work to do!
5872 CURLcode Curl_do_more(struct connectdata *conn, int *complete)
5874 CURLcode result=CURLE_OK;
5878 if(conn->handler->do_more)
5879 result = conn->handler->do_more(conn, complete);
5881 if(!result && (*complete == 1))
5882 /* do_complete must be called after the protocol-specific DO function */