1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2017, 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 https://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>
55 #error "We can't compile without socket() support!"
65 #elif defined(USE_WIN32_IDN)
66 /* prototype for curl_win32_idn_to_ascii() */
67 bool curl_win32_idn_to_ascii(const char *in, char **out);
68 #elif defined(USE_ICU_IDNA)
69 #include <unicode/uidna.h>
70 #endif /* USE_LIBIDN2 */
76 #include "vtls/vtls.h"
87 #include "content_encoding.h"
88 #include "http_digest.h"
89 #include "http_negotiate.h"
93 #include "speedcheck.h"
95 #include "non-ascii.h"
96 #include "inet_pton.h"
99 /* And now for the protocols */
107 #include "curl_ldap.h"
112 #include "inet_ntop.h"
113 #include "http_ntlm.h"
114 #include "curl_ntlm_wb.h"
116 #include "curl_rtmp.h"
118 #include "http_proxy.h"
119 #include "conncache.h"
120 #include "multihandle.h"
121 #include "pipeline.h"
124 /* The last 3 #include files should be in this order */
125 #include "curl_printf.h"
126 #include "curl_memory.h"
127 #include "memdebug.h"
129 #if defined(USE_ICU_IDNA)
130 #define MAX_DOMAIN_NAME_LEN 256
131 #endif /* USE_ICU_IDNA */
133 /* Local static prototypes */
134 static struct connectdata *
135 find_oldest_idle_connection_in_bundle(struct Curl_easy *data,
136 struct connectbundle *bundle);
137 static void conn_free(struct connectdata *conn);
138 static void free_fixed_hostname(struct hostname *host);
139 static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke);
140 static CURLcode parse_url_login(struct Curl_easy *data,
141 struct connectdata *conn,
142 char **userptr, char **passwdptr,
144 static CURLcode parse_login_details(const char *login, const size_t len,
145 char **userptr, char **passwdptr,
147 static unsigned int get_protocol_family(unsigned int protocol);
153 static const struct Curl_handler * const protocols[] = {
155 #ifndef CURL_DISABLE_HTTP
159 #if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)
163 #ifndef CURL_DISABLE_FTP
167 #if defined(USE_SSL) && !defined(CURL_DISABLE_FTP)
171 #ifndef CURL_DISABLE_TELNET
172 &Curl_handler_telnet,
175 #ifndef CURL_DISABLE_DICT
179 #ifndef CURL_DISABLE_LDAP
181 #if !defined(CURL_DISABLE_LDAPS) && \
182 ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \
183 (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)))
188 #ifndef CURL_DISABLE_FILE
192 #ifndef CURL_DISABLE_TFTP
201 #ifndef CURL_DISABLE_IMAP
208 #ifndef CURL_DISABLE_POP3
215 #if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
216 (CURL_SIZEOF_CURL_OFF_T > 4) && \
217 (!defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO))
224 #ifndef CURL_DISABLE_SMTP
231 #ifndef CURL_DISABLE_RTSP
235 #ifndef CURL_DISABLE_GOPHER
236 &Curl_handler_gopher,
243 &Curl_handler_rtmpte,
245 &Curl_handler_rtmpts,
248 (struct Curl_handler *) NULL
252 * Dummy handler for undefined protocol schemes.
255 static const struct Curl_handler Curl_handler_dummy = {
256 "<no protocol>", /* scheme */
257 ZERO_NULL, /* setup_connection */
258 ZERO_NULL, /* do_it */
259 ZERO_NULL, /* done */
260 ZERO_NULL, /* do_more */
261 ZERO_NULL, /* connect_it */
262 ZERO_NULL, /* connecting */
263 ZERO_NULL, /* doing */
264 ZERO_NULL, /* proto_getsock */
265 ZERO_NULL, /* doing_getsock */
266 ZERO_NULL, /* domore_getsock */
267 ZERO_NULL, /* perform_getsock */
268 ZERO_NULL, /* disconnect */
269 ZERO_NULL, /* readwrite */
272 PROTOPT_NONE /* flags */
275 void Curl_freeset(struct Curl_easy *data)
277 /* Free all dynamic strings stored in the data->set substructure. */
279 for(i=(enum dupstring)0; i < STRING_LAST; i++) {
280 Curl_safefree(data->set.str[i]);
283 if(data->change.referer_alloc) {
284 Curl_safefree(data->change.referer);
285 data->change.referer_alloc = FALSE;
287 data->change.referer = NULL;
288 if(data->change.url_alloc) {
289 Curl_safefree(data->change.url);
290 data->change.url_alloc = FALSE;
292 data->change.url = NULL;
295 static CURLcode setstropt(char **charp, const char *s)
297 /* Release the previous storage at `charp' and replace by a dynamic storage
298 copy of `s'. Return CURLE_OK or CURLE_OUT_OF_MEMORY. */
300 Curl_safefree(*charp);
303 char *str = strdup(s);
306 return CURLE_OUT_OF_MEMORY;
314 static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp)
316 CURLcode result = CURLE_OK;
320 /* Parse the login details if specified. It not then we treat NULL as a hint
321 to clear the existing data */
323 result = parse_login_details(option, strlen(option),
324 (userp ? &user : NULL),
325 (passwdp ? &passwd : NULL),
330 /* Store the username part of option if required */
332 if(!user && option && option[0] == ':') {
333 /* Allocate an empty string instead of returning NULL as user name */
336 result = CURLE_OUT_OF_MEMORY;
339 Curl_safefree(*userp);
343 /* Store the password part of option if required */
345 Curl_safefree(*passwdp);
353 CURLcode Curl_dupset(struct Curl_easy *dst, struct Curl_easy *src)
355 CURLcode result = CURLE_OK;
358 /* Copy src->set into dst->set first, then deal with the strings
362 /* clear all string pointers first */
363 memset(dst->set.str, 0, STRING_LAST * sizeof(char *));
365 /* duplicate all strings */
366 for(i=(enum dupstring)0; i< STRING_LASTZEROTERMINATED; i++) {
367 result = setstropt(&dst->set.str[i], src->set.str[i]);
372 /* duplicate memory areas pointed to */
373 i = STRING_COPYPOSTFIELDS;
374 if(src->set.postfieldsize && src->set.str[i]) {
375 /* postfieldsize is curl_off_t, Curl_memdup() takes a size_t ... */
376 dst->set.str[i] = Curl_memdup(src->set.str[i],
377 curlx_sotouz(src->set.postfieldsize));
379 return CURLE_OUT_OF_MEMORY;
380 /* point to the new copy */
381 dst->set.postfields = dst->set.str[i];
388 * This is the internal function curl_easy_cleanup() calls. This should
389 * cleanup and free all resources associated with this sessionhandle.
391 * NOTE: if we ever add something that attempts to write to a socket or
392 * similar here, we must ignore SIGPIPE first. It is currently only done
393 * when curl_easy_perform() is invoked.
396 CURLcode Curl_close(struct Curl_easy *data)
398 struct Curl_multi *m;
403 Curl_expire_clear(data); /* shut off timers */
408 /* This handle is still part of a multi handle, take care of this first
409 and detach this handle from there. */
410 curl_multi_remove_handle(data->multi, data);
413 /* when curl_easy_perform() is used, it creates its own multi handle to
414 use and this is the one */
415 curl_multi_cleanup(data->multi_easy);
417 /* Destroy the timeout list that is held in the easy handle. It is
418 /normally/ done by curl_multi_remove_handle() but this is "just in
420 if(data->state.timeoutlist) {
421 Curl_llist_destroy(data->state.timeoutlist, NULL);
422 data->state.timeoutlist = NULL;
425 data->magic = 0; /* force a clear AFTER the possibly enforced removal from
426 the multi handle, since that function uses the magic
429 if(data->state.rangestringalloc)
430 free(data->state.range);
432 /* Free the pathbuffer */
433 Curl_safefree(data->state.pathbuffer);
434 data->state.path = NULL;
436 /* freed here just in case DONE wasn't called */
437 Curl_free_request_state(data);
439 /* Close down all open SSL info and sessions */
440 Curl_ssl_close_all(data);
441 Curl_safefree(data->state.first_host);
442 Curl_safefree(data->state.scratch);
443 Curl_ssl_free_certinfo(data);
445 /* Cleanup possible redirect junk */
446 free(data->req.newurl);
447 data->req.newurl = NULL;
449 if(data->change.referer_alloc) {
450 Curl_safefree(data->change.referer);
451 data->change.referer_alloc = FALSE;
453 data->change.referer = NULL;
455 if(data->change.url_alloc) {
456 Curl_safefree(data->change.url);
457 data->change.url_alloc = FALSE;
459 data->change.url = NULL;
461 Curl_safefree(data->state.buffer);
462 Curl_safefree(data->state.headerbuff);
464 Curl_flush_cookies(data, 1);
466 Curl_digest_cleanup(data);
468 Curl_safefree(data->info.contenttype);
469 Curl_safefree(data->info.wouldredirect);
471 /* this destroys the channel and we cannot use it anymore after this */
472 Curl_resolver_cleanup(data->state.resolver);
474 Curl_http2_cleanup_dependencies(data);
475 Curl_convert_close(data);
477 /* No longer a dirty share, if it exists */
479 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
480 data->share->dirty--;
481 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
484 if(data->set.wildcardmatch) {
485 /* destruct wildcard structures if it is needed */
486 struct WildcardData *wc = &data->wildcard;
487 Curl_wildcard_dtor(wc);
496 * Initialize the UserDefined fields within a Curl_easy.
497 * This may be safely called on a new or existing Curl_easy.
499 CURLcode Curl_init_userdefined(struct UserDefined *set)
501 CURLcode result = CURLE_OK;
503 set->out = stdout; /* default output to stdout */
504 set->in_set = stdin; /* default input from stdin */
505 set->err = stderr; /* default stderr to stderr */
507 /* use fwrite as default function to store output */
508 set->fwrite_func = (curl_write_callback)fwrite;
510 /* use fread as default function to read input */
511 set->fread_func_set = (curl_read_callback)fread;
512 set->is_fread_set = 0;
513 set->is_fwrite_set = 0;
515 set->seek_func = ZERO_NULL;
516 set->seek_client = ZERO_NULL;
518 /* conversion callbacks for non-ASCII hosts */
519 set->convfromnetwork = ZERO_NULL;
520 set->convtonetwork = ZERO_NULL;
521 set->convfromutf8 = ZERO_NULL;
523 set->filesize = -1; /* we don't know the size */
524 set->postfieldsize = -1; /* unknown size */
525 set->maxredirs = -1; /* allow any amount by default */
527 set->httpreq = HTTPREQ_GET; /* Default HTTP request */
528 set->rtspreq = RTSPREQ_OPTIONS; /* Default RTSP request */
529 set->ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */
530 set->ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */
531 set->ftp_use_pret = FALSE; /* mainly useful for drftpd servers */
532 set->ftp_filemethod = FTPFILE_MULTICWD;
534 set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
536 /* Set the default size of the SSL session ID cache */
537 set->general_ssl.max_ssl_sessions = 5;
540 set->proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
541 set->httpauth = CURLAUTH_BASIC; /* defaults to basic */
542 set->proxyauth = CURLAUTH_BASIC; /* defaults to basic */
544 /* make libcurl quiet by default: */
545 set->hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */
548 * libcurl 7.10 introduced SSL verification *by default*! This needs to be
549 * switched off unless wanted.
551 set->ssl.primary.verifypeer = TRUE;
552 set->ssl.primary.verifyhost = TRUE;
554 set->ssl.authtype = CURL_TLSAUTH_NONE;
556 set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
558 set->ssl.primary.sessionid = TRUE; /* session ID caching enabled by
560 set->proxy_ssl = set->ssl;
562 set->new_file_perms = 0644; /* Default permissions */
563 set->new_directory_perms = 0755; /* Default permissions */
565 /* for the *protocols fields we don't use the CURLPROTO_ALL convenience
566 define since we internally only use the lower 16 bits for the passed
567 in bitmask to not conflict with the private bits */
568 set->allowed_protocols = CURLPROTO_ALL;
569 set->redir_protocols = CURLPROTO_ALL & /* All except FILE, SCP and SMB */
570 ~(CURLPROTO_FILE | CURLPROTO_SCP | CURLPROTO_SMB |
573 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
575 * disallow unprotected protection negotiation NEC reference implementation
576 * seem not to follow rfc1961 section 4.3/4.4
578 set->socks5_gssapi_nec = FALSE;
581 /* This is our preferred CA cert bundle/path since install time */
582 #if defined(CURL_CA_BUNDLE)
583 result = setstropt(&set->str[STRING_SSL_CAFILE_ORIG], CURL_CA_BUNDLE);
587 result = setstropt(&set->str[STRING_SSL_CAFILE_PROXY], CURL_CA_BUNDLE);
591 #if defined(CURL_CA_PATH)
592 result = setstropt(&set->str[STRING_SSL_CAPATH_ORIG], CURL_CA_PATH);
596 result = setstropt(&set->str[STRING_SSL_CAPATH_PROXY], CURL_CA_PATH);
601 set->wildcardmatch = FALSE;
602 set->chunk_bgn = ZERO_NULL;
603 set->chunk_end = ZERO_NULL;
605 /* tcp keepalives are disabled by default, but provide reasonable values for
606 * the interval and idle times.
608 set->tcp_keepalive = FALSE;
609 set->tcp_keepintvl = 60;
610 set->tcp_keepidle = 60;
611 set->tcp_fastopen = FALSE;
612 set->tcp_nodelay = TRUE;
614 set->ssl_enable_npn = TRUE;
615 set->ssl_enable_alpn = TRUE;
617 set->expect_100_timeout = 1000L; /* Wait for a second by default. */
618 set->sep_headers = TRUE; /* separated header lists by default */
620 Curl_http2_init_userset(set);
627 * @param curl is a pointer to a sessionhandle pointer that gets set by this
632 CURLcode Curl_open(struct Curl_easy **curl)
635 struct Curl_easy *data;
637 /* Very simple start-up: alloc the struct, init it with zeroes and return */
638 data = calloc(1, sizeof(struct Curl_easy));
640 /* this is a very serious error */
641 DEBUGF(fprintf(stderr, "Error: calloc of Curl_easy failed\n"));
642 return CURLE_OUT_OF_MEMORY;
645 data->magic = CURLEASY_MAGIC_NUMBER;
647 result = Curl_resolver_init(&data->state.resolver);
649 DEBUGF(fprintf(stderr, "Error: resolver_init failed\n"));
654 /* We do some initial setup here, all those fields that can't be just 0 */
656 data->state.buffer = malloc(BUFSIZE + 1);
657 if(!data->state.buffer) {
658 DEBUGF(fprintf(stderr, "Error: malloc of buffer failed\n"));
659 result = CURLE_OUT_OF_MEMORY;
662 data->state.headerbuff = malloc(HEADERSIZE);
663 if(!data->state.headerbuff) {
664 DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n"));
665 result = CURLE_OUT_OF_MEMORY;
668 result = Curl_init_userdefined(&data->set);
670 data->state.headersize=HEADERSIZE;
672 Curl_convert_init(data);
676 /* most recent connection is not yet defined */
677 data->state.lastconnect = NULL;
679 data->progress.flags |= PGRS_HIDE;
680 data->state.current_speed = -1; /* init to negative == impossible */
682 data->wildcard.state = CURLWC_INIT;
683 data->wildcard.filelist = NULL;
684 data->set.fnmatch = ZERO_NULL;
685 data->set.maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */
687 Curl_http2_init_state(&data->state);
691 Curl_resolver_cleanup(data->state.resolver);
692 free(data->state.buffer);
693 free(data->state.headerbuff);
704 CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
708 CURLcode result = CURLE_OK;
710 #ifndef CURL_DISABLE_HTTP
715 case CURLOPT_DNS_CACHE_TIMEOUT:
716 data->set.dns_cache_timeout = va_arg(param, long);
718 case CURLOPT_DNS_USE_GLOBAL_CACHE:
719 /* remember we want this enabled */
720 arg = va_arg(param, long);
721 data->set.global_dns_cache = (0 != arg) ? TRUE : FALSE;
723 case CURLOPT_SSL_CIPHER_LIST:
724 /* set a list of cipher we want to use in the SSL connection */
725 result = setstropt(&data->set.str[STRING_SSL_CIPHER_LIST_ORIG],
726 va_arg(param, char *));
728 case CURLOPT_PROXY_SSL_CIPHER_LIST:
729 /* set a list of cipher we want to use in the SSL connection for proxy */
730 result = setstropt(&data->set.str[STRING_SSL_CIPHER_LIST_PROXY],
731 va_arg(param, char *));
734 case CURLOPT_RANDOM_FILE:
736 * This is the path name to a file that contains random data to seed
737 * the random SSL stuff with. The file is only used for reading.
739 result = setstropt(&data->set.str[STRING_SSL_RANDOM_FILE],
740 va_arg(param, char *));
742 case CURLOPT_EGDSOCKET:
744 * The Entropy Gathering Daemon socket pathname
746 result = setstropt(&data->set.str[STRING_SSL_EGDSOCKET],
747 va_arg(param, char *));
749 case CURLOPT_MAXCONNECTS:
751 * Set the absolute number of maximum simultaneous alive connection that
752 * libcurl is allowed to have.
754 data->set.maxconnects = va_arg(param, long);
756 case CURLOPT_FORBID_REUSE:
758 * When this transfer is done, it must not be left to be reused by a
759 * subsequent transfer but shall be closed immediately.
761 data->set.reuse_forbid = (0 != va_arg(param, long)) ? TRUE : FALSE;
763 case CURLOPT_FRESH_CONNECT:
765 * This transfer shall not use a previously cached connection but
766 * should be made with a fresh new connect!
768 data->set.reuse_fresh = (0 != va_arg(param, long)) ? TRUE : FALSE;
770 case CURLOPT_VERBOSE:
772 * Verbose means infof() calls that give a lot of information about
773 * the connection and transfer procedures as well as internal choices.
775 data->set.verbose = (0 != va_arg(param, long)) ? TRUE : FALSE;
779 * Set to include the header in the general data output stream.
781 data->set.include_header = (0 != va_arg(param, long)) ? TRUE : FALSE;
783 case CURLOPT_NOPROGRESS:
785 * Shut off the internal supported progress meter
787 data->set.hide_progress = (0 != va_arg(param, long)) ? TRUE : FALSE;
788 if(data->set.hide_progress)
789 data->progress.flags |= PGRS_HIDE;
791 data->progress.flags &= ~PGRS_HIDE;
795 * Do not include the body part in the output data stream.
797 data->set.opt_no_body = (0 != va_arg(param, long)) ? TRUE : FALSE;
799 case CURLOPT_FAILONERROR:
801 * Don't output the >=400 error code HTML-page, but instead only
804 data->set.http_fail_on_error = (0 != va_arg(param, long)) ? TRUE : FALSE;
806 case CURLOPT_KEEP_SENDING_ON_ERROR:
807 data->set.http_keep_sending_on_error = (0 != va_arg(param, long)) ?
813 * We want to sent data to the remote host. If this is HTTP, that equals
814 * using the PUT request.
816 data->set.upload = (0 != va_arg(param, long)) ? TRUE : FALSE;
817 if(data->set.upload) {
818 /* If this is HTTP, PUT is what's needed to "upload" */
819 data->set.httpreq = HTTPREQ_PUT;
820 data->set.opt_no_body = FALSE; /* this is implied */
823 /* In HTTP, the opposite of upload is GET (unless NOBODY is true as
824 then this can be changed to HEAD later on) */
825 data->set.httpreq = HTTPREQ_GET;
827 case CURLOPT_FILETIME:
829 * Try to get the file time of the remote document. The time will
830 * later (possibly) become available using curl_easy_getinfo().
832 data->set.get_filetime = (0 != va_arg(param, long)) ? TRUE : FALSE;
834 case CURLOPT_FTP_CREATE_MISSING_DIRS:
836 * An FTP option that modifies an upload to create missing directories on
839 switch(va_arg(param, long)) {
841 data->set.ftp_create_missing_dirs = 0;
844 data->set.ftp_create_missing_dirs = 1;
847 data->set.ftp_create_missing_dirs = 2;
850 /* reserve other values for future use */
851 result = CURLE_UNKNOWN_OPTION;
855 case CURLOPT_SERVER_RESPONSE_TIMEOUT:
857 * Option that specifies how quickly an server response must be obtained
858 * before it is considered failure. For pingpong protocols.
860 data->set.server_response_timeout = va_arg(param, long) * 1000;
862 case CURLOPT_TFTP_NO_OPTIONS:
864 * Option that prevents libcurl from sending TFTP option requests to the
867 data->set.tftp_no_options = va_arg(param, long) != 0;
869 case CURLOPT_TFTP_BLKSIZE:
871 * TFTP option that specifies the block size to use for data transmission.
873 data->set.tftp_blksize = va_arg(param, long);
875 case CURLOPT_DIRLISTONLY:
877 * An option that changes the command to one that asks for a list
878 * only, no file info details.
880 data->set.ftp_list_only = (0 != va_arg(param, long)) ? TRUE : FALSE;
884 * We want to upload and append to an existing file.
886 data->set.ftp_append = (0 != va_arg(param, long)) ? TRUE : FALSE;
888 case CURLOPT_FTP_FILEMETHOD:
890 * How do access files over FTP.
892 data->set.ftp_filemethod = (curl_ftpfile)va_arg(param, long);
896 * Parse the $HOME/.netrc file
898 data->set.use_netrc = (enum CURL_NETRC_OPTION)va_arg(param, long);
900 case CURLOPT_NETRC_FILE:
902 * Use this file instead of the $HOME/.netrc file
904 result = setstropt(&data->set.str[STRING_NETRC_FILE],
905 va_arg(param, char *));
907 case CURLOPT_TRANSFERTEXT:
909 * This option was previously named 'FTPASCII'. Renamed to work with
910 * more protocols than merely FTP.
912 * Transfer using ASCII (instead of BINARY).
914 data->set.prefer_ascii = (0 != va_arg(param, long)) ? TRUE : FALSE;
916 case CURLOPT_TIMECONDITION:
918 * Set HTTP time condition. This must be one of the defines in the
919 * curl/curl.h header file.
921 data->set.timecondition = (curl_TimeCond)va_arg(param, long);
923 case CURLOPT_TIMEVALUE:
925 * This is the value to compare with the remote document with the
926 * method set with CURLOPT_TIMECONDITION
928 data->set.timevalue = (time_t)va_arg(param, long);
930 case CURLOPT_SSLVERSION:
932 * Set explicit SSL version to try to connect with, as some SSL
933 * implementations are lame.
936 data->set.ssl.primary.version = va_arg(param, long);
938 result = CURLE_UNKNOWN_OPTION;
941 case CURLOPT_PROXY_SSLVERSION:
943 * Set explicit SSL version to try to connect with for proxy, as some SSL
944 * implementations are lame.
947 data->set.proxy_ssl.primary.version = va_arg(param, long);
949 result = CURLE_UNKNOWN_OPTION;
953 #ifndef CURL_DISABLE_HTTP
954 case CURLOPT_AUTOREFERER:
956 * Switch on automatic referer that gets set if curl follows locations.
958 data->set.http_auto_referer = (0 != va_arg(param, long)) ? TRUE : FALSE;
961 case CURLOPT_ACCEPT_ENCODING:
963 * String to use at the value of Accept-Encoding header.
965 * If the encoding is set to "" we use an Accept-Encoding header that
966 * encompasses all the encodings we support.
967 * If the encoding is set to NULL we don't send an Accept-Encoding header
968 * and ignore an received Content-Encoding header.
971 argptr = va_arg(param, char *);
972 result = setstropt(&data->set.str[STRING_ENCODING],
973 (argptr && !*argptr)?
974 ALL_CONTENT_ENCODINGS: argptr);
977 case CURLOPT_TRANSFER_ENCODING:
978 data->set.http_transfer_encoding = (0 != va_arg(param, long)) ?
982 case CURLOPT_FOLLOWLOCATION:
984 * Follow Location: header hints on a HTTP-server.
986 data->set.http_follow_location = (0 != va_arg(param, long)) ? TRUE : FALSE;
989 case CURLOPT_UNRESTRICTED_AUTH:
991 * Send authentication (user+password) when following locations, even when
994 data->set.http_disable_hostname_check_before_authentication =
995 (0 != va_arg(param, long)) ? TRUE : FALSE;
998 case CURLOPT_MAXREDIRS:
1000 * The maximum amount of hops you allow curl to follow Location:
1001 * headers. This should mostly be used to detect never-ending loops.
1003 data->set.maxredirs = va_arg(param, long);
1006 case CURLOPT_POSTREDIR:
1009 * Set the behaviour of POST when redirecting
1010 * CURL_REDIR_GET_ALL - POST is changed to GET after 301 and 302
1011 * CURL_REDIR_POST_301 - POST is kept as POST after 301
1012 * CURL_REDIR_POST_302 - POST is kept as POST after 302
1013 * CURL_REDIR_POST_303 - POST is kept as POST after 303
1014 * CURL_REDIR_POST_ALL - POST is kept as POST after 301, 302 and 303
1015 * other - POST is kept as POST after 301 and 302
1017 int postRedir = curlx_sltosi(va_arg(param, long));
1018 data->set.keep_post = postRedir & CURL_REDIR_POST_ALL;
1023 /* Does this option serve a purpose anymore? Yes it does, when
1024 CURLOPT_POSTFIELDS isn't used and the POST data is read off the
1026 if(va_arg(param, long)) {
1027 data->set.httpreq = HTTPREQ_POST;
1028 data->set.opt_no_body = FALSE; /* this is implied */
1031 data->set.httpreq = HTTPREQ_GET;
1034 case CURLOPT_COPYPOSTFIELDS:
1036 * A string with POST data. Makes curl HTTP POST. Even if it is NULL.
1037 * If needed, CURLOPT_POSTFIELDSIZE must have been set prior to
1038 * CURLOPT_COPYPOSTFIELDS and not altered later.
1040 argptr = va_arg(param, char *);
1042 if(!argptr || data->set.postfieldsize == -1)
1043 result = setstropt(&data->set.str[STRING_COPYPOSTFIELDS], argptr);
1046 * Check that requested length does not overflow the size_t type.
1049 if((data->set.postfieldsize < 0) ||
1050 ((sizeof(curl_off_t) != sizeof(size_t)) &&
1051 (data->set.postfieldsize > (curl_off_t)((size_t)-1))))
1052 result = CURLE_OUT_OF_MEMORY;
1056 (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1058 /* Allocate even when size == 0. This satisfies the need of possible
1059 later address compare to detect the COPYPOSTFIELDS mode, and
1060 to mark that postfields is used rather than read function or
1063 p = malloc((size_t)(data->set.postfieldsize?
1064 data->set.postfieldsize:1));
1067 result = CURLE_OUT_OF_MEMORY;
1069 if(data->set.postfieldsize)
1070 memcpy(p, argptr, (size_t)data->set.postfieldsize);
1072 data->set.str[STRING_COPYPOSTFIELDS] = p;
1077 data->set.postfields = data->set.str[STRING_COPYPOSTFIELDS];
1078 data->set.httpreq = HTTPREQ_POST;
1081 case CURLOPT_POSTFIELDS:
1083 * Like above, but use static data instead of copying it.
1085 data->set.postfields = va_arg(param, void *);
1086 /* Release old copied data. */
1087 (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1088 data->set.httpreq = HTTPREQ_POST;
1091 case CURLOPT_POSTFIELDSIZE:
1093 * The size of the POSTFIELD data to prevent libcurl to do strlen() to
1094 * figure it out. Enables binary posts.
1096 bigsize = va_arg(param, long);
1098 if(data->set.postfieldsize < bigsize &&
1099 data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
1100 /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */
1101 (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1102 data->set.postfields = NULL;
1105 data->set.postfieldsize = bigsize;
1108 case CURLOPT_POSTFIELDSIZE_LARGE:
1110 * The size of the POSTFIELD data to prevent libcurl to do strlen() to
1111 * figure it out. Enables binary posts.
1113 bigsize = va_arg(param, curl_off_t);
1115 if(data->set.postfieldsize < bigsize &&
1116 data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
1117 /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */
1118 (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1119 data->set.postfields = NULL;
1122 data->set.postfieldsize = bigsize;
1125 case CURLOPT_HTTPPOST:
1127 * Set to make us do HTTP POST
1129 data->set.httppost = va_arg(param, struct curl_httppost *);
1130 data->set.httpreq = HTTPREQ_POST_FORM;
1131 data->set.opt_no_body = FALSE; /* this is implied */
1134 case CURLOPT_REFERER:
1136 * String to set in the HTTP Referer: field.
1138 if(data->change.referer_alloc) {
1139 Curl_safefree(data->change.referer);
1140 data->change.referer_alloc = FALSE;
1142 result = setstropt(&data->set.str[STRING_SET_REFERER],
1143 va_arg(param, char *));
1144 data->change.referer = data->set.str[STRING_SET_REFERER];
1147 case CURLOPT_USERAGENT:
1149 * String to use in the HTTP User-Agent field
1151 result = setstropt(&data->set.str[STRING_USERAGENT],
1152 va_arg(param, char *));
1155 case CURLOPT_HTTPHEADER:
1157 * Set a list with HTTP headers to use (or replace internals with)
1159 data->set.headers = va_arg(param, struct curl_slist *);
1162 case CURLOPT_PROXYHEADER:
1164 * Set a list with proxy headers to use (or replace internals with)
1166 * Since CURLOPT_HTTPHEADER was the only way to set HTTP headers for a
1167 * long time we remain doing it this way until CURLOPT_PROXYHEADER is
1168 * used. As soon as this option has been used, if set to anything but
1169 * NULL, custom headers for proxies are only picked from this list.
1171 * Set this option to NULL to restore the previous behavior.
1173 data->set.proxyheaders = va_arg(param, struct curl_slist *);
1176 case CURLOPT_HEADEROPT:
1178 * Set header option.
1180 arg = va_arg(param, long);
1181 data->set.sep_headers = (arg & CURLHEADER_SEPARATE)? TRUE: FALSE;
1184 case CURLOPT_HTTP200ALIASES:
1186 * Set a list of aliases for HTTP 200 in response header
1188 data->set.http200aliases = va_arg(param, struct curl_slist *);
1191 #if !defined(CURL_DISABLE_COOKIES)
1192 case CURLOPT_COOKIE:
1194 * Cookie string to send to the remote server in the request.
1196 result = setstropt(&data->set.str[STRING_COOKIE],
1197 va_arg(param, char *));
1200 case CURLOPT_COOKIEFILE:
1202 * Set cookie file to read and parse. Can be used multiple times.
1204 argptr = (char *)va_arg(param, void *);
1206 struct curl_slist *cl;
1207 /* append the cookie file name to the list of file names, and deal with
1209 cl = curl_slist_append(data->change.cookielist, argptr);
1211 curl_slist_free_all(data->change.cookielist);
1212 data->change.cookielist = NULL;
1213 return CURLE_OUT_OF_MEMORY;
1215 data->change.cookielist = cl; /* store the list for later use */
1219 case CURLOPT_COOKIEJAR:
1221 * Set cookie file name to dump all cookies to when we're done.
1224 struct CookieInfo *newcookies;
1225 result = setstropt(&data->set.str[STRING_COOKIEJAR],
1226 va_arg(param, char *));
1229 * Activate the cookie parser. This may or may not already
1232 newcookies = Curl_cookie_init(data, NULL, data->cookies,
1233 data->set.cookiesession);
1235 result = CURLE_OUT_OF_MEMORY;
1236 data->cookies = newcookies;
1240 case CURLOPT_COOKIESESSION:
1242 * Set this option to TRUE to start a new "cookie session". It will
1243 * prevent the forthcoming read-cookies-from-file actions to accept
1244 * cookies that are marked as being session cookies, as they belong to a
1247 * In the original Netscape cookie spec, "session cookies" are cookies
1248 * with no expire date set. RFC2109 describes the same action if no
1249 * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds
1250 * a 'Discard' action that can enforce the discard even for cookies that
1253 * We run mostly with the original cookie spec, as hardly anyone implements
1256 data->set.cookiesession = (0 != va_arg(param, long)) ? TRUE : FALSE;
1259 case CURLOPT_COOKIELIST:
1260 argptr = va_arg(param, char *);
1265 if(strcasecompare(argptr, "ALL")) {
1266 /* clear all cookies */
1267 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
1268 Curl_cookie_clearall(data->cookies);
1269 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
1271 else if(strcasecompare(argptr, "SESS")) {
1272 /* clear session cookies */
1273 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
1274 Curl_cookie_clearsess(data->cookies);
1275 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
1277 else if(strcasecompare(argptr, "FLUSH")) {
1278 /* flush cookies to file, takes care of the locking */
1279 Curl_flush_cookies(data, 0);
1281 else if(strcasecompare(argptr, "RELOAD")) {
1282 /* reload cookies from file */
1283 Curl_cookie_loadfiles(data);
1288 /* if cookie engine was not running, activate it */
1289 data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE);
1291 argptr = strdup(argptr);
1292 if(!argptr || !data->cookies) {
1293 result = CURLE_OUT_OF_MEMORY;
1297 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
1299 if(checkprefix("Set-Cookie:", argptr))
1300 /* HTTP Header format line */
1301 Curl_cookie_add(data, data->cookies, TRUE, argptr + 11, NULL, NULL);
1304 /* Netscape format line */
1305 Curl_cookie_add(data, data->cookies, FALSE, argptr, NULL, NULL);
1307 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
1313 #endif /* CURL_DISABLE_COOKIES */
1315 case CURLOPT_HTTPGET:
1317 * Set to force us do HTTP GET
1319 if(va_arg(param, long)) {
1320 data->set.httpreq = HTTPREQ_GET;
1321 data->set.upload = FALSE; /* switch off upload */
1322 data->set.opt_no_body = FALSE; /* this is implied */
1326 case CURLOPT_HTTP_VERSION:
1328 * This sets a requested HTTP version to be used. The value is one of
1329 * the listed enums in curl/curl.h.
1331 arg = va_arg(param, long);
1333 if(arg >= CURL_HTTP_VERSION_2)
1334 return CURLE_UNSUPPORTED_PROTOCOL;
1336 data->set.httpversion = arg;
1339 case CURLOPT_HTTPAUTH:
1341 * Set HTTP Authentication type BITMASK.
1346 unsigned long auth = va_arg(param, unsigned long);
1348 if(auth == CURLAUTH_NONE) {
1349 data->set.httpauth = auth;
1353 /* the DIGEST_IE bit is only used to set a special marker, for all the
1354 rest we need to handle it as normal DIGEST */
1355 data->state.authhost.iestyle = (auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE;
1357 if(auth & CURLAUTH_DIGEST_IE) {
1358 auth |= CURLAUTH_DIGEST; /* set standard digest bit */
1359 auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */
1362 /* switch off bits we can't support */
1364 auth &= ~CURLAUTH_NTLM; /* no NTLM support */
1365 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
1366 #elif !defined(NTLM_WB_ENABLED)
1367 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
1370 auth &= ~CURLAUTH_NEGOTIATE; /* no Negotiate (SPNEGO) auth without
1374 /* check if any auth bit lower than CURLAUTH_ONLY is still set */
1377 while(bitcheck < 31) {
1378 if(auth & (1UL << bitcheck++)) {
1384 return CURLE_NOT_BUILT_IN; /* no supported types left! */
1386 data->set.httpauth = auth;
1390 case CURLOPT_EXPECT_100_TIMEOUT_MS:
1392 * Time to wait for a response to a HTTP request containing an
1393 * Expect: 100-continue header before sending the data anyway.
1395 data->set.expect_100_timeout = va_arg(param, long);
1398 #endif /* CURL_DISABLE_HTTP */
1400 case CURLOPT_CUSTOMREQUEST:
1402 * Set a custom string to use as request
1404 result = setstropt(&data->set.str[STRING_CUSTOMREQUEST],
1405 va_arg(param, char *));
1408 data->set.httpreq = HTTPREQ_CUSTOM;
1409 here, we continue as if we were using the already set type
1410 and this just changes the actual request keyword */
1413 #ifndef CURL_DISABLE_PROXY
1414 case CURLOPT_HTTPPROXYTUNNEL:
1416 * Tunnel operations through the proxy instead of normal proxy use
1418 data->set.tunnel_thru_httpproxy = (0 != va_arg(param, long)) ?
1422 case CURLOPT_PROXYPORT:
1424 * Explicitly set HTTP proxy port number.
1426 data->set.proxyport = va_arg(param, long);
1429 case CURLOPT_PROXYAUTH:
1431 * Set HTTP Authentication type BITMASK.
1436 unsigned long auth = va_arg(param, unsigned long);
1438 if(auth == CURLAUTH_NONE) {
1439 data->set.proxyauth = auth;
1443 /* the DIGEST_IE bit is only used to set a special marker, for all the
1444 rest we need to handle it as normal DIGEST */
1445 data->state.authproxy.iestyle = (auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE;
1447 if(auth & CURLAUTH_DIGEST_IE) {
1448 auth |= CURLAUTH_DIGEST; /* set standard digest bit */
1449 auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */
1451 /* switch off bits we can't support */
1453 auth &= ~CURLAUTH_NTLM; /* no NTLM support */
1454 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
1455 #elif !defined(NTLM_WB_ENABLED)
1456 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
1459 auth &= ~CURLAUTH_NEGOTIATE; /* no Negotiate (SPNEGO) auth without
1463 /* check if any auth bit lower than CURLAUTH_ONLY is still set */
1466 while(bitcheck < 31) {
1467 if(auth & (1UL << bitcheck++)) {
1473 return CURLE_NOT_BUILT_IN; /* no supported types left! */
1475 data->set.proxyauth = auth;
1481 * Set proxy server:port to use as proxy.
1483 * If the proxy is set to "" (and CURLOPT_SOCKS_PROXY is set to "" or NULL)
1484 * we explicitly say that we don't want to use a proxy
1485 * (even though there might be environment variables saying so).
1487 * Setting it to NULL, means no proxy but allows the environment variables
1488 * to decide for us (if CURLOPT_SOCKS_PROXY setting it to NULL).
1490 result = setstropt(&data->set.str[STRING_PROXY],
1491 va_arg(param, char *));
1494 case CURLOPT_PRE_PROXY:
1496 * Set proxy server:port to use as SOCKS proxy.
1498 * If the proxy is set to "" or NULL we explicitly say that we don't want
1499 * to use the socks proxy.
1501 result = setstropt(&data->set.str[STRING_PRE_PROXY],
1502 va_arg(param, char *));
1505 case CURLOPT_PROXYTYPE:
1507 * Set proxy type. HTTP/HTTP_1_0/SOCKS4/SOCKS4a/SOCKS5/SOCKS5_HOSTNAME
1509 data->set.proxytype = (curl_proxytype)va_arg(param, long);
1512 case CURLOPT_PROXY_TRANSFER_MODE:
1514 * set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy
1516 switch(va_arg(param, long)) {
1518 data->set.proxy_transfer_mode = FALSE;
1521 data->set.proxy_transfer_mode = TRUE;
1524 /* reserve other values for future use */
1525 result = CURLE_UNKNOWN_OPTION;
1529 #endif /* CURL_DISABLE_PROXY */
1531 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
1532 case CURLOPT_SOCKS5_GSSAPI_NEC:
1534 * Set flag for NEC SOCK5 support
1536 data->set.socks5_gssapi_nec = (0 != va_arg(param, long)) ? TRUE : FALSE;
1539 case CURLOPT_SOCKS5_GSSAPI_SERVICE:
1540 case CURLOPT_PROXY_SERVICE_NAME:
1542 * Set proxy authentication service name for Kerberos 5 and SPNEGO
1544 result = setstropt(&data->set.str[STRING_PROXY_SERVICE_NAME],
1545 va_arg(param, char *));
1549 #if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) || \
1551 case CURLOPT_SERVICE_NAME:
1553 * Set authentication service name for DIGEST-MD5, Kerberos 5 and SPNEGO
1555 result = setstropt(&data->set.str[STRING_SERVICE_NAME],
1556 va_arg(param, char *));
1561 case CURLOPT_HEADERDATA:
1563 * Custom pointer to pass the header write callback function
1565 data->set.writeheader = (void *)va_arg(param, void *);
1567 case CURLOPT_ERRORBUFFER:
1569 * Error buffer provided by the caller to get the human readable
1572 data->set.errorbuffer = va_arg(param, char *);
1574 case CURLOPT_WRITEDATA:
1576 * FILE pointer to write to. Or possibly
1577 * used as argument to the write callback.
1579 data->set.out = va_arg(param, void *);
1581 case CURLOPT_FTPPORT:
1583 * Use FTP PORT, this also specifies which IP address to use
1585 result = setstropt(&data->set.str[STRING_FTPPORT],
1586 va_arg(param, char *));
1587 data->set.ftp_use_port = (data->set.str[STRING_FTPPORT]) ? TRUE : FALSE;
1590 case CURLOPT_FTP_USE_EPRT:
1591 data->set.ftp_use_eprt = (0 != va_arg(param, long)) ? TRUE : FALSE;
1594 case CURLOPT_FTP_USE_EPSV:
1595 data->set.ftp_use_epsv = (0 != va_arg(param, long)) ? TRUE : FALSE;
1598 case CURLOPT_FTP_USE_PRET:
1599 data->set.ftp_use_pret = (0 != va_arg(param, long)) ? TRUE : FALSE;
1602 case CURLOPT_FTP_SSL_CCC:
1603 data->set.ftp_ccc = (curl_ftpccc)va_arg(param, long);
1606 case CURLOPT_FTP_SKIP_PASV_IP:
1608 * Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the
1609 * bypass of the IP address in PASV responses.
1611 data->set.ftp_skip_ip = (0 != va_arg(param, long)) ? TRUE : FALSE;
1614 case CURLOPT_READDATA:
1616 * FILE pointer to read the file to be uploaded from. Or possibly
1617 * used as argument to the read callback.
1619 data->set.in_set = va_arg(param, void *);
1621 case CURLOPT_INFILESIZE:
1623 * If known, this should inform curl about the file size of the
1624 * to-be-uploaded file.
1626 data->set.filesize = va_arg(param, long);
1628 case CURLOPT_INFILESIZE_LARGE:
1630 * If known, this should inform curl about the file size of the
1631 * to-be-uploaded file.
1633 data->set.filesize = va_arg(param, curl_off_t);
1635 case CURLOPT_LOW_SPEED_LIMIT:
1637 * The low speed limit that if transfers are below this for
1638 * CURLOPT_LOW_SPEED_TIME, the transfer is aborted.
1640 data->set.low_speed_limit=va_arg(param, long);
1642 case CURLOPT_MAX_SEND_SPEED_LARGE:
1644 * When transfer uploads are faster then CURLOPT_MAX_SEND_SPEED_LARGE
1645 * bytes per second the transfer is throttled..
1647 data->set.max_send_speed=va_arg(param, curl_off_t);
1649 case CURLOPT_MAX_RECV_SPEED_LARGE:
1651 * When receiving data faster than CURLOPT_MAX_RECV_SPEED_LARGE bytes per
1652 * second the transfer is throttled..
1654 data->set.max_recv_speed=va_arg(param, curl_off_t);
1656 case CURLOPT_LOW_SPEED_TIME:
1658 * The low speed time that if transfers are below the set
1659 * CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted.
1661 data->set.low_speed_time=va_arg(param, long);
1667 if(data->change.url_alloc) {
1668 /* the already set URL is allocated, free it first! */
1669 Curl_safefree(data->change.url);
1670 data->change.url_alloc = FALSE;
1672 result = setstropt(&data->set.str[STRING_SET_URL],
1673 va_arg(param, char *));
1674 data->change.url = data->set.str[STRING_SET_URL];
1678 * The port number to use when getting the URL
1680 data->set.use_port = va_arg(param, long);
1682 case CURLOPT_TIMEOUT:
1684 * The maximum time you allow curl to use for a single transfer
1687 data->set.timeout = va_arg(param, long) * 1000L;
1690 case CURLOPT_TIMEOUT_MS:
1691 data->set.timeout = va_arg(param, long);
1694 case CURLOPT_CONNECTTIMEOUT:
1696 * The maximum time you allow curl to use to connect.
1698 data->set.connecttimeout = va_arg(param, long) * 1000L;
1701 case CURLOPT_CONNECTTIMEOUT_MS:
1702 data->set.connecttimeout = va_arg(param, long);
1705 case CURLOPT_ACCEPTTIMEOUT_MS:
1707 * The maximum time you allow curl to wait for server connect
1709 data->set.accepttimeout = va_arg(param, long);
1712 case CURLOPT_USERPWD:
1714 * user:password to use in the operation
1716 result = setstropt_userpwd(va_arg(param, char *),
1717 &data->set.str[STRING_USERNAME],
1718 &data->set.str[STRING_PASSWORD]);
1721 case CURLOPT_USERNAME:
1723 * authentication user name to use in the operation
1725 result = setstropt(&data->set.str[STRING_USERNAME],
1726 va_arg(param, char *));
1729 case CURLOPT_PASSWORD:
1731 * authentication password to use in the operation
1733 result = setstropt(&data->set.str[STRING_PASSWORD],
1734 va_arg(param, char *));
1737 case CURLOPT_LOGIN_OPTIONS:
1739 * authentication options to use in the operation
1741 result = setstropt(&data->set.str[STRING_OPTIONS],
1742 va_arg(param, char *));
1745 case CURLOPT_XOAUTH2_BEARER:
1747 * OAuth 2.0 bearer token to use in the operation
1749 result = setstropt(&data->set.str[STRING_BEARER],
1750 va_arg(param, char *));
1753 case CURLOPT_POSTQUOTE:
1755 * List of RAW FTP commands to use after a transfer
1757 data->set.postquote = va_arg(param, struct curl_slist *);
1759 case CURLOPT_PREQUOTE:
1761 * List of RAW FTP commands to use prior to RETR (Wesley Laxton)
1763 data->set.prequote = va_arg(param, struct curl_slist *);
1767 * List of RAW FTP commands to use before a transfer
1769 data->set.quote = va_arg(param, struct curl_slist *);
1771 case CURLOPT_RESOLVE:
1773 * List of NAME:[address] names to populate the DNS cache with
1774 * Prefix the NAME with dash (-) to _remove_ the name from the cache.
1776 * Names added with this API will remain in the cache until explicitly
1777 * removed or the handle is cleaned up.
1779 * This API can remove any name from the DNS cache, but only entries
1780 * that aren't actually in use right now will be pruned immediately.
1782 data->set.resolve = va_arg(param, struct curl_slist *);
1783 data->change.resolve = data->set.resolve;
1785 case CURLOPT_PROGRESSFUNCTION:
1787 * Progress callback function
1789 data->set.fprogress = va_arg(param, curl_progress_callback);
1790 if(data->set.fprogress)
1791 data->progress.callback = TRUE; /* no longer internal */
1793 data->progress.callback = FALSE; /* NULL enforces internal */
1796 case CURLOPT_XFERINFOFUNCTION:
1798 * Transfer info callback function
1800 data->set.fxferinfo = va_arg(param, curl_xferinfo_callback);
1801 if(data->set.fxferinfo)
1802 data->progress.callback = TRUE; /* no longer internal */
1804 data->progress.callback = FALSE; /* NULL enforces internal */
1808 case CURLOPT_PROGRESSDATA:
1810 * Custom client data to pass to the progress callback
1812 data->set.progress_client = va_arg(param, void *);
1815 #ifndef CURL_DISABLE_PROXY
1816 case CURLOPT_PROXYUSERPWD:
1818 * user:password needed to use the proxy
1820 result = setstropt_userpwd(va_arg(param, char *),
1821 &data->set.str[STRING_PROXYUSERNAME],
1822 &data->set.str[STRING_PROXYPASSWORD]);
1824 case CURLOPT_PROXYUSERNAME:
1826 * authentication user name to use in the operation
1828 result = setstropt(&data->set.str[STRING_PROXYUSERNAME],
1829 va_arg(param, char *));
1831 case CURLOPT_PROXYPASSWORD:
1833 * authentication password to use in the operation
1835 result = setstropt(&data->set.str[STRING_PROXYPASSWORD],
1836 va_arg(param, char *));
1838 case CURLOPT_NOPROXY:
1840 * proxy exception list
1842 result = setstropt(&data->set.str[STRING_NOPROXY],
1843 va_arg(param, char *));
1849 * What range of the file you want to transfer
1851 result = setstropt(&data->set.str[STRING_SET_RANGE],
1852 va_arg(param, char *));
1854 case CURLOPT_RESUME_FROM:
1856 * Resume transfer at the give file position
1858 data->set.set_resume_from = va_arg(param, long);
1860 case CURLOPT_RESUME_FROM_LARGE:
1862 * Resume transfer at the give file position
1864 data->set.set_resume_from = va_arg(param, curl_off_t);
1866 case CURLOPT_DEBUGFUNCTION:
1868 * stderr write callback.
1870 data->set.fdebug = va_arg(param, curl_debug_callback);
1872 * if the callback provided is NULL, it'll use the default callback
1875 case CURLOPT_DEBUGDATA:
1877 * Set to a void * that should receive all error writes. This
1878 * defaults to CURLOPT_STDERR for normal operations.
1880 data->set.debugdata = va_arg(param, void *);
1882 case CURLOPT_STDERR:
1884 * Set to a FILE * that should receive all error writes. This
1885 * defaults to stderr for normal operations.
1887 data->set.err = va_arg(param, FILE *);
1889 data->set.err = stderr;
1891 case CURLOPT_HEADERFUNCTION:
1893 * Set header write callback
1895 data->set.fwrite_header = va_arg(param, curl_write_callback);
1897 case CURLOPT_WRITEFUNCTION:
1899 * Set data write callback
1901 data->set.fwrite_func = va_arg(param, curl_write_callback);
1902 if(!data->set.fwrite_func) {
1903 data->set.is_fwrite_set = 0;
1904 /* When set to NULL, reset to our internal default function */
1905 data->set.fwrite_func = (curl_write_callback)fwrite;
1908 data->set.is_fwrite_set = 1;
1910 case CURLOPT_READFUNCTION:
1912 * Read data callback
1914 data->set.fread_func_set = va_arg(param, curl_read_callback);
1915 if(!data->set.fread_func_set) {
1916 data->set.is_fread_set = 0;
1917 /* When set to NULL, reset to our internal default function */
1918 data->set.fread_func_set = (curl_read_callback)fread;
1921 data->set.is_fread_set = 1;
1923 case CURLOPT_SEEKFUNCTION:
1925 * Seek callback. Might be NULL.
1927 data->set.seek_func = va_arg(param, curl_seek_callback);
1929 case CURLOPT_SEEKDATA:
1931 * Seek control callback. Might be NULL.
1933 data->set.seek_client = va_arg(param, void *);
1935 case CURLOPT_CONV_FROM_NETWORK_FUNCTION:
1937 * "Convert from network encoding" callback
1939 data->set.convfromnetwork = va_arg(param, curl_conv_callback);
1941 case CURLOPT_CONV_TO_NETWORK_FUNCTION:
1943 * "Convert to network encoding" callback
1945 data->set.convtonetwork = va_arg(param, curl_conv_callback);
1947 case CURLOPT_CONV_FROM_UTF8_FUNCTION:
1949 * "Convert from UTF-8 encoding" callback
1951 data->set.convfromutf8 = va_arg(param, curl_conv_callback);
1953 case CURLOPT_IOCTLFUNCTION:
1955 * I/O control callback. Might be NULL.
1957 data->set.ioctl_func = va_arg(param, curl_ioctl_callback);
1959 case CURLOPT_IOCTLDATA:
1961 * I/O control data pointer. Might be NULL.
1963 data->set.ioctl_client = va_arg(param, void *);
1965 case CURLOPT_SSLCERT:
1967 * String that holds file name of the SSL certificate to use
1969 result = setstropt(&data->set.str[STRING_CERT_ORIG],
1970 va_arg(param, char *));
1972 case CURLOPT_PROXY_SSLCERT:
1974 * String that holds file name of the SSL certificate to use for proxy
1976 result = setstropt(&data->set.str[STRING_CERT_PROXY],
1977 va_arg(param, char *));
1979 case CURLOPT_SSLCERTTYPE:
1981 * String that holds file type of the SSL certificate to use
1983 result = setstropt(&data->set.str[STRING_CERT_TYPE_ORIG],
1984 va_arg(param, char *));
1986 case CURLOPT_PROXY_SSLCERTTYPE:
1988 * String that holds file type of the SSL certificate to use for proxy
1990 result = setstropt(&data->set.str[STRING_CERT_TYPE_PROXY],
1991 va_arg(param, char *));
1993 case CURLOPT_SSLKEY:
1995 * String that holds file name of the SSL key to use
1997 result = setstropt(&data->set.str[STRING_KEY_ORIG],
1998 va_arg(param, char *));
2000 case CURLOPT_PROXY_SSLKEY:
2002 * String that holds file name of the SSL key to use for proxy
2004 result = setstropt(&data->set.str[STRING_KEY_PROXY],
2005 va_arg(param, char *));
2007 case CURLOPT_SSLKEYTYPE:
2009 * String that holds file type of the SSL key to use
2011 result = setstropt(&data->set.str[STRING_KEY_TYPE_ORIG],
2012 va_arg(param, char *));
2014 case CURLOPT_PROXY_SSLKEYTYPE:
2016 * String that holds file type of the SSL key to use for proxy
2018 result = setstropt(&data->set.str[STRING_KEY_TYPE_PROXY],
2019 va_arg(param, char *));
2021 case CURLOPT_KEYPASSWD:
2023 * String that holds the SSL or SSH private key password.
2025 result = setstropt(&data->set.str[STRING_KEY_PASSWD_ORIG],
2026 va_arg(param, char *));
2028 case CURLOPT_PROXY_KEYPASSWD:
2030 * String that holds the SSL private key password for proxy.
2032 result = setstropt(&data->set.str[STRING_KEY_PASSWD_PROXY],
2033 va_arg(param, char *));
2035 case CURLOPT_SSLENGINE:
2037 * String that holds the SSL crypto engine.
2039 argptr = va_arg(param, char *);
2040 if(argptr && argptr[0])
2041 result = Curl_ssl_set_engine(data, argptr);
2044 case CURLOPT_SSLENGINE_DEFAULT:
2046 * flag to set engine as default.
2048 result = Curl_ssl_set_engine_default(data);
2052 * Kludgy option to enable CRLF conversions. Subject for removal.
2054 data->set.crlf = (0 != va_arg(param, long)) ? TRUE : FALSE;
2057 case CURLOPT_INTERFACE:
2059 * Set what interface or address/hostname to bind the socket to when
2060 * performing an operation and thus what from-IP your connection will use.
2062 result = setstropt(&data->set.str[STRING_DEVICE],
2063 va_arg(param, char *));
2065 case CURLOPT_LOCALPORT:
2067 * Set what local port to bind the socket to when performing an operation.
2069 data->set.localport = curlx_sltous(va_arg(param, long));
2071 case CURLOPT_LOCALPORTRANGE:
2073 * Set number of local ports to try, starting with CURLOPT_LOCALPORT.
2075 data->set.localportrange = curlx_sltosi(va_arg(param, long));
2077 case CURLOPT_KRBLEVEL:
2079 * A string that defines the kerberos security level.
2081 result = setstropt(&data->set.str[STRING_KRB_LEVEL],
2082 va_arg(param, char *));
2083 data->set.krb = (data->set.str[STRING_KRB_LEVEL]) ? TRUE : FALSE;
2085 case CURLOPT_GSSAPI_DELEGATION:
2087 * GSS-API credential delegation
2089 data->set.gssapi_delegation = va_arg(param, long);
2091 case CURLOPT_SSL_VERIFYPEER:
2093 * Enable peer SSL verifying.
2095 data->set.ssl.primary.verifypeer = (0 != va_arg(param, long)) ?
2098 case CURLOPT_PROXY_SSL_VERIFYPEER:
2100 * Enable peer SSL verifying for proxy.
2102 data->set.proxy_ssl.primary.verifypeer =
2103 (0 != va_arg(param, long))?TRUE:FALSE;
2105 case CURLOPT_SSL_VERIFYHOST:
2107 * Enable verification of the host name in the peer certificate
2109 arg = va_arg(param, long);
2111 /* Obviously people are not reading documentation and too many thought
2112 this argument took a boolean when it wasn't and misused it. We thus ban
2113 1 as a sensible input and we warn about its use. Then we only have the
2114 2 action internally stored as TRUE. */
2117 failf(data, "CURLOPT_SSL_VERIFYHOST no longer supports 1 as value!");
2118 return CURLE_BAD_FUNCTION_ARGUMENT;
2121 data->set.ssl.primary.verifyhost = (0 != arg) ? TRUE : FALSE;
2123 case CURLOPT_PROXY_SSL_VERIFYHOST:
2125 * Enable verification of the host name in the peer certificate for proxy
2127 arg = va_arg(param, long);
2129 /* Obviously people are not reading documentation and too many thought
2130 this argument took a boolean when it wasn't and misused it. We thus ban
2131 1 as a sensible input and we warn about its use. Then we only have the
2132 2 action internally stored as TRUE. */
2135 failf(data, "CURLOPT_SSL_VERIFYHOST no longer supports 1 as value!");
2136 return CURLE_BAD_FUNCTION_ARGUMENT;
2139 data->set.proxy_ssl.primary.verifyhost = (0 != arg)?TRUE:FALSE;
2141 case CURLOPT_SSL_VERIFYSTATUS:
2143 * Enable certificate status verifying.
2145 if(!Curl_ssl_cert_status_request()) {
2146 result = CURLE_NOT_BUILT_IN;
2150 data->set.ssl.primary.verifystatus = (0 != va_arg(param, long)) ?
2153 case CURLOPT_SSL_CTX_FUNCTION:
2154 #ifdef have_curlssl_ssl_ctx
2156 * Set a SSL_CTX callback
2158 data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback);
2160 result = CURLE_NOT_BUILT_IN;
2163 case CURLOPT_SSL_CTX_DATA:
2164 #ifdef have_curlssl_ssl_ctx
2166 * Set a SSL_CTX callback parameter pointer
2168 data->set.ssl.fsslctxp = va_arg(param, void *);
2170 result = CURLE_NOT_BUILT_IN;
2173 case CURLOPT_SSL_FALSESTART:
2175 * Enable TLS false start.
2177 if(!Curl_ssl_false_start()) {
2178 result = CURLE_NOT_BUILT_IN;
2182 data->set.ssl.falsestart = (0 != va_arg(param, long)) ? TRUE : FALSE;
2184 case CURLOPT_CERTINFO:
2185 #ifdef have_curlssl_certinfo
2186 data->set.ssl.certinfo = (0 != va_arg(param, long)) ? TRUE : FALSE;
2188 result = CURLE_NOT_BUILT_IN;
2191 case CURLOPT_PINNEDPUBLICKEY:
2192 #ifdef have_curlssl_pinnedpubkey /* only by supported backends */
2194 * Set pinned public key for SSL connection.
2195 * Specify file name of the public key in DER format.
2197 result = setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG],
2198 va_arg(param, char *));
2200 result = CURLE_NOT_BUILT_IN;
2203 case CURLOPT_PROXY_PINNEDPUBLICKEY:
2204 #ifdef have_curlssl_pinnedpubkey /* only by supported backends */
2206 * Set pinned public key for SSL connection.
2207 * Specify file name of the public key in DER format.
2209 result = setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY],
2210 va_arg(param, char *));
2212 result = CURLE_NOT_BUILT_IN;
2215 case CURLOPT_CAINFO:
2217 * Set CA info for SSL connection. Specify file name of the CA certificate
2219 result = setstropt(&data->set.str[STRING_SSL_CAFILE_ORIG],
2220 va_arg(param, char *));
2222 case CURLOPT_PROXY_CAINFO:
2224 * Set CA info SSL connection for proxy. Specify file name of the
2227 result = setstropt(&data->set.str[STRING_SSL_CAFILE_PROXY],
2228 va_arg(param, char *));
2230 case CURLOPT_CAPATH:
2231 #ifdef have_curlssl_ca_path /* not supported by all backends */
2233 * Set CA path info for SSL connection. Specify directory name of the CA
2234 * certificates which have been prepared using openssl c_rehash utility.
2236 /* This does not work on windows. */
2237 result = setstropt(&data->set.str[STRING_SSL_CAPATH_ORIG],
2238 va_arg(param, char *));
2240 result = CURLE_NOT_BUILT_IN;
2243 case CURLOPT_PROXY_CAPATH:
2244 #ifdef have_curlssl_ca_path /* not supported by all backends */
2246 * Set CA path info for SSL connection proxy. Specify directory name of the
2247 * CA certificates which have been prepared using openssl c_rehash utility.
2249 /* This does not work on windows. */
2250 result = setstropt(&data->set.str[STRING_SSL_CAPATH_PROXY],
2251 va_arg(param, char *));
2253 result = CURLE_NOT_BUILT_IN;
2256 case CURLOPT_CRLFILE:
2258 * Set CRL file info for SSL connection. Specify file name of the CRL
2259 * to check certificates revocation
2261 result = setstropt(&data->set.str[STRING_SSL_CRLFILE_ORIG],
2262 va_arg(param, char *));
2264 case CURLOPT_PROXY_CRLFILE:
2266 * Set CRL file info for SSL connection for proxy. Specify file name of the
2267 * CRL to check certificates revocation
2269 result = setstropt(&data->set.str[STRING_SSL_CRLFILE_PROXY],
2270 va_arg(param, char *));
2272 case CURLOPT_ISSUERCERT:
2274 * Set Issuer certificate file
2275 * to check certificates issuer
2277 result = setstropt(&data->set.str[STRING_SSL_ISSUERCERT_ORIG],
2278 va_arg(param, char *));
2280 case CURLOPT_TELNETOPTIONS:
2282 * Set a linked list of telnet options
2284 data->set.telnet_options = va_arg(param, struct curl_slist *);
2287 case CURLOPT_BUFFERSIZE:
2289 * The application kindly asks for a differently sized receive buffer.
2290 * If it seems reasonable, we'll use it.
2292 data->set.buffer_size = va_arg(param, long);
2294 if(data->set.buffer_size > MAX_BUFSIZE)
2295 data->set.buffer_size = MAX_BUFSIZE; /* huge internal default */
2296 else if(data->set.buffer_size < 1)
2297 data->set.buffer_size = BUFSIZE;
2299 /* Resize only if larger than default buffer size. */
2300 if(data->set.buffer_size > BUFSIZE) {
2301 data->state.buffer = realloc(data->state.buffer,
2302 data->set.buffer_size + 1);
2303 if(!data->state.buffer) {
2304 DEBUGF(fprintf(stderr, "Error: realloc of buffer failed\n"));
2305 result = CURLE_OUT_OF_MEMORY;
2311 case CURLOPT_NOSIGNAL:
2313 * The application asks not to set any signal() or alarm() handlers,
2314 * even when using a timeout.
2316 data->set.no_signal = (0 != va_arg(param, long)) ? TRUE : FALSE;
2321 struct Curl_share *set;
2322 set = va_arg(param, struct Curl_share *);
2324 /* disconnect from old share, if any */
2326 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
2328 if(data->dns.hostcachetype == HCACHE_SHARED) {
2329 data->dns.hostcache = NULL;
2330 data->dns.hostcachetype = HCACHE_NONE;
2333 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
2334 if(data->share->cookies == data->cookies)
2335 data->cookies = NULL;
2338 if(data->share->sslsession == data->state.session)
2339 data->state.session = NULL;
2341 data->share->dirty--;
2343 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
2347 /* use new share if it set */
2351 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
2353 data->share->dirty++;
2355 if(data->share->specifier & (1<< CURL_LOCK_DATA_DNS)) {
2356 /* use shared host cache */
2357 data->dns.hostcache = &data->share->hostcache;
2358 data->dns.hostcachetype = HCACHE_SHARED;
2360 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
2361 if(data->share->cookies) {
2362 /* use shared cookie list, first free own one if any */
2363 Curl_cookie_cleanup(data->cookies);
2364 /* enable cookies since we now use a share that uses cookies! */
2365 data->cookies = data->share->cookies;
2367 #endif /* CURL_DISABLE_HTTP */
2368 if(data->share->sslsession) {
2369 data->set.general_ssl.max_ssl_sessions = data->share->max_ssl_sessions;
2370 data->state.session = data->share->sslsession;
2372 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
2375 /* check for host cache not needed,
2376 * it will be done by curl_easy_perform */
2380 case CURLOPT_PRIVATE:
2382 * Set private data pointer.
2384 data->set.private_data = va_arg(param, void *);
2387 case CURLOPT_MAXFILESIZE:
2389 * Set the maximum size of a file to download.
2391 data->set.max_filesize = va_arg(param, long);
2395 case CURLOPT_USE_SSL:
2397 * Make transfers attempt to use SSL/TLS.
2399 data->set.use_ssl = (curl_usessl)va_arg(param, long);
2402 case CURLOPT_SSL_OPTIONS:
2403 arg = va_arg(param, long);
2404 data->set.ssl.enable_beast = arg&CURLSSLOPT_ALLOW_BEAST?TRUE:FALSE;
2405 data->set.ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
2408 case CURLOPT_PROXY_SSL_OPTIONS:
2409 arg = va_arg(param, long);
2410 data->set.proxy_ssl.enable_beast = arg&CURLSSLOPT_ALLOW_BEAST?TRUE:FALSE;
2411 data->set.proxy_ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
2415 case CURLOPT_FTPSSLAUTH:
2417 * Set a specific auth for FTP-SSL transfers.
2419 data->set.ftpsslauth = (curl_ftpauth)va_arg(param, long);
2422 case CURLOPT_IPRESOLVE:
2423 data->set.ipver = va_arg(param, long);
2426 case CURLOPT_MAXFILESIZE_LARGE:
2428 * Set the maximum size of a file to download.
2430 data->set.max_filesize = va_arg(param, curl_off_t);
2433 case CURLOPT_TCP_NODELAY:
2435 * Enable or disable TCP_NODELAY, which will disable/enable the Nagle
2438 data->set.tcp_nodelay = (0 != va_arg(param, long)) ? TRUE : FALSE;
2441 case CURLOPT_FTP_ACCOUNT:
2442 result = setstropt(&data->set.str[STRING_FTP_ACCOUNT],
2443 va_arg(param, char *));
2446 case CURLOPT_IGNORE_CONTENT_LENGTH:
2447 data->set.ignorecl = (0 != va_arg(param, long)) ? TRUE : FALSE;
2450 case CURLOPT_CONNECT_ONLY:
2452 * No data transfer, set up connection and let application use the socket
2454 data->set.connect_only = (0 != va_arg(param, long)) ? TRUE : FALSE;
2457 case CURLOPT_FTP_ALTERNATIVE_TO_USER:
2458 result = setstropt(&data->set.str[STRING_FTP_ALTERNATIVE_TO_USER],
2459 va_arg(param, char *));
2462 case CURLOPT_SOCKOPTFUNCTION:
2464 * socket callback function: called after socket() but before connect()
2466 data->set.fsockopt = va_arg(param, curl_sockopt_callback);
2469 case CURLOPT_SOCKOPTDATA:
2471 * socket callback data pointer. Might be NULL.
2473 data->set.sockopt_client = va_arg(param, void *);
2476 case CURLOPT_OPENSOCKETFUNCTION:
2478 * open/create socket callback function: called instead of socket(),
2481 data->set.fopensocket = va_arg(param, curl_opensocket_callback);
2484 case CURLOPT_OPENSOCKETDATA:
2486 * socket callback data pointer. Might be NULL.
2488 data->set.opensocket_client = va_arg(param, void *);
2491 case CURLOPT_CLOSESOCKETFUNCTION:
2493 * close socket callback function: called instead of close()
2494 * when shutting down a connection
2496 data->set.fclosesocket = va_arg(param, curl_closesocket_callback);
2499 case CURLOPT_CLOSESOCKETDATA:
2501 * socket callback data pointer. Might be NULL.
2503 data->set.closesocket_client = va_arg(param, void *);
2506 case CURLOPT_SSL_SESSIONID_CACHE:
2507 data->set.ssl.primary.sessionid = (0 != va_arg(param, long)) ?
2509 data->set.proxy_ssl.primary.sessionid = data->set.ssl.primary.sessionid;
2513 /* we only include SSH options if explicitly built to support SSH */
2514 case CURLOPT_SSH_AUTH_TYPES:
2515 data->set.ssh_auth_types = va_arg(param, long);
2518 case CURLOPT_SSH_PUBLIC_KEYFILE:
2520 * Use this file instead of the $HOME/.ssh/id_dsa.pub file
2522 result = setstropt(&data->set.str[STRING_SSH_PUBLIC_KEY],
2523 va_arg(param, char *));
2526 case CURLOPT_SSH_PRIVATE_KEYFILE:
2528 * Use this file instead of the $HOME/.ssh/id_dsa file
2530 result = setstropt(&data->set.str[STRING_SSH_PRIVATE_KEY],
2531 va_arg(param, char *));
2533 case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5:
2535 * Option to allow for the MD5 of the host public key to be checked
2536 * for validation purposes.
2538 result = setstropt(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5],
2539 va_arg(param, char *));
2541 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2542 case CURLOPT_SSH_KNOWNHOSTS:
2544 * Store the file name to read known hosts from.
2546 result = setstropt(&data->set.str[STRING_SSH_KNOWNHOSTS],
2547 va_arg(param, char *));
2550 case CURLOPT_SSH_KEYFUNCTION:
2551 /* setting to NULL is fine since the ssh.c functions themselves will
2552 then rever to use the internal default */
2553 data->set.ssh_keyfunc = va_arg(param, curl_sshkeycallback);
2556 case CURLOPT_SSH_KEYDATA:
2558 * Custom client data to pass to the SSH keyfunc callback
2560 data->set.ssh_keyfunc_userp = va_arg(param, void *);
2562 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2564 #endif /* USE_LIBSSH2 */
2566 case CURLOPT_HTTP_TRANSFER_DECODING:
2568 * disable libcurl transfer encoding is used
2570 data->set.http_te_skip = (0 == va_arg(param, long)) ? TRUE : FALSE;
2573 case CURLOPT_HTTP_CONTENT_DECODING:
2575 * raw data passed to the application when content encoding is used
2577 data->set.http_ce_skip = (0 == va_arg(param, long)) ? TRUE : FALSE;
2580 case CURLOPT_NEW_FILE_PERMS:
2582 * Uses these permissions instead of 0644
2584 data->set.new_file_perms = va_arg(param, long);
2587 case CURLOPT_NEW_DIRECTORY_PERMS:
2589 * Uses these permissions instead of 0755
2591 data->set.new_directory_perms = va_arg(param, long);
2594 case CURLOPT_ADDRESS_SCOPE:
2596 * We always get longs when passed plain numericals, but for this value we
2597 * know that an unsigned int will always hold the value so we blindly
2598 * typecast to this type
2600 data->set.scope_id = curlx_sltoui(va_arg(param, long));
2603 case CURLOPT_PROTOCOLS:
2604 /* set the bitmask for the protocols that are allowed to be used for the
2605 transfer, which thus helps the app which takes URLs from users or other
2606 external inputs and want to restrict what protocol(s) to deal
2607 with. Defaults to CURLPROTO_ALL. */
2608 data->set.allowed_protocols = va_arg(param, long);
2611 case CURLOPT_REDIR_PROTOCOLS:
2612 /* set the bitmask for the protocols that libcurl is allowed to follow to,
2613 as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
2614 to be set in both bitmasks to be allowed to get redirected to. Defaults
2615 to all protocols except FILE and SCP. */
2616 data->set.redir_protocols = va_arg(param, long);
2619 case CURLOPT_DEFAULT_PROTOCOL:
2620 /* Set the protocol to use when the URL doesn't include any protocol */
2621 result = setstropt(&data->set.str[STRING_DEFAULT_PROTOCOL],
2622 va_arg(param, char *));
2625 case CURLOPT_MAIL_FROM:
2626 /* Set the SMTP mail originator */
2627 result = setstropt(&data->set.str[STRING_MAIL_FROM],
2628 va_arg(param, char *));
2631 case CURLOPT_MAIL_AUTH:
2632 /* Set the SMTP auth originator */
2633 result = setstropt(&data->set.str[STRING_MAIL_AUTH],
2634 va_arg(param, char *));
2637 case CURLOPT_MAIL_RCPT:
2638 /* Set the list of mail recipients */
2639 data->set.mail_rcpt = va_arg(param, struct curl_slist *);
2642 case CURLOPT_SASL_IR:
2643 /* Enable/disable SASL initial response */
2644 data->set.sasl_ir = (0 != va_arg(param, long)) ? TRUE : FALSE;
2647 case CURLOPT_RTSP_REQUEST:
2650 * Set the RTSP request method (OPTIONS, SETUP, PLAY, etc...)
2651 * Would this be better if the RTSPREQ_* were just moved into here?
2653 long curl_rtspreq = va_arg(param, long);
2654 Curl_RtspReq rtspreq = RTSPREQ_NONE;
2655 switch(curl_rtspreq) {
2656 case CURL_RTSPREQ_OPTIONS:
2657 rtspreq = RTSPREQ_OPTIONS;
2660 case CURL_RTSPREQ_DESCRIBE:
2661 rtspreq = RTSPREQ_DESCRIBE;
2664 case CURL_RTSPREQ_ANNOUNCE:
2665 rtspreq = RTSPREQ_ANNOUNCE;
2668 case CURL_RTSPREQ_SETUP:
2669 rtspreq = RTSPREQ_SETUP;
2672 case CURL_RTSPREQ_PLAY:
2673 rtspreq = RTSPREQ_PLAY;
2676 case CURL_RTSPREQ_PAUSE:
2677 rtspreq = RTSPREQ_PAUSE;
2680 case CURL_RTSPREQ_TEARDOWN:
2681 rtspreq = RTSPREQ_TEARDOWN;
2684 case CURL_RTSPREQ_GET_PARAMETER:
2685 rtspreq = RTSPREQ_GET_PARAMETER;
2688 case CURL_RTSPREQ_SET_PARAMETER:
2689 rtspreq = RTSPREQ_SET_PARAMETER;
2692 case CURL_RTSPREQ_RECORD:
2693 rtspreq = RTSPREQ_RECORD;
2696 case CURL_RTSPREQ_RECEIVE:
2697 rtspreq = RTSPREQ_RECEIVE;
2700 rtspreq = RTSPREQ_NONE;
2703 data->set.rtspreq = rtspreq;
2708 case CURLOPT_RTSP_SESSION_ID:
2710 * Set the RTSP Session ID manually. Useful if the application is
2711 * resuming a previously established RTSP session
2713 result = setstropt(&data->set.str[STRING_RTSP_SESSION_ID],
2714 va_arg(param, char *));
2717 case CURLOPT_RTSP_STREAM_URI:
2719 * Set the Stream URI for the RTSP request. Unless the request is
2720 * for generic server options, the application will need to set this.
2722 result = setstropt(&data->set.str[STRING_RTSP_STREAM_URI],
2723 va_arg(param, char *));
2726 case CURLOPT_RTSP_TRANSPORT:
2728 * The content of the Transport: header for the RTSP request
2730 result = setstropt(&data->set.str[STRING_RTSP_TRANSPORT],
2731 va_arg(param, char *));
2734 case CURLOPT_RTSP_CLIENT_CSEQ:
2736 * Set the CSEQ number to issue for the next RTSP request. Useful if the
2737 * application is resuming a previously broken connection. The CSEQ
2738 * will increment from this new number henceforth.
2740 data->state.rtsp_next_client_CSeq = va_arg(param, long);
2743 case CURLOPT_RTSP_SERVER_CSEQ:
2744 /* Same as the above, but for server-initiated requests */
2745 data->state.rtsp_next_client_CSeq = va_arg(param, long);
2748 case CURLOPT_INTERLEAVEDATA:
2749 data->set.rtp_out = va_arg(param, void *);
2751 case CURLOPT_INTERLEAVEFUNCTION:
2752 /* Set the user defined RTP write function */
2753 data->set.fwrite_rtp = va_arg(param, curl_write_callback);
2756 case CURLOPT_WILDCARDMATCH:
2757 data->set.wildcardmatch = (0 != va_arg(param, long)) ? TRUE : FALSE;
2759 case CURLOPT_CHUNK_BGN_FUNCTION:
2760 data->set.chunk_bgn = va_arg(param, curl_chunk_bgn_callback);
2762 case CURLOPT_CHUNK_END_FUNCTION:
2763 data->set.chunk_end = va_arg(param, curl_chunk_end_callback);
2765 case CURLOPT_FNMATCH_FUNCTION:
2766 data->set.fnmatch = va_arg(param, curl_fnmatch_callback);
2768 case CURLOPT_CHUNK_DATA:
2769 data->wildcard.customptr = va_arg(param, void *);
2771 case CURLOPT_FNMATCH_DATA:
2772 data->set.fnmatch_data = va_arg(param, void *);
2775 case CURLOPT_TLSAUTH_USERNAME:
2776 result = setstropt(&data->set.str[STRING_TLSAUTH_USERNAME_ORIG],
2777 va_arg(param, char *));
2778 if(data->set.str[STRING_TLSAUTH_USERNAME_ORIG] && !data->set.ssl.authtype)
2779 data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
2781 case CURLOPT_PROXY_TLSAUTH_USERNAME:
2782 result = setstropt(&data->set.str[STRING_TLSAUTH_USERNAME_PROXY],
2783 va_arg(param, char *));
2784 if(data->set.str[STRING_TLSAUTH_USERNAME_PROXY] &&
2785 !data->set.proxy_ssl.authtype)
2786 data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
2788 case CURLOPT_TLSAUTH_PASSWORD:
2789 result = setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_ORIG],
2790 va_arg(param, char *));
2791 if(data->set.str[STRING_TLSAUTH_USERNAME_ORIG] && !data->set.ssl.authtype)
2792 data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
2794 case CURLOPT_PROXY_TLSAUTH_PASSWORD:
2795 result = setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_PROXY],
2796 va_arg(param, char *));
2797 if(data->set.str[STRING_TLSAUTH_USERNAME_PROXY] &&
2798 !data->set.proxy_ssl.authtype)
2799 data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
2801 case CURLOPT_TLSAUTH_TYPE:
2802 if(strncasecompare((char *)va_arg(param, char *), "SRP", strlen("SRP")))
2803 data->set.ssl.authtype = CURL_TLSAUTH_SRP;
2805 data->set.ssl.authtype = CURL_TLSAUTH_NONE;
2807 case CURLOPT_PROXY_TLSAUTH_TYPE:
2808 if(strncasecompare((char *)va_arg(param, char *), "SRP", strlen("SRP")))
2809 data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP;
2811 data->set.proxy_ssl.authtype = CURL_TLSAUTH_NONE;
2814 case CURLOPT_DNS_SERVERS:
2815 result = Curl_set_dns_servers(data, va_arg(param, char *));
2817 case CURLOPT_DNS_INTERFACE:
2818 result = Curl_set_dns_interface(data, va_arg(param, char *));
2820 case CURLOPT_DNS_LOCAL_IP4:
2821 result = Curl_set_dns_local_ip4(data, va_arg(param, char *));
2823 case CURLOPT_DNS_LOCAL_IP6:
2824 result = Curl_set_dns_local_ip6(data, va_arg(param, char *));
2827 case CURLOPT_TCP_KEEPALIVE:
2828 data->set.tcp_keepalive = (0 != va_arg(param, long)) ? TRUE : FALSE;
2830 case CURLOPT_TCP_KEEPIDLE:
2831 data->set.tcp_keepidle = va_arg(param, long);
2833 case CURLOPT_TCP_KEEPINTVL:
2834 data->set.tcp_keepintvl = va_arg(param, long);
2836 case CURLOPT_TCP_FASTOPEN:
2837 #if defined(CONNECT_DATA_IDEMPOTENT) || defined(MSG_FASTOPEN)
2838 data->set.tcp_fastopen = (0 != va_arg(param, long))?TRUE:FALSE;
2840 result = CURLE_NOT_BUILT_IN;
2843 case CURLOPT_SSL_ENABLE_NPN:
2844 data->set.ssl_enable_npn = (0 != va_arg(param, long)) ? TRUE : FALSE;
2846 case CURLOPT_SSL_ENABLE_ALPN:
2847 data->set.ssl_enable_alpn = (0 != va_arg(param, long)) ? TRUE : FALSE;
2850 #ifdef USE_UNIX_SOCKETS
2851 case CURLOPT_UNIX_SOCKET_PATH:
2852 data->set.abstract_unix_socket = FALSE;
2853 result = setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH],
2854 va_arg(param, char *));
2856 case CURLOPT_ABSTRACT_UNIX_SOCKET:
2857 data->set.abstract_unix_socket = TRUE;
2858 result = setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH],
2859 va_arg(param, char *));
2863 case CURLOPT_PATH_AS_IS:
2864 data->set.path_as_is = (0 != va_arg(param, long)) ? TRUE : FALSE;
2866 case CURLOPT_PIPEWAIT:
2867 data->set.pipewait = (0 != va_arg(param, long)) ? TRUE : FALSE;
2869 case CURLOPT_STREAM_WEIGHT:
2871 return CURLE_NOT_BUILT_IN;
2873 arg = va_arg(param, long);
2874 if((arg>=1) && (arg <= 256))
2875 data->set.stream_weight = (int)arg;
2878 case CURLOPT_STREAM_DEPENDS:
2879 case CURLOPT_STREAM_DEPENDS_E:
2882 return CURLE_NOT_BUILT_IN;
2884 struct Curl_easy *dep = va_arg(param, struct Curl_easy *);
2885 if(!dep || GOOD_EASY_HANDLE(dep)) {
2886 if(data->set.stream_depends_on) {
2887 Curl_http2_remove_child(data->set.stream_depends_on, data);
2889 Curl_http2_add_child(dep, data, (option == CURLOPT_STREAM_DEPENDS_E));
2894 case CURLOPT_CONNECT_TO:
2895 data->set.connect_to = va_arg(param, struct curl_slist *);
2898 /* unknown tag and its companion, just ignore: */
2899 result = CURLE_UNKNOWN_OPTION;
2906 #ifdef USE_RECV_BEFORE_SEND_WORKAROUND
2907 static void conn_reset_postponed_data(struct connectdata *conn, int num)
2909 struct postponed_data * const psnd = &(conn->postponed[num]);
2911 DEBUGASSERT(psnd->allocated_size > 0);
2912 DEBUGASSERT(psnd->recv_size <= psnd->allocated_size);
2913 DEBUGASSERT(psnd->recv_size ?
2914 (psnd->recv_processed < psnd->recv_size) :
2915 (psnd->recv_processed == 0));
2916 DEBUGASSERT(psnd->bindsock != CURL_SOCKET_BAD);
2918 psnd->buffer = NULL;
2919 psnd->allocated_size = 0;
2920 psnd->recv_size = 0;
2921 psnd->recv_processed = 0;
2923 psnd->bindsock = CURL_SOCKET_BAD; /* used only for DEBUGASSERT */
2924 #endif /* DEBUGBUILD */
2927 DEBUGASSERT(psnd->allocated_size == 0);
2928 DEBUGASSERT(psnd->recv_size == 0);
2929 DEBUGASSERT(psnd->recv_processed == 0);
2930 DEBUGASSERT(psnd->bindsock == CURL_SOCKET_BAD);
2934 static void conn_reset_all_postponed_data(struct connectdata *conn)
2936 conn_reset_postponed_data(conn, 0);
2937 conn_reset_postponed_data(conn, 1);
2939 #else /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
2940 /* Use "do-nothing" macros instead of functions when workaround not used */
2941 #define conn_reset_postponed_data(c,n) do {} WHILE_FALSE
2942 #define conn_reset_all_postponed_data(c) do {} WHILE_FALSE
2943 #endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
2945 static void conn_free(struct connectdata *conn)
2950 /* possible left-overs from the async name resolvers */
2951 Curl_resolver_cancel(conn);
2953 /* close the SSL stuff before we close any sockets since they will/may
2954 write to the sockets */
2955 Curl_ssl_close(conn, FIRSTSOCKET);
2956 Curl_ssl_close(conn, SECONDARYSOCKET);
2958 /* close possibly still open sockets */
2959 if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
2960 Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
2961 if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET])
2962 Curl_closesocket(conn, conn->sock[FIRSTSOCKET]);
2963 if(CURL_SOCKET_BAD != conn->tempsock[0])
2964 Curl_closesocket(conn, conn->tempsock[0]);
2965 if(CURL_SOCKET_BAD != conn->tempsock[1])
2966 Curl_closesocket(conn, conn->tempsock[1]);
2968 #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
2969 defined(NTLM_WB_ENABLED)
2970 Curl_ntlm_wb_cleanup(conn);
2973 Curl_safefree(conn->user);
2974 Curl_safefree(conn->passwd);
2975 Curl_safefree(conn->oauth_bearer);
2976 Curl_safefree(conn->options);
2977 Curl_safefree(conn->http_proxy.user);
2978 Curl_safefree(conn->socks_proxy.user);
2979 Curl_safefree(conn->http_proxy.passwd);
2980 Curl_safefree(conn->socks_proxy.passwd);
2981 Curl_safefree(conn->allocptr.proxyuserpwd);
2982 Curl_safefree(conn->allocptr.uagent);
2983 Curl_safefree(conn->allocptr.userpwd);
2984 Curl_safefree(conn->allocptr.accept_encoding);
2985 Curl_safefree(conn->allocptr.te);
2986 Curl_safefree(conn->allocptr.rangeline);
2987 Curl_safefree(conn->allocptr.ref);
2988 Curl_safefree(conn->allocptr.host);
2989 Curl_safefree(conn->allocptr.cookiehost);
2990 Curl_safefree(conn->allocptr.rtsp_transport);
2991 Curl_safefree(conn->trailer);
2992 Curl_safefree(conn->host.rawalloc); /* host name buffer */
2993 Curl_safefree(conn->conn_to_host.rawalloc); /* host name buffer */
2994 Curl_safefree(conn->secondaryhostname);
2995 Curl_safefree(conn->http_proxy.host.rawalloc); /* http proxy name buffer */
2996 Curl_safefree(conn->socks_proxy.host.rawalloc); /* socks proxy name buffer */
2997 Curl_safefree(conn->master_buffer);
2999 conn_reset_all_postponed_data(conn);
3001 Curl_llist_destroy(conn->send_pipe, NULL);
3002 Curl_llist_destroy(conn->recv_pipe, NULL);
3004 conn->send_pipe = NULL;
3005 conn->recv_pipe = NULL;
3007 Curl_safefree(conn->localdev);
3008 Curl_free_primary_ssl_config(&conn->ssl_config);
3009 Curl_free_primary_ssl_config(&conn->proxy_ssl_config);
3011 #ifdef USE_UNIX_SOCKETS
3012 Curl_safefree(conn->unix_domain_socket);
3015 free(conn); /* free all the connection oriented data */
3019 * Disconnects the given connection. Note the connection may not be the
3020 * primary connection, like when freeing room in the connection cache or
3021 * killing of a dead old connection.
3023 * This function MUST NOT reset state in the Curl_easy struct if that
3024 * isn't strictly bound to the life-time of *this* particular connection.
3028 CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
3030 struct Curl_easy *data;
3032 return CURLE_OK; /* this is closed and fine already */
3036 DEBUGF(fprintf(stderr, "DISCONNECT without easy handle, ignoring\n"));
3041 * If this connection isn't marked to force-close, leave it open if there
3042 * are other users of it
3044 if(!conn->bits.close &&
3045 (conn->send_pipe->size + conn->recv_pipe->size)) {
3046 DEBUGF(infof(data, "Curl_disconnect, usecounter: %d\n",
3047 conn->send_pipe->size + conn->recv_pipe->size));
3051 if(conn->dns_entry != NULL) {
3052 Curl_resolv_unlock(data, conn->dns_entry);
3053 conn->dns_entry = NULL;
3056 Curl_hostcache_prune(data); /* kill old DNS cache entries */
3058 #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM)
3059 /* Cleanup NTLM connection-related data */
3060 Curl_http_ntlm_cleanup(conn);
3063 if(conn->handler->disconnect)
3064 /* This is set if protocol-specific cleanups should be made */
3065 conn->handler->disconnect(conn, dead_connection);
3067 /* unlink ourselves! */
3068 infof(data, "Closing connection %ld\n", conn->connection_id);
3069 Curl_conncache_remove_conn(data->state.conn_cache, conn);
3071 free_fixed_hostname(&conn->host);
3072 free_fixed_hostname(&conn->conn_to_host);
3073 free_fixed_hostname(&conn->http_proxy.host);
3074 free_fixed_hostname(&conn->socks_proxy.host);
3076 Curl_ssl_close(conn, FIRSTSOCKET);
3078 /* Indicate to all handles on the pipe that we're dead */
3079 if(Curl_pipeline_wanted(data->multi, CURLPIPE_ANY)) {
3080 signalPipeClose(conn->send_pipe, TRUE);
3081 signalPipeClose(conn->recv_pipe, TRUE);
3090 * This function should return TRUE if the socket is to be assumed to
3091 * be dead. Most commonly this happens when the server has closed the
3092 * connection due to inactivity.
3094 static bool SocketIsDead(curl_socket_t sock)
3097 bool ret_val = TRUE;
3099 sval = SOCKET_READABLE(sock, 0);
3108 * IsPipeliningPossible() returns TRUE if the options set would allow
3109 * pipelining/multiplexing and the connection is using a HTTP protocol.
3111 static bool IsPipeliningPossible(const struct Curl_easy *handle,
3112 const struct connectdata *conn)
3114 /* If a HTTP protocol and pipelining is enabled */
3115 if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
3116 (!conn->bits.protoconnstart || !conn->bits.close)) {
3118 if(Curl_pipeline_wanted(handle->multi, CURLPIPE_HTTP1) &&
3119 (handle->set.httpversion != CURL_HTTP_VERSION_1_0) &&
3120 (handle->set.httpreq == HTTPREQ_GET ||
3121 handle->set.httpreq == HTTPREQ_HEAD))
3122 /* didn't ask for HTTP/1.0 and a GET or HEAD */
3125 if(Curl_pipeline_wanted(handle->multi, CURLPIPE_MULTIPLEX) &&
3126 (handle->set.httpversion >= CURL_HTTP_VERSION_2))
3133 int Curl_removeHandleFromPipeline(struct Curl_easy *handle,
3134 struct curl_llist *pipeline)
3137 struct curl_llist_element *curr;
3139 curr = pipeline->head;
3141 if(curr->ptr == handle) {
3142 Curl_llist_remove(pipeline, curr, NULL);
3143 return 1; /* we removed a handle */
3152 #if 0 /* this code is saved here as it is useful for debugging purposes */
3153 static void Curl_printPipeline(struct curl_llist *pipeline)
3155 struct curl_llist_element *curr;
3157 curr = pipeline->head;
3159 struct Curl_easy *data = (struct Curl_easy *) curr->ptr;
3160 infof(data, "Handle in pipeline: %s\n", data->state.path);
3166 static struct Curl_easy* gethandleathead(struct curl_llist *pipeline)
3168 struct curl_llist_element *curr = pipeline->head;
3170 return (struct Curl_easy *) curr->ptr;
3176 /* remove the specified connection from all (possible) pipelines and related
3178 void Curl_getoff_all_pipelines(struct Curl_easy *data,
3179 struct connectdata *conn)
3181 bool recv_head = (conn->readchannel_inuse &&
3182 Curl_recvpipe_head(data, conn));
3183 bool send_head = (conn->writechannel_inuse &&
3184 Curl_sendpipe_head(data, conn));
3186 if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) && recv_head)
3187 Curl_pipeline_leave_read(conn);
3188 if(Curl_removeHandleFromPipeline(data, conn->send_pipe) && send_head)
3189 Curl_pipeline_leave_write(conn);
3192 static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke)
3194 struct curl_llist_element *curr;
3199 curr = pipeline->head;
3201 struct curl_llist_element *next = curr->next;
3202 struct Curl_easy *data = (struct Curl_easy *) curr->ptr;
3204 #ifdef DEBUGBUILD /* debug-only code */
3205 if(data->magic != CURLEASY_MAGIC_NUMBER) {
3207 infof(data, "signalPipeClose() found BAAD easy handle\n");
3212 data->state.pipe_broke = TRUE;
3213 Curl_multi_handlePipeBreak(data);
3214 Curl_llist_remove(pipeline, curr, NULL);
3220 * This function finds the connection in the connection
3221 * cache that has been unused for the longest time.
3223 * Returns the pointer to the oldest idle connection, or NULL if none was
3226 struct connectdata *
3227 Curl_oldest_idle_connection(struct Curl_easy *data)
3229 struct conncache *bc = data->state.conn_cache;
3230 struct curl_hash_iterator iter;
3231 struct curl_llist_element *curr;
3232 struct curl_hash_element *he;
3233 time_t highscore=-1;
3236 struct connectdata *conn_candidate = NULL;
3237 struct connectbundle *bundle;
3241 Curl_hash_start_iterate(&bc->hash, &iter);
3243 he = Curl_hash_next_element(&iter);
3245 struct connectdata *conn;
3249 curr = bundle->conn_list->head;
3254 /* Set higher score for the age passed since the connection was used */
3255 score = Curl_tvdiff(now, conn->now);
3257 if(score > highscore) {
3259 conn_candidate = conn;
3265 he = Curl_hash_next_element(&iter);
3268 return conn_candidate;
3272 proxy_info_matches(const struct proxy_info* data,
3273 const struct proxy_info* needle)
3275 if((data->proxytype == needle->proxytype) &&
3276 (data->port == needle->port) &&
3277 Curl_safe_strcasecompare(data->host.name, needle->host.name) &&
3278 Curl_safe_strcasecompare(data->user, needle->user) &&
3279 Curl_safe_strcasecompare(data->passwd, needle->passwd))
3287 * This function finds the connection in the connection
3288 * bundle that has been unused for the longest time.
3290 * Returns the pointer to the oldest idle connection, or NULL if none was
3293 static struct connectdata *
3294 find_oldest_idle_connection_in_bundle(struct Curl_easy *data,
3295 struct connectbundle *bundle)
3297 struct curl_llist_element *curr;
3298 time_t highscore=-1;
3301 struct connectdata *conn_candidate = NULL;
3302 struct connectdata *conn;
3308 curr = bundle->conn_list->head;
3313 /* Set higher score for the age passed since the connection was used */
3314 score = Curl_tvdiff(now, conn->now);
3316 if(score > highscore) {
3318 conn_candidate = conn;
3324 return conn_candidate;
3328 * This function checks if given connection is dead and disconnects if so.
3329 * (That also removes it from the connection cache.)
3331 * Returns TRUE if the connection actually was dead and disconnected.
3333 static bool disconnect_if_dead(struct connectdata *conn,
3334 struct Curl_easy *data)
3336 size_t pipeLen = conn->send_pipe->size + conn->recv_pipe->size;
3337 if(!pipeLen && !conn->inuse) {
3338 /* The check for a dead socket makes sense only if there are no
3339 handles in pipeline and the connection isn't already marked in
3342 if(conn->handler->protocol & CURLPROTO_RTSP)
3343 /* RTSP is a special case due to RTP interleaving */
3344 dead = Curl_rtsp_connisdead(conn);
3346 dead = SocketIsDead(conn->sock[FIRSTSOCKET]);
3350 infof(data, "Connection %ld seems to be dead!\n", conn->connection_id);
3352 /* disconnect resources */
3353 Curl_disconnect(conn, /* dead_connection */TRUE);
3361 * Wrapper to use disconnect_if_dead() function in Curl_conncache_foreach()
3365 static int call_disconnect_if_dead(struct connectdata *conn,
3368 struct Curl_easy* data = (struct Curl_easy*)param;
3369 disconnect_if_dead(conn, data);
3370 return 0; /* continue iteration */
3374 * This function scans the connection cache for half-open/dead connections,
3375 * closes and removes them.
3376 * The cleanup is done at most once per second.
3378 static void prune_dead_connections(struct Curl_easy *data)
3380 struct timeval now = Curl_tvnow();
3381 time_t elapsed = Curl_tvdiff(now, data->state.conn_cache->last_cleanup);
3383 if(elapsed >= 1000L) {
3384 Curl_conncache_foreach(data->state.conn_cache, data,
3385 call_disconnect_if_dead);
3386 data->state.conn_cache->last_cleanup = now;
3391 static size_t max_pipeline_length(struct Curl_multi *multi)
3393 return multi ? multi->max_pipeline_length : 0;
3398 * Given one filled in connection struct (named needle), this function should
3399 * detect if there already is one that has all the significant details
3400 * exactly the same and thus should be used instead.
3402 * If there is a match, this function returns TRUE - and has marked the
3403 * connection as 'in-use'. It must later be called with ConnectionDone() to
3404 * return back to 'idle' (unused) state.
3406 * The force_reuse flag is set if the connection must be used, even if
3407 * the pipelining strategy wants to open a new connection instead of reusing.
3410 ConnectionExists(struct Curl_easy *data,
3411 struct connectdata *needle,
3412 struct connectdata **usethis,
3416 struct connectdata *check;
3417 struct connectdata *chosen = 0;
3418 bool foundPendingCandidate = FALSE;
3419 bool canPipeline = IsPipeliningPossible(data, needle);
3420 struct connectbundle *bundle;
3423 bool wantNTLMhttp = ((data->state.authhost.want &
3424 (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
3425 (needle->handler->protocol & PROTO_FAMILY_HTTP));
3426 bool wantProxyNTLMhttp = (needle->bits.proxy_user_passwd &&
3427 ((data->state.authproxy.want &
3428 (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
3429 (needle->handler->protocol & PROTO_FAMILY_HTTP)));
3432 *force_reuse = FALSE;
3435 /* We can't pipe if the site is blacklisted */
3436 if(canPipeline && Curl_pipeline_site_blacklisted(data, needle)) {
3437 canPipeline = FALSE;
3440 /* Look up the bundle with all the connections to this
3442 bundle = Curl_conncache_find_bundle(needle, data->state.conn_cache);
3444 /* Max pipe length is zero (unlimited) for multiplexed connections */
3445 size_t max_pipe_len = (bundle->multiuse != BUNDLE_MULTIPLEX)?
3446 max_pipeline_length(data->multi):0;
3447 size_t best_pipe_len = max_pipe_len;
3448 struct curl_llist_element *curr;
3450 infof(data, "Found bundle for host %s: %p [%s]\n",
3451 (needle->bits.conn_to_host ? needle->conn_to_host.name :
3452 needle->host.name), (void *)bundle,
3453 (bundle->multiuse == BUNDLE_PIPELINING ?
3455 (bundle->multiuse == BUNDLE_MULTIPLEX ?
3456 "can multiplex" : "serially")));
3458 /* We can't pipe if we don't know anything about the server */
3460 if(bundle->multiuse <= BUNDLE_UNKNOWN) {
3461 if((bundle->multiuse == BUNDLE_UNKNOWN) && data->set.pipewait) {
3462 infof(data, "Server doesn't support multi-use yet, wait\n");
3464 return FALSE; /* no re-use */
3467 infof(data, "Server doesn't support multi-use (yet)\n");
3468 canPipeline = FALSE;
3470 if((bundle->multiuse == BUNDLE_PIPELINING) &&
3471 !Curl_pipeline_wanted(data->multi, CURLPIPE_HTTP1)) {
3472 /* not asked for, switch off */
3473 infof(data, "Could pipeline, but not asked to!\n");
3474 canPipeline = FALSE;
3476 else if((bundle->multiuse == BUNDLE_MULTIPLEX) &&
3477 !Curl_pipeline_wanted(data->multi, CURLPIPE_MULTIPLEX)) {
3478 infof(data, "Could multiplex, but not asked to!\n");
3479 canPipeline = FALSE;
3483 curr = bundle->conn_list->head;
3489 * Note that if we use a HTTP proxy in normal mode (no tunneling), we
3490 * check connections to that proxy and not to the actual remote server.
3495 if(disconnect_if_dead(check, data))
3498 pipeLen = check->send_pipe->size + check->recv_pipe->size;
3501 if(check->bits.protoconnstart && check->bits.close)
3504 if(!check->bits.multiplex) {
3505 /* If not multiplexing, make sure the pipe has only GET requests */
3506 struct Curl_easy* sh = gethandleathead(check->send_pipe);
3507 struct Curl_easy* rh = gethandleathead(check->recv_pipe);
3509 if(!IsPipeliningPossible(sh, check))
3513 if(!IsPipeliningPossible(rh, check))
3520 /* can only happen within multi handles, and means that another easy
3521 handle is using this connection */
3525 if(Curl_resolver_asynch()) {
3526 /* ip_addr_str[0] is NUL only if the resolving of the name hasn't
3527 completed yet and until then we don't re-use this connection */
3528 if(!check->ip_addr_str[0]) {
3530 "Connection #%ld is still name resolving, can't reuse\n",
3531 check->connection_id);
3536 if((check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) ||
3537 check->bits.close) {
3538 if(!check->bits.close)
3539 foundPendingCandidate = TRUE;
3540 /* Don't pick a connection that hasn't connected yet or that is going
3542 infof(data, "Connection #%ld isn't open enough, can't reuse\n",
3543 check->connection_id);
3545 if(check->recv_pipe->size > 0) {
3547 "BAD! Unconnected #%ld has a non-empty recv pipeline!\n",
3548 check->connection_id);
3555 #ifdef USE_UNIX_SOCKETS
3556 if(needle->unix_domain_socket) {
3557 if(!check->unix_domain_socket)
3559 if(strcmp(needle->unix_domain_socket, check->unix_domain_socket))
3561 if(needle->abstract_unix_socket != check->abstract_unix_socket)
3564 else if(check->unix_domain_socket)
3568 if((needle->handler->flags&PROTOPT_SSL) !=
3569 (check->handler->flags&PROTOPT_SSL))
3570 /* don't do mixed SSL and non-SSL connections */
3571 if(get_protocol_family(check->handler->protocol) !=
3572 needle->handler->protocol || !check->tls_upgraded)
3573 /* except protocols that have been upgraded via TLS */
3576 if(needle->bits.httpproxy != check->bits.httpproxy ||
3577 needle->bits.socksproxy != check->bits.socksproxy)
3580 if(needle->bits.socksproxy && !proxy_info_matches(&needle->socks_proxy,
3581 &check->socks_proxy))
3584 if(needle->bits.conn_to_host != check->bits.conn_to_host)
3585 /* don't mix connections that use the "connect to host" feature and
3586 * connections that don't use this feature */
3589 if(needle->bits.conn_to_port != check->bits.conn_to_port)
3590 /* don't mix connections that use the "connect to port" feature and
3591 * connections that don't use this feature */
3594 if(needle->bits.httpproxy) {
3595 if(!proxy_info_matches(&needle->http_proxy, &check->http_proxy))
3598 if(needle->bits.tunnel_proxy != check->bits.tunnel_proxy)
3601 if(needle->http_proxy.proxytype == CURLPROXY_HTTPS) {
3602 /* use https proxy */
3603 if(needle->handler->flags&PROTOPT_SSL) {
3604 /* use double layer ssl */
3605 if(!Curl_ssl_config_matches(&needle->proxy_ssl_config,
3606 &check->proxy_ssl_config))
3608 if(check->proxy_ssl[FIRSTSOCKET].state != ssl_connection_complete)
3612 if(!Curl_ssl_config_matches(&needle->ssl_config,
3613 &check->ssl_config))
3615 if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete)
3621 if(!canPipeline && check->inuse)
3622 /* this request can't be pipelined but the checked connection is
3623 already in use so we skip it */
3626 if(needle->localdev || needle->localport) {
3627 /* If we are bound to a specific local end (IP+port), we must not
3628 re-use a random other one, although if we didn't ask for a
3629 particular one we can reuse one that was bound.
3631 This comparison is a bit rough and too strict. Since the input
3632 parameters can be specified in numerous ways and still end up the
3633 same it would take a lot of processing to make it really accurate.
3634 Instead, this matching will assume that re-uses of bound connections
3635 will most likely also re-use the exact same binding parameters and
3636 missing out a few edge cases shouldn't hurt anyone very much.
3638 if((check->localport != needle->localport) ||
3639 (check->localportrange != needle->localportrange) ||
3640 (needle->localdev &&
3641 (!check->localdev || strcmp(check->localdev, needle->localdev))))
3645 if(!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) {
3646 /* This protocol requires credentials per connection,
3647 so verify that we're using the same name and password as well */
3648 if(strcmp(needle->user, check->user) ||
3649 strcmp(needle->passwd, check->passwd)) {
3650 /* one of them was different */
3655 if(!needle->bits.httpproxy || (needle->handler->flags&PROTOPT_SSL) ||
3656 needle->bits.tunnel_proxy) {
3657 /* The requested connection does not use a HTTP proxy or it uses SSL or
3658 it is a non-SSL protocol tunneled or it is a non-SSL protocol which
3659 is allowed to be upgraded via TLS */
3661 if((strcasecompare(needle->handler->scheme, check->handler->scheme) ||
3662 (get_protocol_family(check->handler->protocol) ==
3663 needle->handler->protocol && check->tls_upgraded)) &&
3664 (!needle->bits.conn_to_host || strcasecompare(
3665 needle->conn_to_host.name, check->conn_to_host.name)) &&
3666 (!needle->bits.conn_to_port ||
3667 needle->conn_to_port == check->conn_to_port) &&
3668 strcasecompare(needle->host.name, check->host.name) &&
3669 needle->remote_port == check->remote_port) {
3670 /* The schemes match or the the protocol family is the same and the
3671 previous connection was TLS upgraded, and the hostname and host
3673 if(needle->handler->flags & PROTOPT_SSL) {
3674 /* This is a SSL connection so verify that we're using the same
3675 SSL options as well */
3676 if(!Curl_ssl_config_matches(&needle->ssl_config,
3677 &check->ssl_config)) {
3679 "Connection #%ld has different SSL parameters, "
3681 check->connection_id));
3684 else if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete) {
3685 foundPendingCandidate = TRUE;
3687 "Connection #%ld has not started SSL connect, "
3689 check->connection_id));
3697 /* The requested connection is using the same HTTP proxy in normal
3698 mode (no tunneling) */
3703 #if defined(USE_NTLM)
3704 /* If we are looking for an HTTP+NTLM connection, check if this is
3705 already authenticating with the right credentials. If not, keep
3706 looking so that we can reuse NTLM connections if
3707 possible. (Especially we must not reuse the same connection if
3708 partway through a handshake!) */
3710 if(strcmp(needle->user, check->user) ||
3711 strcmp(needle->passwd, check->passwd))
3714 else if(check->ntlm.state != NTLMSTATE_NONE) {
3715 /* Connection is using NTLM auth but we don't want NTLM */
3719 /* Same for Proxy NTLM authentication */
3720 if(wantProxyNTLMhttp) {
3721 /* Both check->http_proxy.user and check->http_proxy.passwd can be
3723 if(!check->http_proxy.user || !check->http_proxy.passwd)
3726 if(strcmp(needle->http_proxy.user, check->http_proxy.user) ||
3727 strcmp(needle->http_proxy.passwd, check->http_proxy.passwd))
3730 else if(check->proxyntlm.state != NTLMSTATE_NONE) {
3731 /* Proxy connection is using NTLM auth but we don't want NTLM */
3735 if(wantNTLMhttp || wantProxyNTLMhttp) {
3736 /* Credentials are already checked, we can use this connection */
3740 (check->ntlm.state != NTLMSTATE_NONE)) ||
3741 (wantProxyNTLMhttp &&
3742 (check->proxyntlm.state != NTLMSTATE_NONE))) {
3743 /* We must use this connection, no other */
3744 *force_reuse = TRUE;
3748 /* Continue look up for a better connection */
3753 /* We can pipeline if we want to. Let's continue looking for
3754 the optimal connection to use, i.e the shortest pipe that is not
3758 /* We have the optimal connection. Let's stop looking. */
3763 /* We can't use the connection if the pipe is full */
3764 if(max_pipe_len && (pipeLen >= max_pipe_len)) {
3765 infof(data, "Pipe is full, skip (%zu)\n", pipeLen);
3769 /* If multiplexed, make sure we don't go over concurrency limit */
3770 if(check->bits.multiplex) {
3771 /* Multiplexed connections can only be HTTP/2 for now */
3772 struct http_conn *httpc = &check->proto.httpc;
3773 if(pipeLen >= httpc->settings.max_concurrent_streams) {
3774 infof(data, "MAX_CONCURRENT_STREAMS reached, skip (%zu)\n",
3780 /* We can't use the connection if the pipe is penalized */
3781 if(Curl_pipeline_penalized(data, check)) {
3782 infof(data, "Penalized, skip\n");
3787 if(pipeLen < best_pipe_len) {
3788 /* This connection has a shorter pipe so far. We'll pick this
3789 and continue searching */
3791 best_pipe_len = pipeLen;
3796 /* When not pipelining (== multiplexed), we have a match here! */
3798 infof(data, "Multiplexed connection found!\n");
3803 /* We have found a connection. Let's stop searching. */
3813 return TRUE; /* yes, we found one to use! */
3816 if(foundPendingCandidate && data->set.pipewait) {
3818 "Found pending candidate for reuse and CURLOPT_PIPEWAIT is set\n");
3822 return FALSE; /* no matching connecting exists */
3825 /* after a TCP connection to the proxy has been verified, this function does
3826 the next magic step.
3828 Note: this function's sub-functions call failf()
3831 CURLcode Curl_connected_proxy(struct connectdata *conn, int sockindex)
3833 CURLcode result = CURLE_OK;
3835 if(conn->bits.socksproxy) {
3836 #ifndef CURL_DISABLE_PROXY
3837 /* for the secondary socket (FTP), use the "connect to host"
3838 * but ignore the "connect to port" (use the secondary port)
3840 const char * const host = conn->bits.httpproxy ?
3841 conn->http_proxy.host.name :
3842 conn->bits.conn_to_host ?
3843 conn->conn_to_host.name :
3844 sockindex == SECONDARYSOCKET ?
3845 conn->secondaryhostname : conn->host.name;
3846 const int port = conn->bits.httpproxy ? (int)conn->http_proxy.port :
3847 sockindex == SECONDARYSOCKET ? conn->secondary_port :
3848 conn->bits.conn_to_port ? conn->conn_to_port :
3850 conn->bits.socksproxy_connecting = TRUE;
3851 switch(conn->socks_proxy.proxytype) {
3852 case CURLPROXY_SOCKS5:
3853 case CURLPROXY_SOCKS5_HOSTNAME:
3854 result = Curl_SOCKS5(conn->socks_proxy.user, conn->socks_proxy.passwd,
3855 host, port, sockindex, conn);
3858 case CURLPROXY_SOCKS4:
3859 case CURLPROXY_SOCKS4A:
3860 result = Curl_SOCKS4(conn->socks_proxy.user, host, port, sockindex,
3865 failf(conn->data, "unknown proxytype option given");
3866 result = CURLE_COULDNT_CONNECT;
3867 } /* switch proxytype */
3868 conn->bits.socksproxy_connecting = FALSE;
3871 #endif /* CURL_DISABLE_PROXY */
3878 * verboseconnect() displays verbose information after a connect
3880 #ifndef CURL_DISABLE_VERBOSE_STRINGS
3881 void Curl_verboseconnect(struct connectdata *conn)
3883 if(conn->data->set.verbose)
3884 infof(conn->data, "Connected to %s (%s) port %ld (#%ld)\n",
3885 conn->bits.socksproxy ? conn->socks_proxy.host.dispname :
3886 conn->bits.httpproxy ? conn->http_proxy.host.dispname :
3887 conn->bits.conn_to_host ? conn->conn_to_host.dispname :
3888 conn->host.dispname,
3889 conn->ip_addr_str, conn->port, conn->connection_id);
3893 int Curl_protocol_getsock(struct connectdata *conn,
3894 curl_socket_t *socks,
3897 if(conn->handler->proto_getsock)
3898 return conn->handler->proto_getsock(conn, socks, numsocks);
3899 return GETSOCK_BLANK;
3902 int Curl_doing_getsock(struct connectdata *conn,
3903 curl_socket_t *socks,
3906 if(conn && conn->handler->doing_getsock)
3907 return conn->handler->doing_getsock(conn, socks, numsocks);
3908 return GETSOCK_BLANK;
3912 * We are doing protocol-specific connecting and this is being called over and
3913 * over from the multi interface until the connection phase is done on
3917 CURLcode Curl_protocol_connecting(struct connectdata *conn,
3920 CURLcode result=CURLE_OK;
3922 if(conn && conn->handler->connecting) {
3924 result = conn->handler->connecting(conn, done);
3933 * We are DOING this is being called over and over from the multi interface
3934 * until the DOING phase is done on protocol layer.
3937 CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done)
3939 CURLcode result=CURLE_OK;
3941 if(conn && conn->handler->doing) {
3943 result = conn->handler->doing(conn, done);
3952 * We have discovered that the TCP connection has been successful, we can now
3953 * proceed with some action.
3956 CURLcode Curl_protocol_connect(struct connectdata *conn,
3957 bool *protocol_done)
3959 CURLcode result=CURLE_OK;
3961 *protocol_done = FALSE;
3963 if(conn->bits.tcpconnect[FIRSTSOCKET] && conn->bits.protoconnstart) {
3964 /* We already are connected, get back. This may happen when the connect
3965 worked fine in the first call, like when we connect to a local server
3966 or proxy. Note that we don't know if the protocol is actually done.
3968 Unless this protocol doesn't have any protocol-connect callback, as
3969 then we know we're done. */
3970 if(!conn->handler->connecting)
3971 *protocol_done = TRUE;
3976 if(!conn->bits.protoconnstart) {
3978 result = Curl_proxy_connect(conn, FIRSTSOCKET);
3982 if(CONNECT_FIRSTSOCKET_PROXY_SSL())
3983 /* wait for HTTPS proxy SSL initialization to complete */
3986 if(conn->bits.tunnel_proxy && conn->bits.httpproxy &&
3987 (conn->tunnel_state[FIRSTSOCKET] != TUNNEL_COMPLETE))
3988 /* when using an HTTP tunnel proxy, await complete tunnel establishment
3989 before proceeding further. Return CURLE_OK so we'll be called again */
3992 if(conn->handler->connect_it) {
3993 /* is there a protocol-specific connect() procedure? */
3995 /* Call the protocol-specific connect function */
3996 result = conn->handler->connect_it(conn, protocol_done);
3999 *protocol_done = TRUE;
4001 /* it has started, possibly even completed but that knowledge isn't stored
4004 conn->bits.protoconnstart = TRUE;
4007 return result; /* pass back status */
4011 * Helpers for IDNA convertions.
4013 static bool is_ASCII_name(const char *hostname)
4015 const unsigned char *ch = (const unsigned char *)hostname;
4025 * Perform any necessary IDN conversion of hostname
4027 static void fix_hostname(struct connectdata *conn, struct hostname *host)
4030 struct Curl_easy *data = conn->data;
4035 #elif defined(CURL_DISABLE_VERBOSE_STRINGS)
4039 /* set the name we use to display the host name */
4040 host->dispname = host->name;
4042 len = strlen(host->name);
4043 if(len && (host->name[len-1] == '.'))
4044 /* strip off a single trailing dot if present, primarily for SNI but
4045 there's no use for it */
4046 host->name[len-1]=0;
4048 /* Check name for non-ASCII and convert hostname to ACE form if we can */
4049 if(!is_ASCII_name(host->name)) {
4051 if(idn2_check_version(IDN2_VERSION)) {
4052 char *ace_hostname = NULL;
4053 #if IDN2_VERSION_NUMBER >= 0x00140000
4054 /* IDN2_NFC_INPUT: Normalize input string using normalization form C.
4055 IDN2_NONTRANSITIONAL: Perform Unicode TR46 non-transitional
4057 int flags = IDN2_NFC_INPUT | IDN2_NONTRANSITIONAL;
4059 int flags = IDN2_NFC_INPUT;
4061 int rc = idn2_lookup_ul((const char *)host->name, &ace_hostname, flags);
4063 host->encalloc = (char *)ace_hostname;
4064 /* change the name pointer to point to the encoded hostname */
4065 host->name = host->encalloc;
4068 infof(data, "Failed to convert %s to ACE; %s\n", host->name,
4071 #elif defined(USE_WIN32_IDN)
4072 char *ace_hostname = NULL;
4074 if(curl_win32_idn_to_ascii(host->name, &ace_hostname)) {
4075 host->encalloc = ace_hostname;
4076 /* change the name pointer to point to the encoded hostname */
4077 host->name = host->encalloc;
4080 infof(data, "Failed to convert %s to ACE;\n", host->name);
4081 #elif defined(USE_ICU_IDNA)
4082 char *ace_hostname = malloc(MAX_DOMAIN_NAME_LEN * sizeof(char));
4083 UErrorCode errorCode = U_ZERO_ERROR;
4084 UIDNAInfo info = UIDNA_INFO_INITIALIZER;
4086 uidna_openUTS46(UIDNA_USE_STD3_RULES|UIDNA_NONTRANSITIONAL_TO_UNICODE,
4088 int32_t length = uidna_nameToASCII_UTF8(uts46,
4089 host->name, strlen(host->name),
4090 ace_hostname, MAX_DOMAIN_NAME_LEN, &info, &errorCode);
4093 if(errorCode != U_ZERO_ERROR || info.errors || length < 1)
4094 infof(data, "Failed to convert %s to ACE;\n", host->name);
4096 host->encalloc = ace_hostname;
4097 host->name = host->encalloc;
4100 infof(data, "IDN support not present, can't parse Unicode domains\n");
4106 * Frees data allocated by fix_hostname()
4108 static void free_fixed_hostname(struct hostname *host)
4110 #if defined(USE_LIBIDN2)
4111 if(host->encalloc) {
4112 idn2_free(host->encalloc); /* must be freed with idn2_free() since this was
4113 allocated by libidn */
4114 host->encalloc = NULL;
4116 #elif defined(USE_WIN32_IDN)
4117 free(host->encalloc); /* must be freed withidn_free() since this was
4118 allocated by curl_win32_idn_to_ascii */
4119 host->encalloc = NULL;
4120 #elif defined(USE_ICU_IDNA)
4121 free(host->encalloc);
4122 host->encalloc = NULL;
4128 static void llist_dtor(void *user, void *element)
4136 * Allocate and initialize a new connectdata object.
4138 static struct connectdata *allocate_conn(struct Curl_easy *data)
4140 struct connectdata *conn = calloc(1, sizeof(struct connectdata));
4144 conn->handler = &Curl_handler_dummy; /* Be sure we have a handler defined
4145 already from start to avoid NULL
4146 situations and checks */
4148 /* and we setup a few fields in case we end up actually using this struct */
4150 conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
4151 conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
4152 conn->tempsock[0] = CURL_SOCKET_BAD; /* no file descriptor */
4153 conn->tempsock[1] = CURL_SOCKET_BAD; /* no file descriptor */
4154 conn->connection_id = -1; /* no ID */
4155 conn->port = -1; /* unknown at this point */
4156 conn->remote_port = -1; /* unknown at this point */
4157 #if defined(USE_RECV_BEFORE_SEND_WORKAROUND) && defined(DEBUGBUILD)
4158 conn->postponed[0].bindsock = CURL_SOCKET_BAD; /* no file descriptor */
4159 conn->postponed[1].bindsock = CURL_SOCKET_BAD; /* no file descriptor */
4160 #endif /* USE_RECV_BEFORE_SEND_WORKAROUND && DEBUGBUILD */
4162 /* Default protocol-independent behavior doesn't support persistent
4163 connections, so we set this to force-close. Protocols that support
4164 this need to set this to FALSE in their "curl_do" functions. */
4165 connclose(conn, "Default to force-close");
4167 /* Store creation time to help future close decision making */
4168 conn->created = Curl_tvnow();
4170 conn->data = data; /* Setup the association between this connection
4171 and the Curl_easy */
4173 conn->http_proxy.proxytype = data->set.proxytype;
4174 conn->socks_proxy.proxytype = CURLPROXY_SOCKS4;
4176 #ifdef CURL_DISABLE_PROXY
4178 conn->bits.proxy = FALSE;
4179 conn->bits.httpproxy = FALSE;
4180 conn->bits.socksproxy = FALSE;
4181 conn->bits.proxy_user_passwd = FALSE;
4182 conn->bits.tunnel_proxy = FALSE;
4184 #else /* CURL_DISABLE_PROXY */
4186 /* note that these two proxy bits are now just on what looks to be
4187 requested, they may be altered down the road */
4188 conn->bits.proxy = (data->set.str[STRING_PROXY] &&
4189 *data->set.str[STRING_PROXY]) ? TRUE : FALSE;
4190 conn->bits.httpproxy = (conn->bits.proxy &&
4191 (conn->http_proxy.proxytype == CURLPROXY_HTTP ||
4192 conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0 ||
4193 conn->http_proxy.proxytype == CURLPROXY_HTTPS)) ?
4195 conn->bits.socksproxy = (conn->bits.proxy &&
4196 !conn->bits.httpproxy) ? TRUE : FALSE;
4198 if(data->set.str[STRING_PRE_PROXY] && *data->set.str[STRING_PRE_PROXY]) {
4199 conn->bits.proxy = TRUE;
4200 conn->bits.socksproxy = TRUE;
4203 conn->bits.proxy_user_passwd =
4204 (data->set.str[STRING_PROXYUSERNAME]) ? TRUE : FALSE;
4205 conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy;
4207 #endif /* CURL_DISABLE_PROXY */
4209 conn->bits.user_passwd = (data->set.str[STRING_USERNAME]) ? TRUE : FALSE;
4210 conn->bits.ftp_use_epsv = data->set.ftp_use_epsv;
4211 conn->bits.ftp_use_eprt = data->set.ftp_use_eprt;
4213 conn->ssl_config.verifystatus = data->set.ssl.primary.verifystatus;
4214 conn->ssl_config.verifypeer = data->set.ssl.primary.verifypeer;
4215 conn->ssl_config.verifyhost = data->set.ssl.primary.verifyhost;
4216 conn->proxy_ssl_config.verifystatus =
4217 data->set.proxy_ssl.primary.verifystatus;
4218 conn->proxy_ssl_config.verifypeer = data->set.proxy_ssl.primary.verifypeer;
4219 conn->proxy_ssl_config.verifyhost = data->set.proxy_ssl.primary.verifyhost;
4221 conn->ip_version = data->set.ipver;
4223 #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
4224 defined(NTLM_WB_ENABLED)
4225 conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
4226 conn->ntlm_auth_hlpr_pid = 0;
4227 conn->challenge_header = NULL;
4228 conn->response_header = NULL;
4231 if(Curl_pipeline_wanted(data->multi, CURLPIPE_HTTP1) &&
4232 !conn->master_buffer) {
4233 /* Allocate master_buffer to be used for HTTP/1 pipelining */
4234 conn->master_buffer = calloc(BUFSIZE, sizeof(char));
4235 if(!conn->master_buffer)
4239 /* Initialize the pipeline lists */
4240 conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
4241 conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
4242 if(!conn->send_pipe || !conn->recv_pipe)
4246 conn->data_prot = PROT_CLEAR;
4249 /* Store the local bind parameters that will be used for this connection */
4250 if(data->set.str[STRING_DEVICE]) {
4251 conn->localdev = strdup(data->set.str[STRING_DEVICE]);
4255 conn->localportrange = data->set.localportrange;
4256 conn->localport = data->set.localport;
4258 /* the close socket stuff needs to be copied to the connection struct as
4259 it may live on without (this specific) Curl_easy */
4260 conn->fclosesocket = data->set.fclosesocket;
4261 conn->closesocket_client = data->set.closesocket_client;
4266 Curl_llist_destroy(conn->send_pipe, NULL);
4267 Curl_llist_destroy(conn->recv_pipe, NULL);
4269 conn->send_pipe = NULL;
4270 conn->recv_pipe = NULL;
4272 free(conn->master_buffer);
4273 free(conn->localdev);
4278 static CURLcode findprotocol(struct Curl_easy *data,
4279 struct connectdata *conn,
4280 const char *protostr)
4282 const struct Curl_handler * const *pp;
4283 const struct Curl_handler *p;
4285 /* Scan protocol handler table and match against 'protostr' to set a few
4286 variables based on the URL. Now that the handler may be changed later
4287 when the protocol specific setup function is called. */
4288 for(pp = protocols; (p = *pp) != NULL; pp++) {
4289 if(strcasecompare(p->scheme, protostr)) {
4290 /* Protocol found in table. Check if allowed */
4291 if(!(data->set.allowed_protocols & p->protocol))
4295 /* it is allowed for "normal" request, now do an extra check if this is
4296 the result of a redirect */
4297 if(data->state.this_is_a_follow &&
4298 !(data->set.redir_protocols & p->protocol))
4302 /* Perform setup complement if some. */
4303 conn->handler = conn->given = p;
4305 /* 'port' and 'remote_port' are set in setup_connection_internals() */
4311 /* The protocol was not found in the table, but we don't have to assign it
4312 to anything since it is already assigned to a dummy-struct in the
4313 create_conn() function when the connectdata struct is allocated. */
4314 failf(data, "Protocol \"%s\" not supported or disabled in " LIBCURL_NAME,
4317 return CURLE_UNSUPPORTED_PROTOCOL;
4321 * Parse URL and fill in the relevant members of the connection struct.
4323 static CURLcode parseurlandfillconn(struct Curl_easy *data,
4324 struct connectdata *conn,
4326 char **userp, char **passwdp,
4331 char *path = data->state.path;
4335 const char *protop = "";
4337 bool rebuild_url = FALSE;
4338 bool url_has_scheme = FALSE;
4341 *prot_missing = FALSE;
4343 /* We might pass the entire URL into the request so we need to make sure
4344 * there are no bad characters in there.*/
4345 if(strpbrk(data->change.url, "\r\n")) {
4346 failf(data, "Illegal characters found in URL");
4347 return CURLE_URL_MALFORMAT;
4350 /*************************************************************
4353 * We need to parse the url even when using the proxy, because we will need
4354 * the hostname and port in case we are trying to SSL connect through the
4355 * proxy -- and we don't know if we will need to use SSL until we parse the
4357 ************************************************************/
4358 if(data->change.url[0] == ':') {
4359 failf(data, "Bad URL, colon is first character");
4360 return CURLE_URL_MALFORMAT;
4363 /* Make sure we don't mistake a drive letter for a scheme, for example:
4364 curld --proto-default file c:/foo/bar.txt */
4365 if((('a' <= data->change.url[0] && data->change.url[0] <= 'z') ||
4366 ('A' <= data->change.url[0] && data->change.url[0] <= 'Z')) &&
4367 data->change.url[1] == ':' && data->set.str[STRING_DEFAULT_PROTOCOL] &&
4368 strcasecompare(data->set.str[STRING_DEFAULT_PROTOCOL], "file")) {
4371 else { /* check for a scheme */
4372 for(i = 0; i < 16 && data->change.url[i]; ++i) {
4373 if(data->change.url[i] == '/')
4375 if(data->change.url[i] == ':') {
4376 url_has_scheme = TRUE;
4382 /* handle the file: scheme */
4383 if((url_has_scheme && strncasecompare(data->change.url, "file:", 5)) ||
4384 (!url_has_scheme && data->set.str[STRING_DEFAULT_PROTOCOL] &&
4385 strcasecompare(data->set.str[STRING_DEFAULT_PROTOCOL], "file"))) {
4386 bool path_has_drive = FALSE;
4389 rc = sscanf(data->change.url, "%*15[^\n/:]:%[^\n]", path);
4391 rc = sscanf(data->change.url, "%[^\n]", path);
4394 failf(data, "Bad URL");
4395 return CURLE_URL_MALFORMAT;
4398 if(url_has_scheme && path[0] == '/' && path[1] == '/') {
4399 /* Allow omitted hostname (e.g. file:/<path>). This is not strictly
4400 * speaking a valid file: URL by RFC 1738, but treating file:/<path> as
4401 * file://localhost/<path> is similar to how other schemes treat missing
4402 * hostnames. See RFC 1808. */
4404 /* This cannot be done with strcpy() in a portable manner, since the
4405 memory areas overlap! */
4406 memmove(path, path + 2, strlen(path + 2)+1);
4409 /* the path may start with a drive letter. for backwards compatibility
4410 we skip some processing on those paths. */
4411 path_has_drive = (('a' <= path[0] && path[0] <= 'z') ||
4412 ('A' <= path[0] && path[0] <= 'Z')) && path[1] == ':';
4415 * we deal with file://<host>/<path> differently since it supports no
4416 * hostname other than "localhost" and "127.0.0.1", which is unique among
4417 * the URL protocols specified in RFC 1738
4419 if(path[0] != '/' && !path_has_drive) {
4420 /* the URL includes a host name, it must match "localhost" or
4421 "127.0.0.1" to be valid */
4423 if(!checkprefix("localhost/", path) &&
4424 !checkprefix("127.0.0.1/", path)) {
4425 failf(data, "Invalid file://hostname/, "
4426 "expected localhost or 127.0.0.1 or none");
4427 return CURLE_URL_MALFORMAT;
4429 ptr = &path[9]; /* now points to the slash after the host */
4431 /* there was a host name and slash present
4433 RFC1738 (section 3.1, page 5) says:
4435 The rest of the locator consists of data specific to the scheme,
4436 and is known as the "url-path". It supplies the details of how the
4437 specified resource can be accessed. Note that the "/" between the
4438 host (or port) and the url-path is NOT part of the url-path.
4440 As most agents use file://localhost/foo to get '/foo' although the
4441 slash preceding foo is a separator and not a slash for the path,
4442 a URL as file://localhost//foo must be valid as well, to refer to
4443 the same file with an absolute path.
4447 /* if there was two slashes, we skip the first one as that is then
4448 used truly as a separator */
4451 /* This cannot be made with strcpy, as the memory chunks overlap! */
4452 memmove(path, ptr, strlen(ptr)+1);
4454 path_has_drive = (('a' <= path[0] && path[0] <= 'z') ||
4455 ('A' <= path[0] && path[0] <= 'Z')) && path[1] == ':';
4458 #if !defined(MSDOS) && !defined(WIN32) && !defined(__CYGWIN__)
4459 if(path_has_drive) {
4460 failf(data, "File drive letters are only accepted in MSDOS/Windows.");
4461 return CURLE_URL_MALFORMAT;
4465 protop = "file"; /* protocol string */
4466 *prot_missing = !url_has_scheme;
4473 rc = sscanf(data->change.url,
4474 "%15[^\n/:]:%3[/]%[^\n/?#]%[^\n]",
4475 protobuf, slashbuf, conn->host.name, path);
4477 failf(data, "Bad URL");
4478 return CURLE_URL_MALFORMAT;
4483 * The URL was badly formatted, let's try the browser-style _without_
4484 * protocol specified like 'http://'.
4486 rc = sscanf(data->change.url, "%[^\n/?#]%[^\n]", conn->host.name, path);
4489 * We couldn't even get this format.
4490 * djgpp 2.04 has a sscanf() bug where 'conn->host.name' is
4491 * assigned, but the return value is EOF!
4493 #if defined(__DJGPP__) && (DJGPP_MINOR == 4)
4494 if(!(rc == -1 && *conn->host.name))
4497 failf(data, "<url> malformed");
4498 return CURLE_URL_MALFORMAT;
4503 * Since there was no protocol part specified in the URL use the
4504 * user-specified default protocol. If we weren't given a default make a
4505 * guess by matching some protocols against the host's outermost
4506 * sub-domain name. Finally if there was no match use HTTP.
4509 protop = data->set.str[STRING_DEFAULT_PROTOCOL];
4511 /* Note: if you add a new protocol, please update the list in
4512 * lib/version.c too! */
4513 if(checkprefix("FTP.", conn->host.name))
4515 else if(checkprefix("DICT.", conn->host.name))
4517 else if(checkprefix("LDAP.", conn->host.name))
4519 else if(checkprefix("IMAP.", conn->host.name))
4521 else if(checkprefix("SMTP.", conn->host.name))
4523 else if(checkprefix("POP3.", conn->host.name))
4529 *prot_missing = TRUE; /* not given in URL */
4532 size_t s = strlen(slashbuf);
4535 infof(data, "Unwillingly accepted illegal URL using %d slash%s!\n",
4538 if(data->change.url_alloc)
4539 free(data->change.url);
4540 /* repair the URL to use two slashes */
4541 data->change.url = aprintf("%s://%s%s",
4542 protobuf, conn->host.name, path);
4543 if(!data->change.url)
4544 return CURLE_OUT_OF_MEMORY;
4545 data->change.url_alloc = TRUE;
4550 /* We search for '?' in the host name (but only on the right side of a
4551 * @-letter to allow ?-letters in username and password) to handle things
4552 * like http://example.com?param= (notice the missing '/').
4554 at = strchr(conn->host.name, '@');
4556 query = strchr(at+1, '?');
4558 query = strchr(conn->host.name, '?');
4561 /* We must insert a slash before the '?'-letter in the URL. If the URL had
4562 a slash after the '?', that is where the path currently begins and the
4563 '?string' is still part of the host name.
4565 We must move the trailing part from the host name and put it first in
4566 the path. And have it all prefixed with a slash.
4569 size_t hostlen = strlen(query);
4570 size_t pathlen = strlen(path);
4572 /* move the existing path plus the zero byte forward, to make room for
4573 the host-name part */
4574 memmove(path+hostlen+1, path, pathlen+1);
4576 /* now copy the trailing host part in front of the existing path */
4577 memcpy(path+1, query, hostlen);
4579 path[0]='/'; /* prepend the missing slash */
4582 *query=0; /* now cut off the hostname at the ? */
4585 /* if there's no path set, use a single slash */
4590 /* If the URL is malformatted (missing a '/' after hostname before path) we
4591 * insert a slash here. The only letters except '/' that can start a path is
4592 * '?' and '#' - as controlled by the two sscanf() patterns above.
4594 if(path[0] != '/') {
4595 /* We need this function to deal with overlapping memory areas. We know
4596 that the memory area 'path' points to is 'urllen' bytes big and that
4597 is bigger than the path. Use +1 to move the zero byte too. */
4598 memmove(&path[1], path, strlen(path)+1);
4602 else if(!data->set.path_as_is) {
4603 /* sanitise paths and remove ../ and ./ sequences according to RFC3986 */
4604 char *newp = Curl_dedotdotify(path);
4606 return CURLE_OUT_OF_MEMORY;
4608 if(strcmp(newp, path)) {
4610 free(data->state.pathbuffer);
4611 data->state.pathbuffer = newp;
4612 data->state.path = newp;
4620 * "rebuild_url" means that one or more URL components have been modified so
4621 * we need to generate an updated full version. We need the corrected URL
4622 * when communicating over HTTP proxy and we don't know at this point if
4623 * we're using a proxy or not.
4628 size_t plen = strlen(path); /* new path, should be 1 byte longer than
4630 size_t prefixlen = strlen(conn->host.name);
4632 if(!*prot_missing) {
4633 size_t protolen = strlen(protop);
4635 if(curl_strnequal(protop, data->change.url, protolen))
4636 prefixlen += protolen;
4638 failf(data, "<url> malformed");
4639 return CURLE_URL_MALFORMAT;
4642 if(curl_strnequal("://", &data->change.url[protolen], 3))
4644 /* only file: is allowed to omit one or both slashes */
4645 else if(curl_strnequal("file:", data->change.url, 5))
4646 prefixlen += 1 + (data->change.url[5] == '/');
4648 failf(data, "<url> malformed");
4649 return CURLE_URL_MALFORMAT;
4653 reurl = malloc(prefixlen + plen + 1);
4655 return CURLE_OUT_OF_MEMORY;
4657 /* copy the prefix */
4658 memcpy(reurl, data->change.url, prefixlen);
4660 /* append the trailing piece + zerobyte */
4661 memcpy(&reurl[prefixlen], path, plen + 1);
4663 /* possible free the old one */
4664 if(data->change.url_alloc) {
4665 Curl_safefree(data->change.url);
4666 data->change.url_alloc = FALSE;
4669 infof(data, "Rebuilt URL to: %s\n", reurl);
4671 data->change.url = reurl;
4672 data->change.url_alloc = TRUE; /* free this later */
4675 result = findprotocol(data, conn, protop);
4680 * Parse the login details from the URL and strip them out of
4683 result = parse_url_login(data, conn, userp, passwdp, optionsp);
4687 if(conn->host.name[0] == '[') {
4688 /* This looks like an IPv6 address literal. See if there is an address
4689 scope if there is no location header */
4690 char *percent = strchr(conn->host.name, '%');
4692 unsigned int identifier_offset = 3;
4694 unsigned long scope;
4695 if(strncmp("%25", percent, 3) != 0) {
4697 "Please URL encode %% as %%25, see RFC 6874.\n");
4698 identifier_offset = 1;
4700 scope = strtoul(percent + identifier_offset, &endp, 10);
4702 /* The address scope was well formed. Knock it out of the
4704 memmove(percent, endp, strlen(endp)+1);
4705 conn->scope_id = (unsigned int)scope;
4708 /* Zone identifier is not numeric */
4709 #if defined(HAVE_NET_IF_H) && defined(IFNAMSIZ) && defined(HAVE_IF_NAMETOINDEX)
4710 char ifname[IFNAMSIZ + 2];
4711 char *square_bracket;
4712 unsigned int scopeidx = 0;
4713 strncpy(ifname, percent + identifier_offset, IFNAMSIZ + 2);
4714 /* Ensure nullbyte termination */
4715 ifname[IFNAMSIZ + 1] = '\0';
4716 square_bracket = strchr(ifname, ']');
4717 if(square_bracket) {
4719 *square_bracket = '\0';
4720 scopeidx = if_nametoindex(ifname);
4722 infof(data, "Invalid network interface: %s; %s\n", ifname,
4727 char *p = percent + identifier_offset + strlen(ifname);
4729 /* Remove zone identifier from hostname */
4730 memmove(percent, p, strlen(p) + 1);
4731 conn->scope_id = scopeidx;
4734 #endif /* HAVE_NET_IF_H && IFNAMSIZ */
4735 infof(data, "Invalid IPv6 address format\n");
4740 if(data->set.scope_id)
4741 /* Override any scope that was set above. */
4742 conn->scope_id = data->set.scope_id;
4744 /* Remove the fragment part of the path. Per RFC 2396, this is always the
4745 last part of the URI. We are looking for the first '#' so that we deal
4746 gracefully with non conformant URI such as http://example.com#foo#bar. */
4747 fragment = strchr(path, '#');
4751 /* we know the path part ended with a fragment, so we know the full URL
4752 string does too and we need to cut it off from there so it isn't used
4754 fragment = strchr(data->change.url, '#');
4760 * So if the URL was A://B/C#D,
4762 * conn->host.name is B
4763 * data->state.path is /C
4769 * If we're doing a resumed transfer, we need to setup our stuff
4772 static CURLcode setup_range(struct Curl_easy *data)
4774 struct UrlState *s = &data->state;
4775 s->resume_from = data->set.set_resume_from;
4776 if(s->resume_from || data->set.str[STRING_SET_RANGE]) {
4777 if(s->rangestringalloc)
4781 s->range = aprintf("%" CURL_FORMAT_CURL_OFF_TU "-", s->resume_from);
4783 s->range = strdup(data->set.str[STRING_SET_RANGE]);
4785 s->rangestringalloc = (s->range) ? TRUE : FALSE;
4788 return CURLE_OUT_OF_MEMORY;
4790 /* tell ourselves to fetch this range */
4791 s->use_range = TRUE; /* enable range download */
4794 s->use_range = FALSE; /* disable range download */
4801 * setup_connection_internals() -
4803 * Setup connection internals specific to the requested protocol in the
4804 * Curl_easy. This is inited and setup before the connection is made but
4805 * is about the particular protocol that is to be used.
4807 * This MUST get called after proxy magic has been figured out.
4809 static CURLcode setup_connection_internals(struct connectdata *conn)
4811 const struct Curl_handler * p;
4813 struct Curl_easy *data = conn->data;
4815 /* in some case in the multi state-machine, we go back to the CONNECT state
4816 and then a second (or third or...) call to this function will be made
4817 without doing a DISCONNECT or DONE in between (since the connection is
4818 yet in place) and therefore this function needs to first make sure
4819 there's no lingering previous data allocated. */
4820 Curl_free_request_state(data);
4822 memset(&data->req, 0, sizeof(struct SingleRequest));
4823 data->req.maxdownload = -1;
4825 conn->socktype = SOCK_STREAM; /* most of them are TCP streams */
4827 /* Perform setup complement if some. */
4830 if(p->setup_connection) {
4831 result = (*p->setup_connection)(conn);
4836 p = conn->handler; /* May have changed. */
4840 /* we check for -1 here since if proxy was detected already, this
4841 was very likely already set to the proxy port */
4842 conn->port = p->defport;
4848 * Curl_free_request_state() should free temp data that was allocated in the
4849 * Curl_easy for this single request.
4852 void Curl_free_request_state(struct Curl_easy *data)
4854 Curl_safefree(data->req.protop);
4855 Curl_safefree(data->req.newurl);
4859 #ifndef CURL_DISABLE_PROXY
4860 /****************************************************************
4861 * Checks if the host is in the noproxy list. returns true if it matches
4862 * and therefore the proxy should NOT be used.
4863 ****************************************************************/
4864 static bool check_noproxy(const char *name, const char *no_proxy)
4866 /* no_proxy=domain1.dom,host.domain2.dom
4867 * (a comma-separated list of hosts which should
4868 * not be proxied, or an asterisk to override
4869 * all proxy variables)
4873 const char *separator = ", ";
4874 size_t no_proxy_len;
4878 if(no_proxy && no_proxy[0]) {
4879 if(strcasecompare("*", no_proxy)) {
4883 /* NO_PROXY was specified and it wasn't just an asterisk */
4885 no_proxy_len = strlen(no_proxy);
4886 endptr = strchr(name, ':');
4888 namelen = endptr - name;
4890 namelen = strlen(name);
4892 for(tok_start = 0; tok_start < no_proxy_len; tok_start = tok_end + 1) {
4893 while(tok_start < no_proxy_len &&
4894 strchr(separator, no_proxy[tok_start]) != NULL) {
4895 /* Look for the beginning of the token. */
4899 if(tok_start == no_proxy_len)
4900 break; /* It was all trailing separator chars, no more tokens. */
4902 for(tok_end = tok_start; tok_end < no_proxy_len &&
4903 strchr(separator, no_proxy[tok_end]) == NULL; ++tok_end)
4904 /* Look for the end of the token. */
4907 /* To match previous behaviour, where it was necessary to specify
4908 * ".local.com" to prevent matching "notlocal.com", we will leave
4911 if(no_proxy[tok_start] == '.')
4914 if((tok_end - tok_start) <= namelen) {
4915 /* Match the last part of the name to the domain we are checking. */
4916 const char *checkn = name + namelen - (tok_end - tok_start);
4917 if(strncasecompare(no_proxy + tok_start, checkn,
4918 tok_end - tok_start)) {
4919 if((tok_end - tok_start) == namelen || *(checkn - 1) == '.') {
4920 /* We either have an exact match, or the previous character is a .
4921 * so it is within the same domain, so no proxy for this host.
4926 } /* if((tok_end - tok_start) <= namelen) */
4927 } /* for(tok_start = 0; tok_start < no_proxy_len;
4928 tok_start = tok_end + 1) */
4929 } /* NO_PROXY was specified and it wasn't just an asterisk */
4934 /****************************************************************
4935 * Detect what (if any) proxy to use. Remember that this selects a host
4936 * name and is not limited to HTTP proxies only.
4937 * The returned pointer must be freed by the caller (unless NULL)
4938 ****************************************************************/
4939 static char *detect_proxy(struct connectdata *conn)
4943 /* If proxy was not specified, we check for default proxy environment
4944 * variables, to enable i.e Lynx compliance:
4946 * http_proxy=http://some.server.dom:port/
4947 * https_proxy=http://some.server.dom:port/
4948 * ftp_proxy=http://some.server.dom:port/
4949 * no_proxy=domain1.dom,host.domain2.dom
4950 * (a comma-separated list of hosts which should
4951 * not be proxied, or an asterisk to override
4952 * all proxy variables)
4953 * all_proxy=http://some.server.dom:port/
4954 * (seems to exist for the CERN www lib. Probably
4955 * the first to check for.)
4957 * For compatibility, the all-uppercase versions of these variables are
4958 * checked if the lowercase versions don't exist.
4960 char proxy_env[128];
4961 const char *protop = conn->handler->scheme;
4962 char *envp = proxy_env;
4965 /* Now, build <protocol>_proxy and check for such a one to use */
4967 *envp++ = (char)tolower((int)*protop++);
4970 strcpy(envp, "_proxy");
4972 /* read the protocol proxy: */
4973 prox=curl_getenv(proxy_env);
4976 * We don't try the uppercase version of HTTP_PROXY because of
4979 * When curl is used in a webserver application
4980 * environment (cgi or php), this environment variable can
4981 * be controlled by the web server user by setting the
4982 * http header 'Proxy:' to some value.
4984 * This can cause 'internal' http/ftp requests to be
4985 * arbitrarily redirected by any external attacker.
4987 if(!prox && !strcasecompare("http_proxy", proxy_env)) {
4988 /* There was no lowercase variable, try the uppercase version: */
4989 Curl_strntoupper(proxy_env, proxy_env, sizeof(proxy_env));
4990 prox=curl_getenv(proxy_env);
4994 proxy = prox; /* use this */
4996 proxy = curl_getenv("all_proxy"); /* default proxy to use */
4998 proxy=curl_getenv("ALL_PROXY");
5005 * If this is supposed to use a proxy, we need to figure out the proxy
5006 * host name, so that we can re-use an existing connection
5007 * that may exist registered to the same proxy host.
5009 static CURLcode parse_proxy(struct Curl_easy *data,
5010 struct connectdata *conn, char *proxy,
5011 curl_proxytype proxytype)
5016 /* We use 'proxyptr' to point to the proxy name from now on... */
5021 char *proxyuser = NULL;
5022 char *proxypasswd = NULL;
5025 /* We do the proxy host string parsing here. We want the host name and the
5026 * port name. Accept a protocol:// prefix
5029 /* Parse the protocol part if present */
5030 endofprot = strstr(proxy, "://");
5032 proxyptr = endofprot+3;
5033 if(checkprefix("https", proxy))
5034 proxytype = CURLPROXY_HTTPS;
5035 else if(checkprefix("socks5h", proxy))
5036 proxytype = CURLPROXY_SOCKS5_HOSTNAME;
5037 else if(checkprefix("socks5", proxy))
5038 proxytype = CURLPROXY_SOCKS5;
5039 else if(checkprefix("socks4a", proxy))
5040 proxytype = CURLPROXY_SOCKS4A;
5041 else if(checkprefix("socks4", proxy) || checkprefix("socks", proxy))
5042 proxytype = CURLPROXY_SOCKS4;
5043 else if(checkprefix("http:", proxy))
5044 ; /* leave it as HTTP or HTTP/1.0 */
5046 /* Any other xxx:// reject! */
5047 failf(data, "Unsupported proxy scheme for \'%s\'", proxy);
5048 return CURLE_COULDNT_CONNECT;
5052 proxyptr = proxy; /* No xxx:// head: It's a HTTP proxy */
5054 #ifndef HTTPS_PROXY_SUPPORT
5055 if(proxytype == CURLPROXY_HTTPS) {
5056 failf(data, "Unsupported proxy \'%s\'"
5057 ", libcurl is built without the HTTPS-proxy support.", proxy);
5058 return CURLE_NOT_BUILT_IN;
5062 sockstype = proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
5063 proxytype == CURLPROXY_SOCKS5 ||
5064 proxytype == CURLPROXY_SOCKS4A ||
5065 proxytype == CURLPROXY_SOCKS4;
5067 /* Is there a username and password given in this proxy url? */
5068 atsign = strchr(proxyptr, '@');
5071 parse_login_details(proxyptr, atsign - proxyptr,
5072 &proxyuser, &proxypasswd, NULL);
5075 proxyptr = atsign + 1;
5078 /* start scanning for port number at this point */
5081 /* detect and extract RFC6874-style IPv6-addresses */
5082 if(*proxyptr == '[') {
5083 char *ptr = ++proxyptr; /* advance beyond the initial bracket */
5084 while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '.')))
5087 /* There might be a zone identifier */
5088 if(strncmp("%25", ptr, 3))
5089 infof(data, "Please URL encode %% as %%25, see RFC 6874.\n");
5091 /* Allow unreserved characters as defined in RFC 3986 */
5092 while(*ptr && (ISALPHA(*ptr) || ISXDIGIT(*ptr) || (*ptr == '-') ||
5093 (*ptr == '.') || (*ptr == '_') || (*ptr == '~')))
5097 /* yeps, it ended nicely with a bracket as well */
5100 infof(data, "Invalid IPv6 address format\n");
5102 /* Note that if this didn't end with a bracket, we still advanced the
5103 * proxyptr first, but I can't see anything wrong with that as no host
5104 * name nor a numeric can legally start with a bracket.
5108 /* Get port number off proxy.server.com:1080 */
5109 prox_portno = strchr(portptr, ':');
5113 *prox_portno = 0x0; /* cut off number from host name */
5115 /* now set the local port number */
5116 port = strtol(prox_portno, &endp, 10);
5117 if((endp && *endp && (*endp != '/') && (*endp != ' ')) ||
5118 (port < 0) || (port > 65535)) {
5119 /* meant to detect for example invalid IPv6 numerical addresses without
5120 brackets: "2a00:fac0:a000::7:13". Accept a trailing slash only
5121 because we then allow "URL style" with the number followed by a
5122 slash, used in curl test cases already. Space is also an acceptable
5123 terminating symbol. */
5124 infof(data, "No valid port number in proxy string (%s)\n",
5131 if(proxyptr[0]=='/')
5132 /* If the first character in the proxy string is a slash, fail
5133 immediately. The following code will otherwise clear the string which
5134 will lead to code running as if no proxy was set! */
5135 return CURLE_COULDNT_RESOLVE_PROXY;
5137 /* without a port number after the host name, some people seem to use
5138 a slash so we strip everything from the first slash */
5139 atsign = strchr(proxyptr, '/');
5141 *atsign = '\0'; /* cut off path part from host name */
5143 if(data->set.proxyport)
5144 /* None given in the proxy string, then get the default one if it is
5146 port = data->set.proxyport;
5148 if(proxytype == CURLPROXY_HTTPS)
5149 port = CURL_DEFAULT_HTTPS_PROXY_PORT;
5151 port = CURL_DEFAULT_PROXY_PORT;
5156 struct proxy_info *proxyinfo =
5157 sockstype ? &conn->socks_proxy : &conn->http_proxy;
5158 proxyinfo->proxytype = proxytype;
5161 /* found user and password, rip them out. note that we are unescaping
5162 them, as there is otherwise no way to have a username or password
5163 with reserved characters like ':' in them. */
5164 Curl_safefree(proxyinfo->user);
5165 proxyinfo->user = curl_easy_unescape(data, proxyuser, 0, NULL);
5167 if(!proxyinfo->user)
5168 return CURLE_OUT_OF_MEMORY;
5170 Curl_safefree(proxyinfo->passwd);
5171 if(proxypasswd && strlen(proxypasswd) < MAX_CURL_PASSWORD_LENGTH)
5172 proxyinfo->passwd = curl_easy_unescape(data, proxypasswd, 0, NULL);
5174 proxyinfo->passwd = strdup("");
5176 if(!proxyinfo->passwd)
5177 return CURLE_OUT_OF_MEMORY;
5179 conn->bits.proxy_user_passwd = TRUE; /* enable it */
5183 proxyinfo->port = port;
5184 if(conn->port < 0 || sockstype || !conn->socks_proxy.host.rawalloc)
5188 /* now, clone the cleaned proxy host name */
5189 Curl_safefree(proxyinfo->host.rawalloc);
5190 proxyinfo->host.rawalloc = strdup(proxyptr);
5191 proxyinfo->host.name = proxyinfo->host.rawalloc;
5193 if(!proxyinfo->host.rawalloc)
5194 return CURLE_OUT_OF_MEMORY;
5197 Curl_safefree(proxyuser);
5198 Curl_safefree(proxypasswd);
5204 * Extract the user and password from the authentication string
5206 static CURLcode parse_proxy_auth(struct Curl_easy *data,
5207 struct connectdata *conn)
5209 char proxyuser[MAX_CURL_USER_LENGTH]="";
5210 char proxypasswd[MAX_CURL_PASSWORD_LENGTH]="";
5213 if(data->set.str[STRING_PROXYUSERNAME] != NULL) {
5214 strncpy(proxyuser, data->set.str[STRING_PROXYUSERNAME],
5215 MAX_CURL_USER_LENGTH);
5216 proxyuser[MAX_CURL_USER_LENGTH-1] = '\0'; /*To be on safe side*/
5218 if(data->set.str[STRING_PROXYPASSWORD] != NULL) {
5219 strncpy(proxypasswd, data->set.str[STRING_PROXYPASSWORD],
5220 MAX_CURL_PASSWORD_LENGTH);
5221 proxypasswd[MAX_CURL_PASSWORD_LENGTH-1] = '\0'; /*To be on safe side*/
5224 result = Curl_urldecode(data, proxyuser, 0, &conn->http_proxy.user, NULL,
5227 result = Curl_urldecode(data, proxypasswd, 0, &conn->http_proxy.passwd,
5231 #endif /* CURL_DISABLE_PROXY */
5236 * Parse the login details (user name, password and options) from the URL and
5237 * strip them out of the host name
5239 * Inputs: data->set.use_netrc (CURLOPT_NETRC)
5242 * Outputs: (almost :- all currently undefined)
5243 * conn->bits.user_passwd - non-zero if non-default passwords exist
5244 * user - non-zero length if defined
5245 * passwd - non-zero length if defined
5246 * options - non-zero length if defined
5247 * conn->host.name - remove user name and password
5249 static CURLcode parse_url_login(struct Curl_easy *data,
5250 struct connectdata *conn,
5251 char **user, char **passwd, char **options)
5253 CURLcode result = CURLE_OK;
5255 char *passwdp = NULL;
5256 char *optionsp = NULL;
5258 /* At this point, we're hoping all the other special cases have
5259 * been taken care of, so conn->host.name is at most
5260 * [user[:password][;options]]@]hostname
5262 * We need somewhere to put the embedded details, so do that first.
5265 char *ptr = strchr(conn->host.name, '@');
5266 char *login = conn->host.name;
5268 DEBUGASSERT(!**user);
5269 DEBUGASSERT(!**passwd);
5270 DEBUGASSERT(!**options);
5271 DEBUGASSERT(conn->handler);
5276 /* We will now try to extract the
5277 * possible login information in a string like:
5278 * ftp://user:password@ftp.my.site:8021/README */
5279 conn->host.name = ++ptr;
5281 /* So the hostname is sane. Only bother interpreting the
5282 * results if we could care. It could still be wasted
5283 * work because it might be overtaken by the programmatically
5284 * set user/passwd, but doing that first adds more cases here :-(
5287 if(data->set.use_netrc == CURL_NETRC_REQUIRED)
5290 /* We could use the login information in the URL so extract it. Only parse
5291 options if the handler says we should. */
5292 result = parse_login_details(login, ptr - login - 1,
5294 (conn->handler->flags & PROTOPT_URLOPTIONS)?
5302 /* We have a user in the URL */
5303 conn->bits.userpwd_in_url = TRUE;
5304 conn->bits.user_passwd = TRUE; /* enable user+password */
5306 /* Decode the user */
5307 result = Curl_urldecode(data, userp, 0, &newname, NULL, FALSE);
5317 /* We have a password in the URL so decode it */
5319 result = Curl_urldecode(data, passwdp, 0, &newpasswd, NULL, FALSE);
5325 *passwd = newpasswd;
5329 /* We have an options list in the URL so decode it */
5331 result = Curl_urldecode(data, optionsp, 0, &newoptions, NULL, FALSE);
5337 *options = newoptions;
5351 * parse_login_details()
5353 * This is used to parse a login string for user name, password and options in
5354 * the following formats:
5358 * user:password;options
5360 * user;options:password
5368 * login [in] - The login string.
5369 * len [in] - The length of the login string.
5370 * userp [in/out] - The address where a pointer to newly allocated memory
5371 * holding the user will be stored upon completion.
5372 * passdwp [in/out] - The address where a pointer to newly allocated memory
5373 * holding the password will be stored upon completion.
5374 * optionsp [in/out] - The address where a pointer to newly allocated memory
5375 * holding the options will be stored upon completion.
5377 * Returns CURLE_OK on success.
5379 static CURLcode parse_login_details(const char *login, const size_t len,
5380 char **userp, char **passwdp,
5383 CURLcode result = CURLE_OK;
5387 const char *psep = NULL;
5388 const char *osep = NULL;
5393 /* Attempt to find the password separator */
5395 psep = strchr(login, ':');
5397 /* Within the constraint of the login string */
5398 if(psep >= login + len)
5402 /* Attempt to find the options separator */
5404 osep = strchr(login, ';');
5406 /* Within the constraint of the login string */
5407 if(osep >= login + len)
5411 /* Calculate the portion lengths */
5413 (size_t)(osep && psep > osep ? osep - login : psep - login) :
5414 (osep ? (size_t)(osep - login) : len));
5416 (osep && osep > psep ? (size_t)(osep - psep) :
5417 (size_t)(login + len - psep)) - 1 : 0);
5419 (psep && psep > osep ? (size_t)(psep - osep) :
5420 (size_t)(login + len - osep)) - 1 : 0);
5422 /* Allocate the user portion buffer */
5424 ubuf = malloc(ulen + 1);
5426 result = CURLE_OUT_OF_MEMORY;
5429 /* Allocate the password portion buffer */
5430 if(!result && passwdp && plen) {
5431 pbuf = malloc(plen + 1);
5434 result = CURLE_OUT_OF_MEMORY;
5438 /* Allocate the options portion buffer */
5439 if(!result && optionsp && olen) {
5440 obuf = malloc(olen + 1);
5444 result = CURLE_OUT_OF_MEMORY;
5449 /* Store the user portion if necessary */
5451 memcpy(ubuf, login, ulen);
5453 Curl_safefree(*userp);
5457 /* Store the password portion if necessary */
5459 memcpy(pbuf, psep + 1, plen);
5461 Curl_safefree(*passwdp);
5465 /* Store the options portion if necessary */
5467 memcpy(obuf, osep + 1, olen);
5469 Curl_safefree(*optionsp);
5477 /*************************************************************
5478 * Figure out the remote port number and fix it in the URL
5480 * No matter if we use a proxy or not, we have to figure out the remote
5481 * port number of various reasons.
5483 * To be able to detect port number flawlessly, we must not confuse them
5484 * IPv6-specified addresses in the [0::1] style. (RFC2732)
5486 * The conn->host.name is currently [user:passwd@]host[:port] where host
5487 * could be a hostname, IPv4 address or IPv6 address.
5489 * The port number embedded in the URL is replaced, if necessary.
5490 *************************************************************/
5491 static CURLcode parse_remote_port(struct Curl_easy *data,
5492 struct connectdata *conn)
5497 /* Note that at this point, the IPv6 address cannot contain any scope
5498 suffix as that has already been removed in the parseurlandfillconn()
5500 if((1 == sscanf(conn->host.name, "[%*45[0123456789abcdefABCDEF:.]%c",
5502 (']' == endbracket)) {
5503 /* this is a RFC2732-style specified IP-address */
5504 conn->bits.ipv6_ip = TRUE;
5506 conn->host.name++; /* skip over the starting bracket */
5507 portptr = strchr(conn->host.name, ']');
5509 *portptr++ = '\0'; /* zero terminate, killing the bracket */
5511 portptr = NULL; /* no port number available */
5516 struct in6_addr in6;
5517 if(Curl_inet_pton(AF_INET6, conn->host.name, &in6) > 0) {
5518 /* This is a numerical IPv6 address, meaning this is a wrongly formatted
5520 failf(data, "IPv6 numerical address used in URL without brackets");
5521 return CURLE_URL_MALFORMAT;
5525 portptr = strrchr(conn->host.name, ':');
5528 if(data->set.use_port && data->state.allow_port) {
5529 /* if set, we use this and ignore the port possibly given in the URL */
5530 conn->remote_port = (unsigned short)data->set.use_port;
5532 *portptr = '\0'; /* cut off the name there anyway - if there was a port
5533 number - since the port number is to be ignored! */
5534 if(conn->bits.httpproxy) {
5535 /* we need to create new URL with the new port number */
5539 if(conn->bits.type_set)
5540 snprintf(type, sizeof(type), ";type=%c",
5541 data->set.prefer_ascii?'A':
5542 (data->set.ftp_list_only?'D':'I'));
5545 * This synthesized URL isn't always right--suffixes like ;type=A are
5546 * stripped off. It would be better to work directly from the original
5547 * URL and simply replace the port part of it.
5549 url = aprintf("%s://%s%s%s:%hu%s%s%s", conn->given->scheme,
5550 conn->bits.ipv6_ip?"[":"", conn->host.name,
5551 conn->bits.ipv6_ip?"]":"", conn->remote_port,
5552 data->state.slash_removed?"/":"", data->state.path,
5555 return CURLE_OUT_OF_MEMORY;
5557 if(data->change.url_alloc) {
5558 Curl_safefree(data->change.url);
5559 data->change.url_alloc = FALSE;
5562 data->change.url = url;
5563 data->change.url_alloc = TRUE;
5567 /* no CURLOPT_PORT given, extract the one from the URL */
5572 port=strtol(portptr+1, &rest, 10); /* Port number must be decimal */
5574 if((port < 0) || (port > 0xffff)) {
5575 /* Single unix standard says port numbers are 16 bits long */
5576 failf(data, "Port number out of range");
5577 return CURLE_URL_MALFORMAT;
5580 else if(rest != &portptr[1]) {
5581 *portptr = '\0'; /* cut off the name there */
5582 conn->remote_port = curlx_ultous(port);
5586 failf(data, "Illegal port number");
5587 return CURLE_URL_MALFORMAT;
5589 /* Browser behavior adaptation. If there's a colon with no digits after,
5590 just cut off the name there which makes us ignore the colon and just
5591 use the default port. Firefox and Chrome both do that. */
5596 /* only if remote_port was not already parsed off the URL we use the
5597 default port number */
5598 if(conn->remote_port < 0)
5599 conn->remote_port = (unsigned short)conn->given->defport;
5605 * Override the login details from the URL with that in the CURLOPT_USERPWD
5606 * option or a .netrc file, if applicable.
5608 static CURLcode override_login(struct Curl_easy *data,
5609 struct connectdata *conn,
5610 char **userp, char **passwdp, char **optionsp)
5612 if(data->set.str[STRING_USERNAME]) {
5614 *userp = strdup(data->set.str[STRING_USERNAME]);
5616 return CURLE_OUT_OF_MEMORY;
5619 if(data->set.str[STRING_PASSWORD]) {
5621 *passwdp = strdup(data->set.str[STRING_PASSWORD]);
5623 return CURLE_OUT_OF_MEMORY;
5626 if(data->set.str[STRING_OPTIONS]) {
5628 *optionsp = strdup(data->set.str[STRING_OPTIONS]);
5630 return CURLE_OUT_OF_MEMORY;
5633 conn->bits.netrc = FALSE;
5634 if(data->set.use_netrc != CURL_NETRC_IGNORED) {
5635 int ret = Curl_parsenetrc(conn->host.name,
5637 data->set.str[STRING_NETRC_FILE]);
5639 infof(data, "Couldn't find host %s in the "
5640 DOT_CHAR "netrc file; using defaults\n",
5644 return CURLE_OUT_OF_MEMORY;
5647 /* set bits.netrc TRUE to remember that we got the name from a .netrc
5648 file, so that it is safe to use even if we followed a Location: to a
5649 different host or similar. */
5650 conn->bits.netrc = TRUE;
5652 conn->bits.user_passwd = TRUE; /* enable user+password */
5660 * Set the login details so they're available in the connection
5662 static CURLcode set_login(struct connectdata *conn,
5663 const char *user, const char *passwd,
5664 const char *options)
5666 CURLcode result = CURLE_OK;
5668 /* If our protocol needs a password and we have none, use the defaults */
5669 if((conn->handler->flags & PROTOPT_NEEDSPWD) && !conn->bits.user_passwd) {
5670 /* Store the default user */
5671 conn->user = strdup(CURL_DEFAULT_USER);
5673 /* Store the default password */
5675 conn->passwd = strdup(CURL_DEFAULT_PASSWORD);
5677 conn->passwd = NULL;
5679 /* This is the default password, so DON'T set conn->bits.user_passwd */
5682 /* Store the user, zero-length if not set */
5683 conn->user = strdup(user);
5685 /* Store the password (only if user is present), zero-length if not set */
5687 conn->passwd = strdup(passwd);
5689 conn->passwd = NULL;
5692 if(!conn->user || !conn->passwd)
5693 result = CURLE_OUT_OF_MEMORY;
5695 /* Store the options, null if not set */
5696 if(!result && options[0]) {
5697 conn->options = strdup(options);
5700 result = CURLE_OUT_OF_MEMORY;
5707 * Parses a "host:port" string to connect to.
5708 * The hostname and the port may be empty; in this case, NULL is returned for
5709 * the hostname and -1 for the port.
5711 static CURLcode parse_connect_to_host_port(struct Curl_easy *data,
5713 char **hostname_result,
5722 #if defined(CURL_DISABLE_VERBOSE_STRINGS)
5726 *hostname_result = NULL;
5732 host_dup = strdup(host);
5734 return CURLE_OUT_OF_MEMORY;
5738 /* start scanning for port number at this point */
5741 /* detect and extract RFC6874-style IPv6-addresses */
5742 if(*hostptr == '[') {
5743 char *ptr = ++hostptr; /* advance beyond the initial bracket */
5744 while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '.')))
5747 /* There might be a zone identifier */
5748 if(strncmp("%25", ptr, 3))
5749 infof(data, "Please URL encode %% as %%25, see RFC 6874.\n");
5751 /* Allow unreserved characters as defined in RFC 3986 */
5752 while(*ptr && (ISALPHA(*ptr) || ISXDIGIT(*ptr) || (*ptr == '-') ||
5753 (*ptr == '.') || (*ptr == '_') || (*ptr == '~')))
5757 /* yeps, it ended nicely with a bracket as well */
5760 infof(data, "Invalid IPv6 address format\n");
5762 /* Note that if this didn't end with a bracket, we still advanced the
5763 * hostptr first, but I can't see anything wrong with that as no host
5764 * name nor a numeric can legally start with a bracket.
5768 /* Get port number off server.com:1080 */
5769 host_portno = strchr(portptr, ':');
5772 *host_portno = '\0'; /* cut off number from host name */
5775 long portparse = strtol(host_portno, &endp, 10);
5776 if((endp && *endp) || (portparse < 0) || (portparse > 65535)) {
5777 infof(data, "No valid port number in connect to host string (%s)\n",
5783 port = (int)portparse; /* we know it will fit */
5787 /* now, clone the cleaned host name */
5789 *hostname_result = strdup(hostptr);
5790 if(!*hostname_result) {
5792 return CURLE_OUT_OF_MEMORY;
5796 *port_result = port;
5803 * Parses one "connect to" string in the form:
5804 * "HOST:PORT:CONNECT-TO-HOST:CONNECT-TO-PORT".
5806 static CURLcode parse_connect_to_string(struct Curl_easy *data,
5807 struct connectdata *conn,
5808 const char *conn_to_host,
5812 CURLcode result = CURLE_OK;
5813 const char *ptr = conn_to_host;
5814 int host_match = FALSE;
5815 int port_match = FALSE;
5817 *host_result = NULL;
5821 /* an empty hostname always matches */
5826 /* check whether the URL's hostname matches */
5827 size_t hostname_to_match_len;
5828 char *hostname_to_match = aprintf("%s%s%s",
5829 conn->bits.ipv6_ip ? "[" : "",
5831 conn->bits.ipv6_ip ? "]" : "");
5832 if(!hostname_to_match)
5833 return CURLE_OUT_OF_MEMORY;
5834 hostname_to_match_len = strlen(hostname_to_match);
5835 host_match = strncasecompare(ptr, hostname_to_match,
5836 hostname_to_match_len);
5837 free(hostname_to_match);
5838 ptr += hostname_to_match_len;
5840 host_match = host_match && *ptr == ':';
5846 /* an empty port always matches */
5851 /* check whether the URL's port matches */
5852 char *ptr_next = strchr(ptr, ':');
5855 long port_to_match = strtol(ptr, &endp, 10);
5856 if((endp == ptr_next) && (port_to_match == conn->remote_port)) {
5864 if(host_match && port_match) {
5865 /* parse the hostname and port to connect to */
5866 result = parse_connect_to_host_port(data, ptr, host_result, port_result);
5873 * Processes all strings in the "connect to" slist, and uses the "connect
5874 * to host" and "connect to port" of the first string that matches.
5876 static CURLcode parse_connect_to_slist(struct Curl_easy *data,
5877 struct connectdata *conn,
5878 struct curl_slist *conn_to_host)
5880 CURLcode result = CURLE_OK;
5884 while(conn_to_host && !host && port == -1) {
5885 result = parse_connect_to_string(data, conn, conn_to_host->data,
5891 conn->conn_to_host.rawalloc = host;
5892 conn->conn_to_host.name = host;
5893 conn->bits.conn_to_host = TRUE;
5895 infof(data, "Connecting to hostname: %s\n", host);
5898 /* no "connect to host" */
5899 conn->bits.conn_to_host = FALSE;
5900 Curl_safefree(host);
5904 conn->conn_to_port = port;
5905 conn->bits.conn_to_port = TRUE;
5906 infof(data, "Connecting to port: %d\n", port);
5909 /* no "connect to port" */
5910 conn->bits.conn_to_port = FALSE;
5914 conn_to_host = conn_to_host->next;
5920 /*************************************************************
5921 * Resolve the address of the server or proxy
5922 *************************************************************/
5923 static CURLcode resolve_server(struct Curl_easy *data,
5924 struct connectdata *conn,
5927 CURLcode result=CURLE_OK;
5928 time_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
5930 /*************************************************************
5931 * Resolve the name of the server or proxy
5932 *************************************************************/
5933 if(conn->bits.reuse)
5934 /* We're reusing the connection - no need to resolve anything, and
5935 fix_hostname() was called already in create_conn() for the re-use
5940 /* this is a fresh connect */
5942 struct Curl_dns_entry *hostaddr;
5944 #ifdef USE_UNIX_SOCKETS
5945 if(conn->unix_domain_socket) {
5946 /* Unix domain sockets are local. The host gets ignored, just use the
5947 * specified domain socket address. Do not cache "DNS entries". There is
5948 * no DNS involved and we already have the filesystem path available */
5949 const char *path = conn->unix_domain_socket;
5951 hostaddr = calloc(1, sizeof(struct Curl_dns_entry));
5953 result = CURLE_OUT_OF_MEMORY;
5955 bool longpath = FALSE;
5956 hostaddr->addr = Curl_unix2addr(path, &longpath,
5957 conn->abstract_unix_socket);
5961 /* Long paths are not supported for now */
5963 failf(data, "Unix socket path too long: '%s'", path);
5964 result = CURLE_COULDNT_RESOLVE_HOST;
5967 result = CURLE_OUT_OF_MEMORY;
5975 if(!conn->bits.proxy) {
5976 struct hostname *connhost;
5977 if(conn->bits.conn_to_host)
5978 connhost = &conn->conn_to_host;
5980 connhost = &conn->host;
5982 /* If not connecting via a proxy, extract the port from the URL, if it is
5983 * there, thus overriding any defaults that might have been set above. */
5984 if(conn->bits.conn_to_port)
5985 conn->port = conn->conn_to_port;
5987 conn->port = conn->remote_port;
5989 /* Resolve target host right on */
5990 rc = Curl_resolv_timeout(conn, connhost->name, (int)conn->port,
5991 &hostaddr, timeout_ms);
5992 if(rc == CURLRESOLV_PENDING)
5995 else if(rc == CURLRESOLV_TIMEDOUT)
5996 result = CURLE_OPERATION_TIMEDOUT;
5998 else if(!hostaddr) {
5999 failf(data, "Couldn't resolve host '%s'", connhost->dispname);
6000 result = CURLE_COULDNT_RESOLVE_HOST;
6001 /* don't return yet, we need to clean up the timeout first */
6005 /* This is a proxy that hasn't been resolved yet. */
6007 struct hostname * const host = conn->bits.socksproxy ?
6008 &conn->socks_proxy.host : &conn->http_proxy.host;
6011 rc = Curl_resolv_timeout(conn, host->name, (int)conn->port,
6012 &hostaddr, timeout_ms);
6014 if(rc == CURLRESOLV_PENDING)
6017 else if(rc == CURLRESOLV_TIMEDOUT)
6018 result = CURLE_OPERATION_TIMEDOUT;
6020 else if(!hostaddr) {
6021 failf(data, "Couldn't resolve proxy '%s'", host->dispname);
6022 result = CURLE_COULDNT_RESOLVE_PROXY;
6023 /* don't return yet, we need to clean up the timeout first */
6026 DEBUGASSERT(conn->dns_entry == NULL);
6027 conn->dns_entry = hostaddr;
6034 * Cleanup the connection just allocated before we can move along and use the
6035 * previously existing one. All relevant data is copied over and old_conn is
6036 * ready for freeing once this function returns.
6038 static void reuse_conn(struct connectdata *old_conn,
6039 struct connectdata *conn)
6041 free_fixed_hostname(&old_conn->http_proxy.host);
6042 free_fixed_hostname(&old_conn->socks_proxy.host);
6044 free(old_conn->http_proxy.host.rawalloc);
6045 free(old_conn->socks_proxy.host.rawalloc);
6047 /* free the SSL config struct from this connection struct as this was
6048 allocated in vain and is targeted for destruction */
6049 Curl_free_primary_ssl_config(&old_conn->ssl_config);
6050 Curl_free_primary_ssl_config(&old_conn->proxy_ssl_config);
6052 conn->data = old_conn->data;
6054 /* get the user+password information from the old_conn struct since it may
6055 * be new for this request even when we re-use an existing connection */
6056 conn->bits.user_passwd = old_conn->bits.user_passwd;
6057 if(conn->bits.user_passwd) {
6058 /* use the new user name and password though */
6059 Curl_safefree(conn->user);
6060 Curl_safefree(conn->passwd);
6061 conn->user = old_conn->user;
6062 conn->passwd = old_conn->passwd;
6063 old_conn->user = NULL;
6064 old_conn->passwd = NULL;
6067 conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd;
6068 if(conn->bits.proxy_user_passwd) {
6069 /* use the new proxy user name and proxy password though */
6070 Curl_safefree(conn->http_proxy.user);
6071 Curl_safefree(conn->socks_proxy.user);
6072 Curl_safefree(conn->http_proxy.passwd);
6073 Curl_safefree(conn->socks_proxy.passwd);
6074 conn->http_proxy.user = old_conn->http_proxy.user;
6075 conn->socks_proxy.user = old_conn->socks_proxy.user;
6076 conn->http_proxy.passwd = old_conn->http_proxy.passwd;
6077 conn->socks_proxy.passwd = old_conn->socks_proxy.passwd;
6078 old_conn->http_proxy.user = NULL;
6079 old_conn->socks_proxy.user = NULL;
6080 old_conn->http_proxy.passwd = NULL;
6081 old_conn->socks_proxy.passwd = NULL;
6084 /* host can change, when doing keepalive with a proxy or if the case is
6085 different this time etc */
6086 free_fixed_hostname(&conn->host);
6087 free_fixed_hostname(&conn->conn_to_host);
6088 Curl_safefree(conn->host.rawalloc);
6089 Curl_safefree(conn->conn_to_host.rawalloc);
6090 conn->host=old_conn->host;
6091 conn->bits.conn_to_host = old_conn->bits.conn_to_host;
6092 conn->conn_to_host = old_conn->conn_to_host;
6093 conn->bits.conn_to_port = old_conn->bits.conn_to_port;
6094 conn->conn_to_port = old_conn->conn_to_port;
6096 /* persist connection info in session handle */
6097 Curl_persistconninfo(conn);
6099 conn_reset_all_postponed_data(old_conn); /* free buffers */
6100 conn_reset_all_postponed_data(conn); /* reset unprocessed data */
6103 conn->bits.reuse = TRUE; /* yes, we're re-using here */
6105 Curl_safefree(old_conn->user);
6106 Curl_safefree(old_conn->passwd);
6107 Curl_safefree(old_conn->http_proxy.user);
6108 Curl_safefree(old_conn->socks_proxy.user);
6109 Curl_safefree(old_conn->http_proxy.passwd);
6110 Curl_safefree(old_conn->socks_proxy.passwd);
6111 Curl_safefree(old_conn->localdev);
6113 Curl_llist_destroy(old_conn->send_pipe, NULL);
6114 Curl_llist_destroy(old_conn->recv_pipe, NULL);
6116 old_conn->send_pipe = NULL;
6117 old_conn->recv_pipe = NULL;
6119 Curl_safefree(old_conn->master_buffer);
6121 #ifdef USE_UNIX_SOCKETS
6122 Curl_safefree(old_conn->unix_domain_socket);
6127 * create_conn() sets up a new connectdata struct, or re-uses an already
6128 * existing one, and resolves host name.
6130 * if this function returns CURLE_OK and *async is set to TRUE, the resolve
6131 * response will be coming asynchronously. If *async is FALSE, the name is
6134 * @param data The sessionhandle pointer
6135 * @param in_connect is set to the next connection data pointer
6136 * @param async is set TRUE when an async DNS resolution is pending
6137 * @see Curl_setup_conn()
6139 * *NOTE* this function assigns the conn->data pointer!
6142 static CURLcode create_conn(struct Curl_easy *data,
6143 struct connectdata **in_connect,
6146 CURLcode result = CURLE_OK;
6147 struct connectdata *conn;
6148 struct connectdata *conn_temp = NULL;
6151 char *passwd = NULL;
6152 char *options = NULL;
6155 char *socksproxy = NULL;
6156 char *no_proxy = NULL;
6157 bool prot_missing = FALSE;
6158 bool connections_available = TRUE;
6159 bool force_reuse = FALSE;
6160 bool waitpipe = FALSE;
6161 size_t max_host_connections = Curl_multi_max_host_connections(data->multi);
6162 size_t max_total_connections = Curl_multi_max_total_connections(data->multi);
6166 /*************************************************************
6168 *************************************************************/
6170 if(!data->change.url) {
6171 result = CURLE_URL_MALFORMAT;
6175 /* First, split up the current URL in parts so that we can use the
6176 parts for checking against the already present connections. In order
6177 to not have to modify everything at once, we allocate a temporary
6178 connection data struct and fill in for comparison purposes. */
6179 conn = allocate_conn(data);
6182 result = CURLE_OUT_OF_MEMORY;
6186 /* We must set the return variable as soon as possible, so that our
6187 parent can cleanup any possible allocs we may have done before
6191 /* This initing continues below, see the comment "Continue connectdata
6192 * initialization here" */
6194 /***********************************************************
6195 * We need to allocate memory to store the path in. We get the size of the
6196 * full URL to be sure, and we need to make it at least 256 bytes since
6197 * other parts of the code will rely on this fact
6198 ***********************************************************/
6199 #define LEAST_PATH_ALLOC 256
6200 urllen=strlen(data->change.url);
6201 if(urllen < LEAST_PATH_ALLOC)
6202 urllen=LEAST_PATH_ALLOC;
6205 * We malloc() the buffers below urllen+2 to make room for 2 possibilities:
6206 * 1 - an extra terminating zero
6207 * 2 - an extra slash (in case a syntax like "www.host.com?moo" is used)
6210 Curl_safefree(data->state.pathbuffer);
6211 data->state.path = NULL;
6213 data->state.pathbuffer = malloc(urllen+2);
6214 if(NULL == data->state.pathbuffer) {
6215 result = CURLE_OUT_OF_MEMORY; /* really bad error */
6218 data->state.path = data->state.pathbuffer;
6220 conn->host.rawalloc = malloc(urllen+2);
6221 if(NULL == conn->host.rawalloc) {
6222 Curl_safefree(data->state.pathbuffer);
6223 data->state.path = NULL;
6224 result = CURLE_OUT_OF_MEMORY;
6228 conn->host.name = conn->host.rawalloc;
6229 conn->host.name[0] = 0;
6232 passwd = strdup("");
6233 options = strdup("");
6234 if(!user || !passwd || !options) {
6235 result = CURLE_OUT_OF_MEMORY;
6239 result = parseurlandfillconn(data, conn, &prot_missing, &user, &passwd,
6244 /*************************************************************
6245 * No protocol part in URL was used, add it!
6246 *************************************************************/
6248 /* We're guessing prefixes here and if we're told to use a proxy or if
6249 we're gonna follow a Location: later or... then we need the protocol
6250 part added so that we have a valid URL. */
6254 reurl = aprintf("%s://%s", conn->handler->scheme, data->change.url);
6257 result = CURLE_OUT_OF_MEMORY;
6261 /* Change protocol prefix to lower-case */
6262 for(ch_lower = reurl; *ch_lower != ':'; ch_lower++)
6263 *ch_lower = (char)TOLOWER(*ch_lower);
6265 if(data->change.url_alloc) {
6266 Curl_safefree(data->change.url);
6267 data->change.url_alloc = FALSE;
6270 data->change.url = reurl;
6271 data->change.url_alloc = TRUE; /* free this later */
6274 /*************************************************************
6275 * If the protocol can't handle url query strings, then cut
6276 * off the unhandable part
6277 *************************************************************/
6278 if((conn->given->flags&PROTOPT_NOURLQUERY)) {
6279 char *path_q_sep = strchr(conn->data->state.path, '?');
6281 /* according to rfc3986, allow the query (?foo=bar)
6282 also on protocols that can't handle it.
6284 cut the string-part after '?'
6287 /* terminate the string */
6292 if(data->set.str[STRING_BEARER]) {
6293 conn->oauth_bearer = strdup(data->set.str[STRING_BEARER]);
6294 if(!conn->oauth_bearer) {
6295 result = CURLE_OUT_OF_MEMORY;
6300 #ifndef CURL_DISABLE_PROXY
6301 /*************************************************************
6302 * Extract the user and password from the authentication string
6303 *************************************************************/
6304 if(conn->bits.proxy_user_passwd) {
6305 result = parse_proxy_auth(data, conn);
6310 /*************************************************************
6311 * Detect what (if any) proxy to use
6312 *************************************************************/
6313 if(data->set.str[STRING_PROXY]) {
6314 proxy = strdup(data->set.str[STRING_PROXY]);
6315 /* if global proxy is set, this is it */
6317 failf(data, "memory shortage");
6318 result = CURLE_OUT_OF_MEMORY;
6323 if(data->set.str[STRING_PRE_PROXY]) {
6324 socksproxy = strdup(data->set.str[STRING_PRE_PROXY]);
6325 /* if global socks proxy is set, this is it */
6326 if(NULL == socksproxy) {
6327 failf(data, "memory shortage");
6328 result = CURLE_OUT_OF_MEMORY;
6333 no_proxy = curl_getenv("no_proxy");
6335 no_proxy = curl_getenv("NO_PROXY");
6337 if(check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY]) ||
6338 (!data->set.str[STRING_NOPROXY] &&
6339 check_noproxy(conn->host.name, no_proxy))) {
6340 Curl_safefree(proxy);
6341 Curl_safefree(socksproxy);
6343 else if(!proxy && !socksproxy)
6344 #ifndef CURL_DISABLE_HTTP
6345 /* if the host is not in the noproxy list, detect proxy. */
6346 proxy = detect_proxy(conn);
6347 #else /* !CURL_DISABLE_HTTP */
6349 #endif /* CURL_DISABLE_HTTP */
6351 Curl_safefree(no_proxy);
6353 #ifdef USE_UNIX_SOCKETS
6354 if(data->set.str[STRING_UNIX_SOCKET_PATH]) {
6356 free(proxy); /* Unix domain sockets cannot be proxied, so disable it */
6359 conn->unix_domain_socket = strdup(data->set.str[STRING_UNIX_SOCKET_PATH]);
6360 if(conn->unix_domain_socket == NULL) {
6361 result = CURLE_OUT_OF_MEMORY;
6364 conn->abstract_unix_socket = data->set.abstract_unix_socket;
6368 if(proxy && (!*proxy || (conn->handler->flags & PROTOPT_NONETWORK))) {
6369 free(proxy); /* Don't bother with an empty proxy string or if the
6370 protocol doesn't work with network */
6373 if(socksproxy && (!*socksproxy ||
6374 (conn->handler->flags & PROTOPT_NONETWORK))) {
6375 free(socksproxy); /* Don't bother with an empty socks proxy string or if
6376 the protocol doesn't work with network */
6380 /***********************************************************************
6381 * If this is supposed to use a proxy, we need to figure out the proxy host
6382 * name, proxy type and port number, so that we can re-use an existing
6383 * connection that may exist registered to the same proxy host.
6384 ***********************************************************************/
6385 if(proxy || socksproxy) {
6387 result = parse_proxy(data, conn, proxy, conn->http_proxy.proxytype);
6388 Curl_safefree(proxy); /* parse_proxy copies the proxy string */
6394 result = parse_proxy(data, conn, socksproxy,
6395 conn->socks_proxy.proxytype);
6396 /* parse_proxy copies the socks proxy string */
6397 Curl_safefree(socksproxy);
6402 if(conn->http_proxy.host.rawalloc) {
6403 #ifdef CURL_DISABLE_HTTP
6404 /* asking for a HTTP proxy is a bit funny when HTTP is disabled... */
6405 result = CURLE_UNSUPPORTED_PROTOCOL;
6408 /* force this connection's protocol to become HTTP if not already
6409 compatible - if it isn't tunneling through */
6410 if(!(conn->handler->protocol & PROTO_FAMILY_HTTP) &&
6411 !conn->bits.tunnel_proxy)
6412 conn->handler = &Curl_handler_http;
6414 conn->bits.httpproxy = TRUE;
6418 conn->bits.httpproxy = FALSE; /* not a HTTP proxy */
6419 conn->bits.tunnel_proxy = FALSE; /* no tunneling if not HTTP */
6422 if(conn->socks_proxy.host.rawalloc) {
6423 if(!conn->http_proxy.host.rawalloc) {
6424 /* once a socks proxy */
6425 if(!conn->socks_proxy.user) {
6426 conn->socks_proxy.user = conn->http_proxy.user;
6427 conn->http_proxy.user = NULL;
6428 Curl_safefree(conn->socks_proxy.passwd);
6429 conn->socks_proxy.passwd = conn->http_proxy.passwd;
6430 conn->http_proxy.passwd = NULL;
6433 conn->bits.socksproxy = TRUE;
6436 conn->bits.socksproxy = FALSE; /* not a socks proxy */
6439 conn->bits.socksproxy = FALSE;
6440 conn->bits.httpproxy = FALSE;
6442 conn->bits.proxy = conn->bits.httpproxy || conn->bits.socksproxy;
6444 if(!conn->bits.proxy) {
6445 /* we aren't using the proxy after all... */
6446 conn->bits.proxy = FALSE;
6447 conn->bits.httpproxy = FALSE;
6448 conn->bits.socksproxy = FALSE;
6449 conn->bits.proxy_user_passwd = FALSE;
6450 conn->bits.tunnel_proxy = FALSE;
6453 #endif /* CURL_DISABLE_PROXY */
6455 /*************************************************************
6456 * If the protocol is using SSL and HTTP proxy is used, we set
6457 * the tunnel_proxy bit.
6458 *************************************************************/
6459 if((conn->given->flags&PROTOPT_SSL) && conn->bits.httpproxy)
6460 conn->bits.tunnel_proxy = TRUE;
6462 /*************************************************************
6463 * Figure out the remote port number and fix it in the URL
6464 *************************************************************/
6465 result = parse_remote_port(data, conn);
6469 /* Check for overridden login details and set them accordingly so they
6470 they are known when protocol->setup_connection is called! */
6471 result = override_login(data, conn, &user, &passwd, &options);
6474 result = set_login(conn, user, passwd, options);
6478 /*************************************************************
6479 * Process the "connect to" linked list of hostname/port mappings.
6480 * Do this after the remote port number has been fixed in the URL.
6481 *************************************************************/
6482 result = parse_connect_to_slist(data, conn, data->set.connect_to);
6486 /*************************************************************
6487 * IDN-fix the hostnames
6488 *************************************************************/
6489 fix_hostname(conn, &conn->host);
6490 if(conn->bits.conn_to_host)
6491 fix_hostname(conn, &conn->conn_to_host);
6492 if(conn->bits.httpproxy)
6493 fix_hostname(conn, &conn->http_proxy.host);
6494 if(conn->bits.socksproxy)
6495 fix_hostname(conn, &conn->socks_proxy.host);
6497 /*************************************************************
6498 * Check whether the host and the "connect to host" are equal.
6499 * Do this after the hostnames have been IDN-fixed.
6500 *************************************************************/
6501 if(conn->bits.conn_to_host &&
6502 strcasecompare(conn->conn_to_host.name, conn->host.name)) {
6503 conn->bits.conn_to_host = FALSE;
6506 /*************************************************************
6507 * Check whether the port and the "connect to port" are equal.
6508 * Do this after the remote port number has been fixed in the URL.
6509 *************************************************************/
6510 if(conn->bits.conn_to_port && conn->conn_to_port == conn->remote_port) {
6511 conn->bits.conn_to_port = FALSE;
6514 /*************************************************************
6515 * If the "connect to" feature is used with an HTTP proxy,
6516 * we set the tunnel_proxy bit.
6517 *************************************************************/
6518 if((conn->bits.conn_to_host || conn->bits.conn_to_port) &&
6519 conn->bits.httpproxy)
6520 conn->bits.tunnel_proxy = TRUE;
6522 /*************************************************************
6523 * Setup internals depending on protocol. Needs to be done after
6524 * we figured out what/if proxy to use.
6525 *************************************************************/
6526 result = setup_connection_internals(conn);
6530 conn->recv[FIRSTSOCKET] = Curl_recv_plain;
6531 conn->send[FIRSTSOCKET] = Curl_send_plain;
6532 conn->recv[SECONDARYSOCKET] = Curl_recv_plain;
6533 conn->send[SECONDARYSOCKET] = Curl_send_plain;
6535 conn->bits.tcp_fastopen = data->set.tcp_fastopen;
6537 /***********************************************************************
6538 * file: is a special case in that it doesn't need a network connection
6539 ***********************************************************************/
6540 #ifndef CURL_DISABLE_FILE
6541 if(conn->handler->flags & PROTOPT_NONETWORK) {
6543 /* this is supposed to be the connect function so we better at least check
6544 that the file is present here! */
6545 DEBUGASSERT(conn->handler->connect_it);
6546 result = conn->handler->connect_it(conn, &done);
6548 /* Setup a "faked" transfer that'll do nothing */
6551 conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; /* we are "connected */
6553 Curl_conncache_add_conn(data->state.conn_cache, conn);
6556 * Setup whatever necessary for a resumed transfer
6558 result = setup_range(data);
6560 DEBUGASSERT(conn->handler->done);
6561 /* we ignore the return code for the protocol-specific DONE */
6562 (void)conn->handler->done(conn, result, FALSE);
6566 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */
6567 -1, NULL); /* no upload */
6570 /* since we skip do_init() */
6571 Curl_init_do(data, conn);
6577 /* Get a cloned copy of the SSL config situation stored in the
6578 connection struct. But to get this going nicely, we must first make
6579 sure that the strings in the master copy are pointing to the correct
6580 strings in the session handle strings array!
6582 Keep in mind that the pointers in the master copy are pointing to strings
6583 that will be freed as part of the Curl_easy struct, but all cloned
6584 copies will be separately allocated.
6586 data->set.ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_ORIG];
6587 data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY];
6588 data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_ORIG];
6589 data->set.proxy_ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY];
6590 data->set.ssl.primary.random_file = data->set.str[STRING_SSL_RANDOM_FILE];
6591 data->set.proxy_ssl.primary.random_file =
6592 data->set.str[STRING_SSL_RANDOM_FILE];
6593 data->set.ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
6594 data->set.proxy_ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
6595 data->set.ssl.primary.cipher_list =
6596 data->set.str[STRING_SSL_CIPHER_LIST_ORIG];
6597 data->set.proxy_ssl.primary.cipher_list =
6598 data->set.str[STRING_SSL_CIPHER_LIST_PROXY];
6600 data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_ORIG];
6601 data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY];
6602 data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_ORIG];
6603 data->set.proxy_ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY];
6604 data->set.ssl.cert = data->set.str[STRING_CERT_ORIG];
6605 data->set.proxy_ssl.cert = data->set.str[STRING_CERT_PROXY];
6606 data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE_ORIG];
6607 data->set.proxy_ssl.cert_type = data->set.str[STRING_CERT_TYPE_PROXY];
6608 data->set.ssl.key = data->set.str[STRING_KEY_ORIG];
6609 data->set.proxy_ssl.key = data->set.str[STRING_KEY_PROXY];
6610 data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE_ORIG];
6611 data->set.proxy_ssl.key_type = data->set.str[STRING_KEY_TYPE_PROXY];
6612 data->set.ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_ORIG];
6613 data->set.proxy_ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_PROXY];
6614 data->set.ssl.primary.clientcert = data->set.str[STRING_CERT_ORIG];
6615 data->set.proxy_ssl.primary.clientcert = data->set.str[STRING_CERT_PROXY];
6617 data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_ORIG];
6618 data->set.proxy_ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_PROXY];
6619 data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_ORIG];
6620 data->set.proxy_ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_PROXY];
6623 if(!Curl_clone_primary_ssl_config(&data->set.ssl.primary,
6624 &conn->ssl_config)) {
6625 result = CURLE_OUT_OF_MEMORY;
6629 if(!Curl_clone_primary_ssl_config(&data->set.proxy_ssl.primary,
6630 &conn->proxy_ssl_config)) {
6631 result = CURLE_OUT_OF_MEMORY;
6635 prune_dead_connections(data);
6637 /*************************************************************
6638 * Check the current list of connections to see if we can
6639 * re-use an already existing one or if we have to create a
6641 *************************************************************/
6643 /* reuse_fresh is TRUE if we are told to use a new connection by force, but
6644 we only acknowledge this option if this is not a re-used connection
6645 already (which happens due to follow-location or during a HTTP
6646 authentication phase). */
6647 if(data->set.reuse_fresh && !data->state.this_is_a_follow)
6650 reuse = ConnectionExists(data, conn, &conn_temp, &force_reuse, &waitpipe);
6652 /* If we found a reusable connection, we may still want to
6653 open a new connection if we are pipelining. */
6654 if(reuse && !force_reuse && IsPipeliningPossible(data, conn_temp)) {
6655 size_t pipelen = conn_temp->send_pipe->size + conn_temp->recv_pipe->size;
6657 infof(data, "Found connection %ld, with requests in the pipe (%zu)\n",
6658 conn_temp->connection_id, pipelen);
6660 if(conn_temp->bundle->num_connections < max_host_connections &&
6661 data->state.conn_cache->num_connections < max_total_connections) {
6662 /* We want a new connection anyway */
6665 infof(data, "We can reuse, but we want a new connection anyway\n");
6672 * We already have a connection for this, we got the former connection
6673 * in the conn_temp variable and thus we need to cleanup the one we
6674 * just allocated before we can move along and use the previously
6677 conn_temp->inuse = TRUE; /* mark this as being in use so that no other
6678 handle in a multi stack may nick it */
6679 reuse_conn(conn, conn_temp);
6680 free(conn); /* we don't need this anymore */
6684 infof(data, "Re-using existing connection! (#%ld) with %s %s\n",
6685 conn->connection_id,
6686 conn->bits.proxy?"proxy":"host",
6687 conn->socks_proxy.host.name ? conn->socks_proxy.host.dispname :
6688 conn->http_proxy.host.name ? conn->http_proxy.host.dispname :
6689 conn->host.dispname);
6692 /* We have decided that we want a new connection. However, we may not
6693 be able to do that if we have reached the limit of how many
6694 connections we are allowed to open. */
6695 struct connectbundle *bundle = NULL;
6697 if(conn->handler->flags & PROTOPT_ALPN_NPN) {
6698 /* The protocol wants it, so set the bits if enabled in the easy handle
6700 if(data->set.ssl_enable_alpn)
6701 conn->bits.tls_enable_alpn = TRUE;
6702 if(data->set.ssl_enable_npn)
6703 conn->bits.tls_enable_npn = TRUE;
6707 /* There is a connection that *might* become usable for pipelining
6708 "soon", and we wait for that */
6709 connections_available = FALSE;
6711 bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache);
6713 if(max_host_connections > 0 && bundle &&
6714 (bundle->num_connections >= max_host_connections)) {
6715 struct connectdata *conn_candidate;
6717 /* The bundle is full. Let's see if we can kill a connection. */
6718 conn_candidate = find_oldest_idle_connection_in_bundle(data, bundle);
6720 if(conn_candidate) {
6721 /* Set the connection's owner correctly, then kill it */
6722 conn_candidate->data = data;
6723 (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
6726 infof(data, "No more connections allowed to host: %d\n",
6727 max_host_connections);
6728 connections_available = FALSE;
6732 if(connections_available &&
6733 (max_total_connections > 0) &&
6734 (data->state.conn_cache->num_connections >= max_total_connections)) {
6735 struct connectdata *conn_candidate;
6737 /* The cache is full. Let's see if we can kill a connection. */
6738 conn_candidate = Curl_oldest_idle_connection(data);
6740 if(conn_candidate) {
6741 /* Set the connection's owner correctly, then kill it */
6742 conn_candidate->data = data;
6743 (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
6746 infof(data, "No connections available in cache\n");
6747 connections_available = FALSE;
6751 if(!connections_available) {
6752 infof(data, "No connections available.\n");
6757 result = CURLE_NO_CONNECTION_AVAILABLE;
6762 * This is a brand new connection, so let's store it in the connection
6765 Curl_conncache_add_conn(data->state.conn_cache, conn);
6768 #if defined(USE_NTLM)
6769 /* If NTLM is requested in a part of this connection, make sure we don't
6770 assume the state is fine as this is a fresh connection and NTLM is
6771 connection based. */
6772 if((data->state.authhost.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
6773 data->state.authhost.done) {
6774 infof(data, "NTLM picked AND auth done set, clear picked!\n");
6775 data->state.authhost.picked = CURLAUTH_NONE;
6776 data->state.authhost.done = FALSE;
6779 if((data->state.authproxy.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
6780 data->state.authproxy.done) {
6781 infof(data, "NTLM-proxy picked AND auth done set, clear picked!\n");
6782 data->state.authproxy.picked = CURLAUTH_NONE;
6783 data->state.authproxy.done = FALSE;
6788 /* Mark the connection as used */
6791 /* Setup and init stuff before DO starts, in preparing for the transfer. */
6792 Curl_init_do(data, conn);
6795 * Setup whatever necessary for a resumed transfer
6797 result = setup_range(data);
6801 /* Continue connectdata initialization here. */
6804 * Inherit the proper values from the urldata struct AFTER we have arranged
6805 * the persistent connection stuff
6807 conn->seek_func = data->set.seek_func;
6808 conn->seek_client = data->set.seek_client;
6810 /*************************************************************
6811 * Resolve the address of the server or proxy
6812 *************************************************************/
6813 result = resolve_server(data, conn, async);
6825 /* Curl_setup_conn() is called after the name resolve initiated in
6826 * create_conn() is all done.
6828 * Curl_setup_conn() also handles reused connections
6830 * conn->data MUST already have been setup fine (in create_conn)
6833 CURLcode Curl_setup_conn(struct connectdata *conn,
6834 bool *protocol_done)
6836 CURLcode result = CURLE_OK;
6837 struct Curl_easy *data = conn->data;
6839 Curl_pgrsTime(data, TIMER_NAMELOOKUP);
6841 if(conn->handler->flags & PROTOPT_NONETWORK) {
6842 /* nothing to setup when not using a network */
6843 *protocol_done = TRUE;
6846 *protocol_done = FALSE; /* default to not done */
6848 /* set proxy_connect_closed to false unconditionally already here since it
6849 is used strictly to provide extra information to a parent function in the
6850 case of proxy CONNECT failures and we must make sure we don't have it
6851 lingering set from a previous invoke */
6852 conn->bits.proxy_connect_closed = FALSE;
6855 * Set user-agent. Used for HTTP, but since we can attempt to tunnel
6856 * basically anything through a http proxy we can't limit this based on
6859 if(data->set.str[STRING_USERAGENT]) {
6860 Curl_safefree(conn->allocptr.uagent);
6861 conn->allocptr.uagent =
6862 aprintf("User-Agent: %s\r\n", data->set.str[STRING_USERAGENT]);
6863 if(!conn->allocptr.uagent)
6864 return CURLE_OUT_OF_MEMORY;
6867 data->req.headerbytecount = 0;
6869 #ifdef CURL_DO_LINEEND_CONV
6870 data->state.crlf_conversions = 0; /* reset CRLF conversion counter */
6871 #endif /* CURL_DO_LINEEND_CONV */
6873 /* set start time here for timeout purposes in the connect procedure, it
6874 is later set again for the progress meter purpose */
6875 conn->now = Curl_tvnow();
6877 if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
6878 conn->bits.tcpconnect[FIRSTSOCKET] = FALSE;
6879 result = Curl_connecthost(conn, conn->dns_entry);
6884 Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */
6885 Curl_pgrsTime(data, TIMER_APPCONNECT); /* we're connected already */
6886 conn->bits.tcpconnect[FIRSTSOCKET] = TRUE;
6887 *protocol_done = TRUE;
6888 Curl_updateconninfo(conn, conn->sock[FIRSTSOCKET]);
6889 Curl_verboseconnect(conn);
6892 conn->now = Curl_tvnow(); /* time this *after* the connect is done, we
6893 set this here perhaps a second time */
6897 * This check is quite a hack. We're calling _fsetmode to fix the problem
6898 * with fwrite converting newline characters (you get mangled text files,
6899 * and corrupted binary files when you download to stdout and redirect it to
6903 if((data->set.out)->_handle == NULL) {
6904 _fsetmode(stdout, "b");
6911 CURLcode Curl_connect(struct Curl_easy *data,
6912 struct connectdata **in_connect,
6914 bool *protocol_done)
6918 *asyncp = FALSE; /* assume synchronous resolves by default */
6920 /* call the stuff that needs to be called */
6921 result = create_conn(data, in_connect, asyncp);
6925 if((*in_connect)->send_pipe->size || (*in_connect)->recv_pipe->size)
6927 *protocol_done = TRUE;
6929 /* DNS resolution is done: that's either because this is a reused
6930 connection, in which case DNS was unnecessary, or because DNS
6931 really did finish already (synch resolver/fast async resolve) */
6932 result = Curl_setup_conn(*in_connect, protocol_done);
6936 if(result == CURLE_NO_CONNECTION_AVAILABLE) {
6941 if(result && *in_connect) {
6942 /* We're not allowed to return failure with memory left allocated
6943 in the connectdata struct, free those here */
6944 Curl_disconnect(*in_connect, FALSE); /* close the connection */
6945 *in_connect = NULL; /* return a NULL */
6952 * Curl_init_do() inits the readwrite session. This is inited each time (in
6953 * the DO function before the protocol-specific DO functions are invoked) for
6954 * a transfer, sometimes multiple times on the same Curl_easy. Make sure
6955 * nothing in here depends on stuff that are setup dynamically for the
6958 * Allow this function to get called with 'conn' set to NULL.
6961 CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn)
6963 struct SingleRequest *k = &data->req;
6966 conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to
6969 data->state.done = FALSE; /* *_done() is not called yet */
6970 data->state.expect100header = FALSE;
6972 if(data->set.opt_no_body)
6973 /* in HTTP lingo, no body means using the HEAD request... */
6974 data->set.httpreq = HTTPREQ_HEAD;
6975 else if(HTTPREQ_HEAD == data->set.httpreq)
6976 /* ... but if unset there really is no perfect method that is the
6977 "opposite" of HEAD but in reality most people probably think GET
6978 then. The important thing is that we can't let it remain HEAD if the
6979 opt_no_body is set FALSE since then we'll behave wrong when getting
6981 data->set.httpreq = HTTPREQ_GET;
6983 k->start = Curl_tvnow(); /* start time */
6984 k->now = k->start; /* current time is now */
6985 k->header = TRUE; /* assume header */
6989 k->buf = data->state.buffer;
6990 k->uploadbuf = data->state.uploadbuffer;
6991 k->hbufp = data->state.headerbuff;
6992 k->ignorebody=FALSE;
6994 Curl_speedinit(data);
6996 Curl_pgrsSetUploadCounter(data, 0);
6997 Curl_pgrsSetDownloadCounter(data, 0);
7003 * get_protocol_family()
7005 * This is used to return the protocol family for a given protocol.
7009 * protocol [in] - A single bit protocol identifier such as HTTP or HTTPS.
7011 * Returns the family as a single bit protocol identifier.
7014 unsigned int get_protocol_family(unsigned int protocol)
7016 unsigned int family;
7019 case CURLPROTO_HTTP:
7020 case CURLPROTO_HTTPS:
7021 family = CURLPROTO_HTTP;
7025 case CURLPROTO_FTPS:
7026 family = CURLPROTO_FTP;
7030 family = CURLPROTO_SCP;
7033 case CURLPROTO_SFTP:
7034 family = CURLPROTO_SFTP;
7037 case CURLPROTO_TELNET:
7038 family = CURLPROTO_TELNET;
7041 case CURLPROTO_LDAP:
7042 case CURLPROTO_LDAPS:
7043 family = CURLPROTO_LDAP;
7046 case CURLPROTO_DICT:
7047 family = CURLPROTO_DICT;
7050 case CURLPROTO_FILE:
7051 family = CURLPROTO_FILE;
7054 case CURLPROTO_TFTP:
7055 family = CURLPROTO_TFTP;
7058 case CURLPROTO_IMAP:
7059 case CURLPROTO_IMAPS:
7060 family = CURLPROTO_IMAP;
7063 case CURLPROTO_POP3:
7064 case CURLPROTO_POP3S:
7065 family = CURLPROTO_POP3;
7068 case CURLPROTO_SMTP:
7069 case CURLPROTO_SMTPS:
7070 family = CURLPROTO_SMTP;
7073 case CURLPROTO_RTSP:
7074 family = CURLPROTO_RTSP;
7077 case CURLPROTO_RTMP:
7078 case CURLPROTO_RTMPS:
7079 family = CURLPROTO_RTMP;
7082 case CURLPROTO_RTMPT:
7083 case CURLPROTO_RTMPTS:
7084 family = CURLPROTO_RTMPT;
7087 case CURLPROTO_RTMPE:
7088 family = CURLPROTO_RTMPE;
7091 case CURLPROTO_RTMPTE:
7092 family = CURLPROTO_RTMPTE;
7095 case CURLPROTO_GOPHER:
7096 family = CURLPROTO_GOPHER;
7100 case CURLPROTO_SMBS:
7101 family = CURLPROTO_SMB;