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_GLIB2_HOSTNAME)
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 /* Local static prototypes */
130 static struct connectdata *
131 find_oldest_idle_connection_in_bundle(struct Curl_easy *data,
132 struct connectbundle *bundle);
133 static void conn_free(struct connectdata *conn);
134 static void free_fixed_hostname(struct hostname *host);
135 static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke);
136 static CURLcode parse_url_login(struct Curl_easy *data,
137 struct connectdata *conn,
138 char **userptr, char **passwdptr,
140 static CURLcode parse_login_details(const char *login, const size_t len,
141 char **userptr, char **passwdptr,
143 static unsigned int get_protocol_family(unsigned int protocol);
149 static const struct Curl_handler * const protocols[] = {
151 #ifndef CURL_DISABLE_HTTP
155 #if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)
159 #ifndef CURL_DISABLE_FTP
163 #if defined(USE_SSL) && !defined(CURL_DISABLE_FTP)
167 #ifndef CURL_DISABLE_TELNET
168 &Curl_handler_telnet,
171 #ifndef CURL_DISABLE_DICT
175 #ifndef CURL_DISABLE_LDAP
177 #if !defined(CURL_DISABLE_LDAPS) && \
178 ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \
179 (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)))
184 #ifndef CURL_DISABLE_FILE
188 #ifndef CURL_DISABLE_TFTP
197 #ifndef CURL_DISABLE_IMAP
204 #ifndef CURL_DISABLE_POP3
211 #if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
212 (CURL_SIZEOF_CURL_OFF_T > 4) && \
213 (!defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO))
220 #ifndef CURL_DISABLE_SMTP
227 #ifndef CURL_DISABLE_RTSP
231 #ifndef CURL_DISABLE_GOPHER
232 &Curl_handler_gopher,
239 &Curl_handler_rtmpte,
241 &Curl_handler_rtmpts,
244 (struct Curl_handler *) NULL
248 * Dummy handler for undefined protocol schemes.
251 static const struct Curl_handler Curl_handler_dummy = {
252 "<no protocol>", /* scheme */
253 ZERO_NULL, /* setup_connection */
254 ZERO_NULL, /* do_it */
255 ZERO_NULL, /* done */
256 ZERO_NULL, /* do_more */
257 ZERO_NULL, /* connect_it */
258 ZERO_NULL, /* connecting */
259 ZERO_NULL, /* doing */
260 ZERO_NULL, /* proto_getsock */
261 ZERO_NULL, /* doing_getsock */
262 ZERO_NULL, /* domore_getsock */
263 ZERO_NULL, /* perform_getsock */
264 ZERO_NULL, /* disconnect */
265 ZERO_NULL, /* readwrite */
268 PROTOPT_NONE /* flags */
271 void Curl_freeset(struct Curl_easy *data)
273 /* Free all dynamic strings stored in the data->set substructure. */
275 for(i=(enum dupstring)0; i < STRING_LAST; i++) {
276 Curl_safefree(data->set.str[i]);
279 if(data->change.referer_alloc) {
280 Curl_safefree(data->change.referer);
281 data->change.referer_alloc = FALSE;
283 data->change.referer = NULL;
284 if(data->change.url_alloc) {
285 Curl_safefree(data->change.url);
286 data->change.url_alloc = FALSE;
288 data->change.url = NULL;
291 static CURLcode setstropt(char **charp, const char *s)
293 /* Release the previous storage at `charp' and replace by a dynamic storage
294 copy of `s'. Return CURLE_OK or CURLE_OUT_OF_MEMORY. */
296 Curl_safefree(*charp);
299 char *str = strdup(s);
302 return CURLE_OUT_OF_MEMORY;
310 static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp)
312 CURLcode result = CURLE_OK;
316 /* Parse the login details if specified. It not then we treat NULL as a hint
317 to clear the existing data */
319 result = parse_login_details(option, strlen(option),
320 (userp ? &user : NULL),
321 (passwdp ? &passwd : NULL),
326 /* Store the username part of option if required */
328 if(!user && option && option[0] == ':') {
329 /* Allocate an empty string instead of returning NULL as user name */
332 result = CURLE_OUT_OF_MEMORY;
335 Curl_safefree(*userp);
339 /* Store the password part of option if required */
341 Curl_safefree(*passwdp);
349 CURLcode Curl_dupset(struct Curl_easy *dst, struct Curl_easy *src)
351 CURLcode result = CURLE_OK;
354 /* Copy src->set into dst->set first, then deal with the strings
358 /* clear all string pointers first */
359 memset(dst->set.str, 0, STRING_LAST * sizeof(char *));
361 /* duplicate all strings */
362 for(i=(enum dupstring)0; i< STRING_LASTZEROTERMINATED; i++) {
363 result = setstropt(&dst->set.str[i], src->set.str[i]);
368 /* duplicate memory areas pointed to */
369 i = STRING_COPYPOSTFIELDS;
370 if(src->set.postfieldsize && src->set.str[i]) {
371 /* postfieldsize is curl_off_t, Curl_memdup() takes a size_t ... */
372 dst->set.str[i] = Curl_memdup(src->set.str[i],
373 curlx_sotouz(src->set.postfieldsize));
375 return CURLE_OUT_OF_MEMORY;
376 /* point to the new copy */
377 dst->set.postfields = dst->set.str[i];
384 * This is the internal function curl_easy_cleanup() calls. This should
385 * cleanup and free all resources associated with this sessionhandle.
387 * NOTE: if we ever add something that attempts to write to a socket or
388 * similar here, we must ignore SIGPIPE first. It is currently only done
389 * when curl_easy_perform() is invoked.
392 CURLcode Curl_close(struct Curl_easy *data)
394 struct Curl_multi *m;
399 Curl_expire_clear(data); /* shut off timers */
404 /* This handle is still part of a multi handle, take care of this first
405 and detach this handle from there. */
406 curl_multi_remove_handle(data->multi, data);
409 /* when curl_easy_perform() is used, it creates its own multi handle to
410 use and this is the one */
411 curl_multi_cleanup(data->multi_easy);
413 /* Destroy the timeout list that is held in the easy handle. It is
414 /normally/ done by curl_multi_remove_handle() but this is "just in
416 if(data->state.timeoutlist) {
417 Curl_llist_destroy(data->state.timeoutlist, NULL);
418 data->state.timeoutlist = NULL;
421 data->magic = 0; /* force a clear AFTER the possibly enforced removal from
422 the multi handle, since that function uses the magic
425 if(data->state.rangestringalloc)
426 free(data->state.range);
428 /* Free the pathbuffer */
429 Curl_safefree(data->state.pathbuffer);
430 data->state.path = NULL;
432 /* freed here just in case DONE wasn't called */
433 Curl_free_request_state(data);
435 /* Close down all open SSL info and sessions */
436 Curl_ssl_close_all(data);
437 Curl_safefree(data->state.first_host);
438 Curl_safefree(data->state.scratch);
439 Curl_ssl_free_certinfo(data);
441 /* Cleanup possible redirect junk */
442 free(data->req.newurl);
443 data->req.newurl = NULL;
445 if(data->change.referer_alloc) {
446 Curl_safefree(data->change.referer);
447 data->change.referer_alloc = FALSE;
449 data->change.referer = NULL;
451 if(data->change.url_alloc) {
452 Curl_safefree(data->change.url);
453 data->change.url_alloc = FALSE;
455 data->change.url = NULL;
457 Curl_safefree(data->state.buffer);
458 Curl_safefree(data->state.headerbuff);
460 Curl_flush_cookies(data, 1);
462 Curl_digest_cleanup(data);
464 Curl_safefree(data->info.contenttype);
465 Curl_safefree(data->info.wouldredirect);
467 /* this destroys the channel and we cannot use it anymore after this */
468 Curl_resolver_cleanup(data->state.resolver);
470 Curl_http2_cleanup_dependencies(data);
471 Curl_convert_close(data);
473 /* No longer a dirty share, if it exists */
475 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
476 data->share->dirty--;
477 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
480 if(data->set.wildcardmatch) {
481 /* destruct wildcard structures if it is needed */
482 struct WildcardData *wc = &data->wildcard;
483 Curl_wildcard_dtor(wc);
492 * Initialize the UserDefined fields within a Curl_easy.
493 * This may be safely called on a new or existing Curl_easy.
495 CURLcode Curl_init_userdefined(struct UserDefined *set)
497 CURLcode result = CURLE_OK;
499 set->out = stdout; /* default output to stdout */
500 set->in_set = stdin; /* default input from stdin */
501 set->err = stderr; /* default stderr to stderr */
503 /* use fwrite as default function to store output */
504 set->fwrite_func = (curl_write_callback)fwrite;
506 /* use fread as default function to read input */
507 set->fread_func_set = (curl_read_callback)fread;
508 set->is_fread_set = 0;
509 set->is_fwrite_set = 0;
511 set->seek_func = ZERO_NULL;
512 set->seek_client = ZERO_NULL;
514 /* conversion callbacks for non-ASCII hosts */
515 set->convfromnetwork = ZERO_NULL;
516 set->convtonetwork = ZERO_NULL;
517 set->convfromutf8 = ZERO_NULL;
519 set->filesize = -1; /* we don't know the size */
520 set->postfieldsize = -1; /* unknown size */
521 set->maxredirs = -1; /* allow any amount by default */
523 set->httpreq = HTTPREQ_GET; /* Default HTTP request */
524 set->rtspreq = RTSPREQ_OPTIONS; /* Default RTSP request */
525 set->ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */
526 set->ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */
527 set->ftp_use_pret = FALSE; /* mainly useful for drftpd servers */
528 set->ftp_filemethod = FTPFILE_MULTICWD;
530 set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
532 /* Set the default size of the SSL session ID cache */
533 set->general_ssl.max_ssl_sessions = 5;
536 set->proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
537 set->httpauth = CURLAUTH_BASIC; /* defaults to basic */
538 set->proxyauth = CURLAUTH_BASIC; /* defaults to basic */
540 /* make libcurl quiet by default: */
541 set->hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */
544 * libcurl 7.10 introduced SSL verification *by default*! This needs to be
545 * switched off unless wanted.
547 set->ssl.primary.verifypeer = TRUE;
548 set->ssl.primary.verifyhost = TRUE;
550 set->ssl.authtype = CURL_TLSAUTH_NONE;
552 set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
554 set->ssl.primary.sessionid = TRUE; /* session ID caching enabled by
556 set->proxy_ssl = set->ssl;
558 set->new_file_perms = 0644; /* Default permissions */
559 set->new_directory_perms = 0755; /* Default permissions */
561 /* for the *protocols fields we don't use the CURLPROTO_ALL convenience
562 define since we internally only use the lower 16 bits for the passed
563 in bitmask to not conflict with the private bits */
564 set->allowed_protocols = CURLPROTO_ALL;
565 set->redir_protocols = CURLPROTO_ALL & /* All except FILE, SCP and SMB */
566 ~(CURLPROTO_FILE | CURLPROTO_SCP | CURLPROTO_SMB |
569 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
571 * disallow unprotected protection negotiation NEC reference implementation
572 * seem not to follow rfc1961 section 4.3/4.4
574 set->socks5_gssapi_nec = FALSE;
577 /* This is our preferred CA cert bundle/path since install time */
578 #if defined(CURL_CA_BUNDLE)
579 result = setstropt(&set->str[STRING_SSL_CAFILE_ORIG], CURL_CA_BUNDLE);
583 result = setstropt(&set->str[STRING_SSL_CAFILE_PROXY], CURL_CA_BUNDLE);
587 #if defined(CURL_CA_PATH)
588 result = setstropt(&set->str[STRING_SSL_CAPATH_ORIG], CURL_CA_PATH);
592 result = setstropt(&set->str[STRING_SSL_CAPATH_PROXY], CURL_CA_PATH);
597 set->wildcardmatch = FALSE;
598 set->chunk_bgn = ZERO_NULL;
599 set->chunk_end = ZERO_NULL;
601 /* tcp keepalives are disabled by default, but provide reasonable values for
602 * the interval and idle times.
604 set->tcp_keepalive = FALSE;
605 set->tcp_keepintvl = 60;
606 set->tcp_keepidle = 60;
607 set->tcp_fastopen = FALSE;
608 set->tcp_nodelay = TRUE;
610 set->ssl_enable_npn = TRUE;
611 set->ssl_enable_alpn = TRUE;
613 set->expect_100_timeout = 1000L; /* Wait for a second by default. */
614 set->sep_headers = TRUE; /* separated header lists by default */
616 Curl_http2_init_userset(set);
623 * @param curl is a pointer to a sessionhandle pointer that gets set by this
628 CURLcode Curl_open(struct Curl_easy **curl)
631 struct Curl_easy *data;
633 /* Very simple start-up: alloc the struct, init it with zeroes and return */
634 data = calloc(1, sizeof(struct Curl_easy));
636 /* this is a very serious error */
637 DEBUGF(fprintf(stderr, "Error: calloc of Curl_easy failed\n"));
638 return CURLE_OUT_OF_MEMORY;
641 data->magic = CURLEASY_MAGIC_NUMBER;
643 result = Curl_resolver_init(&data->state.resolver);
645 DEBUGF(fprintf(stderr, "Error: resolver_init failed\n"));
650 /* We do some initial setup here, all those fields that can't be just 0 */
652 data->state.buffer = malloc(BUFSIZE + 1);
653 if(!data->state.buffer) {
654 DEBUGF(fprintf(stderr, "Error: malloc of buffer failed\n"));
655 result = CURLE_OUT_OF_MEMORY;
658 data->state.headerbuff = malloc(HEADERSIZE);
659 if(!data->state.headerbuff) {
660 DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n"));
661 result = CURLE_OUT_OF_MEMORY;
664 result = Curl_init_userdefined(&data->set);
666 data->state.headersize=HEADERSIZE;
668 Curl_convert_init(data);
672 /* most recent connection is not yet defined */
673 data->state.lastconnect = NULL;
675 data->progress.flags |= PGRS_HIDE;
676 data->state.current_speed = -1; /* init to negative == impossible */
678 data->wildcard.state = CURLWC_INIT;
679 data->wildcard.filelist = NULL;
680 data->set.fnmatch = ZERO_NULL;
681 data->set.maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */
683 Curl_http2_init_state(&data->state);
687 Curl_resolver_cleanup(data->state.resolver);
688 free(data->state.buffer);
689 free(data->state.headerbuff);
700 CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
704 CURLcode result = CURLE_OK;
706 #ifndef CURL_DISABLE_HTTP
711 case CURLOPT_DNS_CACHE_TIMEOUT:
712 data->set.dns_cache_timeout = va_arg(param, long);
714 case CURLOPT_DNS_USE_GLOBAL_CACHE:
715 /* remember we want this enabled */
716 arg = va_arg(param, long);
717 data->set.global_dns_cache = (0 != arg) ? TRUE : FALSE;
719 case CURLOPT_SSL_CIPHER_LIST:
720 /* set a list of cipher we want to use in the SSL connection */
721 result = setstropt(&data->set.str[STRING_SSL_CIPHER_LIST_ORIG],
722 va_arg(param, char *));
724 case CURLOPT_PROXY_SSL_CIPHER_LIST:
725 /* set a list of cipher we want to use in the SSL connection for proxy */
726 result = setstropt(&data->set.str[STRING_SSL_CIPHER_LIST_PROXY],
727 va_arg(param, char *));
730 case CURLOPT_RANDOM_FILE:
732 * This is the path name to a file that contains random data to seed
733 * the random SSL stuff with. The file is only used for reading.
735 result = setstropt(&data->set.str[STRING_SSL_RANDOM_FILE],
736 va_arg(param, char *));
738 case CURLOPT_EGDSOCKET:
740 * The Entropy Gathering Daemon socket pathname
742 result = setstropt(&data->set.str[STRING_SSL_EGDSOCKET],
743 va_arg(param, char *));
745 case CURLOPT_MAXCONNECTS:
747 * Set the absolute number of maximum simultaneous alive connection that
748 * libcurl is allowed to have.
750 data->set.maxconnects = va_arg(param, long);
752 case CURLOPT_FORBID_REUSE:
754 * When this transfer is done, it must not be left to be reused by a
755 * subsequent transfer but shall be closed immediately.
757 data->set.reuse_forbid = (0 != va_arg(param, long)) ? TRUE : FALSE;
759 case CURLOPT_FRESH_CONNECT:
761 * This transfer shall not use a previously cached connection but
762 * should be made with a fresh new connect!
764 data->set.reuse_fresh = (0 != va_arg(param, long)) ? TRUE : FALSE;
766 case CURLOPT_VERBOSE:
768 * Verbose means infof() calls that give a lot of information about
769 * the connection and transfer procedures as well as internal choices.
771 data->set.verbose = (0 != va_arg(param, long)) ? TRUE : FALSE;
775 * Set to include the header in the general data output stream.
777 data->set.include_header = (0 != va_arg(param, long)) ? TRUE : FALSE;
779 case CURLOPT_NOPROGRESS:
781 * Shut off the internal supported progress meter
783 data->set.hide_progress = (0 != va_arg(param, long)) ? TRUE : FALSE;
784 if(data->set.hide_progress)
785 data->progress.flags |= PGRS_HIDE;
787 data->progress.flags &= ~PGRS_HIDE;
791 * Do not include the body part in the output data stream.
793 data->set.opt_no_body = (0 != va_arg(param, long)) ? TRUE : FALSE;
795 case CURLOPT_FAILONERROR:
797 * Don't output the >=400 error code HTML-page, but instead only
800 data->set.http_fail_on_error = (0 != va_arg(param, long)) ? TRUE : FALSE;
802 case CURLOPT_KEEP_SENDING_ON_ERROR:
803 data->set.http_keep_sending_on_error = (0 != va_arg(param, long)) ?
809 * We want to sent data to the remote host. If this is HTTP, that equals
810 * using the PUT request.
812 data->set.upload = (0 != va_arg(param, long)) ? TRUE : FALSE;
813 if(data->set.upload) {
814 /* If this is HTTP, PUT is what's needed to "upload" */
815 data->set.httpreq = HTTPREQ_PUT;
816 data->set.opt_no_body = FALSE; /* this is implied */
819 /* In HTTP, the opposite of upload is GET (unless NOBODY is true as
820 then this can be changed to HEAD later on) */
821 data->set.httpreq = HTTPREQ_GET;
823 case CURLOPT_FILETIME:
825 * Try to get the file time of the remote document. The time will
826 * later (possibly) become available using curl_easy_getinfo().
828 data->set.get_filetime = (0 != va_arg(param, long)) ? TRUE : FALSE;
830 case CURLOPT_FTP_CREATE_MISSING_DIRS:
832 * An FTP option that modifies an upload to create missing directories on
835 switch(va_arg(param, long)) {
837 data->set.ftp_create_missing_dirs = 0;
840 data->set.ftp_create_missing_dirs = 1;
843 data->set.ftp_create_missing_dirs = 2;
846 /* reserve other values for future use */
847 result = CURLE_UNKNOWN_OPTION;
851 case CURLOPT_SERVER_RESPONSE_TIMEOUT:
853 * Option that specifies how quickly an server response must be obtained
854 * before it is considered failure. For pingpong protocols.
856 data->set.server_response_timeout = va_arg(param, long) * 1000;
858 case CURLOPT_TFTP_NO_OPTIONS:
860 * Option that prevents libcurl from sending TFTP option requests to the
863 data->set.tftp_no_options = va_arg(param, long) != 0;
865 case CURLOPT_TFTP_BLKSIZE:
867 * TFTP option that specifies the block size to use for data transmission.
869 data->set.tftp_blksize = va_arg(param, long);
871 case CURLOPT_DIRLISTONLY:
873 * An option that changes the command to one that asks for a list
874 * only, no file info details.
876 data->set.ftp_list_only = (0 != va_arg(param, long)) ? TRUE : FALSE;
880 * We want to upload and append to an existing file.
882 data->set.ftp_append = (0 != va_arg(param, long)) ? TRUE : FALSE;
884 case CURLOPT_FTP_FILEMETHOD:
886 * How do access files over FTP.
888 data->set.ftp_filemethod = (curl_ftpfile)va_arg(param, long);
892 * Parse the $HOME/.netrc file
894 data->set.use_netrc = (enum CURL_NETRC_OPTION)va_arg(param, long);
896 case CURLOPT_NETRC_FILE:
898 * Use this file instead of the $HOME/.netrc file
900 result = setstropt(&data->set.str[STRING_NETRC_FILE],
901 va_arg(param, char *));
903 case CURLOPT_TRANSFERTEXT:
905 * This option was previously named 'FTPASCII'. Renamed to work with
906 * more protocols than merely FTP.
908 * Transfer using ASCII (instead of BINARY).
910 data->set.prefer_ascii = (0 != va_arg(param, long)) ? TRUE : FALSE;
912 case CURLOPT_TIMECONDITION:
914 * Set HTTP time condition. This must be one of the defines in the
915 * curl/curl.h header file.
917 data->set.timecondition = (curl_TimeCond)va_arg(param, long);
919 case CURLOPT_TIMEVALUE:
921 * This is the value to compare with the remote document with the
922 * method set with CURLOPT_TIMECONDITION
924 data->set.timevalue = (time_t)va_arg(param, long);
926 case CURLOPT_SSLVERSION:
928 * Set explicit SSL version to try to connect with, as some SSL
929 * implementations are lame.
932 data->set.ssl.primary.version = va_arg(param, long);
934 result = CURLE_UNKNOWN_OPTION;
937 case CURLOPT_PROXY_SSLVERSION:
939 * Set explicit SSL version to try to connect with for proxy, as some SSL
940 * implementations are lame.
943 data->set.proxy_ssl.primary.version = va_arg(param, long);
945 result = CURLE_UNKNOWN_OPTION;
949 #ifndef CURL_DISABLE_HTTP
950 case CURLOPT_AUTOREFERER:
952 * Switch on automatic referer that gets set if curl follows locations.
954 data->set.http_auto_referer = (0 != va_arg(param, long)) ? TRUE : FALSE;
957 case CURLOPT_ACCEPT_ENCODING:
959 * String to use at the value of Accept-Encoding header.
961 * If the encoding is set to "" we use an Accept-Encoding header that
962 * encompasses all the encodings we support.
963 * If the encoding is set to NULL we don't send an Accept-Encoding header
964 * and ignore an received Content-Encoding header.
967 argptr = va_arg(param, char *);
968 result = setstropt(&data->set.str[STRING_ENCODING],
969 (argptr && !*argptr)?
970 ALL_CONTENT_ENCODINGS: argptr);
973 case CURLOPT_TRANSFER_ENCODING:
974 data->set.http_transfer_encoding = (0 != va_arg(param, long)) ?
978 case CURLOPT_FOLLOWLOCATION:
980 * Follow Location: header hints on a HTTP-server.
982 data->set.http_follow_location = (0 != va_arg(param, long)) ? TRUE : FALSE;
985 case CURLOPT_UNRESTRICTED_AUTH:
987 * Send authentication (user+password) when following locations, even when
990 data->set.http_disable_hostname_check_before_authentication =
991 (0 != va_arg(param, long)) ? TRUE : FALSE;
994 case CURLOPT_MAXREDIRS:
996 * The maximum amount of hops you allow curl to follow Location:
997 * headers. This should mostly be used to detect never-ending loops.
999 data->set.maxredirs = va_arg(param, long);
1002 case CURLOPT_POSTREDIR:
1005 * Set the behaviour of POST when redirecting
1006 * CURL_REDIR_GET_ALL - POST is changed to GET after 301 and 302
1007 * CURL_REDIR_POST_301 - POST is kept as POST after 301
1008 * CURL_REDIR_POST_302 - POST is kept as POST after 302
1009 * CURL_REDIR_POST_303 - POST is kept as POST after 303
1010 * CURL_REDIR_POST_ALL - POST is kept as POST after 301, 302 and 303
1011 * other - POST is kept as POST after 301 and 302
1013 int postRedir = curlx_sltosi(va_arg(param, long));
1014 data->set.keep_post = postRedir & CURL_REDIR_POST_ALL;
1019 /* Does this option serve a purpose anymore? Yes it does, when
1020 CURLOPT_POSTFIELDS isn't used and the POST data is read off the
1022 if(va_arg(param, long)) {
1023 data->set.httpreq = HTTPREQ_POST;
1024 data->set.opt_no_body = FALSE; /* this is implied */
1027 data->set.httpreq = HTTPREQ_GET;
1030 case CURLOPT_COPYPOSTFIELDS:
1032 * A string with POST data. Makes curl HTTP POST. Even if it is NULL.
1033 * If needed, CURLOPT_POSTFIELDSIZE must have been set prior to
1034 * CURLOPT_COPYPOSTFIELDS and not altered later.
1036 argptr = va_arg(param, char *);
1038 if(!argptr || data->set.postfieldsize == -1)
1039 result = setstropt(&data->set.str[STRING_COPYPOSTFIELDS], argptr);
1042 * Check that requested length does not overflow the size_t type.
1045 if((data->set.postfieldsize < 0) ||
1046 ((sizeof(curl_off_t) != sizeof(size_t)) &&
1047 (data->set.postfieldsize > (curl_off_t)((size_t)-1))))
1048 result = CURLE_OUT_OF_MEMORY;
1052 (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1054 /* Allocate even when size == 0. This satisfies the need of possible
1055 later address compare to detect the COPYPOSTFIELDS mode, and
1056 to mark that postfields is used rather than read function or
1059 p = malloc((size_t)(data->set.postfieldsize?
1060 data->set.postfieldsize:1));
1063 result = CURLE_OUT_OF_MEMORY;
1065 if(data->set.postfieldsize)
1066 memcpy(p, argptr, (size_t)data->set.postfieldsize);
1068 data->set.str[STRING_COPYPOSTFIELDS] = p;
1073 data->set.postfields = data->set.str[STRING_COPYPOSTFIELDS];
1074 data->set.httpreq = HTTPREQ_POST;
1077 case CURLOPT_POSTFIELDS:
1079 * Like above, but use static data instead of copying it.
1081 data->set.postfields = va_arg(param, void *);
1082 /* Release old copied data. */
1083 (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1084 data->set.httpreq = HTTPREQ_POST;
1087 case CURLOPT_POSTFIELDSIZE:
1089 * The size of the POSTFIELD data to prevent libcurl to do strlen() to
1090 * figure it out. Enables binary posts.
1092 bigsize = va_arg(param, long);
1094 if(data->set.postfieldsize < bigsize &&
1095 data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
1096 /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */
1097 (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1098 data->set.postfields = NULL;
1101 data->set.postfieldsize = bigsize;
1104 case CURLOPT_POSTFIELDSIZE_LARGE:
1106 * The size of the POSTFIELD data to prevent libcurl to do strlen() to
1107 * figure it out. Enables binary posts.
1109 bigsize = va_arg(param, curl_off_t);
1111 if(data->set.postfieldsize < bigsize &&
1112 data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
1113 /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */
1114 (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1115 data->set.postfields = NULL;
1118 data->set.postfieldsize = bigsize;
1121 case CURLOPT_HTTPPOST:
1123 * Set to make us do HTTP POST
1125 data->set.httppost = va_arg(param, struct curl_httppost *);
1126 data->set.httpreq = HTTPREQ_POST_FORM;
1127 data->set.opt_no_body = FALSE; /* this is implied */
1130 case CURLOPT_REFERER:
1132 * String to set in the HTTP Referer: field.
1134 if(data->change.referer_alloc) {
1135 Curl_safefree(data->change.referer);
1136 data->change.referer_alloc = FALSE;
1138 result = setstropt(&data->set.str[STRING_SET_REFERER],
1139 va_arg(param, char *));
1140 data->change.referer = data->set.str[STRING_SET_REFERER];
1143 case CURLOPT_USERAGENT:
1145 * String to use in the HTTP User-Agent field
1147 result = setstropt(&data->set.str[STRING_USERAGENT],
1148 va_arg(param, char *));
1151 case CURLOPT_HTTPHEADER:
1153 * Set a list with HTTP headers to use (or replace internals with)
1155 data->set.headers = va_arg(param, struct curl_slist *);
1158 case CURLOPT_PROXYHEADER:
1160 * Set a list with proxy headers to use (or replace internals with)
1162 * Since CURLOPT_HTTPHEADER was the only way to set HTTP headers for a
1163 * long time we remain doing it this way until CURLOPT_PROXYHEADER is
1164 * used. As soon as this option has been used, if set to anything but
1165 * NULL, custom headers for proxies are only picked from this list.
1167 * Set this option to NULL to restore the previous behavior.
1169 data->set.proxyheaders = va_arg(param, struct curl_slist *);
1172 case CURLOPT_HEADEROPT:
1174 * Set header option.
1176 arg = va_arg(param, long);
1177 data->set.sep_headers = (arg & CURLHEADER_SEPARATE)? TRUE: FALSE;
1180 case CURLOPT_HTTP200ALIASES:
1182 * Set a list of aliases for HTTP 200 in response header
1184 data->set.http200aliases = va_arg(param, struct curl_slist *);
1187 #if !defined(CURL_DISABLE_COOKIES)
1188 case CURLOPT_COOKIE:
1190 * Cookie string to send to the remote server in the request.
1192 result = setstropt(&data->set.str[STRING_COOKIE],
1193 va_arg(param, char *));
1196 case CURLOPT_COOKIEFILE:
1198 * Set cookie file to read and parse. Can be used multiple times.
1200 argptr = (char *)va_arg(param, void *);
1202 struct curl_slist *cl;
1203 /* append the cookie file name to the list of file names, and deal with
1205 cl = curl_slist_append(data->change.cookielist, argptr);
1207 curl_slist_free_all(data->change.cookielist);
1208 data->change.cookielist = NULL;
1209 return CURLE_OUT_OF_MEMORY;
1211 data->change.cookielist = cl; /* store the list for later use */
1215 case CURLOPT_COOKIEJAR:
1217 * Set cookie file name to dump all cookies to when we're done.
1220 struct CookieInfo *newcookies;
1221 result = setstropt(&data->set.str[STRING_COOKIEJAR],
1222 va_arg(param, char *));
1225 * Activate the cookie parser. This may or may not already
1228 newcookies = Curl_cookie_init(data, NULL, data->cookies,
1229 data->set.cookiesession);
1231 result = CURLE_OUT_OF_MEMORY;
1232 data->cookies = newcookies;
1236 case CURLOPT_COOKIESESSION:
1238 * Set this option to TRUE to start a new "cookie session". It will
1239 * prevent the forthcoming read-cookies-from-file actions to accept
1240 * cookies that are marked as being session cookies, as they belong to a
1243 * In the original Netscape cookie spec, "session cookies" are cookies
1244 * with no expire date set. RFC2109 describes the same action if no
1245 * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds
1246 * a 'Discard' action that can enforce the discard even for cookies that
1249 * We run mostly with the original cookie spec, as hardly anyone implements
1252 data->set.cookiesession = (0 != va_arg(param, long)) ? TRUE : FALSE;
1255 case CURLOPT_COOKIELIST:
1256 argptr = va_arg(param, char *);
1261 if(strcasecompare(argptr, "ALL")) {
1262 /* clear all cookies */
1263 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
1264 Curl_cookie_clearall(data->cookies);
1265 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
1267 else if(strcasecompare(argptr, "SESS")) {
1268 /* clear session cookies */
1269 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
1270 Curl_cookie_clearsess(data->cookies);
1271 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
1273 else if(strcasecompare(argptr, "FLUSH")) {
1274 /* flush cookies to file, takes care of the locking */
1275 Curl_flush_cookies(data, 0);
1277 else if(strcasecompare(argptr, "RELOAD")) {
1278 /* reload cookies from file */
1279 Curl_cookie_loadfiles(data);
1284 /* if cookie engine was not running, activate it */
1285 data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE);
1287 argptr = strdup(argptr);
1288 if(!argptr || !data->cookies) {
1289 result = CURLE_OUT_OF_MEMORY;
1293 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
1295 if(checkprefix("Set-Cookie:", argptr))
1296 /* HTTP Header format line */
1297 Curl_cookie_add(data, data->cookies, TRUE, argptr + 11, NULL, NULL);
1300 /* Netscape format line */
1301 Curl_cookie_add(data, data->cookies, FALSE, argptr, NULL, NULL);
1303 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
1309 #endif /* CURL_DISABLE_COOKIES */
1311 case CURLOPT_HTTPGET:
1313 * Set to force us do HTTP GET
1315 if(va_arg(param, long)) {
1316 data->set.httpreq = HTTPREQ_GET;
1317 data->set.upload = FALSE; /* switch off upload */
1318 data->set.opt_no_body = FALSE; /* this is implied */
1322 case CURLOPT_HTTP_VERSION:
1324 * This sets a requested HTTP version to be used. The value is one of
1325 * the listed enums in curl/curl.h.
1327 arg = va_arg(param, long);
1329 if(arg >= CURL_HTTP_VERSION_2)
1330 return CURLE_UNSUPPORTED_PROTOCOL;
1332 data->set.httpversion = arg;
1335 case CURLOPT_HTTPAUTH:
1337 * Set HTTP Authentication type BITMASK.
1342 unsigned long auth = va_arg(param, unsigned long);
1344 if(auth == CURLAUTH_NONE) {
1345 data->set.httpauth = auth;
1349 /* the DIGEST_IE bit is only used to set a special marker, for all the
1350 rest we need to handle it as normal DIGEST */
1351 data->state.authhost.iestyle = (auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE;
1353 if(auth & CURLAUTH_DIGEST_IE) {
1354 auth |= CURLAUTH_DIGEST; /* set standard digest bit */
1355 auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */
1358 /* switch off bits we can't support */
1360 auth &= ~CURLAUTH_NTLM; /* no NTLM support */
1361 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
1362 #elif !defined(NTLM_WB_ENABLED)
1363 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
1366 auth &= ~CURLAUTH_NEGOTIATE; /* no Negotiate (SPNEGO) auth without
1370 /* check if any auth bit lower than CURLAUTH_ONLY is still set */
1373 while(bitcheck < 31) {
1374 if(auth & (1UL << bitcheck++)) {
1380 return CURLE_NOT_BUILT_IN; /* no supported types left! */
1382 data->set.httpauth = auth;
1386 case CURLOPT_EXPECT_100_TIMEOUT_MS:
1388 * Time to wait for a response to a HTTP request containing an
1389 * Expect: 100-continue header before sending the data anyway.
1391 data->set.expect_100_timeout = va_arg(param, long);
1394 #endif /* CURL_DISABLE_HTTP */
1396 case CURLOPT_CUSTOMREQUEST:
1398 * Set a custom string to use as request
1400 result = setstropt(&data->set.str[STRING_CUSTOMREQUEST],
1401 va_arg(param, char *));
1404 data->set.httpreq = HTTPREQ_CUSTOM;
1405 here, we continue as if we were using the already set type
1406 and this just changes the actual request keyword */
1409 #ifndef CURL_DISABLE_PROXY
1410 case CURLOPT_HTTPPROXYTUNNEL:
1412 * Tunnel operations through the proxy instead of normal proxy use
1414 data->set.tunnel_thru_httpproxy = (0 != va_arg(param, long)) ?
1418 case CURLOPT_PROXYPORT:
1420 * Explicitly set HTTP proxy port number.
1422 data->set.proxyport = va_arg(param, long);
1425 case CURLOPT_PROXYAUTH:
1427 * Set HTTP Authentication type BITMASK.
1432 unsigned long auth = va_arg(param, unsigned long);
1434 if(auth == CURLAUTH_NONE) {
1435 data->set.proxyauth = auth;
1439 /* the DIGEST_IE bit is only used to set a special marker, for all the
1440 rest we need to handle it as normal DIGEST */
1441 data->state.authproxy.iestyle = (auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE;
1443 if(auth & CURLAUTH_DIGEST_IE) {
1444 auth |= CURLAUTH_DIGEST; /* set standard digest bit */
1445 auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */
1447 /* switch off bits we can't support */
1449 auth &= ~CURLAUTH_NTLM; /* no NTLM support */
1450 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
1451 #elif !defined(NTLM_WB_ENABLED)
1452 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
1455 auth &= ~CURLAUTH_NEGOTIATE; /* no Negotiate (SPNEGO) auth without
1459 /* check if any auth bit lower than CURLAUTH_ONLY is still set */
1462 while(bitcheck < 31) {
1463 if(auth & (1UL << bitcheck++)) {
1469 return CURLE_NOT_BUILT_IN; /* no supported types left! */
1471 data->set.proxyauth = auth;
1477 * Set proxy server:port to use as proxy.
1479 * If the proxy is set to "" (and CURLOPT_SOCKS_PROXY is set to "" or NULL)
1480 * we explicitly say that we don't want to use a proxy
1481 * (even though there might be environment variables saying so).
1483 * Setting it to NULL, means no proxy but allows the environment variables
1484 * to decide for us (if CURLOPT_SOCKS_PROXY setting it to NULL).
1486 result = setstropt(&data->set.str[STRING_PROXY],
1487 va_arg(param, char *));
1490 case CURLOPT_PRE_PROXY:
1492 * Set proxy server:port to use as SOCKS proxy.
1494 * If the proxy is set to "" or NULL we explicitly say that we don't want
1495 * to use the socks proxy.
1497 result = setstropt(&data->set.str[STRING_PRE_PROXY],
1498 va_arg(param, char *));
1501 case CURLOPT_PROXYTYPE:
1503 * Set proxy type. HTTP/HTTP_1_0/SOCKS4/SOCKS4a/SOCKS5/SOCKS5_HOSTNAME
1505 data->set.proxytype = (curl_proxytype)va_arg(param, long);
1508 case CURLOPT_PROXY_TRANSFER_MODE:
1510 * set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy
1512 switch(va_arg(param, long)) {
1514 data->set.proxy_transfer_mode = FALSE;
1517 data->set.proxy_transfer_mode = TRUE;
1520 /* reserve other values for future use */
1521 result = CURLE_UNKNOWN_OPTION;
1525 #endif /* CURL_DISABLE_PROXY */
1527 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
1528 case CURLOPT_SOCKS5_GSSAPI_NEC:
1530 * Set flag for NEC SOCK5 support
1532 data->set.socks5_gssapi_nec = (0 != va_arg(param, long)) ? TRUE : FALSE;
1535 case CURLOPT_SOCKS5_GSSAPI_SERVICE:
1536 case CURLOPT_PROXY_SERVICE_NAME:
1538 * Set proxy authentication service name for Kerberos 5 and SPNEGO
1540 result = setstropt(&data->set.str[STRING_PROXY_SERVICE_NAME],
1541 va_arg(param, char *));
1545 #if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) || \
1547 case CURLOPT_SERVICE_NAME:
1549 * Set authentication service name for DIGEST-MD5, Kerberos 5 and SPNEGO
1551 result = setstropt(&data->set.str[STRING_SERVICE_NAME],
1552 va_arg(param, char *));
1557 case CURLOPT_HEADERDATA:
1559 * Custom pointer to pass the header write callback function
1561 data->set.writeheader = (void *)va_arg(param, void *);
1563 case CURLOPT_ERRORBUFFER:
1565 * Error buffer provided by the caller to get the human readable
1568 data->set.errorbuffer = va_arg(param, char *);
1570 case CURLOPT_WRITEDATA:
1572 * FILE pointer to write to. Or possibly
1573 * used as argument to the write callback.
1575 data->set.out = va_arg(param, void *);
1577 case CURLOPT_FTPPORT:
1579 * Use FTP PORT, this also specifies which IP address to use
1581 result = setstropt(&data->set.str[STRING_FTPPORT],
1582 va_arg(param, char *));
1583 data->set.ftp_use_port = (data->set.str[STRING_FTPPORT]) ? TRUE : FALSE;
1586 case CURLOPT_FTP_USE_EPRT:
1587 data->set.ftp_use_eprt = (0 != va_arg(param, long)) ? TRUE : FALSE;
1590 case CURLOPT_FTP_USE_EPSV:
1591 data->set.ftp_use_epsv = (0 != va_arg(param, long)) ? TRUE : FALSE;
1594 case CURLOPT_FTP_USE_PRET:
1595 data->set.ftp_use_pret = (0 != va_arg(param, long)) ? TRUE : FALSE;
1598 case CURLOPT_FTP_SSL_CCC:
1599 data->set.ftp_ccc = (curl_ftpccc)va_arg(param, long);
1602 case CURLOPT_FTP_SKIP_PASV_IP:
1604 * Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the
1605 * bypass of the IP address in PASV responses.
1607 data->set.ftp_skip_ip = (0 != va_arg(param, long)) ? TRUE : FALSE;
1610 case CURLOPT_READDATA:
1612 * FILE pointer to read the file to be uploaded from. Or possibly
1613 * used as argument to the read callback.
1615 data->set.in_set = va_arg(param, void *);
1617 case CURLOPT_INFILESIZE:
1619 * If known, this should inform curl about the file size of the
1620 * to-be-uploaded file.
1622 data->set.filesize = va_arg(param, long);
1624 case CURLOPT_INFILESIZE_LARGE:
1626 * If known, this should inform curl about the file size of the
1627 * to-be-uploaded file.
1629 data->set.filesize = va_arg(param, curl_off_t);
1631 case CURLOPT_LOW_SPEED_LIMIT:
1633 * The low speed limit that if transfers are below this for
1634 * CURLOPT_LOW_SPEED_TIME, the transfer is aborted.
1636 data->set.low_speed_limit=va_arg(param, long);
1638 case CURLOPT_MAX_SEND_SPEED_LARGE:
1640 * When transfer uploads are faster then CURLOPT_MAX_SEND_SPEED_LARGE
1641 * bytes per second the transfer is throttled..
1643 data->set.max_send_speed=va_arg(param, curl_off_t);
1645 case CURLOPT_MAX_RECV_SPEED_LARGE:
1647 * When receiving data faster than CURLOPT_MAX_RECV_SPEED_LARGE bytes per
1648 * second the transfer is throttled..
1650 data->set.max_recv_speed=va_arg(param, curl_off_t);
1652 case CURLOPT_LOW_SPEED_TIME:
1654 * The low speed time that if transfers are below the set
1655 * CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted.
1657 data->set.low_speed_time=va_arg(param, long);
1663 if(data->change.url_alloc) {
1664 /* the already set URL is allocated, free it first! */
1665 Curl_safefree(data->change.url);
1666 data->change.url_alloc = FALSE;
1668 result = setstropt(&data->set.str[STRING_SET_URL],
1669 va_arg(param, char *));
1670 data->change.url = data->set.str[STRING_SET_URL];
1674 * The port number to use when getting the URL
1676 data->set.use_port = va_arg(param, long);
1678 case CURLOPT_TIMEOUT:
1680 * The maximum time you allow curl to use for a single transfer
1683 data->set.timeout = va_arg(param, long) * 1000L;
1686 case CURLOPT_TIMEOUT_MS:
1687 data->set.timeout = va_arg(param, long);
1690 case CURLOPT_CONNECTTIMEOUT:
1692 * The maximum time you allow curl to use to connect.
1694 data->set.connecttimeout = va_arg(param, long) * 1000L;
1697 case CURLOPT_CONNECTTIMEOUT_MS:
1698 data->set.connecttimeout = va_arg(param, long);
1701 case CURLOPT_ACCEPTTIMEOUT_MS:
1703 * The maximum time you allow curl to wait for server connect
1705 data->set.accepttimeout = va_arg(param, long);
1708 case CURLOPT_USERPWD:
1710 * user:password to use in the operation
1712 result = setstropt_userpwd(va_arg(param, char *),
1713 &data->set.str[STRING_USERNAME],
1714 &data->set.str[STRING_PASSWORD]);
1717 case CURLOPT_USERNAME:
1719 * authentication user name to use in the operation
1721 result = setstropt(&data->set.str[STRING_USERNAME],
1722 va_arg(param, char *));
1725 case CURLOPT_PASSWORD:
1727 * authentication password to use in the operation
1729 result = setstropt(&data->set.str[STRING_PASSWORD],
1730 va_arg(param, char *));
1733 case CURLOPT_LOGIN_OPTIONS:
1735 * authentication options to use in the operation
1737 result = setstropt(&data->set.str[STRING_OPTIONS],
1738 va_arg(param, char *));
1741 case CURLOPT_XOAUTH2_BEARER:
1743 * OAuth 2.0 bearer token to use in the operation
1745 result = setstropt(&data->set.str[STRING_BEARER],
1746 va_arg(param, char *));
1749 case CURLOPT_POSTQUOTE:
1751 * List of RAW FTP commands to use after a transfer
1753 data->set.postquote = va_arg(param, struct curl_slist *);
1755 case CURLOPT_PREQUOTE:
1757 * List of RAW FTP commands to use prior to RETR (Wesley Laxton)
1759 data->set.prequote = va_arg(param, struct curl_slist *);
1763 * List of RAW FTP commands to use before a transfer
1765 data->set.quote = va_arg(param, struct curl_slist *);
1767 case CURLOPT_RESOLVE:
1769 * List of NAME:[address] names to populate the DNS cache with
1770 * Prefix the NAME with dash (-) to _remove_ the name from the cache.
1772 * Names added with this API will remain in the cache until explicitly
1773 * removed or the handle is cleaned up.
1775 * This API can remove any name from the DNS cache, but only entries
1776 * that aren't actually in use right now will be pruned immediately.
1778 data->set.resolve = va_arg(param, struct curl_slist *);
1779 data->change.resolve = data->set.resolve;
1781 case CURLOPT_PROGRESSFUNCTION:
1783 * Progress callback function
1785 data->set.fprogress = va_arg(param, curl_progress_callback);
1786 if(data->set.fprogress)
1787 data->progress.callback = TRUE; /* no longer internal */
1789 data->progress.callback = FALSE; /* NULL enforces internal */
1792 case CURLOPT_XFERINFOFUNCTION:
1794 * Transfer info callback function
1796 data->set.fxferinfo = va_arg(param, curl_xferinfo_callback);
1797 if(data->set.fxferinfo)
1798 data->progress.callback = TRUE; /* no longer internal */
1800 data->progress.callback = FALSE; /* NULL enforces internal */
1804 case CURLOPT_PROGRESSDATA:
1806 * Custom client data to pass to the progress callback
1808 data->set.progress_client = va_arg(param, void *);
1811 #ifndef CURL_DISABLE_PROXY
1812 case CURLOPT_PROXYUSERPWD:
1814 * user:password needed to use the proxy
1816 result = setstropt_userpwd(va_arg(param, char *),
1817 &data->set.str[STRING_PROXYUSERNAME],
1818 &data->set.str[STRING_PROXYPASSWORD]);
1820 case CURLOPT_PROXYUSERNAME:
1822 * authentication user name to use in the operation
1824 result = setstropt(&data->set.str[STRING_PROXYUSERNAME],
1825 va_arg(param, char *));
1827 case CURLOPT_PROXYPASSWORD:
1829 * authentication password to use in the operation
1831 result = setstropt(&data->set.str[STRING_PROXYPASSWORD],
1832 va_arg(param, char *));
1834 case CURLOPT_NOPROXY:
1836 * proxy exception list
1838 result = setstropt(&data->set.str[STRING_NOPROXY],
1839 va_arg(param, char *));
1845 * What range of the file you want to transfer
1847 result = setstropt(&data->set.str[STRING_SET_RANGE],
1848 va_arg(param, char *));
1850 case CURLOPT_RESUME_FROM:
1852 * Resume transfer at the give file position
1854 data->set.set_resume_from = va_arg(param, long);
1856 case CURLOPT_RESUME_FROM_LARGE:
1858 * Resume transfer at the give file position
1860 data->set.set_resume_from = va_arg(param, curl_off_t);
1862 case CURLOPT_DEBUGFUNCTION:
1864 * stderr write callback.
1866 data->set.fdebug = va_arg(param, curl_debug_callback);
1868 * if the callback provided is NULL, it'll use the default callback
1871 case CURLOPT_DEBUGDATA:
1873 * Set to a void * that should receive all error writes. This
1874 * defaults to CURLOPT_STDERR for normal operations.
1876 data->set.debugdata = va_arg(param, void *);
1878 case CURLOPT_STDERR:
1880 * Set to a FILE * that should receive all error writes. This
1881 * defaults to stderr for normal operations.
1883 data->set.err = va_arg(param, FILE *);
1885 data->set.err = stderr;
1887 case CURLOPT_HEADERFUNCTION:
1889 * Set header write callback
1891 data->set.fwrite_header = va_arg(param, curl_write_callback);
1893 case CURLOPT_WRITEFUNCTION:
1895 * Set data write callback
1897 data->set.fwrite_func = va_arg(param, curl_write_callback);
1898 if(!data->set.fwrite_func) {
1899 data->set.is_fwrite_set = 0;
1900 /* When set to NULL, reset to our internal default function */
1901 data->set.fwrite_func = (curl_write_callback)fwrite;
1904 data->set.is_fwrite_set = 1;
1906 case CURLOPT_READFUNCTION:
1908 * Read data callback
1910 data->set.fread_func_set = va_arg(param, curl_read_callback);
1911 if(!data->set.fread_func_set) {
1912 data->set.is_fread_set = 0;
1913 /* When set to NULL, reset to our internal default function */
1914 data->set.fread_func_set = (curl_read_callback)fread;
1917 data->set.is_fread_set = 1;
1919 case CURLOPT_SEEKFUNCTION:
1921 * Seek callback. Might be NULL.
1923 data->set.seek_func = va_arg(param, curl_seek_callback);
1925 case CURLOPT_SEEKDATA:
1927 * Seek control callback. Might be NULL.
1929 data->set.seek_client = va_arg(param, void *);
1931 case CURLOPT_CONV_FROM_NETWORK_FUNCTION:
1933 * "Convert from network encoding" callback
1935 data->set.convfromnetwork = va_arg(param, curl_conv_callback);
1937 case CURLOPT_CONV_TO_NETWORK_FUNCTION:
1939 * "Convert to network encoding" callback
1941 data->set.convtonetwork = va_arg(param, curl_conv_callback);
1943 case CURLOPT_CONV_FROM_UTF8_FUNCTION:
1945 * "Convert from UTF-8 encoding" callback
1947 data->set.convfromutf8 = va_arg(param, curl_conv_callback);
1949 case CURLOPT_IOCTLFUNCTION:
1951 * I/O control callback. Might be NULL.
1953 data->set.ioctl_func = va_arg(param, curl_ioctl_callback);
1955 case CURLOPT_IOCTLDATA:
1957 * I/O control data pointer. Might be NULL.
1959 data->set.ioctl_client = va_arg(param, void *);
1961 case CURLOPT_SSLCERT:
1963 * String that holds file name of the SSL certificate to use
1965 result = setstropt(&data->set.str[STRING_CERT_ORIG],
1966 va_arg(param, char *));
1968 case CURLOPT_PROXY_SSLCERT:
1970 * String that holds file name of the SSL certificate to use for proxy
1972 result = setstropt(&data->set.str[STRING_CERT_PROXY],
1973 va_arg(param, char *));
1975 case CURLOPT_SSLCERTTYPE:
1977 * String that holds file type of the SSL certificate to use
1979 result = setstropt(&data->set.str[STRING_CERT_TYPE_ORIG],
1980 va_arg(param, char *));
1982 case CURLOPT_PROXY_SSLCERTTYPE:
1984 * String that holds file type of the SSL certificate to use for proxy
1986 result = setstropt(&data->set.str[STRING_CERT_TYPE_PROXY],
1987 va_arg(param, char *));
1989 case CURLOPT_SSLKEY:
1991 * String that holds file name of the SSL key to use
1993 result = setstropt(&data->set.str[STRING_KEY_ORIG],
1994 va_arg(param, char *));
1996 case CURLOPT_PROXY_SSLKEY:
1998 * String that holds file name of the SSL key to use for proxy
2000 result = setstropt(&data->set.str[STRING_KEY_PROXY],
2001 va_arg(param, char *));
2003 case CURLOPT_SSLKEYTYPE:
2005 * String that holds file type of the SSL key to use
2007 result = setstropt(&data->set.str[STRING_KEY_TYPE_ORIG],
2008 va_arg(param, char *));
2010 case CURLOPT_PROXY_SSLKEYTYPE:
2012 * String that holds file type of the SSL key to use for proxy
2014 result = setstropt(&data->set.str[STRING_KEY_TYPE_PROXY],
2015 va_arg(param, char *));
2017 case CURLOPT_KEYPASSWD:
2019 * String that holds the SSL or SSH private key password.
2021 result = setstropt(&data->set.str[STRING_KEY_PASSWD_ORIG],
2022 va_arg(param, char *));
2024 case CURLOPT_PROXY_KEYPASSWD:
2026 * String that holds the SSL private key password for proxy.
2028 result = setstropt(&data->set.str[STRING_KEY_PASSWD_PROXY],
2029 va_arg(param, char *));
2031 case CURLOPT_SSLENGINE:
2033 * String that holds the SSL crypto engine.
2035 argptr = va_arg(param, char *);
2036 if(argptr && argptr[0])
2037 result = Curl_ssl_set_engine(data, argptr);
2040 case CURLOPT_SSLENGINE_DEFAULT:
2042 * flag to set engine as default.
2044 result = Curl_ssl_set_engine_default(data);
2048 * Kludgy option to enable CRLF conversions. Subject for removal.
2050 data->set.crlf = (0 != va_arg(param, long)) ? TRUE : FALSE;
2053 case CURLOPT_INTERFACE:
2055 * Set what interface or address/hostname to bind the socket to when
2056 * performing an operation and thus what from-IP your connection will use.
2058 result = setstropt(&data->set.str[STRING_DEVICE],
2059 va_arg(param, char *));
2061 case CURLOPT_LOCALPORT:
2063 * Set what local port to bind the socket to when performing an operation.
2065 data->set.localport = curlx_sltous(va_arg(param, long));
2067 case CURLOPT_LOCALPORTRANGE:
2069 * Set number of local ports to try, starting with CURLOPT_LOCALPORT.
2071 data->set.localportrange = curlx_sltosi(va_arg(param, long));
2073 case CURLOPT_KRBLEVEL:
2075 * A string that defines the kerberos security level.
2077 result = setstropt(&data->set.str[STRING_KRB_LEVEL],
2078 va_arg(param, char *));
2079 data->set.krb = (data->set.str[STRING_KRB_LEVEL]) ? TRUE : FALSE;
2081 case CURLOPT_GSSAPI_DELEGATION:
2083 * GSS-API credential delegation
2085 data->set.gssapi_delegation = va_arg(param, long);
2087 case CURLOPT_SSL_VERIFYPEER:
2089 * Enable peer SSL verifying.
2091 data->set.ssl.primary.verifypeer = (0 != va_arg(param, long)) ?
2094 case CURLOPT_PROXY_SSL_VERIFYPEER:
2096 * Enable peer SSL verifying for proxy.
2098 data->set.proxy_ssl.primary.verifypeer =
2099 (0 != va_arg(param, long))?TRUE:FALSE;
2101 case CURLOPT_SSL_VERIFYHOST:
2103 * Enable verification of the host name in the peer certificate
2105 arg = va_arg(param, long);
2107 /* Obviously people are not reading documentation and too many thought
2108 this argument took a boolean when it wasn't and misused it. We thus ban
2109 1 as a sensible input and we warn about its use. Then we only have the
2110 2 action internally stored as TRUE. */
2113 failf(data, "CURLOPT_SSL_VERIFYHOST no longer supports 1 as value!");
2114 return CURLE_BAD_FUNCTION_ARGUMENT;
2117 data->set.ssl.primary.verifyhost = (0 != arg) ? TRUE : FALSE;
2119 case CURLOPT_PROXY_SSL_VERIFYHOST:
2121 * Enable verification of the host name in the peer certificate for proxy
2123 arg = va_arg(param, long);
2125 /* Obviously people are not reading documentation and too many thought
2126 this argument took a boolean when it wasn't and misused it. We thus ban
2127 1 as a sensible input and we warn about its use. Then we only have the
2128 2 action internally stored as TRUE. */
2131 failf(data, "CURLOPT_SSL_VERIFYHOST no longer supports 1 as value!");
2132 return CURLE_BAD_FUNCTION_ARGUMENT;
2135 data->set.proxy_ssl.primary.verifyhost = (0 != arg)?TRUE:FALSE;
2137 case CURLOPT_SSL_VERIFYSTATUS:
2139 * Enable certificate status verifying.
2141 if(!Curl_ssl_cert_status_request()) {
2142 result = CURLE_NOT_BUILT_IN;
2146 data->set.ssl.primary.verifystatus = (0 != va_arg(param, long)) ?
2149 case CURLOPT_SSL_CTX_FUNCTION:
2150 #ifdef have_curlssl_ssl_ctx
2152 * Set a SSL_CTX callback
2154 data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback);
2156 result = CURLE_NOT_BUILT_IN;
2159 case CURLOPT_SSL_CTX_DATA:
2160 #ifdef have_curlssl_ssl_ctx
2162 * Set a SSL_CTX callback parameter pointer
2164 data->set.ssl.fsslctxp = va_arg(param, void *);
2166 result = CURLE_NOT_BUILT_IN;
2169 case CURLOPT_SSL_FALSESTART:
2171 * Enable TLS false start.
2173 if(!Curl_ssl_false_start()) {
2174 result = CURLE_NOT_BUILT_IN;
2178 data->set.ssl.falsestart = (0 != va_arg(param, long)) ? TRUE : FALSE;
2180 case CURLOPT_CERTINFO:
2181 #ifdef have_curlssl_certinfo
2182 data->set.ssl.certinfo = (0 != va_arg(param, long)) ? TRUE : FALSE;
2184 result = CURLE_NOT_BUILT_IN;
2187 case CURLOPT_PINNEDPUBLICKEY:
2188 #ifdef have_curlssl_pinnedpubkey /* only by supported backends */
2190 * Set pinned public key for SSL connection.
2191 * Specify file name of the public key in DER format.
2193 result = setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG],
2194 va_arg(param, char *));
2196 result = CURLE_NOT_BUILT_IN;
2199 case CURLOPT_PROXY_PINNEDPUBLICKEY:
2200 #ifdef have_curlssl_pinnedpubkey /* only by supported backends */
2202 * Set pinned public key for SSL connection.
2203 * Specify file name of the public key in DER format.
2205 result = setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY],
2206 va_arg(param, char *));
2208 result = CURLE_NOT_BUILT_IN;
2211 case CURLOPT_CAINFO:
2213 * Set CA info for SSL connection. Specify file name of the CA certificate
2215 result = setstropt(&data->set.str[STRING_SSL_CAFILE_ORIG],
2216 va_arg(param, char *));
2218 case CURLOPT_PROXY_CAINFO:
2220 * Set CA info SSL connection for proxy. Specify file name of the
2223 result = setstropt(&data->set.str[STRING_SSL_CAFILE_PROXY],
2224 va_arg(param, char *));
2226 case CURLOPT_CAPATH:
2227 #ifdef have_curlssl_ca_path /* not supported by all backends */
2229 * Set CA path info for SSL connection. Specify directory name of the CA
2230 * certificates which have been prepared using openssl c_rehash utility.
2232 /* This does not work on windows. */
2233 result = setstropt(&data->set.str[STRING_SSL_CAPATH_ORIG],
2234 va_arg(param, char *));
2236 result = CURLE_NOT_BUILT_IN;
2239 case CURLOPT_PROXY_CAPATH:
2240 #ifdef have_curlssl_ca_path /* not supported by all backends */
2242 * Set CA path info for SSL connection proxy. Specify directory name of the
2243 * CA certificates which have been prepared using openssl c_rehash utility.
2245 /* This does not work on windows. */
2246 result = setstropt(&data->set.str[STRING_SSL_CAPATH_PROXY],
2247 va_arg(param, char *));
2249 result = CURLE_NOT_BUILT_IN;
2252 case CURLOPT_CRLFILE:
2254 * Set CRL file info for SSL connection. Specify file name of the CRL
2255 * to check certificates revocation
2257 result = setstropt(&data->set.str[STRING_SSL_CRLFILE_ORIG],
2258 va_arg(param, char *));
2260 case CURLOPT_PROXY_CRLFILE:
2262 * Set CRL file info for SSL connection for proxy. Specify file name of the
2263 * CRL to check certificates revocation
2265 result = setstropt(&data->set.str[STRING_SSL_CRLFILE_PROXY],
2266 va_arg(param, char *));
2268 case CURLOPT_ISSUERCERT:
2270 * Set Issuer certificate file
2271 * to check certificates issuer
2273 result = setstropt(&data->set.str[STRING_SSL_ISSUERCERT_ORIG],
2274 va_arg(param, char *));
2276 case CURLOPT_TELNETOPTIONS:
2278 * Set a linked list of telnet options
2280 data->set.telnet_options = va_arg(param, struct curl_slist *);
2283 case CURLOPT_BUFFERSIZE:
2285 * The application kindly asks for a differently sized receive buffer.
2286 * If it seems reasonable, we'll use it.
2288 data->set.buffer_size = va_arg(param, long);
2290 if(data->set.buffer_size > MAX_BUFSIZE)
2291 data->set.buffer_size = MAX_BUFSIZE; /* huge internal default */
2292 else if(data->set.buffer_size < 1)
2293 data->set.buffer_size = BUFSIZE;
2295 /* Resize only if larger than default buffer size. */
2296 if(data->set.buffer_size > BUFSIZE) {
2297 data->state.buffer = realloc(data->state.buffer,
2298 data->set.buffer_size + 1);
2299 if(!data->state.buffer) {
2300 DEBUGF(fprintf(stderr, "Error: realloc of buffer failed\n"));
2301 result = CURLE_OUT_OF_MEMORY;
2307 case CURLOPT_NOSIGNAL:
2309 * The application asks not to set any signal() or alarm() handlers,
2310 * even when using a timeout.
2312 data->set.no_signal = (0 != va_arg(param, long)) ? TRUE : FALSE;
2317 struct Curl_share *set;
2318 set = va_arg(param, struct Curl_share *);
2320 /* disconnect from old share, if any */
2322 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
2324 if(data->dns.hostcachetype == HCACHE_SHARED) {
2325 data->dns.hostcache = NULL;
2326 data->dns.hostcachetype = HCACHE_NONE;
2329 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
2330 if(data->share->cookies == data->cookies)
2331 data->cookies = NULL;
2334 if(data->share->sslsession == data->state.session)
2335 data->state.session = NULL;
2337 data->share->dirty--;
2339 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
2343 /* use new share if it set */
2347 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
2349 data->share->dirty++;
2351 if(data->share->specifier & (1<< CURL_LOCK_DATA_DNS)) {
2352 /* use shared host cache */
2353 data->dns.hostcache = &data->share->hostcache;
2354 data->dns.hostcachetype = HCACHE_SHARED;
2356 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
2357 if(data->share->cookies) {
2358 /* use shared cookie list, first free own one if any */
2359 Curl_cookie_cleanup(data->cookies);
2360 /* enable cookies since we now use a share that uses cookies! */
2361 data->cookies = data->share->cookies;
2363 #endif /* CURL_DISABLE_HTTP */
2364 if(data->share->sslsession) {
2365 data->set.general_ssl.max_ssl_sessions = data->share->max_ssl_sessions;
2366 data->state.session = data->share->sslsession;
2368 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
2371 /* check for host cache not needed,
2372 * it will be done by curl_easy_perform */
2376 case CURLOPT_PRIVATE:
2378 * Set private data pointer.
2380 data->set.private_data = va_arg(param, void *);
2383 case CURLOPT_MAXFILESIZE:
2385 * Set the maximum size of a file to download.
2387 data->set.max_filesize = va_arg(param, long);
2391 case CURLOPT_USE_SSL:
2393 * Make transfers attempt to use SSL/TLS.
2395 data->set.use_ssl = (curl_usessl)va_arg(param, long);
2398 case CURLOPT_SSL_OPTIONS:
2399 arg = va_arg(param, long);
2400 data->set.ssl.enable_beast = arg&CURLSSLOPT_ALLOW_BEAST?TRUE:FALSE;
2401 data->set.ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
2404 case CURLOPT_PROXY_SSL_OPTIONS:
2405 arg = va_arg(param, long);
2406 data->set.proxy_ssl.enable_beast = arg&CURLSSLOPT_ALLOW_BEAST?TRUE:FALSE;
2407 data->set.proxy_ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
2411 case CURLOPT_FTPSSLAUTH:
2413 * Set a specific auth for FTP-SSL transfers.
2415 data->set.ftpsslauth = (curl_ftpauth)va_arg(param, long);
2418 case CURLOPT_IPRESOLVE:
2419 data->set.ipver = va_arg(param, long);
2422 case CURLOPT_MAXFILESIZE_LARGE:
2424 * Set the maximum size of a file to download.
2426 data->set.max_filesize = va_arg(param, curl_off_t);
2429 case CURLOPT_TCP_NODELAY:
2431 * Enable or disable TCP_NODELAY, which will disable/enable the Nagle
2434 data->set.tcp_nodelay = (0 != va_arg(param, long)) ? TRUE : FALSE;
2437 case CURLOPT_FTP_ACCOUNT:
2438 result = setstropt(&data->set.str[STRING_FTP_ACCOUNT],
2439 va_arg(param, char *));
2442 case CURLOPT_IGNORE_CONTENT_LENGTH:
2443 data->set.ignorecl = (0 != va_arg(param, long)) ? TRUE : FALSE;
2446 case CURLOPT_CONNECT_ONLY:
2448 * No data transfer, set up connection and let application use the socket
2450 data->set.connect_only = (0 != va_arg(param, long)) ? TRUE : FALSE;
2453 case CURLOPT_FTP_ALTERNATIVE_TO_USER:
2454 result = setstropt(&data->set.str[STRING_FTP_ALTERNATIVE_TO_USER],
2455 va_arg(param, char *));
2458 case CURLOPT_SOCKOPTFUNCTION:
2460 * socket callback function: called after socket() but before connect()
2462 data->set.fsockopt = va_arg(param, curl_sockopt_callback);
2465 case CURLOPT_SOCKOPTDATA:
2467 * socket callback data pointer. Might be NULL.
2469 data->set.sockopt_client = va_arg(param, void *);
2472 case CURLOPT_OPENSOCKETFUNCTION:
2474 * open/create socket callback function: called instead of socket(),
2477 data->set.fopensocket = va_arg(param, curl_opensocket_callback);
2480 case CURLOPT_OPENSOCKETDATA:
2482 * socket callback data pointer. Might be NULL.
2484 data->set.opensocket_client = va_arg(param, void *);
2487 case CURLOPT_CLOSESOCKETFUNCTION:
2489 * close socket callback function: called instead of close()
2490 * when shutting down a connection
2492 data->set.fclosesocket = va_arg(param, curl_closesocket_callback);
2495 case CURLOPT_CLOSESOCKETDATA:
2497 * socket callback data pointer. Might be NULL.
2499 data->set.closesocket_client = va_arg(param, void *);
2502 case CURLOPT_SSL_SESSIONID_CACHE:
2503 data->set.ssl.primary.sessionid = (0 != va_arg(param, long)) ?
2505 data->set.proxy_ssl.primary.sessionid = data->set.ssl.primary.sessionid;
2509 /* we only include SSH options if explicitly built to support SSH */
2510 case CURLOPT_SSH_AUTH_TYPES:
2511 data->set.ssh_auth_types = va_arg(param, long);
2514 case CURLOPT_SSH_PUBLIC_KEYFILE:
2516 * Use this file instead of the $HOME/.ssh/id_dsa.pub file
2518 result = setstropt(&data->set.str[STRING_SSH_PUBLIC_KEY],
2519 va_arg(param, char *));
2522 case CURLOPT_SSH_PRIVATE_KEYFILE:
2524 * Use this file instead of the $HOME/.ssh/id_dsa file
2526 result = setstropt(&data->set.str[STRING_SSH_PRIVATE_KEY],
2527 va_arg(param, char *));
2529 case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5:
2531 * Option to allow for the MD5 of the host public key to be checked
2532 * for validation purposes.
2534 result = setstropt(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5],
2535 va_arg(param, char *));
2537 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2538 case CURLOPT_SSH_KNOWNHOSTS:
2540 * Store the file name to read known hosts from.
2542 result = setstropt(&data->set.str[STRING_SSH_KNOWNHOSTS],
2543 va_arg(param, char *));
2546 case CURLOPT_SSH_KEYFUNCTION:
2547 /* setting to NULL is fine since the ssh.c functions themselves will
2548 then rever to use the internal default */
2549 data->set.ssh_keyfunc = va_arg(param, curl_sshkeycallback);
2552 case CURLOPT_SSH_KEYDATA:
2554 * Custom client data to pass to the SSH keyfunc callback
2556 data->set.ssh_keyfunc_userp = va_arg(param, void *);
2558 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2560 #endif /* USE_LIBSSH2 */
2562 case CURLOPT_HTTP_TRANSFER_DECODING:
2564 * disable libcurl transfer encoding is used
2566 data->set.http_te_skip = (0 == va_arg(param, long)) ? TRUE : FALSE;
2569 case CURLOPT_HTTP_CONTENT_DECODING:
2571 * raw data passed to the application when content encoding is used
2573 data->set.http_ce_skip = (0 == va_arg(param, long)) ? TRUE : FALSE;
2576 case CURLOPT_NEW_FILE_PERMS:
2578 * Uses these permissions instead of 0644
2580 data->set.new_file_perms = va_arg(param, long);
2583 case CURLOPT_NEW_DIRECTORY_PERMS:
2585 * Uses these permissions instead of 0755
2587 data->set.new_directory_perms = va_arg(param, long);
2590 case CURLOPT_ADDRESS_SCOPE:
2592 * We always get longs when passed plain numericals, but for this value we
2593 * know that an unsigned int will always hold the value so we blindly
2594 * typecast to this type
2596 data->set.scope_id = curlx_sltoui(va_arg(param, long));
2599 case CURLOPT_PROTOCOLS:
2600 /* set the bitmask for the protocols that are allowed to be used for the
2601 transfer, which thus helps the app which takes URLs from users or other
2602 external inputs and want to restrict what protocol(s) to deal
2603 with. Defaults to CURLPROTO_ALL. */
2604 data->set.allowed_protocols = va_arg(param, long);
2607 case CURLOPT_REDIR_PROTOCOLS:
2608 /* set the bitmask for the protocols that libcurl is allowed to follow to,
2609 as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
2610 to be set in both bitmasks to be allowed to get redirected to. Defaults
2611 to all protocols except FILE and SCP. */
2612 data->set.redir_protocols = va_arg(param, long);
2615 case CURLOPT_DEFAULT_PROTOCOL:
2616 /* Set the protocol to use when the URL doesn't include any protocol */
2617 result = setstropt(&data->set.str[STRING_DEFAULT_PROTOCOL],
2618 va_arg(param, char *));
2621 case CURLOPT_MAIL_FROM:
2622 /* Set the SMTP mail originator */
2623 result = setstropt(&data->set.str[STRING_MAIL_FROM],
2624 va_arg(param, char *));
2627 case CURLOPT_MAIL_AUTH:
2628 /* Set the SMTP auth originator */
2629 result = setstropt(&data->set.str[STRING_MAIL_AUTH],
2630 va_arg(param, char *));
2633 case CURLOPT_MAIL_RCPT:
2634 /* Set the list of mail recipients */
2635 data->set.mail_rcpt = va_arg(param, struct curl_slist *);
2638 case CURLOPT_SASL_IR:
2639 /* Enable/disable SASL initial response */
2640 data->set.sasl_ir = (0 != va_arg(param, long)) ? TRUE : FALSE;
2643 case CURLOPT_RTSP_REQUEST:
2646 * Set the RTSP request method (OPTIONS, SETUP, PLAY, etc...)
2647 * Would this be better if the RTSPREQ_* were just moved into here?
2649 long curl_rtspreq = va_arg(param, long);
2650 Curl_RtspReq rtspreq = RTSPREQ_NONE;
2651 switch(curl_rtspreq) {
2652 case CURL_RTSPREQ_OPTIONS:
2653 rtspreq = RTSPREQ_OPTIONS;
2656 case CURL_RTSPREQ_DESCRIBE:
2657 rtspreq = RTSPREQ_DESCRIBE;
2660 case CURL_RTSPREQ_ANNOUNCE:
2661 rtspreq = RTSPREQ_ANNOUNCE;
2664 case CURL_RTSPREQ_SETUP:
2665 rtspreq = RTSPREQ_SETUP;
2668 case CURL_RTSPREQ_PLAY:
2669 rtspreq = RTSPREQ_PLAY;
2672 case CURL_RTSPREQ_PAUSE:
2673 rtspreq = RTSPREQ_PAUSE;
2676 case CURL_RTSPREQ_TEARDOWN:
2677 rtspreq = RTSPREQ_TEARDOWN;
2680 case CURL_RTSPREQ_GET_PARAMETER:
2681 rtspreq = RTSPREQ_GET_PARAMETER;
2684 case CURL_RTSPREQ_SET_PARAMETER:
2685 rtspreq = RTSPREQ_SET_PARAMETER;
2688 case CURL_RTSPREQ_RECORD:
2689 rtspreq = RTSPREQ_RECORD;
2692 case CURL_RTSPREQ_RECEIVE:
2693 rtspreq = RTSPREQ_RECEIVE;
2696 rtspreq = RTSPREQ_NONE;
2699 data->set.rtspreq = rtspreq;
2704 case CURLOPT_RTSP_SESSION_ID:
2706 * Set the RTSP Session ID manually. Useful if the application is
2707 * resuming a previously established RTSP session
2709 result = setstropt(&data->set.str[STRING_RTSP_SESSION_ID],
2710 va_arg(param, char *));
2713 case CURLOPT_RTSP_STREAM_URI:
2715 * Set the Stream URI for the RTSP request. Unless the request is
2716 * for generic server options, the application will need to set this.
2718 result = setstropt(&data->set.str[STRING_RTSP_STREAM_URI],
2719 va_arg(param, char *));
2722 case CURLOPT_RTSP_TRANSPORT:
2724 * The content of the Transport: header for the RTSP request
2726 result = setstropt(&data->set.str[STRING_RTSP_TRANSPORT],
2727 va_arg(param, char *));
2730 case CURLOPT_RTSP_CLIENT_CSEQ:
2732 * Set the CSEQ number to issue for the next RTSP request. Useful if the
2733 * application is resuming a previously broken connection. The CSEQ
2734 * will increment from this new number henceforth.
2736 data->state.rtsp_next_client_CSeq = va_arg(param, long);
2739 case CURLOPT_RTSP_SERVER_CSEQ:
2740 /* Same as the above, but for server-initiated requests */
2741 data->state.rtsp_next_client_CSeq = va_arg(param, long);
2744 case CURLOPT_INTERLEAVEDATA:
2745 data->set.rtp_out = va_arg(param, void *);
2747 case CURLOPT_INTERLEAVEFUNCTION:
2748 /* Set the user defined RTP write function */
2749 data->set.fwrite_rtp = va_arg(param, curl_write_callback);
2752 case CURLOPT_WILDCARDMATCH:
2753 data->set.wildcardmatch = (0 != va_arg(param, long)) ? TRUE : FALSE;
2755 case CURLOPT_CHUNK_BGN_FUNCTION:
2756 data->set.chunk_bgn = va_arg(param, curl_chunk_bgn_callback);
2758 case CURLOPT_CHUNK_END_FUNCTION:
2759 data->set.chunk_end = va_arg(param, curl_chunk_end_callback);
2761 case CURLOPT_FNMATCH_FUNCTION:
2762 data->set.fnmatch = va_arg(param, curl_fnmatch_callback);
2764 case CURLOPT_CHUNK_DATA:
2765 data->wildcard.customptr = va_arg(param, void *);
2767 case CURLOPT_FNMATCH_DATA:
2768 data->set.fnmatch_data = va_arg(param, void *);
2771 case CURLOPT_TLSAUTH_USERNAME:
2772 result = setstropt(&data->set.str[STRING_TLSAUTH_USERNAME_ORIG],
2773 va_arg(param, char *));
2774 if(data->set.str[STRING_TLSAUTH_USERNAME_ORIG] && !data->set.ssl.authtype)
2775 data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
2777 case CURLOPT_PROXY_TLSAUTH_USERNAME:
2778 result = setstropt(&data->set.str[STRING_TLSAUTH_USERNAME_PROXY],
2779 va_arg(param, char *));
2780 if(data->set.str[STRING_TLSAUTH_USERNAME_PROXY] &&
2781 !data->set.proxy_ssl.authtype)
2782 data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
2784 case CURLOPT_TLSAUTH_PASSWORD:
2785 result = setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_ORIG],
2786 va_arg(param, char *));
2787 if(data->set.str[STRING_TLSAUTH_USERNAME_ORIG] && !data->set.ssl.authtype)
2788 data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
2790 case CURLOPT_PROXY_TLSAUTH_PASSWORD:
2791 result = setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_PROXY],
2792 va_arg(param, char *));
2793 if(data->set.str[STRING_TLSAUTH_USERNAME_PROXY] &&
2794 !data->set.proxy_ssl.authtype)
2795 data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
2797 case CURLOPT_TLSAUTH_TYPE:
2798 if(strncasecompare((char *)va_arg(param, char *), "SRP", strlen("SRP")))
2799 data->set.ssl.authtype = CURL_TLSAUTH_SRP;
2801 data->set.ssl.authtype = CURL_TLSAUTH_NONE;
2803 case CURLOPT_PROXY_TLSAUTH_TYPE:
2804 if(strncasecompare((char *)va_arg(param, char *), "SRP", strlen("SRP")))
2805 data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP;
2807 data->set.proxy_ssl.authtype = CURL_TLSAUTH_NONE;
2810 case CURLOPT_DNS_SERVERS:
2811 result = Curl_set_dns_servers(data, va_arg(param, char *));
2813 case CURLOPT_DNS_INTERFACE:
2814 result = Curl_set_dns_interface(data, va_arg(param, char *));
2816 case CURLOPT_DNS_LOCAL_IP4:
2817 result = Curl_set_dns_local_ip4(data, va_arg(param, char *));
2819 case CURLOPT_DNS_LOCAL_IP6:
2820 result = Curl_set_dns_local_ip6(data, va_arg(param, char *));
2823 case CURLOPT_TCP_KEEPALIVE:
2824 data->set.tcp_keepalive = (0 != va_arg(param, long)) ? TRUE : FALSE;
2826 case CURLOPT_TCP_KEEPIDLE:
2827 data->set.tcp_keepidle = va_arg(param, long);
2829 case CURLOPT_TCP_KEEPINTVL:
2830 data->set.tcp_keepintvl = va_arg(param, long);
2832 case CURLOPT_TCP_FASTOPEN:
2833 #if defined(CONNECT_DATA_IDEMPOTENT) || defined(MSG_FASTOPEN)
2834 data->set.tcp_fastopen = (0 != va_arg(param, long))?TRUE:FALSE;
2836 result = CURLE_NOT_BUILT_IN;
2839 case CURLOPT_SSL_ENABLE_NPN:
2840 data->set.ssl_enable_npn = (0 != va_arg(param, long)) ? TRUE : FALSE;
2842 case CURLOPT_SSL_ENABLE_ALPN:
2843 data->set.ssl_enable_alpn = (0 != va_arg(param, long)) ? TRUE : FALSE;
2846 #ifdef USE_UNIX_SOCKETS
2847 case CURLOPT_UNIX_SOCKET_PATH:
2848 data->set.abstract_unix_socket = FALSE;
2849 result = setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH],
2850 va_arg(param, char *));
2852 case CURLOPT_ABSTRACT_UNIX_SOCKET:
2853 data->set.abstract_unix_socket = TRUE;
2854 result = setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH],
2855 va_arg(param, char *));
2859 case CURLOPT_PATH_AS_IS:
2860 data->set.path_as_is = (0 != va_arg(param, long)) ? TRUE : FALSE;
2862 case CURLOPT_PIPEWAIT:
2863 data->set.pipewait = (0 != va_arg(param, long)) ? TRUE : FALSE;
2865 case CURLOPT_STREAM_WEIGHT:
2867 return CURLE_NOT_BUILT_IN;
2869 arg = va_arg(param, long);
2870 if((arg>=1) && (arg <= 256))
2871 data->set.stream_weight = (int)arg;
2874 case CURLOPT_STREAM_DEPENDS:
2875 case CURLOPT_STREAM_DEPENDS_E:
2878 return CURLE_NOT_BUILT_IN;
2880 struct Curl_easy *dep = va_arg(param, struct Curl_easy *);
2881 if(!dep || GOOD_EASY_HANDLE(dep)) {
2882 if(data->set.stream_depends_on) {
2883 Curl_http2_remove_child(data->set.stream_depends_on, data);
2885 Curl_http2_add_child(dep, data, (option == CURLOPT_STREAM_DEPENDS_E));
2890 case CURLOPT_CONNECT_TO:
2891 data->set.connect_to = va_arg(param, struct curl_slist *);
2894 /* unknown tag and its companion, just ignore: */
2895 result = CURLE_UNKNOWN_OPTION;
2902 #ifdef USE_RECV_BEFORE_SEND_WORKAROUND
2903 static void conn_reset_postponed_data(struct connectdata *conn, int num)
2905 struct postponed_data * const psnd = &(conn->postponed[num]);
2907 DEBUGASSERT(psnd->allocated_size > 0);
2908 DEBUGASSERT(psnd->recv_size <= psnd->allocated_size);
2909 DEBUGASSERT(psnd->recv_size ?
2910 (psnd->recv_processed < psnd->recv_size) :
2911 (psnd->recv_processed == 0));
2912 DEBUGASSERT(psnd->bindsock != CURL_SOCKET_BAD);
2914 psnd->buffer = NULL;
2915 psnd->allocated_size = 0;
2916 psnd->recv_size = 0;
2917 psnd->recv_processed = 0;
2919 psnd->bindsock = CURL_SOCKET_BAD; /* used only for DEBUGASSERT */
2920 #endif /* DEBUGBUILD */
2923 DEBUGASSERT(psnd->allocated_size == 0);
2924 DEBUGASSERT(psnd->recv_size == 0);
2925 DEBUGASSERT(psnd->recv_processed == 0);
2926 DEBUGASSERT(psnd->bindsock == CURL_SOCKET_BAD);
2930 static void conn_reset_all_postponed_data(struct connectdata *conn)
2932 conn_reset_postponed_data(conn, 0);
2933 conn_reset_postponed_data(conn, 1);
2935 #else /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
2936 /* Use "do-nothing" macros instead of functions when workaround not used */
2937 #define conn_reset_postponed_data(c,n) do {} WHILE_FALSE
2938 #define conn_reset_all_postponed_data(c) do {} WHILE_FALSE
2939 #endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
2941 static void conn_free(struct connectdata *conn)
2946 /* possible left-overs from the async name resolvers */
2947 Curl_resolver_cancel(conn);
2949 /* close the SSL stuff before we close any sockets since they will/may
2950 write to the sockets */
2951 Curl_ssl_close(conn, FIRSTSOCKET);
2952 Curl_ssl_close(conn, SECONDARYSOCKET);
2954 /* close possibly still open sockets */
2955 if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
2956 Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
2957 if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET])
2958 Curl_closesocket(conn, conn->sock[FIRSTSOCKET]);
2959 if(CURL_SOCKET_BAD != conn->tempsock[0])
2960 Curl_closesocket(conn, conn->tempsock[0]);
2961 if(CURL_SOCKET_BAD != conn->tempsock[1])
2962 Curl_closesocket(conn, conn->tempsock[1]);
2964 #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
2965 defined(NTLM_WB_ENABLED)
2966 Curl_ntlm_wb_cleanup(conn);
2969 Curl_safefree(conn->user);
2970 Curl_safefree(conn->passwd);
2971 Curl_safefree(conn->oauth_bearer);
2972 Curl_safefree(conn->options);
2973 Curl_safefree(conn->http_proxy.user);
2974 Curl_safefree(conn->socks_proxy.user);
2975 Curl_safefree(conn->http_proxy.passwd);
2976 Curl_safefree(conn->socks_proxy.passwd);
2977 Curl_safefree(conn->allocptr.proxyuserpwd);
2978 Curl_safefree(conn->allocptr.uagent);
2979 Curl_safefree(conn->allocptr.userpwd);
2980 Curl_safefree(conn->allocptr.accept_encoding);
2981 Curl_safefree(conn->allocptr.te);
2982 Curl_safefree(conn->allocptr.rangeline);
2983 Curl_safefree(conn->allocptr.ref);
2984 Curl_safefree(conn->allocptr.host);
2985 Curl_safefree(conn->allocptr.cookiehost);
2986 Curl_safefree(conn->allocptr.rtsp_transport);
2987 Curl_safefree(conn->trailer);
2988 Curl_safefree(conn->host.rawalloc); /* host name buffer */
2989 Curl_safefree(conn->conn_to_host.rawalloc); /* host name buffer */
2990 Curl_safefree(conn->secondaryhostname);
2991 Curl_safefree(conn->http_proxy.host.rawalloc); /* http proxy name buffer */
2992 Curl_safefree(conn->socks_proxy.host.rawalloc); /* socks proxy name buffer */
2993 Curl_safefree(conn->master_buffer);
2995 conn_reset_all_postponed_data(conn);
2997 Curl_llist_destroy(conn->send_pipe, NULL);
2998 Curl_llist_destroy(conn->recv_pipe, NULL);
3000 conn->send_pipe = NULL;
3001 conn->recv_pipe = NULL;
3003 Curl_safefree(conn->localdev);
3004 Curl_free_primary_ssl_config(&conn->ssl_config);
3005 Curl_free_primary_ssl_config(&conn->proxy_ssl_config);
3007 #ifdef USE_UNIX_SOCKETS
3008 Curl_safefree(conn->unix_domain_socket);
3011 free(conn); /* free all the connection oriented data */
3015 * Disconnects the given connection. Note the connection may not be the
3016 * primary connection, like when freeing room in the connection cache or
3017 * killing of a dead old connection.
3019 * This function MUST NOT reset state in the Curl_easy struct if that
3020 * isn't strictly bound to the life-time of *this* particular connection.
3024 CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
3026 struct Curl_easy *data;
3028 return CURLE_OK; /* this is closed and fine already */
3032 DEBUGF(fprintf(stderr, "DISCONNECT without easy handle, ignoring\n"));
3037 * If this connection isn't marked to force-close, leave it open if there
3038 * are other users of it
3040 if(!conn->bits.close &&
3041 (conn->send_pipe->size + conn->recv_pipe->size)) {
3042 DEBUGF(infof(data, "Curl_disconnect, usecounter: %d\n",
3043 conn->send_pipe->size + conn->recv_pipe->size));
3047 if(conn->dns_entry != NULL) {
3048 Curl_resolv_unlock(data, conn->dns_entry);
3049 conn->dns_entry = NULL;
3052 Curl_hostcache_prune(data); /* kill old DNS cache entries */
3054 #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM)
3055 /* Cleanup NTLM connection-related data */
3056 Curl_http_ntlm_cleanup(conn);
3059 if(conn->handler->disconnect)
3060 /* This is set if protocol-specific cleanups should be made */
3061 conn->handler->disconnect(conn, dead_connection);
3063 /* unlink ourselves! */
3064 infof(data, "Closing connection %ld\n", conn->connection_id);
3065 Curl_conncache_remove_conn(data->state.conn_cache, conn);
3067 free_fixed_hostname(&conn->host);
3068 free_fixed_hostname(&conn->conn_to_host);
3069 free_fixed_hostname(&conn->http_proxy.host);
3070 free_fixed_hostname(&conn->socks_proxy.host);
3072 Curl_ssl_close(conn, FIRSTSOCKET);
3074 /* Indicate to all handles on the pipe that we're dead */
3075 if(Curl_pipeline_wanted(data->multi, CURLPIPE_ANY)) {
3076 signalPipeClose(conn->send_pipe, TRUE);
3077 signalPipeClose(conn->recv_pipe, TRUE);
3086 * This function should return TRUE if the socket is to be assumed to
3087 * be dead. Most commonly this happens when the server has closed the
3088 * connection due to inactivity.
3090 static bool SocketIsDead(curl_socket_t sock)
3093 bool ret_val = TRUE;
3095 sval = SOCKET_READABLE(sock, 0);
3104 * IsPipeliningPossible() returns TRUE if the options set would allow
3105 * pipelining/multiplexing and the connection is using a HTTP protocol.
3107 static bool IsPipeliningPossible(const struct Curl_easy *handle,
3108 const struct connectdata *conn)
3110 /* If a HTTP protocol and pipelining is enabled */
3111 if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
3112 (!conn->bits.protoconnstart || !conn->bits.close)) {
3114 if(Curl_pipeline_wanted(handle->multi, CURLPIPE_HTTP1) &&
3115 (handle->set.httpversion != CURL_HTTP_VERSION_1_0) &&
3116 (handle->set.httpreq == HTTPREQ_GET ||
3117 handle->set.httpreq == HTTPREQ_HEAD))
3118 /* didn't ask for HTTP/1.0 and a GET or HEAD */
3121 if(Curl_pipeline_wanted(handle->multi, CURLPIPE_MULTIPLEX) &&
3122 (handle->set.httpversion >= CURL_HTTP_VERSION_2))
3129 int Curl_removeHandleFromPipeline(struct Curl_easy *handle,
3130 struct curl_llist *pipeline)
3133 struct curl_llist_element *curr;
3135 curr = pipeline->head;
3137 if(curr->ptr == handle) {
3138 Curl_llist_remove(pipeline, curr, NULL);
3139 return 1; /* we removed a handle */
3148 #if 0 /* this code is saved here as it is useful for debugging purposes */
3149 static void Curl_printPipeline(struct curl_llist *pipeline)
3151 struct curl_llist_element *curr;
3153 curr = pipeline->head;
3155 struct Curl_easy *data = (struct Curl_easy *) curr->ptr;
3156 infof(data, "Handle in pipeline: %s\n", data->state.path);
3162 static struct Curl_easy* gethandleathead(struct curl_llist *pipeline)
3164 struct curl_llist_element *curr = pipeline->head;
3166 return (struct Curl_easy *) curr->ptr;
3172 /* remove the specified connection from all (possible) pipelines and related
3174 void Curl_getoff_all_pipelines(struct Curl_easy *data,
3175 struct connectdata *conn)
3177 bool recv_head = (conn->readchannel_inuse &&
3178 Curl_recvpipe_head(data, conn));
3179 bool send_head = (conn->writechannel_inuse &&
3180 Curl_sendpipe_head(data, conn));
3182 if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) && recv_head)
3183 Curl_pipeline_leave_read(conn);
3184 if(Curl_removeHandleFromPipeline(data, conn->send_pipe) && send_head)
3185 Curl_pipeline_leave_write(conn);
3188 static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke)
3190 struct curl_llist_element *curr;
3195 curr = pipeline->head;
3197 struct curl_llist_element *next = curr->next;
3198 struct Curl_easy *data = (struct Curl_easy *) curr->ptr;
3200 #ifdef DEBUGBUILD /* debug-only code */
3201 if(data->magic != CURLEASY_MAGIC_NUMBER) {
3203 infof(data, "signalPipeClose() found BAAD easy handle\n");
3208 data->state.pipe_broke = TRUE;
3209 Curl_multi_handlePipeBreak(data);
3210 Curl_llist_remove(pipeline, curr, NULL);
3216 * This function finds the connection in the connection
3217 * cache that has been unused for the longest time.
3219 * Returns the pointer to the oldest idle connection, or NULL if none was
3222 struct connectdata *
3223 Curl_oldest_idle_connection(struct Curl_easy *data)
3225 struct conncache *bc = data->state.conn_cache;
3226 struct curl_hash_iterator iter;
3227 struct curl_llist_element *curr;
3228 struct curl_hash_element *he;
3229 time_t highscore=-1;
3232 struct connectdata *conn_candidate = NULL;
3233 struct connectbundle *bundle;
3237 Curl_hash_start_iterate(&bc->hash, &iter);
3239 he = Curl_hash_next_element(&iter);
3241 struct connectdata *conn;
3245 curr = bundle->conn_list->head;
3250 /* Set higher score for the age passed since the connection was used */
3251 score = Curl_tvdiff(now, conn->now);
3253 if(score > highscore) {
3255 conn_candidate = conn;
3261 he = Curl_hash_next_element(&iter);
3264 return conn_candidate;
3268 proxy_info_matches(const struct proxy_info* data,
3269 const struct proxy_info* needle)
3271 if((data->proxytype == needle->proxytype) &&
3272 (data->port == needle->port) &&
3273 Curl_safe_strcasecompare(data->host.name, needle->host.name) &&
3274 Curl_safe_strcasecompare(data->user, needle->user) &&
3275 Curl_safe_strcasecompare(data->passwd, needle->passwd))
3283 * This function finds the connection in the connection
3284 * bundle that has been unused for the longest time.
3286 * Returns the pointer to the oldest idle connection, or NULL if none was
3289 static struct connectdata *
3290 find_oldest_idle_connection_in_bundle(struct Curl_easy *data,
3291 struct connectbundle *bundle)
3293 struct curl_llist_element *curr;
3294 time_t highscore=-1;
3297 struct connectdata *conn_candidate = NULL;
3298 struct connectdata *conn;
3304 curr = bundle->conn_list->head;
3309 /* Set higher score for the age passed since the connection was used */
3310 score = Curl_tvdiff(now, conn->now);
3312 if(score > highscore) {
3314 conn_candidate = conn;
3320 return conn_candidate;
3324 * This function checks if given connection is dead and disconnects if so.
3325 * (That also removes it from the connection cache.)
3327 * Returns TRUE if the connection actually was dead and disconnected.
3329 static bool disconnect_if_dead(struct connectdata *conn,
3330 struct Curl_easy *data)
3332 size_t pipeLen = conn->send_pipe->size + conn->recv_pipe->size;
3333 if(!pipeLen && !conn->inuse) {
3334 /* The check for a dead socket makes sense only if there are no
3335 handles in pipeline and the connection isn't already marked in
3338 if(conn->handler->protocol & CURLPROTO_RTSP)
3339 /* RTSP is a special case due to RTP interleaving */
3340 dead = Curl_rtsp_connisdead(conn);
3342 dead = SocketIsDead(conn->sock[FIRSTSOCKET]);
3346 infof(data, "Connection %ld seems to be dead!\n", conn->connection_id);
3348 /* disconnect resources */
3349 Curl_disconnect(conn, /* dead_connection */TRUE);
3357 * Wrapper to use disconnect_if_dead() function in Curl_conncache_foreach()
3361 static int call_disconnect_if_dead(struct connectdata *conn,
3364 struct Curl_easy* data = (struct Curl_easy*)param;
3365 disconnect_if_dead(conn, data);
3366 return 0; /* continue iteration */
3370 * This function scans the connection cache for half-open/dead connections,
3371 * closes and removes them.
3372 * The cleanup is done at most once per second.
3374 static void prune_dead_connections(struct Curl_easy *data)
3376 struct timeval now = Curl_tvnow();
3377 time_t elapsed = Curl_tvdiff(now, data->state.conn_cache->last_cleanup);
3379 if(elapsed >= 1000L) {
3380 Curl_conncache_foreach(data->state.conn_cache, data,
3381 call_disconnect_if_dead);
3382 data->state.conn_cache->last_cleanup = now;
3387 static size_t max_pipeline_length(struct Curl_multi *multi)
3389 return multi ? multi->max_pipeline_length : 0;
3394 * Given one filled in connection struct (named needle), this function should
3395 * detect if there already is one that has all the significant details
3396 * exactly the same and thus should be used instead.
3398 * If there is a match, this function returns TRUE - and has marked the
3399 * connection as 'in-use'. It must later be called with ConnectionDone() to
3400 * return back to 'idle' (unused) state.
3402 * The force_reuse flag is set if the connection must be used, even if
3403 * the pipelining strategy wants to open a new connection instead of reusing.
3406 ConnectionExists(struct Curl_easy *data,
3407 struct connectdata *needle,
3408 struct connectdata **usethis,
3412 struct connectdata *check;
3413 struct connectdata *chosen = 0;
3414 bool foundPendingCandidate = FALSE;
3415 bool canPipeline = IsPipeliningPossible(data, needle);
3416 struct connectbundle *bundle;
3419 bool wantNTLMhttp = ((data->state.authhost.want &
3420 (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
3421 (needle->handler->protocol & PROTO_FAMILY_HTTP));
3422 bool wantProxyNTLMhttp = (needle->bits.proxy_user_passwd &&
3423 ((data->state.authproxy.want &
3424 (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
3425 (needle->handler->protocol & PROTO_FAMILY_HTTP)));
3428 *force_reuse = FALSE;
3431 /* We can't pipe if the site is blacklisted */
3432 if(canPipeline && Curl_pipeline_site_blacklisted(data, needle)) {
3433 canPipeline = FALSE;
3436 /* Look up the bundle with all the connections to this
3438 bundle = Curl_conncache_find_bundle(needle, data->state.conn_cache);
3440 /* Max pipe length is zero (unlimited) for multiplexed connections */
3441 size_t max_pipe_len = (bundle->multiuse != BUNDLE_MULTIPLEX)?
3442 max_pipeline_length(data->multi):0;
3443 size_t best_pipe_len = max_pipe_len;
3444 struct curl_llist_element *curr;
3446 infof(data, "Found bundle for host %s: %p [%s]\n",
3447 (needle->bits.conn_to_host ? needle->conn_to_host.name :
3448 needle->host.name), (void *)bundle,
3449 (bundle->multiuse == BUNDLE_PIPELINING ?
3451 (bundle->multiuse == BUNDLE_MULTIPLEX ?
3452 "can multiplex" : "serially")));
3454 /* We can't pipe if we don't know anything about the server */
3456 if(bundle->multiuse <= BUNDLE_UNKNOWN) {
3457 if((bundle->multiuse == BUNDLE_UNKNOWN) && data->set.pipewait) {
3458 infof(data, "Server doesn't support multi-use yet, wait\n");
3460 return FALSE; /* no re-use */
3463 infof(data, "Server doesn't support multi-use (yet)\n");
3464 canPipeline = FALSE;
3466 if((bundle->multiuse == BUNDLE_PIPELINING) &&
3467 !Curl_pipeline_wanted(data->multi, CURLPIPE_HTTP1)) {
3468 /* not asked for, switch off */
3469 infof(data, "Could pipeline, but not asked to!\n");
3470 canPipeline = FALSE;
3472 else if((bundle->multiuse == BUNDLE_MULTIPLEX) &&
3473 !Curl_pipeline_wanted(data->multi, CURLPIPE_MULTIPLEX)) {
3474 infof(data, "Could multiplex, but not asked to!\n");
3475 canPipeline = FALSE;
3479 curr = bundle->conn_list->head;
3485 * Note that if we use a HTTP proxy in normal mode (no tunneling), we
3486 * check connections to that proxy and not to the actual remote server.
3491 if(disconnect_if_dead(check, data))
3494 pipeLen = check->send_pipe->size + check->recv_pipe->size;
3497 if(check->bits.protoconnstart && check->bits.close)
3500 if(!check->bits.multiplex) {
3501 /* If not multiplexing, make sure the pipe has only GET requests */
3502 struct Curl_easy* sh = gethandleathead(check->send_pipe);
3503 struct Curl_easy* rh = gethandleathead(check->recv_pipe);
3505 if(!IsPipeliningPossible(sh, check))
3509 if(!IsPipeliningPossible(rh, check))
3516 /* can only happen within multi handles, and means that another easy
3517 handle is using this connection */
3521 if(Curl_resolver_asynch()) {
3522 /* ip_addr_str[0] is NUL only if the resolving of the name hasn't
3523 completed yet and until then we don't re-use this connection */
3524 if(!check->ip_addr_str[0]) {
3526 "Connection #%ld is still name resolving, can't reuse\n",
3527 check->connection_id);
3532 if((check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) ||
3533 check->bits.close) {
3534 if(!check->bits.close)
3535 foundPendingCandidate = TRUE;
3536 /* Don't pick a connection that hasn't connected yet or that is going
3538 infof(data, "Connection #%ld isn't open enough, can't reuse\n",
3539 check->connection_id);
3541 if(check->recv_pipe->size > 0) {
3543 "BAD! Unconnected #%ld has a non-empty recv pipeline!\n",
3544 check->connection_id);
3551 #ifdef USE_UNIX_SOCKETS
3552 if(needle->unix_domain_socket) {
3553 if(!check->unix_domain_socket)
3555 if(strcmp(needle->unix_domain_socket, check->unix_domain_socket))
3557 if(needle->abstract_unix_socket != check->abstract_unix_socket)
3560 else if(check->unix_domain_socket)
3564 if((needle->handler->flags&PROTOPT_SSL) !=
3565 (check->handler->flags&PROTOPT_SSL))
3566 /* don't do mixed SSL and non-SSL connections */
3567 if(get_protocol_family(check->handler->protocol) !=
3568 needle->handler->protocol || !check->tls_upgraded)
3569 /* except protocols that have been upgraded via TLS */
3572 if(needle->bits.httpproxy != check->bits.httpproxy ||
3573 needle->bits.socksproxy != check->bits.socksproxy)
3576 if(needle->bits.socksproxy && !proxy_info_matches(&needle->socks_proxy,
3577 &check->socks_proxy))
3580 if(needle->bits.conn_to_host != check->bits.conn_to_host)
3581 /* don't mix connections that use the "connect to host" feature and
3582 * connections that don't use this feature */
3585 if(needle->bits.conn_to_port != check->bits.conn_to_port)
3586 /* don't mix connections that use the "connect to port" feature and
3587 * connections that don't use this feature */
3590 if(needle->bits.httpproxy) {
3591 if(!proxy_info_matches(&needle->http_proxy, &check->http_proxy))
3594 if(needle->bits.tunnel_proxy != check->bits.tunnel_proxy)
3597 if(needle->http_proxy.proxytype == CURLPROXY_HTTPS) {
3598 /* use https proxy */
3599 if(needle->handler->flags&PROTOPT_SSL) {
3600 /* use double layer ssl */
3601 if(!Curl_ssl_config_matches(&needle->proxy_ssl_config,
3602 &check->proxy_ssl_config))
3604 if(check->proxy_ssl[FIRSTSOCKET].state != ssl_connection_complete)
3608 if(!Curl_ssl_config_matches(&needle->ssl_config,
3609 &check->ssl_config))
3611 if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete)
3617 if(!canPipeline && check->inuse)
3618 /* this request can't be pipelined but the checked connection is
3619 already in use so we skip it */
3622 if(needle->localdev || needle->localport) {
3623 /* If we are bound to a specific local end (IP+port), we must not
3624 re-use a random other one, although if we didn't ask for a
3625 particular one we can reuse one that was bound.
3627 This comparison is a bit rough and too strict. Since the input
3628 parameters can be specified in numerous ways and still end up the
3629 same it would take a lot of processing to make it really accurate.
3630 Instead, this matching will assume that re-uses of bound connections
3631 will most likely also re-use the exact same binding parameters and
3632 missing out a few edge cases shouldn't hurt anyone very much.
3634 if((check->localport != needle->localport) ||
3635 (check->localportrange != needle->localportrange) ||
3636 (needle->localdev &&
3637 (!check->localdev || strcmp(check->localdev, needle->localdev))))
3641 if(!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) {
3642 /* This protocol requires credentials per connection,
3643 so verify that we're using the same name and password as well */
3644 if(strcmp(needle->user, check->user) ||
3645 strcmp(needle->passwd, check->passwd)) {
3646 /* one of them was different */
3651 if(!needle->bits.httpproxy || (needle->handler->flags&PROTOPT_SSL) ||
3652 needle->bits.tunnel_proxy) {
3653 /* The requested connection does not use a HTTP proxy or it uses SSL or
3654 it is a non-SSL protocol tunneled or it is a non-SSL protocol which
3655 is allowed to be upgraded via TLS */
3657 if((strcasecompare(needle->handler->scheme, check->handler->scheme) ||
3658 (get_protocol_family(check->handler->protocol) ==
3659 needle->handler->protocol && check->tls_upgraded)) &&
3660 (!needle->bits.conn_to_host || strcasecompare(
3661 needle->conn_to_host.name, check->conn_to_host.name)) &&
3662 (!needle->bits.conn_to_port ||
3663 needle->conn_to_port == check->conn_to_port) &&
3664 strcasecompare(needle->host.name, check->host.name) &&
3665 needle->remote_port == check->remote_port) {
3666 /* The schemes match or the the protocol family is the same and the
3667 previous connection was TLS upgraded, and the hostname and host
3669 if(needle->handler->flags & PROTOPT_SSL) {
3670 /* This is a SSL connection so verify that we're using the same
3671 SSL options as well */
3672 if(!Curl_ssl_config_matches(&needle->ssl_config,
3673 &check->ssl_config)) {
3675 "Connection #%ld has different SSL parameters, "
3677 check->connection_id));
3680 else if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete) {
3681 foundPendingCandidate = TRUE;
3683 "Connection #%ld has not started SSL connect, "
3685 check->connection_id));
3693 /* The requested connection is using the same HTTP proxy in normal
3694 mode (no tunneling) */
3699 #if defined(USE_NTLM)
3700 /* If we are looking for an HTTP+NTLM connection, check if this is
3701 already authenticating with the right credentials. If not, keep
3702 looking so that we can reuse NTLM connections if
3703 possible. (Especially we must not reuse the same connection if
3704 partway through a handshake!) */
3706 if(strcmp(needle->user, check->user) ||
3707 strcmp(needle->passwd, check->passwd))
3710 else if(check->ntlm.state != NTLMSTATE_NONE) {
3711 /* Connection is using NTLM auth but we don't want NTLM */
3715 /* Same for Proxy NTLM authentication */
3716 if(wantProxyNTLMhttp) {
3717 /* Both check->http_proxy.user and check->http_proxy.passwd can be
3719 if(!check->http_proxy.user || !check->http_proxy.passwd)
3722 if(strcmp(needle->http_proxy.user, check->http_proxy.user) ||
3723 strcmp(needle->http_proxy.passwd, check->http_proxy.passwd))
3726 else if(check->proxyntlm.state != NTLMSTATE_NONE) {
3727 /* Proxy connection is using NTLM auth but we don't want NTLM */
3731 if(wantNTLMhttp || wantProxyNTLMhttp) {
3732 /* Credentials are already checked, we can use this connection */
3736 (check->ntlm.state != NTLMSTATE_NONE)) ||
3737 (wantProxyNTLMhttp &&
3738 (check->proxyntlm.state != NTLMSTATE_NONE))) {
3739 /* We must use this connection, no other */
3740 *force_reuse = TRUE;
3744 /* Continue look up for a better connection */
3749 /* We can pipeline if we want to. Let's continue looking for
3750 the optimal connection to use, i.e the shortest pipe that is not
3754 /* We have the optimal connection. Let's stop looking. */
3759 /* We can't use the connection if the pipe is full */
3760 if(max_pipe_len && (pipeLen >= max_pipe_len)) {
3761 infof(data, "Pipe is full, skip (%zu)\n", pipeLen);
3765 /* If multiplexed, make sure we don't go over concurrency limit */
3766 if(check->bits.multiplex) {
3767 /* Multiplexed connections can only be HTTP/2 for now */
3768 struct http_conn *httpc = &check->proto.httpc;
3769 if(pipeLen >= httpc->settings.max_concurrent_streams) {
3770 infof(data, "MAX_CONCURRENT_STREAMS reached, skip (%zu)\n",
3776 /* We can't use the connection if the pipe is penalized */
3777 if(Curl_pipeline_penalized(data, check)) {
3778 infof(data, "Penalized, skip\n");
3783 if(pipeLen < best_pipe_len) {
3784 /* This connection has a shorter pipe so far. We'll pick this
3785 and continue searching */
3787 best_pipe_len = pipeLen;
3792 /* When not pipelining (== multiplexed), we have a match here! */
3794 infof(data, "Multiplexed connection found!\n");
3799 /* We have found a connection. Let's stop searching. */
3809 return TRUE; /* yes, we found one to use! */
3812 if(foundPendingCandidate && data->set.pipewait) {
3814 "Found pending candidate for reuse and CURLOPT_PIPEWAIT is set\n");
3818 return FALSE; /* no matching connecting exists */
3821 /* after a TCP connection to the proxy has been verified, this function does
3822 the next magic step.
3824 Note: this function's sub-functions call failf()
3827 CURLcode Curl_connected_proxy(struct connectdata *conn, int sockindex)
3829 CURLcode result = CURLE_OK;
3831 if(conn->bits.socksproxy) {
3832 #ifndef CURL_DISABLE_PROXY
3833 /* for the secondary socket (FTP), use the "connect to host"
3834 * but ignore the "connect to port" (use the secondary port)
3836 const char * const host = conn->bits.httpproxy ?
3837 conn->http_proxy.host.name :
3838 conn->bits.conn_to_host ?
3839 conn->conn_to_host.name :
3840 sockindex == SECONDARYSOCKET ?
3841 conn->secondaryhostname : conn->host.name;
3842 const int port = conn->bits.httpproxy ? (int)conn->http_proxy.port :
3843 sockindex == SECONDARYSOCKET ? conn->secondary_port :
3844 conn->bits.conn_to_port ? conn->conn_to_port :
3846 conn->bits.socksproxy_connecting = TRUE;
3847 switch(conn->socks_proxy.proxytype) {
3848 case CURLPROXY_SOCKS5:
3849 case CURLPROXY_SOCKS5_HOSTNAME:
3850 result = Curl_SOCKS5(conn->socks_proxy.user, conn->socks_proxy.passwd,
3851 host, port, sockindex, conn);
3854 case CURLPROXY_SOCKS4:
3855 case CURLPROXY_SOCKS4A:
3856 result = Curl_SOCKS4(conn->socks_proxy.user, host, port, sockindex,
3861 failf(conn->data, "unknown proxytype option given");
3862 result = CURLE_COULDNT_CONNECT;
3863 } /* switch proxytype */
3864 conn->bits.socksproxy_connecting = FALSE;
3867 #endif /* CURL_DISABLE_PROXY */
3874 * verboseconnect() displays verbose information after a connect
3876 #ifndef CURL_DISABLE_VERBOSE_STRINGS
3877 void Curl_verboseconnect(struct connectdata *conn)
3879 if(conn->data->set.verbose)
3880 infof(conn->data, "Connected to %s (%s) port %ld (#%ld)\n",
3881 conn->bits.socksproxy ? conn->socks_proxy.host.dispname :
3882 conn->bits.httpproxy ? conn->http_proxy.host.dispname :
3883 conn->bits.conn_to_host ? conn->conn_to_host.dispname :
3884 conn->host.dispname,
3885 conn->ip_addr_str, conn->port, conn->connection_id);
3889 int Curl_protocol_getsock(struct connectdata *conn,
3890 curl_socket_t *socks,
3893 if(conn->handler->proto_getsock)
3894 return conn->handler->proto_getsock(conn, socks, numsocks);
3895 return GETSOCK_BLANK;
3898 int Curl_doing_getsock(struct connectdata *conn,
3899 curl_socket_t *socks,
3902 if(conn && conn->handler->doing_getsock)
3903 return conn->handler->doing_getsock(conn, socks, numsocks);
3904 return GETSOCK_BLANK;
3908 * We are doing protocol-specific connecting and this is being called over and
3909 * over from the multi interface until the connection phase is done on
3913 CURLcode Curl_protocol_connecting(struct connectdata *conn,
3916 CURLcode result=CURLE_OK;
3918 if(conn && conn->handler->connecting) {
3920 result = conn->handler->connecting(conn, done);
3929 * We are DOING this is being called over and over from the multi interface
3930 * until the DOING phase is done on protocol layer.
3933 CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done)
3935 CURLcode result=CURLE_OK;
3937 if(conn && conn->handler->doing) {
3939 result = conn->handler->doing(conn, done);
3948 * We have discovered that the TCP connection has been successful, we can now
3949 * proceed with some action.
3952 CURLcode Curl_protocol_connect(struct connectdata *conn,
3953 bool *protocol_done)
3955 CURLcode result=CURLE_OK;
3957 *protocol_done = FALSE;
3959 if(conn->bits.tcpconnect[FIRSTSOCKET] && conn->bits.protoconnstart) {
3960 /* We already are connected, get back. This may happen when the connect
3961 worked fine in the first call, like when we connect to a local server
3962 or proxy. Note that we don't know if the protocol is actually done.
3964 Unless this protocol doesn't have any protocol-connect callback, as
3965 then we know we're done. */
3966 if(!conn->handler->connecting)
3967 *protocol_done = TRUE;
3972 if(!conn->bits.protoconnstart) {
3974 result = Curl_proxy_connect(conn, FIRSTSOCKET);
3978 if(CONNECT_FIRSTSOCKET_PROXY_SSL())
3979 /* wait for HTTPS proxy SSL initialization to complete */
3982 if(conn->bits.tunnel_proxy && conn->bits.httpproxy &&
3983 (conn->tunnel_state[FIRSTSOCKET] != TUNNEL_COMPLETE))
3984 /* when using an HTTP tunnel proxy, await complete tunnel establishment
3985 before proceeding further. Return CURLE_OK so we'll be called again */
3988 if(conn->handler->connect_it) {
3989 /* is there a protocol-specific connect() procedure? */
3991 /* Call the protocol-specific connect function */
3992 result = conn->handler->connect_it(conn, protocol_done);
3995 *protocol_done = TRUE;
3997 /* it has started, possibly even completed but that knowledge isn't stored
4000 conn->bits.protoconnstart = TRUE;
4003 return result; /* pass back status */
4007 * Helpers for IDNA convertions.
4009 static bool is_ASCII_name(const char *hostname)
4011 const unsigned char *ch = (const unsigned char *)hostname;
4021 * Perform any necessary IDN conversion of hostname
4023 static void fix_hostname(struct connectdata *conn, struct hostname *host)
4026 struct Curl_easy *data = conn->data;
4031 #elif defined(CURL_DISABLE_VERBOSE_STRINGS)
4035 /* set the name we use to display the host name */
4036 host->dispname = host->name;
4038 len = strlen(host->name);
4039 if(len && (host->name[len-1] == '.'))
4040 /* strip off a single trailing dot if present, primarily for SNI but
4041 there's no use for it */
4042 host->name[len-1]=0;
4044 /* Check name for non-ASCII and convert hostname to ACE form if we can */
4045 if(!is_ASCII_name(host->name)) {
4047 if(idn2_check_version(IDN2_VERSION)) {
4048 char *ace_hostname = NULL;
4049 #if IDN2_VERSION_NUMBER >= 0x00140000
4050 /* IDN2_NFC_INPUT: Normalize input string using normalization form C.
4051 IDN2_NONTRANSITIONAL: Perform Unicode TR46 non-transitional
4053 int flags = IDN2_NFC_INPUT | IDN2_NONTRANSITIONAL;
4055 int flags = IDN2_NFC_INPUT;
4057 int rc = idn2_lookup_ul((const char *)host->name, &ace_hostname, flags);
4059 host->encalloc = (char *)ace_hostname;
4060 /* change the name pointer to point to the encoded hostname */
4061 host->name = host->encalloc;
4064 infof(data, "Failed to convert %s to ACE; %s\n", host->name,
4067 #elif defined(USE_WIN32_IDN)
4068 char *ace_hostname = NULL;
4070 if(curl_win32_idn_to_ascii(host->name, &ace_hostname)) {
4071 host->encalloc = ace_hostname;
4072 /* change the name pointer to point to the encoded hostname */
4073 host->name = host->encalloc;
4076 infof(data, "Failed to convert %s to ACE;\n", host->name);
4077 #elif defined(USE_GLIB2_HOSTNAME)
4078 gchar *ace_hostname = NULL;
4079 ace_hostname = g_hostname_to_ascii(host->name);
4081 host->encalloc = (char *)ace_hostname;
4082 host->name = host->encalloc;
4085 infof(data, "Failed to convert %s to ACE;\n", host->name);
4087 infof(data, "IDN support not present, can't parse Unicode domains\n");
4093 * Frees data allocated by fix_hostname()
4095 static void free_fixed_hostname(struct hostname *host)
4097 #if defined(USE_LIBIDN2)
4098 if(host->encalloc) {
4099 idn2_free(host->encalloc); /* must be freed with idn2_free() since this was
4100 allocated by libidn */
4101 host->encalloc = NULL;
4103 #elif defined(USE_WIN32_IDN)
4104 free(host->encalloc); /* must be freed withidn_free() since this was
4105 allocated by curl_win32_idn_to_ascii */
4106 host->encalloc = NULL;
4112 static void llist_dtor(void *user, void *element)
4120 * Allocate and initialize a new connectdata object.
4122 static struct connectdata *allocate_conn(struct Curl_easy *data)
4124 struct connectdata *conn = calloc(1, sizeof(struct connectdata));
4128 conn->handler = &Curl_handler_dummy; /* Be sure we have a handler defined
4129 already from start to avoid NULL
4130 situations and checks */
4132 /* and we setup a few fields in case we end up actually using this struct */
4134 conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
4135 conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
4136 conn->tempsock[0] = CURL_SOCKET_BAD; /* no file descriptor */
4137 conn->tempsock[1] = CURL_SOCKET_BAD; /* no file descriptor */
4138 conn->connection_id = -1; /* no ID */
4139 conn->port = -1; /* unknown at this point */
4140 conn->remote_port = -1; /* unknown at this point */
4141 #if defined(USE_RECV_BEFORE_SEND_WORKAROUND) && defined(DEBUGBUILD)
4142 conn->postponed[0].bindsock = CURL_SOCKET_BAD; /* no file descriptor */
4143 conn->postponed[1].bindsock = CURL_SOCKET_BAD; /* no file descriptor */
4144 #endif /* USE_RECV_BEFORE_SEND_WORKAROUND && DEBUGBUILD */
4146 /* Default protocol-independent behavior doesn't support persistent
4147 connections, so we set this to force-close. Protocols that support
4148 this need to set this to FALSE in their "curl_do" functions. */
4149 connclose(conn, "Default to force-close");
4151 /* Store creation time to help future close decision making */
4152 conn->created = Curl_tvnow();
4154 conn->data = data; /* Setup the association between this connection
4155 and the Curl_easy */
4157 conn->http_proxy.proxytype = data->set.proxytype;
4158 conn->socks_proxy.proxytype = CURLPROXY_SOCKS4;
4160 #ifdef CURL_DISABLE_PROXY
4162 conn->bits.proxy = FALSE;
4163 conn->bits.httpproxy = FALSE;
4164 conn->bits.socksproxy = FALSE;
4165 conn->bits.proxy_user_passwd = FALSE;
4166 conn->bits.tunnel_proxy = FALSE;
4168 #else /* CURL_DISABLE_PROXY */
4170 /* note that these two proxy bits are now just on what looks to be
4171 requested, they may be altered down the road */
4172 conn->bits.proxy = (data->set.str[STRING_PROXY] &&
4173 *data->set.str[STRING_PROXY]) ? TRUE : FALSE;
4174 conn->bits.httpproxy = (conn->bits.proxy &&
4175 (conn->http_proxy.proxytype == CURLPROXY_HTTP ||
4176 conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0 ||
4177 conn->http_proxy.proxytype == CURLPROXY_HTTPS)) ?
4179 conn->bits.socksproxy = (conn->bits.proxy &&
4180 !conn->bits.httpproxy) ? TRUE : FALSE;
4182 if(data->set.str[STRING_PRE_PROXY] && *data->set.str[STRING_PRE_PROXY]) {
4183 conn->bits.proxy = TRUE;
4184 conn->bits.socksproxy = TRUE;
4187 conn->bits.proxy_user_passwd =
4188 (data->set.str[STRING_PROXYUSERNAME]) ? TRUE : FALSE;
4189 conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy;
4191 #endif /* CURL_DISABLE_PROXY */
4193 conn->bits.user_passwd = (data->set.str[STRING_USERNAME]) ? TRUE : FALSE;
4194 conn->bits.ftp_use_epsv = data->set.ftp_use_epsv;
4195 conn->bits.ftp_use_eprt = data->set.ftp_use_eprt;
4197 conn->ssl_config.verifystatus = data->set.ssl.primary.verifystatus;
4198 conn->ssl_config.verifypeer = data->set.ssl.primary.verifypeer;
4199 conn->ssl_config.verifyhost = data->set.ssl.primary.verifyhost;
4200 conn->proxy_ssl_config.verifystatus =
4201 data->set.proxy_ssl.primary.verifystatus;
4202 conn->proxy_ssl_config.verifypeer = data->set.proxy_ssl.primary.verifypeer;
4203 conn->proxy_ssl_config.verifyhost = data->set.proxy_ssl.primary.verifyhost;
4205 conn->ip_version = data->set.ipver;
4207 #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
4208 defined(NTLM_WB_ENABLED)
4209 conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
4210 conn->ntlm_auth_hlpr_pid = 0;
4211 conn->challenge_header = NULL;
4212 conn->response_header = NULL;
4215 if(Curl_pipeline_wanted(data->multi, CURLPIPE_HTTP1) &&
4216 !conn->master_buffer) {
4217 /* Allocate master_buffer to be used for HTTP/1 pipelining */
4218 conn->master_buffer = calloc(BUFSIZE, sizeof(char));
4219 if(!conn->master_buffer)
4223 /* Initialize the pipeline lists */
4224 conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
4225 conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
4226 if(!conn->send_pipe || !conn->recv_pipe)
4230 conn->data_prot = PROT_CLEAR;
4233 /* Store the local bind parameters that will be used for this connection */
4234 if(data->set.str[STRING_DEVICE]) {
4235 conn->localdev = strdup(data->set.str[STRING_DEVICE]);
4239 conn->localportrange = data->set.localportrange;
4240 conn->localport = data->set.localport;
4242 /* the close socket stuff needs to be copied to the connection struct as
4243 it may live on without (this specific) Curl_easy */
4244 conn->fclosesocket = data->set.fclosesocket;
4245 conn->closesocket_client = data->set.closesocket_client;
4250 Curl_llist_destroy(conn->send_pipe, NULL);
4251 Curl_llist_destroy(conn->recv_pipe, NULL);
4253 conn->send_pipe = NULL;
4254 conn->recv_pipe = NULL;
4256 free(conn->master_buffer);
4257 free(conn->localdev);
4262 static CURLcode findprotocol(struct Curl_easy *data,
4263 struct connectdata *conn,
4264 const char *protostr)
4266 const struct Curl_handler * const *pp;
4267 const struct Curl_handler *p;
4269 /* Scan protocol handler table and match against 'protostr' to set a few
4270 variables based on the URL. Now that the handler may be changed later
4271 when the protocol specific setup function is called. */
4272 for(pp = protocols; (p = *pp) != NULL; pp++) {
4273 if(strcasecompare(p->scheme, protostr)) {
4274 /* Protocol found in table. Check if allowed */
4275 if(!(data->set.allowed_protocols & p->protocol))
4279 /* it is allowed for "normal" request, now do an extra check if this is
4280 the result of a redirect */
4281 if(data->state.this_is_a_follow &&
4282 !(data->set.redir_protocols & p->protocol))
4286 /* Perform setup complement if some. */
4287 conn->handler = conn->given = p;
4289 /* 'port' and 'remote_port' are set in setup_connection_internals() */
4295 /* The protocol was not found in the table, but we don't have to assign it
4296 to anything since it is already assigned to a dummy-struct in the
4297 create_conn() function when the connectdata struct is allocated. */
4298 failf(data, "Protocol \"%s\" not supported or disabled in " LIBCURL_NAME,
4301 return CURLE_UNSUPPORTED_PROTOCOL;
4305 * Parse URL and fill in the relevant members of the connection struct.
4307 static CURLcode parseurlandfillconn(struct Curl_easy *data,
4308 struct connectdata *conn,
4310 char **userp, char **passwdp,
4315 char *path = data->state.path;
4319 const char *protop = "";
4321 bool rebuild_url = FALSE;
4322 bool url_has_scheme = FALSE;
4325 *prot_missing = FALSE;
4327 /* We might pass the entire URL into the request so we need to make sure
4328 * there are no bad characters in there.*/
4329 if(strpbrk(data->change.url, "\r\n")) {
4330 failf(data, "Illegal characters found in URL");
4331 return CURLE_URL_MALFORMAT;
4334 /*************************************************************
4337 * We need to parse the url even when using the proxy, because we will need
4338 * the hostname and port in case we are trying to SSL connect through the
4339 * proxy -- and we don't know if we will need to use SSL until we parse the
4341 ************************************************************/
4342 if(data->change.url[0] == ':') {
4343 failf(data, "Bad URL, colon is first character");
4344 return CURLE_URL_MALFORMAT;
4347 /* Make sure we don't mistake a drive letter for a scheme, for example:
4348 curld --proto-default file c:/foo/bar.txt */
4349 if((('a' <= data->change.url[0] && data->change.url[0] <= 'z') ||
4350 ('A' <= data->change.url[0] && data->change.url[0] <= 'Z')) &&
4351 data->change.url[1] == ':' && data->set.str[STRING_DEFAULT_PROTOCOL] &&
4352 strcasecompare(data->set.str[STRING_DEFAULT_PROTOCOL], "file")) {
4355 else { /* check for a scheme */
4356 for(i = 0; i < 16 && data->change.url[i]; ++i) {
4357 if(data->change.url[i] == '/')
4359 if(data->change.url[i] == ':') {
4360 url_has_scheme = TRUE;
4366 /* handle the file: scheme */
4367 if((url_has_scheme && strncasecompare(data->change.url, "file:", 5)) ||
4368 (!url_has_scheme && data->set.str[STRING_DEFAULT_PROTOCOL] &&
4369 strcasecompare(data->set.str[STRING_DEFAULT_PROTOCOL], "file"))) {
4370 bool path_has_drive = FALSE;
4373 rc = sscanf(data->change.url, "%*15[^\n/:]:%[^\n]", path);
4375 rc = sscanf(data->change.url, "%[^\n]", path);
4378 failf(data, "Bad URL");
4379 return CURLE_URL_MALFORMAT;
4382 if(url_has_scheme && path[0] == '/' && path[1] == '/') {
4383 /* Allow omitted hostname (e.g. file:/<path>). This is not strictly
4384 * speaking a valid file: URL by RFC 1738, but treating file:/<path> as
4385 * file://localhost/<path> is similar to how other schemes treat missing
4386 * hostnames. See RFC 1808. */
4388 /* This cannot be done with strcpy() in a portable manner, since the
4389 memory areas overlap! */
4390 memmove(path, path + 2, strlen(path + 2)+1);
4393 /* the path may start with a drive letter. for backwards compatibility
4394 we skip some processing on those paths. */
4395 path_has_drive = (('a' <= path[0] && path[0] <= 'z') ||
4396 ('A' <= path[0] && path[0] <= 'Z')) && path[1] == ':';
4399 * we deal with file://<host>/<path> differently since it supports no
4400 * hostname other than "localhost" and "127.0.0.1", which is unique among
4401 * the URL protocols specified in RFC 1738
4403 if(path[0] != '/' && !path_has_drive) {
4404 /* the URL includes a host name, it must match "localhost" or
4405 "127.0.0.1" to be valid */
4407 if(!checkprefix("localhost/", path) &&
4408 !checkprefix("127.0.0.1/", path)) {
4409 failf(data, "Invalid file://hostname/, "
4410 "expected localhost or 127.0.0.1 or none");
4411 return CURLE_URL_MALFORMAT;
4413 ptr = &path[9]; /* now points to the slash after the host */
4415 /* there was a host name and slash present
4417 RFC1738 (section 3.1, page 5) says:
4419 The rest of the locator consists of data specific to the scheme,
4420 and is known as the "url-path". It supplies the details of how the
4421 specified resource can be accessed. Note that the "/" between the
4422 host (or port) and the url-path is NOT part of the url-path.
4424 As most agents use file://localhost/foo to get '/foo' although the
4425 slash preceding foo is a separator and not a slash for the path,
4426 a URL as file://localhost//foo must be valid as well, to refer to
4427 the same file with an absolute path.
4431 /* if there was two slashes, we skip the first one as that is then
4432 used truly as a separator */
4435 /* This cannot be made with strcpy, as the memory chunks overlap! */
4436 memmove(path, ptr, strlen(ptr)+1);
4438 path_has_drive = (('a' <= path[0] && path[0] <= 'z') ||
4439 ('A' <= path[0] && path[0] <= 'Z')) && path[1] == ':';
4442 #if !defined(MSDOS) && !defined(WIN32) && !defined(__CYGWIN__)
4443 if(path_has_drive) {
4444 failf(data, "File drive letters are only accepted in MSDOS/Windows.");
4445 return CURLE_URL_MALFORMAT;
4449 protop = "file"; /* protocol string */
4450 *prot_missing = !url_has_scheme;
4457 rc = sscanf(data->change.url,
4458 "%15[^\n/:]:%3[/]%[^\n/?#]%[^\n]",
4459 protobuf, slashbuf, conn->host.name, path);
4461 failf(data, "Bad URL");
4462 return CURLE_URL_MALFORMAT;
4467 * The URL was badly formatted, let's try the browser-style _without_
4468 * protocol specified like 'http://'.
4470 rc = sscanf(data->change.url, "%[^\n/?#]%[^\n]", conn->host.name, path);
4473 * We couldn't even get this format.
4474 * djgpp 2.04 has a sscanf() bug where 'conn->host.name' is
4475 * assigned, but the return value is EOF!
4477 #if defined(__DJGPP__) && (DJGPP_MINOR == 4)
4478 if(!(rc == -1 && *conn->host.name))
4481 failf(data, "<url> malformed");
4482 return CURLE_URL_MALFORMAT;
4487 * Since there was no protocol part specified in the URL use the
4488 * user-specified default protocol. If we weren't given a default make a
4489 * guess by matching some protocols against the host's outermost
4490 * sub-domain name. Finally if there was no match use HTTP.
4493 protop = data->set.str[STRING_DEFAULT_PROTOCOL];
4495 /* Note: if you add a new protocol, please update the list in
4496 * lib/version.c too! */
4497 if(checkprefix("FTP.", conn->host.name))
4499 else if(checkprefix("DICT.", conn->host.name))
4501 else if(checkprefix("LDAP.", conn->host.name))
4503 else if(checkprefix("IMAP.", conn->host.name))
4505 else if(checkprefix("SMTP.", conn->host.name))
4507 else if(checkprefix("POP3.", conn->host.name))
4513 *prot_missing = TRUE; /* not given in URL */
4516 size_t s = strlen(slashbuf);
4519 infof(data, "Unwillingly accepted illegal URL using %d slash%s!\n",
4522 if(data->change.url_alloc)
4523 free(data->change.url);
4524 /* repair the URL to use two slashes */
4525 data->change.url = aprintf("%s://%s%s",
4526 protobuf, conn->host.name, path);
4527 if(!data->change.url)
4528 return CURLE_OUT_OF_MEMORY;
4529 data->change.url_alloc = TRUE;
4534 /* We search for '?' in the host name (but only on the right side of a
4535 * @-letter to allow ?-letters in username and password) to handle things
4536 * like http://example.com?param= (notice the missing '/').
4538 at = strchr(conn->host.name, '@');
4540 query = strchr(at+1, '?');
4542 query = strchr(conn->host.name, '?');
4545 /* We must insert a slash before the '?'-letter in the URL. If the URL had
4546 a slash after the '?', that is where the path currently begins and the
4547 '?string' is still part of the host name.
4549 We must move the trailing part from the host name and put it first in
4550 the path. And have it all prefixed with a slash.
4553 size_t hostlen = strlen(query);
4554 size_t pathlen = strlen(path);
4556 /* move the existing path plus the zero byte forward, to make room for
4557 the host-name part */
4558 memmove(path+hostlen+1, path, pathlen+1);
4560 /* now copy the trailing host part in front of the existing path */
4561 memcpy(path+1, query, hostlen);
4563 path[0]='/'; /* prepend the missing slash */
4566 *query=0; /* now cut off the hostname at the ? */
4569 /* if there's no path set, use a single slash */
4574 /* If the URL is malformatted (missing a '/' after hostname before path) we
4575 * insert a slash here. The only letters except '/' that can start a path is
4576 * '?' and '#' - as controlled by the two sscanf() patterns above.
4578 if(path[0] != '/') {
4579 /* We need this function to deal with overlapping memory areas. We know
4580 that the memory area 'path' points to is 'urllen' bytes big and that
4581 is bigger than the path. Use +1 to move the zero byte too. */
4582 memmove(&path[1], path, strlen(path)+1);
4586 else if(!data->set.path_as_is) {
4587 /* sanitise paths and remove ../ and ./ sequences according to RFC3986 */
4588 char *newp = Curl_dedotdotify(path);
4590 return CURLE_OUT_OF_MEMORY;
4592 if(strcmp(newp, path)) {
4594 free(data->state.pathbuffer);
4595 data->state.pathbuffer = newp;
4596 data->state.path = newp;
4604 * "rebuild_url" means that one or more URL components have been modified so
4605 * we need to generate an updated full version. We need the corrected URL
4606 * when communicating over HTTP proxy and we don't know at this point if
4607 * we're using a proxy or not.
4612 size_t plen = strlen(path); /* new path, should be 1 byte longer than
4614 size_t prefixlen = strlen(conn->host.name);
4616 if(!*prot_missing) {
4617 size_t protolen = strlen(protop);
4619 if(curl_strnequal(protop, data->change.url, protolen))
4620 prefixlen += protolen;
4622 failf(data, "<url> malformed");
4623 return CURLE_URL_MALFORMAT;
4626 if(curl_strnequal("://", &data->change.url[protolen], 3))
4628 /* only file: is allowed to omit one or both slashes */
4629 else if(curl_strnequal("file:", data->change.url, 5))
4630 prefixlen += 1 + (data->change.url[5] == '/');
4632 failf(data, "<url> malformed");
4633 return CURLE_URL_MALFORMAT;
4637 reurl = malloc(prefixlen + plen + 1);
4639 return CURLE_OUT_OF_MEMORY;
4641 /* copy the prefix */
4642 memcpy(reurl, data->change.url, prefixlen);
4644 /* append the trailing piece + zerobyte */
4645 memcpy(&reurl[prefixlen], path, plen + 1);
4647 /* possible free the old one */
4648 if(data->change.url_alloc) {
4649 Curl_safefree(data->change.url);
4650 data->change.url_alloc = FALSE;
4653 infof(data, "Rebuilt URL to: %s\n", reurl);
4655 data->change.url = reurl;
4656 data->change.url_alloc = TRUE; /* free this later */
4659 result = findprotocol(data, conn, protop);
4664 * Parse the login details from the URL and strip them out of
4667 result = parse_url_login(data, conn, userp, passwdp, optionsp);
4671 if(conn->host.name[0] == '[') {
4672 /* This looks like an IPv6 address literal. See if there is an address
4673 scope if there is no location header */
4674 char *percent = strchr(conn->host.name, '%');
4676 unsigned int identifier_offset = 3;
4678 unsigned long scope;
4679 if(strncmp("%25", percent, 3) != 0) {
4681 "Please URL encode %% as %%25, see RFC 6874.\n");
4682 identifier_offset = 1;
4684 scope = strtoul(percent + identifier_offset, &endp, 10);
4686 /* The address scope was well formed. Knock it out of the
4688 memmove(percent, endp, strlen(endp)+1);
4689 conn->scope_id = (unsigned int)scope;
4692 /* Zone identifier is not numeric */
4693 #if defined(HAVE_NET_IF_H) && defined(IFNAMSIZ) && defined(HAVE_IF_NAMETOINDEX)
4694 char ifname[IFNAMSIZ + 2];
4695 char *square_bracket;
4696 unsigned int scopeidx = 0;
4697 strncpy(ifname, percent + identifier_offset, IFNAMSIZ + 2);
4698 /* Ensure nullbyte termination */
4699 ifname[IFNAMSIZ + 1] = '\0';
4700 square_bracket = strchr(ifname, ']');
4701 if(square_bracket) {
4703 *square_bracket = '\0';
4704 scopeidx = if_nametoindex(ifname);
4706 infof(data, "Invalid network interface: %s; %s\n", ifname,
4711 char *p = percent + identifier_offset + strlen(ifname);
4713 /* Remove zone identifier from hostname */
4714 memmove(percent, p, strlen(p) + 1);
4715 conn->scope_id = scopeidx;
4718 #endif /* HAVE_NET_IF_H && IFNAMSIZ */
4719 infof(data, "Invalid IPv6 address format\n");
4724 if(data->set.scope_id)
4725 /* Override any scope that was set above. */
4726 conn->scope_id = data->set.scope_id;
4728 /* Remove the fragment part of the path. Per RFC 2396, this is always the
4729 last part of the URI. We are looking for the first '#' so that we deal
4730 gracefully with non conformant URI such as http://example.com#foo#bar. */
4731 fragment = strchr(path, '#');
4735 /* we know the path part ended with a fragment, so we know the full URL
4736 string does too and we need to cut it off from there so it isn't used
4738 fragment = strchr(data->change.url, '#');
4744 * So if the URL was A://B/C#D,
4746 * conn->host.name is B
4747 * data->state.path is /C
4753 * If we're doing a resumed transfer, we need to setup our stuff
4756 static CURLcode setup_range(struct Curl_easy *data)
4758 struct UrlState *s = &data->state;
4759 s->resume_from = data->set.set_resume_from;
4760 if(s->resume_from || data->set.str[STRING_SET_RANGE]) {
4761 if(s->rangestringalloc)
4765 s->range = aprintf("%" CURL_FORMAT_CURL_OFF_TU "-", s->resume_from);
4767 s->range = strdup(data->set.str[STRING_SET_RANGE]);
4769 s->rangestringalloc = (s->range) ? TRUE : FALSE;
4772 return CURLE_OUT_OF_MEMORY;
4774 /* tell ourselves to fetch this range */
4775 s->use_range = TRUE; /* enable range download */
4778 s->use_range = FALSE; /* disable range download */
4785 * setup_connection_internals() -
4787 * Setup connection internals specific to the requested protocol in the
4788 * Curl_easy. This is inited and setup before the connection is made but
4789 * is about the particular protocol that is to be used.
4791 * This MUST get called after proxy magic has been figured out.
4793 static CURLcode setup_connection_internals(struct connectdata *conn)
4795 const struct Curl_handler * p;
4797 struct Curl_easy *data = conn->data;
4799 /* in some case in the multi state-machine, we go back to the CONNECT state
4800 and then a second (or third or...) call to this function will be made
4801 without doing a DISCONNECT or DONE in between (since the connection is
4802 yet in place) and therefore this function needs to first make sure
4803 there's no lingering previous data allocated. */
4804 Curl_free_request_state(data);
4806 memset(&data->req, 0, sizeof(struct SingleRequest));
4807 data->req.maxdownload = -1;
4809 conn->socktype = SOCK_STREAM; /* most of them are TCP streams */
4811 /* Perform setup complement if some. */
4814 if(p->setup_connection) {
4815 result = (*p->setup_connection)(conn);
4820 p = conn->handler; /* May have changed. */
4824 /* we check for -1 here since if proxy was detected already, this
4825 was very likely already set to the proxy port */
4826 conn->port = p->defport;
4832 * Curl_free_request_state() should free temp data that was allocated in the
4833 * Curl_easy for this single request.
4836 void Curl_free_request_state(struct Curl_easy *data)
4838 Curl_safefree(data->req.protop);
4839 Curl_safefree(data->req.newurl);
4843 #ifndef CURL_DISABLE_PROXY
4844 /****************************************************************
4845 * Checks if the host is in the noproxy list. returns true if it matches
4846 * and therefore the proxy should NOT be used.
4847 ****************************************************************/
4848 static bool check_noproxy(const char *name, const char *no_proxy)
4850 /* no_proxy=domain1.dom,host.domain2.dom
4851 * (a comma-separated list of hosts which should
4852 * not be proxied, or an asterisk to override
4853 * all proxy variables)
4857 const char *separator = ", ";
4858 size_t no_proxy_len;
4862 if(no_proxy && no_proxy[0]) {
4863 if(strcasecompare("*", no_proxy)) {
4867 /* NO_PROXY was specified and it wasn't just an asterisk */
4869 no_proxy_len = strlen(no_proxy);
4870 endptr = strchr(name, ':');
4872 namelen = endptr - name;
4874 namelen = strlen(name);
4876 for(tok_start = 0; tok_start < no_proxy_len; tok_start = tok_end + 1) {
4877 while(tok_start < no_proxy_len &&
4878 strchr(separator, no_proxy[tok_start]) != NULL) {
4879 /* Look for the beginning of the token. */
4883 if(tok_start == no_proxy_len)
4884 break; /* It was all trailing separator chars, no more tokens. */
4886 for(tok_end = tok_start; tok_end < no_proxy_len &&
4887 strchr(separator, no_proxy[tok_end]) == NULL; ++tok_end)
4888 /* Look for the end of the token. */
4891 /* To match previous behaviour, where it was necessary to specify
4892 * ".local.com" to prevent matching "notlocal.com", we will leave
4895 if(no_proxy[tok_start] == '.')
4898 if((tok_end - tok_start) <= namelen) {
4899 /* Match the last part of the name to the domain we are checking. */
4900 const char *checkn = name + namelen - (tok_end - tok_start);
4901 if(strncasecompare(no_proxy + tok_start, checkn,
4902 tok_end - tok_start)) {
4903 if((tok_end - tok_start) == namelen || *(checkn - 1) == '.') {
4904 /* We either have an exact match, or the previous character is a .
4905 * so it is within the same domain, so no proxy for this host.
4910 } /* if((tok_end - tok_start) <= namelen) */
4911 } /* for(tok_start = 0; tok_start < no_proxy_len;
4912 tok_start = tok_end + 1) */
4913 } /* NO_PROXY was specified and it wasn't just an asterisk */
4918 /****************************************************************
4919 * Detect what (if any) proxy to use. Remember that this selects a host
4920 * name and is not limited to HTTP proxies only.
4921 * The returned pointer must be freed by the caller (unless NULL)
4922 ****************************************************************/
4923 static char *detect_proxy(struct connectdata *conn)
4927 /* If proxy was not specified, we check for default proxy environment
4928 * variables, to enable i.e Lynx compliance:
4930 * http_proxy=http://some.server.dom:port/
4931 * https_proxy=http://some.server.dom:port/
4932 * ftp_proxy=http://some.server.dom:port/
4933 * no_proxy=domain1.dom,host.domain2.dom
4934 * (a comma-separated list of hosts which should
4935 * not be proxied, or an asterisk to override
4936 * all proxy variables)
4937 * all_proxy=http://some.server.dom:port/
4938 * (seems to exist for the CERN www lib. Probably
4939 * the first to check for.)
4941 * For compatibility, the all-uppercase versions of these variables are
4942 * checked if the lowercase versions don't exist.
4944 char proxy_env[128];
4945 const char *protop = conn->handler->scheme;
4946 char *envp = proxy_env;
4949 /* Now, build <protocol>_proxy and check for such a one to use */
4951 *envp++ = (char)tolower((int)*protop++);
4954 strcpy(envp, "_proxy");
4956 /* read the protocol proxy: */
4957 prox=curl_getenv(proxy_env);
4960 * We don't try the uppercase version of HTTP_PROXY because of
4963 * When curl is used in a webserver application
4964 * environment (cgi or php), this environment variable can
4965 * be controlled by the web server user by setting the
4966 * http header 'Proxy:' to some value.
4968 * This can cause 'internal' http/ftp requests to be
4969 * arbitrarily redirected by any external attacker.
4971 if(!prox && !strcasecompare("http_proxy", proxy_env)) {
4972 /* There was no lowercase variable, try the uppercase version: */
4973 Curl_strntoupper(proxy_env, proxy_env, sizeof(proxy_env));
4974 prox=curl_getenv(proxy_env);
4978 proxy = prox; /* use this */
4980 proxy = curl_getenv("all_proxy"); /* default proxy to use */
4982 proxy=curl_getenv("ALL_PROXY");
4989 * If this is supposed to use a proxy, we need to figure out the proxy
4990 * host name, so that we can re-use an existing connection
4991 * that may exist registered to the same proxy host.
4993 static CURLcode parse_proxy(struct Curl_easy *data,
4994 struct connectdata *conn, char *proxy,
4995 curl_proxytype proxytype)
5000 /* We use 'proxyptr' to point to the proxy name from now on... */
5005 char *proxyuser = NULL;
5006 char *proxypasswd = NULL;
5009 /* We do the proxy host string parsing here. We want the host name and the
5010 * port name. Accept a protocol:// prefix
5013 /* Parse the protocol part if present */
5014 endofprot = strstr(proxy, "://");
5016 proxyptr = endofprot+3;
5017 if(checkprefix("https", proxy))
5018 proxytype = CURLPROXY_HTTPS;
5019 else if(checkprefix("socks5h", proxy))
5020 proxytype = CURLPROXY_SOCKS5_HOSTNAME;
5021 else if(checkprefix("socks5", proxy))
5022 proxytype = CURLPROXY_SOCKS5;
5023 else if(checkprefix("socks4a", proxy))
5024 proxytype = CURLPROXY_SOCKS4A;
5025 else if(checkprefix("socks4", proxy) || checkprefix("socks", proxy))
5026 proxytype = CURLPROXY_SOCKS4;
5027 else if(checkprefix("http:", proxy))
5028 ; /* leave it as HTTP or HTTP/1.0 */
5030 /* Any other xxx:// reject! */
5031 failf(data, "Unsupported proxy scheme for \'%s\'", proxy);
5032 return CURLE_COULDNT_CONNECT;
5036 proxyptr = proxy; /* No xxx:// head: It's a HTTP proxy */
5038 #ifndef HTTPS_PROXY_SUPPORT
5039 if(proxytype == CURLPROXY_HTTPS) {
5040 failf(data, "Unsupported proxy \'%s\'"
5041 ", libcurl is built without the HTTPS-proxy support.", proxy);
5042 return CURLE_NOT_BUILT_IN;
5046 sockstype = proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
5047 proxytype == CURLPROXY_SOCKS5 ||
5048 proxytype == CURLPROXY_SOCKS4A ||
5049 proxytype == CURLPROXY_SOCKS4;
5051 /* Is there a username and password given in this proxy url? */
5052 atsign = strchr(proxyptr, '@');
5055 parse_login_details(proxyptr, atsign - proxyptr,
5056 &proxyuser, &proxypasswd, NULL);
5059 proxyptr = atsign + 1;
5062 /* start scanning for port number at this point */
5065 /* detect and extract RFC6874-style IPv6-addresses */
5066 if(*proxyptr == '[') {
5067 char *ptr = ++proxyptr; /* advance beyond the initial bracket */
5068 while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '.')))
5071 /* There might be a zone identifier */
5072 if(strncmp("%25", ptr, 3))
5073 infof(data, "Please URL encode %% as %%25, see RFC 6874.\n");
5075 /* Allow unreserved characters as defined in RFC 3986 */
5076 while(*ptr && (ISALPHA(*ptr) || ISXDIGIT(*ptr) || (*ptr == '-') ||
5077 (*ptr == '.') || (*ptr == '_') || (*ptr == '~')))
5081 /* yeps, it ended nicely with a bracket as well */
5084 infof(data, "Invalid IPv6 address format\n");
5086 /* Note that if this didn't end with a bracket, we still advanced the
5087 * proxyptr first, but I can't see anything wrong with that as no host
5088 * name nor a numeric can legally start with a bracket.
5092 /* Get port number off proxy.server.com:1080 */
5093 prox_portno = strchr(portptr, ':');
5097 *prox_portno = 0x0; /* cut off number from host name */
5099 /* now set the local port number */
5100 port = strtol(prox_portno, &endp, 10);
5101 if((endp && *endp && (*endp != '/') && (*endp != ' ')) ||
5102 (port < 0) || (port > 65535)) {
5103 /* meant to detect for example invalid IPv6 numerical addresses without
5104 brackets: "2a00:fac0:a000::7:13". Accept a trailing slash only
5105 because we then allow "URL style" with the number followed by a
5106 slash, used in curl test cases already. Space is also an acceptable
5107 terminating symbol. */
5108 infof(data, "No valid port number in proxy string (%s)\n",
5115 if(proxyptr[0]=='/')
5116 /* If the first character in the proxy string is a slash, fail
5117 immediately. The following code will otherwise clear the string which
5118 will lead to code running as if no proxy was set! */
5119 return CURLE_COULDNT_RESOLVE_PROXY;
5121 /* without a port number after the host name, some people seem to use
5122 a slash so we strip everything from the first slash */
5123 atsign = strchr(proxyptr, '/');
5125 *atsign = '\0'; /* cut off path part from host name */
5127 if(data->set.proxyport)
5128 /* None given in the proxy string, then get the default one if it is
5130 port = data->set.proxyport;
5132 if(proxytype == CURLPROXY_HTTPS)
5133 port = CURL_DEFAULT_HTTPS_PROXY_PORT;
5135 port = CURL_DEFAULT_PROXY_PORT;
5140 struct proxy_info *proxyinfo =
5141 sockstype ? &conn->socks_proxy : &conn->http_proxy;
5142 proxyinfo->proxytype = proxytype;
5145 /* found user and password, rip them out. note that we are unescaping
5146 them, as there is otherwise no way to have a username or password
5147 with reserved characters like ':' in them. */
5148 Curl_safefree(proxyinfo->user);
5149 proxyinfo->user = curl_easy_unescape(data, proxyuser, 0, NULL);
5151 if(!proxyinfo->user)
5152 return CURLE_OUT_OF_MEMORY;
5154 Curl_safefree(proxyinfo->passwd);
5155 if(proxypasswd && strlen(proxypasswd) < MAX_CURL_PASSWORD_LENGTH)
5156 proxyinfo->passwd = curl_easy_unescape(data, proxypasswd, 0, NULL);
5158 proxyinfo->passwd = strdup("");
5160 if(!proxyinfo->passwd)
5161 return CURLE_OUT_OF_MEMORY;
5163 conn->bits.proxy_user_passwd = TRUE; /* enable it */
5167 proxyinfo->port = port;
5168 if(conn->port < 0 || sockstype || !conn->socks_proxy.host.rawalloc)
5172 /* now, clone the cleaned proxy host name */
5173 Curl_safefree(proxyinfo->host.rawalloc);
5174 proxyinfo->host.rawalloc = strdup(proxyptr);
5175 proxyinfo->host.name = proxyinfo->host.rawalloc;
5177 if(!proxyinfo->host.rawalloc)
5178 return CURLE_OUT_OF_MEMORY;
5181 Curl_safefree(proxyuser);
5182 Curl_safefree(proxypasswd);
5188 * Extract the user and password from the authentication string
5190 static CURLcode parse_proxy_auth(struct Curl_easy *data,
5191 struct connectdata *conn)
5193 char proxyuser[MAX_CURL_USER_LENGTH]="";
5194 char proxypasswd[MAX_CURL_PASSWORD_LENGTH]="";
5197 if(data->set.str[STRING_PROXYUSERNAME] != NULL) {
5198 strncpy(proxyuser, data->set.str[STRING_PROXYUSERNAME],
5199 MAX_CURL_USER_LENGTH);
5200 proxyuser[MAX_CURL_USER_LENGTH-1] = '\0'; /*To be on safe side*/
5202 if(data->set.str[STRING_PROXYPASSWORD] != NULL) {
5203 strncpy(proxypasswd, data->set.str[STRING_PROXYPASSWORD],
5204 MAX_CURL_PASSWORD_LENGTH);
5205 proxypasswd[MAX_CURL_PASSWORD_LENGTH-1] = '\0'; /*To be on safe side*/
5208 result = Curl_urldecode(data, proxyuser, 0, &conn->http_proxy.user, NULL,
5211 result = Curl_urldecode(data, proxypasswd, 0, &conn->http_proxy.passwd,
5215 #endif /* CURL_DISABLE_PROXY */
5220 * Parse the login details (user name, password and options) from the URL and
5221 * strip them out of the host name
5223 * Inputs: data->set.use_netrc (CURLOPT_NETRC)
5226 * Outputs: (almost :- all currently undefined)
5227 * conn->bits.user_passwd - non-zero if non-default passwords exist
5228 * user - non-zero length if defined
5229 * passwd - non-zero length if defined
5230 * options - non-zero length if defined
5231 * conn->host.name - remove user name and password
5233 static CURLcode parse_url_login(struct Curl_easy *data,
5234 struct connectdata *conn,
5235 char **user, char **passwd, char **options)
5237 CURLcode result = CURLE_OK;
5239 char *passwdp = NULL;
5240 char *optionsp = NULL;
5242 /* At this point, we're hoping all the other special cases have
5243 * been taken care of, so conn->host.name is at most
5244 * [user[:password][;options]]@]hostname
5246 * We need somewhere to put the embedded details, so do that first.
5249 char *ptr = strchr(conn->host.name, '@');
5250 char *login = conn->host.name;
5252 DEBUGASSERT(!**user);
5253 DEBUGASSERT(!**passwd);
5254 DEBUGASSERT(!**options);
5255 DEBUGASSERT(conn->handler);
5260 /* We will now try to extract the
5261 * possible login information in a string like:
5262 * ftp://user:password@ftp.my.site:8021/README */
5263 conn->host.name = ++ptr;
5265 /* So the hostname is sane. Only bother interpreting the
5266 * results if we could care. It could still be wasted
5267 * work because it might be overtaken by the programmatically
5268 * set user/passwd, but doing that first adds more cases here :-(
5271 if(data->set.use_netrc == CURL_NETRC_REQUIRED)
5274 /* We could use the login information in the URL so extract it. Only parse
5275 options if the handler says we should. */
5276 result = parse_login_details(login, ptr - login - 1,
5278 (conn->handler->flags & PROTOPT_URLOPTIONS)?
5286 /* We have a user in the URL */
5287 conn->bits.userpwd_in_url = TRUE;
5288 conn->bits.user_passwd = TRUE; /* enable user+password */
5290 /* Decode the user */
5291 result = Curl_urldecode(data, userp, 0, &newname, NULL, FALSE);
5301 /* We have a password in the URL so decode it */
5303 result = Curl_urldecode(data, passwdp, 0, &newpasswd, NULL, FALSE);
5309 *passwd = newpasswd;
5313 /* We have an options list in the URL so decode it */
5315 result = Curl_urldecode(data, optionsp, 0, &newoptions, NULL, FALSE);
5321 *options = newoptions;
5335 * parse_login_details()
5337 * This is used to parse a login string for user name, password and options in
5338 * the following formats:
5342 * user:password;options
5344 * user;options:password
5352 * login [in] - The login string.
5353 * len [in] - The length of the login string.
5354 * userp [in/out] - The address where a pointer to newly allocated memory
5355 * holding the user will be stored upon completion.
5356 * passdwp [in/out] - The address where a pointer to newly allocated memory
5357 * holding the password will be stored upon completion.
5358 * optionsp [in/out] - The address where a pointer to newly allocated memory
5359 * holding the options will be stored upon completion.
5361 * Returns CURLE_OK on success.
5363 static CURLcode parse_login_details(const char *login, const size_t len,
5364 char **userp, char **passwdp,
5367 CURLcode result = CURLE_OK;
5371 const char *psep = NULL;
5372 const char *osep = NULL;
5377 /* Attempt to find the password separator */
5379 psep = strchr(login, ':');
5381 /* Within the constraint of the login string */
5382 if(psep >= login + len)
5386 /* Attempt to find the options separator */
5388 osep = strchr(login, ';');
5390 /* Within the constraint of the login string */
5391 if(osep >= login + len)
5395 /* Calculate the portion lengths */
5397 (size_t)(osep && psep > osep ? osep - login : psep - login) :
5398 (osep ? (size_t)(osep - login) : len));
5400 (osep && osep > psep ? (size_t)(osep - psep) :
5401 (size_t)(login + len - psep)) - 1 : 0);
5403 (psep && psep > osep ? (size_t)(psep - osep) :
5404 (size_t)(login + len - osep)) - 1 : 0);
5406 /* Allocate the user portion buffer */
5408 ubuf = malloc(ulen + 1);
5410 result = CURLE_OUT_OF_MEMORY;
5413 /* Allocate the password portion buffer */
5414 if(!result && passwdp && plen) {
5415 pbuf = malloc(plen + 1);
5418 result = CURLE_OUT_OF_MEMORY;
5422 /* Allocate the options portion buffer */
5423 if(!result && optionsp && olen) {
5424 obuf = malloc(olen + 1);
5428 result = CURLE_OUT_OF_MEMORY;
5433 /* Store the user portion if necessary */
5435 memcpy(ubuf, login, ulen);
5437 Curl_safefree(*userp);
5441 /* Store the password portion if necessary */
5443 memcpy(pbuf, psep + 1, plen);
5445 Curl_safefree(*passwdp);
5449 /* Store the options portion if necessary */
5451 memcpy(obuf, osep + 1, olen);
5453 Curl_safefree(*optionsp);
5461 /*************************************************************
5462 * Figure out the remote port number and fix it in the URL
5464 * No matter if we use a proxy or not, we have to figure out the remote
5465 * port number of various reasons.
5467 * To be able to detect port number flawlessly, we must not confuse them
5468 * IPv6-specified addresses in the [0::1] style. (RFC2732)
5470 * The conn->host.name is currently [user:passwd@]host[:port] where host
5471 * could be a hostname, IPv4 address or IPv6 address.
5473 * The port number embedded in the URL is replaced, if necessary.
5474 *************************************************************/
5475 static CURLcode parse_remote_port(struct Curl_easy *data,
5476 struct connectdata *conn)
5481 /* Note that at this point, the IPv6 address cannot contain any scope
5482 suffix as that has already been removed in the parseurlandfillconn()
5484 if((1 == sscanf(conn->host.name, "[%*45[0123456789abcdefABCDEF:.]%c",
5486 (']' == endbracket)) {
5487 /* this is a RFC2732-style specified IP-address */
5488 conn->bits.ipv6_ip = TRUE;
5490 conn->host.name++; /* skip over the starting bracket */
5491 portptr = strchr(conn->host.name, ']');
5493 *portptr++ = '\0'; /* zero terminate, killing the bracket */
5495 portptr = NULL; /* no port number available */
5500 struct in6_addr in6;
5501 if(Curl_inet_pton(AF_INET6, conn->host.name, &in6) > 0) {
5502 /* This is a numerical IPv6 address, meaning this is a wrongly formatted
5504 failf(data, "IPv6 numerical address used in URL without brackets");
5505 return CURLE_URL_MALFORMAT;
5509 portptr = strrchr(conn->host.name, ':');
5512 if(data->set.use_port && data->state.allow_port) {
5513 /* if set, we use this and ignore the port possibly given in the URL */
5514 conn->remote_port = (unsigned short)data->set.use_port;
5516 *portptr = '\0'; /* cut off the name there anyway - if there was a port
5517 number - since the port number is to be ignored! */
5518 if(conn->bits.httpproxy) {
5519 /* we need to create new URL with the new port number */
5523 if(conn->bits.type_set)
5524 snprintf(type, sizeof(type), ";type=%c",
5525 data->set.prefer_ascii?'A':
5526 (data->set.ftp_list_only?'D':'I'));
5529 * This synthesized URL isn't always right--suffixes like ;type=A are
5530 * stripped off. It would be better to work directly from the original
5531 * URL and simply replace the port part of it.
5533 url = aprintf("%s://%s%s%s:%hu%s%s%s", conn->given->scheme,
5534 conn->bits.ipv6_ip?"[":"", conn->host.name,
5535 conn->bits.ipv6_ip?"]":"", conn->remote_port,
5536 data->state.slash_removed?"/":"", data->state.path,
5539 return CURLE_OUT_OF_MEMORY;
5541 if(data->change.url_alloc) {
5542 Curl_safefree(data->change.url);
5543 data->change.url_alloc = FALSE;
5546 data->change.url = url;
5547 data->change.url_alloc = TRUE;
5551 /* no CURLOPT_PORT given, extract the one from the URL */
5556 port=strtol(portptr+1, &rest, 10); /* Port number must be decimal */
5558 if((port < 0) || (port > 0xffff)) {
5559 /* Single unix standard says port numbers are 16 bits long */
5560 failf(data, "Port number out of range");
5561 return CURLE_URL_MALFORMAT;
5564 else if(rest != &portptr[1]) {
5565 *portptr = '\0'; /* cut off the name there */
5566 conn->remote_port = curlx_ultous(port);
5570 failf(data, "Illegal port number");
5571 return CURLE_URL_MALFORMAT;
5573 /* Browser behavior adaptation. If there's a colon with no digits after,
5574 just cut off the name there which makes us ignore the colon and just
5575 use the default port. Firefox and Chrome both do that. */
5580 /* only if remote_port was not already parsed off the URL we use the
5581 default port number */
5582 if(conn->remote_port < 0)
5583 conn->remote_port = (unsigned short)conn->given->defport;
5589 * Override the login details from the URL with that in the CURLOPT_USERPWD
5590 * option or a .netrc file, if applicable.
5592 static CURLcode override_login(struct Curl_easy *data,
5593 struct connectdata *conn,
5594 char **userp, char **passwdp, char **optionsp)
5596 if(data->set.str[STRING_USERNAME]) {
5598 *userp = strdup(data->set.str[STRING_USERNAME]);
5600 return CURLE_OUT_OF_MEMORY;
5603 if(data->set.str[STRING_PASSWORD]) {
5605 *passwdp = strdup(data->set.str[STRING_PASSWORD]);
5607 return CURLE_OUT_OF_MEMORY;
5610 if(data->set.str[STRING_OPTIONS]) {
5612 *optionsp = strdup(data->set.str[STRING_OPTIONS]);
5614 return CURLE_OUT_OF_MEMORY;
5617 conn->bits.netrc = FALSE;
5618 if(data->set.use_netrc != CURL_NETRC_IGNORED) {
5619 int ret = Curl_parsenetrc(conn->host.name,
5621 data->set.str[STRING_NETRC_FILE]);
5623 infof(data, "Couldn't find host %s in the "
5624 DOT_CHAR "netrc file; using defaults\n",
5628 return CURLE_OUT_OF_MEMORY;
5631 /* set bits.netrc TRUE to remember that we got the name from a .netrc
5632 file, so that it is safe to use even if we followed a Location: to a
5633 different host or similar. */
5634 conn->bits.netrc = TRUE;
5636 conn->bits.user_passwd = TRUE; /* enable user+password */
5644 * Set the login details so they're available in the connection
5646 static CURLcode set_login(struct connectdata *conn,
5647 const char *user, const char *passwd,
5648 const char *options)
5650 CURLcode result = CURLE_OK;
5652 /* If our protocol needs a password and we have none, use the defaults */
5653 if((conn->handler->flags & PROTOPT_NEEDSPWD) && !conn->bits.user_passwd) {
5654 /* Store the default user */
5655 conn->user = strdup(CURL_DEFAULT_USER);
5657 /* Store the default password */
5659 conn->passwd = strdup(CURL_DEFAULT_PASSWORD);
5661 conn->passwd = NULL;
5663 /* This is the default password, so DON'T set conn->bits.user_passwd */
5666 /* Store the user, zero-length if not set */
5667 conn->user = strdup(user);
5669 /* Store the password (only if user is present), zero-length if not set */
5671 conn->passwd = strdup(passwd);
5673 conn->passwd = NULL;
5676 if(!conn->user || !conn->passwd)
5677 result = CURLE_OUT_OF_MEMORY;
5679 /* Store the options, null if not set */
5680 if(!result && options[0]) {
5681 conn->options = strdup(options);
5684 result = CURLE_OUT_OF_MEMORY;
5691 * Parses a "host:port" string to connect to.
5692 * The hostname and the port may be empty; in this case, NULL is returned for
5693 * the hostname and -1 for the port.
5695 static CURLcode parse_connect_to_host_port(struct Curl_easy *data,
5697 char **hostname_result,
5706 #if defined(CURL_DISABLE_VERBOSE_STRINGS)
5710 *hostname_result = NULL;
5716 host_dup = strdup(host);
5718 return CURLE_OUT_OF_MEMORY;
5722 /* start scanning for port number at this point */
5725 /* detect and extract RFC6874-style IPv6-addresses */
5726 if(*hostptr == '[') {
5727 char *ptr = ++hostptr; /* advance beyond the initial bracket */
5728 while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '.')))
5731 /* There might be a zone identifier */
5732 if(strncmp("%25", ptr, 3))
5733 infof(data, "Please URL encode %% as %%25, see RFC 6874.\n");
5735 /* Allow unreserved characters as defined in RFC 3986 */
5736 while(*ptr && (ISALPHA(*ptr) || ISXDIGIT(*ptr) || (*ptr == '-') ||
5737 (*ptr == '.') || (*ptr == '_') || (*ptr == '~')))
5741 /* yeps, it ended nicely with a bracket as well */
5744 infof(data, "Invalid IPv6 address format\n");
5746 /* Note that if this didn't end with a bracket, we still advanced the
5747 * hostptr first, but I can't see anything wrong with that as no host
5748 * name nor a numeric can legally start with a bracket.
5752 /* Get port number off server.com:1080 */
5753 host_portno = strchr(portptr, ':');
5756 *host_portno = '\0'; /* cut off number from host name */
5759 long portparse = strtol(host_portno, &endp, 10);
5760 if((endp && *endp) || (portparse < 0) || (portparse > 65535)) {
5761 infof(data, "No valid port number in connect to host string (%s)\n",
5767 port = (int)portparse; /* we know it will fit */
5771 /* now, clone the cleaned host name */
5773 *hostname_result = strdup(hostptr);
5774 if(!*hostname_result) {
5776 return CURLE_OUT_OF_MEMORY;
5780 *port_result = port;
5787 * Parses one "connect to" string in the form:
5788 * "HOST:PORT:CONNECT-TO-HOST:CONNECT-TO-PORT".
5790 static CURLcode parse_connect_to_string(struct Curl_easy *data,
5791 struct connectdata *conn,
5792 const char *conn_to_host,
5796 CURLcode result = CURLE_OK;
5797 const char *ptr = conn_to_host;
5798 int host_match = FALSE;
5799 int port_match = FALSE;
5801 *host_result = NULL;
5805 /* an empty hostname always matches */
5810 /* check whether the URL's hostname matches */
5811 size_t hostname_to_match_len;
5812 char *hostname_to_match = aprintf("%s%s%s",
5813 conn->bits.ipv6_ip ? "[" : "",
5815 conn->bits.ipv6_ip ? "]" : "");
5816 if(!hostname_to_match)
5817 return CURLE_OUT_OF_MEMORY;
5818 hostname_to_match_len = strlen(hostname_to_match);
5819 host_match = strncasecompare(ptr, hostname_to_match,
5820 hostname_to_match_len);
5821 free(hostname_to_match);
5822 ptr += hostname_to_match_len;
5824 host_match = host_match && *ptr == ':';
5830 /* an empty port always matches */
5835 /* check whether the URL's port matches */
5836 char *ptr_next = strchr(ptr, ':');
5839 long port_to_match = strtol(ptr, &endp, 10);
5840 if((endp == ptr_next) && (port_to_match == conn->remote_port)) {
5848 if(host_match && port_match) {
5849 /* parse the hostname and port to connect to */
5850 result = parse_connect_to_host_port(data, ptr, host_result, port_result);
5857 * Processes all strings in the "connect to" slist, and uses the "connect
5858 * to host" and "connect to port" of the first string that matches.
5860 static CURLcode parse_connect_to_slist(struct Curl_easy *data,
5861 struct connectdata *conn,
5862 struct curl_slist *conn_to_host)
5864 CURLcode result = CURLE_OK;
5868 while(conn_to_host && !host && port == -1) {
5869 result = parse_connect_to_string(data, conn, conn_to_host->data,
5875 conn->conn_to_host.rawalloc = host;
5876 conn->conn_to_host.name = host;
5877 conn->bits.conn_to_host = TRUE;
5879 infof(data, "Connecting to hostname: %s\n", host);
5882 /* no "connect to host" */
5883 conn->bits.conn_to_host = FALSE;
5884 Curl_safefree(host);
5888 conn->conn_to_port = port;
5889 conn->bits.conn_to_port = TRUE;
5890 infof(data, "Connecting to port: %d\n", port);
5893 /* no "connect to port" */
5894 conn->bits.conn_to_port = FALSE;
5898 conn_to_host = conn_to_host->next;
5904 /*************************************************************
5905 * Resolve the address of the server or proxy
5906 *************************************************************/
5907 static CURLcode resolve_server(struct Curl_easy *data,
5908 struct connectdata *conn,
5911 CURLcode result=CURLE_OK;
5912 time_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
5914 /*************************************************************
5915 * Resolve the name of the server or proxy
5916 *************************************************************/
5917 if(conn->bits.reuse)
5918 /* We're reusing the connection - no need to resolve anything, and
5919 fix_hostname() was called already in create_conn() for the re-use
5924 /* this is a fresh connect */
5926 struct Curl_dns_entry *hostaddr;
5928 #ifdef USE_UNIX_SOCKETS
5929 if(conn->unix_domain_socket) {
5930 /* Unix domain sockets are local. The host gets ignored, just use the
5931 * specified domain socket address. Do not cache "DNS entries". There is
5932 * no DNS involved and we already have the filesystem path available */
5933 const char *path = conn->unix_domain_socket;
5935 hostaddr = calloc(1, sizeof(struct Curl_dns_entry));
5937 result = CURLE_OUT_OF_MEMORY;
5939 bool longpath = FALSE;
5940 hostaddr->addr = Curl_unix2addr(path, &longpath,
5941 conn->abstract_unix_socket);
5945 /* Long paths are not supported for now */
5947 failf(data, "Unix socket path too long: '%s'", path);
5948 result = CURLE_COULDNT_RESOLVE_HOST;
5951 result = CURLE_OUT_OF_MEMORY;
5959 if(!conn->bits.proxy) {
5960 struct hostname *connhost;
5961 if(conn->bits.conn_to_host)
5962 connhost = &conn->conn_to_host;
5964 connhost = &conn->host;
5966 /* If not connecting via a proxy, extract the port from the URL, if it is
5967 * there, thus overriding any defaults that might have been set above. */
5968 if(conn->bits.conn_to_port)
5969 conn->port = conn->conn_to_port;
5971 conn->port = conn->remote_port;
5973 /* Resolve target host right on */
5974 rc = Curl_resolv_timeout(conn, connhost->name, (int)conn->port,
5975 &hostaddr, timeout_ms);
5976 if(rc == CURLRESOLV_PENDING)
5979 else if(rc == CURLRESOLV_TIMEDOUT)
5980 result = CURLE_OPERATION_TIMEDOUT;
5982 else if(!hostaddr) {
5983 failf(data, "Couldn't resolve host '%s'", connhost->dispname);
5984 result = CURLE_COULDNT_RESOLVE_HOST;
5985 /* don't return yet, we need to clean up the timeout first */
5989 /* This is a proxy that hasn't been resolved yet. */
5991 struct hostname * const host = conn->bits.socksproxy ?
5992 &conn->socks_proxy.host : &conn->http_proxy.host;
5995 rc = Curl_resolv_timeout(conn, host->name, (int)conn->port,
5996 &hostaddr, timeout_ms);
5998 if(rc == CURLRESOLV_PENDING)
6001 else if(rc == CURLRESOLV_TIMEDOUT)
6002 result = CURLE_OPERATION_TIMEDOUT;
6004 else if(!hostaddr) {
6005 failf(data, "Couldn't resolve proxy '%s'", host->dispname);
6006 result = CURLE_COULDNT_RESOLVE_PROXY;
6007 /* don't return yet, we need to clean up the timeout first */
6010 DEBUGASSERT(conn->dns_entry == NULL);
6011 conn->dns_entry = hostaddr;
6018 * Cleanup the connection just allocated before we can move along and use the
6019 * previously existing one. All relevant data is copied over and old_conn is
6020 * ready for freeing once this function returns.
6022 static void reuse_conn(struct connectdata *old_conn,
6023 struct connectdata *conn)
6025 free_fixed_hostname(&old_conn->http_proxy.host);
6026 free_fixed_hostname(&old_conn->socks_proxy.host);
6028 free(old_conn->http_proxy.host.rawalloc);
6029 free(old_conn->socks_proxy.host.rawalloc);
6031 /* free the SSL config struct from this connection struct as this was
6032 allocated in vain and is targeted for destruction */
6033 Curl_free_primary_ssl_config(&old_conn->ssl_config);
6034 Curl_free_primary_ssl_config(&old_conn->proxy_ssl_config);
6036 conn->data = old_conn->data;
6038 /* get the user+password information from the old_conn struct since it may
6039 * be new for this request even when we re-use an existing connection */
6040 conn->bits.user_passwd = old_conn->bits.user_passwd;
6041 if(conn->bits.user_passwd) {
6042 /* use the new user name and password though */
6043 Curl_safefree(conn->user);
6044 Curl_safefree(conn->passwd);
6045 conn->user = old_conn->user;
6046 conn->passwd = old_conn->passwd;
6047 old_conn->user = NULL;
6048 old_conn->passwd = NULL;
6051 conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd;
6052 if(conn->bits.proxy_user_passwd) {
6053 /* use the new proxy user name and proxy password though */
6054 Curl_safefree(conn->http_proxy.user);
6055 Curl_safefree(conn->socks_proxy.user);
6056 Curl_safefree(conn->http_proxy.passwd);
6057 Curl_safefree(conn->socks_proxy.passwd);
6058 conn->http_proxy.user = old_conn->http_proxy.user;
6059 conn->socks_proxy.user = old_conn->socks_proxy.user;
6060 conn->http_proxy.passwd = old_conn->http_proxy.passwd;
6061 conn->socks_proxy.passwd = old_conn->socks_proxy.passwd;
6062 old_conn->http_proxy.user = NULL;
6063 old_conn->socks_proxy.user = NULL;
6064 old_conn->http_proxy.passwd = NULL;
6065 old_conn->socks_proxy.passwd = NULL;
6068 /* host can change, when doing keepalive with a proxy or if the case is
6069 different this time etc */
6070 free_fixed_hostname(&conn->host);
6071 free_fixed_hostname(&conn->conn_to_host);
6072 Curl_safefree(conn->host.rawalloc);
6073 Curl_safefree(conn->conn_to_host.rawalloc);
6074 conn->host=old_conn->host;
6075 conn->bits.conn_to_host = old_conn->bits.conn_to_host;
6076 conn->conn_to_host = old_conn->conn_to_host;
6077 conn->bits.conn_to_port = old_conn->bits.conn_to_port;
6078 conn->conn_to_port = old_conn->conn_to_port;
6080 /* persist connection info in session handle */
6081 Curl_persistconninfo(conn);
6083 conn_reset_all_postponed_data(old_conn); /* free buffers */
6084 conn_reset_all_postponed_data(conn); /* reset unprocessed data */
6087 conn->bits.reuse = TRUE; /* yes, we're re-using here */
6089 Curl_safefree(old_conn->user);
6090 Curl_safefree(old_conn->passwd);
6091 Curl_safefree(old_conn->http_proxy.user);
6092 Curl_safefree(old_conn->socks_proxy.user);
6093 Curl_safefree(old_conn->http_proxy.passwd);
6094 Curl_safefree(old_conn->socks_proxy.passwd);
6095 Curl_safefree(old_conn->localdev);
6097 Curl_llist_destroy(old_conn->send_pipe, NULL);
6098 Curl_llist_destroy(old_conn->recv_pipe, NULL);
6100 old_conn->send_pipe = NULL;
6101 old_conn->recv_pipe = NULL;
6103 Curl_safefree(old_conn->master_buffer);
6105 #ifdef USE_UNIX_SOCKETS
6106 Curl_safefree(old_conn->unix_domain_socket);
6111 * create_conn() sets up a new connectdata struct, or re-uses an already
6112 * existing one, and resolves host name.
6114 * if this function returns CURLE_OK and *async is set to TRUE, the resolve
6115 * response will be coming asynchronously. If *async is FALSE, the name is
6118 * @param data The sessionhandle pointer
6119 * @param in_connect is set to the next connection data pointer
6120 * @param async is set TRUE when an async DNS resolution is pending
6121 * @see Curl_setup_conn()
6123 * *NOTE* this function assigns the conn->data pointer!
6126 static CURLcode create_conn(struct Curl_easy *data,
6127 struct connectdata **in_connect,
6130 CURLcode result = CURLE_OK;
6131 struct connectdata *conn;
6132 struct connectdata *conn_temp = NULL;
6135 char *passwd = NULL;
6136 char *options = NULL;
6139 char *socksproxy = NULL;
6140 char *no_proxy = NULL;
6141 bool prot_missing = FALSE;
6142 bool connections_available = TRUE;
6143 bool force_reuse = FALSE;
6144 bool waitpipe = FALSE;
6145 size_t max_host_connections = Curl_multi_max_host_connections(data->multi);
6146 size_t max_total_connections = Curl_multi_max_total_connections(data->multi);
6150 /*************************************************************
6152 *************************************************************/
6154 if(!data->change.url) {
6155 result = CURLE_URL_MALFORMAT;
6159 /* First, split up the current URL in parts so that we can use the
6160 parts for checking against the already present connections. In order
6161 to not have to modify everything at once, we allocate a temporary
6162 connection data struct and fill in for comparison purposes. */
6163 conn = allocate_conn(data);
6166 result = CURLE_OUT_OF_MEMORY;
6170 /* We must set the return variable as soon as possible, so that our
6171 parent can cleanup any possible allocs we may have done before
6175 /* This initing continues below, see the comment "Continue connectdata
6176 * initialization here" */
6178 /***********************************************************
6179 * We need to allocate memory to store the path in. We get the size of the
6180 * full URL to be sure, and we need to make it at least 256 bytes since
6181 * other parts of the code will rely on this fact
6182 ***********************************************************/
6183 #define LEAST_PATH_ALLOC 256
6184 urllen=strlen(data->change.url);
6185 if(urllen < LEAST_PATH_ALLOC)
6186 urllen=LEAST_PATH_ALLOC;
6189 * We malloc() the buffers below urllen+2 to make room for 2 possibilities:
6190 * 1 - an extra terminating zero
6191 * 2 - an extra slash (in case a syntax like "www.host.com?moo" is used)
6194 Curl_safefree(data->state.pathbuffer);
6195 data->state.path = NULL;
6197 data->state.pathbuffer = malloc(urllen+2);
6198 if(NULL == data->state.pathbuffer) {
6199 result = CURLE_OUT_OF_MEMORY; /* really bad error */
6202 data->state.path = data->state.pathbuffer;
6204 conn->host.rawalloc = malloc(urllen+2);
6205 if(NULL == conn->host.rawalloc) {
6206 Curl_safefree(data->state.pathbuffer);
6207 data->state.path = NULL;
6208 result = CURLE_OUT_OF_MEMORY;
6212 conn->host.name = conn->host.rawalloc;
6213 conn->host.name[0] = 0;
6216 passwd = strdup("");
6217 options = strdup("");
6218 if(!user || !passwd || !options) {
6219 result = CURLE_OUT_OF_MEMORY;
6223 result = parseurlandfillconn(data, conn, &prot_missing, &user, &passwd,
6228 /*************************************************************
6229 * No protocol part in URL was used, add it!
6230 *************************************************************/
6232 /* We're guessing prefixes here and if we're told to use a proxy or if
6233 we're gonna follow a Location: later or... then we need the protocol
6234 part added so that we have a valid URL. */
6238 reurl = aprintf("%s://%s", conn->handler->scheme, data->change.url);
6241 result = CURLE_OUT_OF_MEMORY;
6245 /* Change protocol prefix to lower-case */
6246 for(ch_lower = reurl; *ch_lower != ':'; ch_lower++)
6247 *ch_lower = (char)TOLOWER(*ch_lower);
6249 if(data->change.url_alloc) {
6250 Curl_safefree(data->change.url);
6251 data->change.url_alloc = FALSE;
6254 data->change.url = reurl;
6255 data->change.url_alloc = TRUE; /* free this later */
6258 /*************************************************************
6259 * If the protocol can't handle url query strings, then cut
6260 * off the unhandable part
6261 *************************************************************/
6262 if((conn->given->flags&PROTOPT_NOURLQUERY)) {
6263 char *path_q_sep = strchr(conn->data->state.path, '?');
6265 /* according to rfc3986, allow the query (?foo=bar)
6266 also on protocols that can't handle it.
6268 cut the string-part after '?'
6271 /* terminate the string */
6276 if(data->set.str[STRING_BEARER]) {
6277 conn->oauth_bearer = strdup(data->set.str[STRING_BEARER]);
6278 if(!conn->oauth_bearer) {
6279 result = CURLE_OUT_OF_MEMORY;
6284 #ifndef CURL_DISABLE_PROXY
6285 /*************************************************************
6286 * Extract the user and password from the authentication string
6287 *************************************************************/
6288 if(conn->bits.proxy_user_passwd) {
6289 result = parse_proxy_auth(data, conn);
6294 /*************************************************************
6295 * Detect what (if any) proxy to use
6296 *************************************************************/
6297 if(data->set.str[STRING_PROXY]) {
6298 proxy = strdup(data->set.str[STRING_PROXY]);
6299 /* if global proxy is set, this is it */
6301 failf(data, "memory shortage");
6302 result = CURLE_OUT_OF_MEMORY;
6307 if(data->set.str[STRING_PRE_PROXY]) {
6308 socksproxy = strdup(data->set.str[STRING_PRE_PROXY]);
6309 /* if global socks proxy is set, this is it */
6310 if(NULL == socksproxy) {
6311 failf(data, "memory shortage");
6312 result = CURLE_OUT_OF_MEMORY;
6317 no_proxy = curl_getenv("no_proxy");
6319 no_proxy = curl_getenv("NO_PROXY");
6321 if(check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY]) ||
6322 (!data->set.str[STRING_NOPROXY] &&
6323 check_noproxy(conn->host.name, no_proxy))) {
6324 Curl_safefree(proxy);
6325 Curl_safefree(socksproxy);
6327 else if(!proxy && !socksproxy)
6328 #ifndef CURL_DISABLE_HTTP
6329 /* if the host is not in the noproxy list, detect proxy. */
6330 proxy = detect_proxy(conn);
6331 #else /* !CURL_DISABLE_HTTP */
6333 #endif /* CURL_DISABLE_HTTP */
6335 Curl_safefree(no_proxy);
6337 #ifdef USE_UNIX_SOCKETS
6338 if(data->set.str[STRING_UNIX_SOCKET_PATH]) {
6340 free(proxy); /* Unix domain sockets cannot be proxied, so disable it */
6343 conn->unix_domain_socket = strdup(data->set.str[STRING_UNIX_SOCKET_PATH]);
6344 if(conn->unix_domain_socket == NULL) {
6345 result = CURLE_OUT_OF_MEMORY;
6348 conn->abstract_unix_socket = data->set.abstract_unix_socket;
6352 if(proxy && (!*proxy || (conn->handler->flags & PROTOPT_NONETWORK))) {
6353 free(proxy); /* Don't bother with an empty proxy string or if the
6354 protocol doesn't work with network */
6357 if(socksproxy && (!*socksproxy ||
6358 (conn->handler->flags & PROTOPT_NONETWORK))) {
6359 free(socksproxy); /* Don't bother with an empty socks proxy string or if
6360 the protocol doesn't work with network */
6364 /***********************************************************************
6365 * If this is supposed to use a proxy, we need to figure out the proxy host
6366 * name, proxy type and port number, so that we can re-use an existing
6367 * connection that may exist registered to the same proxy host.
6368 ***********************************************************************/
6369 if(proxy || socksproxy) {
6371 result = parse_proxy(data, conn, proxy, conn->http_proxy.proxytype);
6372 Curl_safefree(proxy); /* parse_proxy copies the proxy string */
6378 result = parse_proxy(data, conn, socksproxy,
6379 conn->socks_proxy.proxytype);
6380 /* parse_proxy copies the socks proxy string */
6381 Curl_safefree(socksproxy);
6386 if(conn->http_proxy.host.rawalloc) {
6387 #ifdef CURL_DISABLE_HTTP
6388 /* asking for a HTTP proxy is a bit funny when HTTP is disabled... */
6389 result = CURLE_UNSUPPORTED_PROTOCOL;
6392 /* force this connection's protocol to become HTTP if not already
6393 compatible - if it isn't tunneling through */
6394 if(!(conn->handler->protocol & PROTO_FAMILY_HTTP) &&
6395 !conn->bits.tunnel_proxy)
6396 conn->handler = &Curl_handler_http;
6398 conn->bits.httpproxy = TRUE;
6402 conn->bits.httpproxy = FALSE; /* not a HTTP proxy */
6403 conn->bits.tunnel_proxy = FALSE; /* no tunneling if not HTTP */
6406 if(conn->socks_proxy.host.rawalloc) {
6407 if(!conn->http_proxy.host.rawalloc) {
6408 /* once a socks proxy */
6409 if(!conn->socks_proxy.user) {
6410 conn->socks_proxy.user = conn->http_proxy.user;
6411 conn->http_proxy.user = NULL;
6412 Curl_safefree(conn->socks_proxy.passwd);
6413 conn->socks_proxy.passwd = conn->http_proxy.passwd;
6414 conn->http_proxy.passwd = NULL;
6417 conn->bits.socksproxy = TRUE;
6420 conn->bits.socksproxy = FALSE; /* not a socks proxy */
6423 conn->bits.socksproxy = FALSE;
6424 conn->bits.httpproxy = FALSE;
6426 conn->bits.proxy = conn->bits.httpproxy || conn->bits.socksproxy;
6428 if(!conn->bits.proxy) {
6429 /* we aren't using the proxy after all... */
6430 conn->bits.proxy = FALSE;
6431 conn->bits.httpproxy = FALSE;
6432 conn->bits.socksproxy = FALSE;
6433 conn->bits.proxy_user_passwd = FALSE;
6434 conn->bits.tunnel_proxy = FALSE;
6437 #endif /* CURL_DISABLE_PROXY */
6439 /*************************************************************
6440 * If the protocol is using SSL and HTTP proxy is used, we set
6441 * the tunnel_proxy bit.
6442 *************************************************************/
6443 if((conn->given->flags&PROTOPT_SSL) && conn->bits.httpproxy)
6444 conn->bits.tunnel_proxy = TRUE;
6446 /*************************************************************
6447 * Figure out the remote port number and fix it in the URL
6448 *************************************************************/
6449 result = parse_remote_port(data, conn);
6453 /* Check for overridden login details and set them accordingly so they
6454 they are known when protocol->setup_connection is called! */
6455 result = override_login(data, conn, &user, &passwd, &options);
6458 result = set_login(conn, user, passwd, options);
6462 /*************************************************************
6463 * Process the "connect to" linked list of hostname/port mappings.
6464 * Do this after the remote port number has been fixed in the URL.
6465 *************************************************************/
6466 result = parse_connect_to_slist(data, conn, data->set.connect_to);
6470 /*************************************************************
6471 * IDN-fix the hostnames
6472 *************************************************************/
6473 fix_hostname(conn, &conn->host);
6474 if(conn->bits.conn_to_host)
6475 fix_hostname(conn, &conn->conn_to_host);
6476 if(conn->bits.httpproxy)
6477 fix_hostname(conn, &conn->http_proxy.host);
6478 if(conn->bits.socksproxy)
6479 fix_hostname(conn, &conn->socks_proxy.host);
6481 /*************************************************************
6482 * Check whether the host and the "connect to host" are equal.
6483 * Do this after the hostnames have been IDN-fixed.
6484 *************************************************************/
6485 if(conn->bits.conn_to_host &&
6486 strcasecompare(conn->conn_to_host.name, conn->host.name)) {
6487 conn->bits.conn_to_host = FALSE;
6490 /*************************************************************
6491 * Check whether the port and the "connect to port" are equal.
6492 * Do this after the remote port number has been fixed in the URL.
6493 *************************************************************/
6494 if(conn->bits.conn_to_port && conn->conn_to_port == conn->remote_port) {
6495 conn->bits.conn_to_port = FALSE;
6498 /*************************************************************
6499 * If the "connect to" feature is used with an HTTP proxy,
6500 * we set the tunnel_proxy bit.
6501 *************************************************************/
6502 if((conn->bits.conn_to_host || conn->bits.conn_to_port) &&
6503 conn->bits.httpproxy)
6504 conn->bits.tunnel_proxy = TRUE;
6506 /*************************************************************
6507 * Setup internals depending on protocol. Needs to be done after
6508 * we figured out what/if proxy to use.
6509 *************************************************************/
6510 result = setup_connection_internals(conn);
6514 conn->recv[FIRSTSOCKET] = Curl_recv_plain;
6515 conn->send[FIRSTSOCKET] = Curl_send_plain;
6516 conn->recv[SECONDARYSOCKET] = Curl_recv_plain;
6517 conn->send[SECONDARYSOCKET] = Curl_send_plain;
6519 conn->bits.tcp_fastopen = data->set.tcp_fastopen;
6521 /***********************************************************************
6522 * file: is a special case in that it doesn't need a network connection
6523 ***********************************************************************/
6524 #ifndef CURL_DISABLE_FILE
6525 if(conn->handler->flags & PROTOPT_NONETWORK) {
6527 /* this is supposed to be the connect function so we better at least check
6528 that the file is present here! */
6529 DEBUGASSERT(conn->handler->connect_it);
6530 result = conn->handler->connect_it(conn, &done);
6532 /* Setup a "faked" transfer that'll do nothing */
6535 conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; /* we are "connected */
6537 Curl_conncache_add_conn(data->state.conn_cache, conn);
6540 * Setup whatever necessary for a resumed transfer
6542 result = setup_range(data);
6544 DEBUGASSERT(conn->handler->done);
6545 /* we ignore the return code for the protocol-specific DONE */
6546 (void)conn->handler->done(conn, result, FALSE);
6550 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */
6551 -1, NULL); /* no upload */
6554 /* since we skip do_init() */
6555 Curl_init_do(data, conn);
6561 /* Get a cloned copy of the SSL config situation stored in the
6562 connection struct. But to get this going nicely, we must first make
6563 sure that the strings in the master copy are pointing to the correct
6564 strings in the session handle strings array!
6566 Keep in mind that the pointers in the master copy are pointing to strings
6567 that will be freed as part of the Curl_easy struct, but all cloned
6568 copies will be separately allocated.
6570 data->set.ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_ORIG];
6571 data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY];
6572 data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_ORIG];
6573 data->set.proxy_ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY];
6574 data->set.ssl.primary.random_file = data->set.str[STRING_SSL_RANDOM_FILE];
6575 data->set.proxy_ssl.primary.random_file =
6576 data->set.str[STRING_SSL_RANDOM_FILE];
6577 data->set.ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
6578 data->set.proxy_ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
6579 data->set.ssl.primary.cipher_list =
6580 data->set.str[STRING_SSL_CIPHER_LIST_ORIG];
6581 data->set.proxy_ssl.primary.cipher_list =
6582 data->set.str[STRING_SSL_CIPHER_LIST_PROXY];
6584 data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_ORIG];
6585 data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY];
6586 data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_ORIG];
6587 data->set.proxy_ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY];
6588 data->set.ssl.cert = data->set.str[STRING_CERT_ORIG];
6589 data->set.proxy_ssl.cert = data->set.str[STRING_CERT_PROXY];
6590 data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE_ORIG];
6591 data->set.proxy_ssl.cert_type = data->set.str[STRING_CERT_TYPE_PROXY];
6592 data->set.ssl.key = data->set.str[STRING_KEY_ORIG];
6593 data->set.proxy_ssl.key = data->set.str[STRING_KEY_PROXY];
6594 data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE_ORIG];
6595 data->set.proxy_ssl.key_type = data->set.str[STRING_KEY_TYPE_PROXY];
6596 data->set.ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_ORIG];
6597 data->set.proxy_ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_PROXY];
6598 data->set.ssl.primary.clientcert = data->set.str[STRING_CERT_ORIG];
6599 data->set.proxy_ssl.primary.clientcert = data->set.str[STRING_CERT_PROXY];
6601 data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_ORIG];
6602 data->set.proxy_ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_PROXY];
6603 data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_ORIG];
6604 data->set.proxy_ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_PROXY];
6607 if(!Curl_clone_primary_ssl_config(&data->set.ssl.primary,
6608 &conn->ssl_config)) {
6609 result = CURLE_OUT_OF_MEMORY;
6613 if(!Curl_clone_primary_ssl_config(&data->set.proxy_ssl.primary,
6614 &conn->proxy_ssl_config)) {
6615 result = CURLE_OUT_OF_MEMORY;
6619 prune_dead_connections(data);
6621 /*************************************************************
6622 * Check the current list of connections to see if we can
6623 * re-use an already existing one or if we have to create a
6625 *************************************************************/
6627 /* reuse_fresh is TRUE if we are told to use a new connection by force, but
6628 we only acknowledge this option if this is not a re-used connection
6629 already (which happens due to follow-location or during a HTTP
6630 authentication phase). */
6631 if(data->set.reuse_fresh && !data->state.this_is_a_follow)
6634 reuse = ConnectionExists(data, conn, &conn_temp, &force_reuse, &waitpipe);
6636 /* If we found a reusable connection, we may still want to
6637 open a new connection if we are pipelining. */
6638 if(reuse && !force_reuse && IsPipeliningPossible(data, conn_temp)) {
6639 size_t pipelen = conn_temp->send_pipe->size + conn_temp->recv_pipe->size;
6641 infof(data, "Found connection %ld, with requests in the pipe (%zu)\n",
6642 conn_temp->connection_id, pipelen);
6644 if(conn_temp->bundle->num_connections < max_host_connections &&
6645 data->state.conn_cache->num_connections < max_total_connections) {
6646 /* We want a new connection anyway */
6649 infof(data, "We can reuse, but we want a new connection anyway\n");
6656 * We already have a connection for this, we got the former connection
6657 * in the conn_temp variable and thus we need to cleanup the one we
6658 * just allocated before we can move along and use the previously
6661 conn_temp->inuse = TRUE; /* mark this as being in use so that no other
6662 handle in a multi stack may nick it */
6663 reuse_conn(conn, conn_temp);
6664 free(conn); /* we don't need this anymore */
6668 infof(data, "Re-using existing connection! (#%ld) with %s %s\n",
6669 conn->connection_id,
6670 conn->bits.proxy?"proxy":"host",
6671 conn->socks_proxy.host.name ? conn->socks_proxy.host.dispname :
6672 conn->http_proxy.host.name ? conn->http_proxy.host.dispname :
6673 conn->host.dispname);
6676 /* We have decided that we want a new connection. However, we may not
6677 be able to do that if we have reached the limit of how many
6678 connections we are allowed to open. */
6679 struct connectbundle *bundle = NULL;
6681 if(conn->handler->flags & PROTOPT_ALPN_NPN) {
6682 /* The protocol wants it, so set the bits if enabled in the easy handle
6684 if(data->set.ssl_enable_alpn)
6685 conn->bits.tls_enable_alpn = TRUE;
6686 if(data->set.ssl_enable_npn)
6687 conn->bits.tls_enable_npn = TRUE;
6691 /* There is a connection that *might* become usable for pipelining
6692 "soon", and we wait for that */
6693 connections_available = FALSE;
6695 bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache);
6697 if(max_host_connections > 0 && bundle &&
6698 (bundle->num_connections >= max_host_connections)) {
6699 struct connectdata *conn_candidate;
6701 /* The bundle is full. Let's see if we can kill a connection. */
6702 conn_candidate = find_oldest_idle_connection_in_bundle(data, bundle);
6704 if(conn_candidate) {
6705 /* Set the connection's owner correctly, then kill it */
6706 conn_candidate->data = data;
6707 (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
6710 infof(data, "No more connections allowed to host: %d\n",
6711 max_host_connections);
6712 connections_available = FALSE;
6716 if(connections_available &&
6717 (max_total_connections > 0) &&
6718 (data->state.conn_cache->num_connections >= max_total_connections)) {
6719 struct connectdata *conn_candidate;
6721 /* The cache is full. Let's see if we can kill a connection. */
6722 conn_candidate = Curl_oldest_idle_connection(data);
6724 if(conn_candidate) {
6725 /* Set the connection's owner correctly, then kill it */
6726 conn_candidate->data = data;
6727 (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
6730 infof(data, "No connections available in cache\n");
6731 connections_available = FALSE;
6735 if(!connections_available) {
6736 infof(data, "No connections available.\n");
6741 result = CURLE_NO_CONNECTION_AVAILABLE;
6746 * This is a brand new connection, so let's store it in the connection
6749 Curl_conncache_add_conn(data->state.conn_cache, conn);
6752 #if defined(USE_NTLM)
6753 /* If NTLM is requested in a part of this connection, make sure we don't
6754 assume the state is fine as this is a fresh connection and NTLM is
6755 connection based. */
6756 if((data->state.authhost.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
6757 data->state.authhost.done) {
6758 infof(data, "NTLM picked AND auth done set, clear picked!\n");
6759 data->state.authhost.picked = CURLAUTH_NONE;
6760 data->state.authhost.done = FALSE;
6763 if((data->state.authproxy.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
6764 data->state.authproxy.done) {
6765 infof(data, "NTLM-proxy picked AND auth done set, clear picked!\n");
6766 data->state.authproxy.picked = CURLAUTH_NONE;
6767 data->state.authproxy.done = FALSE;
6772 /* Mark the connection as used */
6775 /* Setup and init stuff before DO starts, in preparing for the transfer. */
6776 Curl_init_do(data, conn);
6779 * Setup whatever necessary for a resumed transfer
6781 result = setup_range(data);
6785 /* Continue connectdata initialization here. */
6788 * Inherit the proper values from the urldata struct AFTER we have arranged
6789 * the persistent connection stuff
6791 conn->seek_func = data->set.seek_func;
6792 conn->seek_client = data->set.seek_client;
6794 /*************************************************************
6795 * Resolve the address of the server or proxy
6796 *************************************************************/
6797 result = resolve_server(data, conn, async);
6809 /* Curl_setup_conn() is called after the name resolve initiated in
6810 * create_conn() is all done.
6812 * Curl_setup_conn() also handles reused connections
6814 * conn->data MUST already have been setup fine (in create_conn)
6817 CURLcode Curl_setup_conn(struct connectdata *conn,
6818 bool *protocol_done)
6820 CURLcode result = CURLE_OK;
6821 struct Curl_easy *data = conn->data;
6823 Curl_pgrsTime(data, TIMER_NAMELOOKUP);
6825 if(conn->handler->flags & PROTOPT_NONETWORK) {
6826 /* nothing to setup when not using a network */
6827 *protocol_done = TRUE;
6830 *protocol_done = FALSE; /* default to not done */
6832 /* set proxy_connect_closed to false unconditionally already here since it
6833 is used strictly to provide extra information to a parent function in the
6834 case of proxy CONNECT failures and we must make sure we don't have it
6835 lingering set from a previous invoke */
6836 conn->bits.proxy_connect_closed = FALSE;
6839 * Set user-agent. Used for HTTP, but since we can attempt to tunnel
6840 * basically anything through a http proxy we can't limit this based on
6843 if(data->set.str[STRING_USERAGENT]) {
6844 Curl_safefree(conn->allocptr.uagent);
6845 conn->allocptr.uagent =
6846 aprintf("User-Agent: %s\r\n", data->set.str[STRING_USERAGENT]);
6847 if(!conn->allocptr.uagent)
6848 return CURLE_OUT_OF_MEMORY;
6851 data->req.headerbytecount = 0;
6853 #ifdef CURL_DO_LINEEND_CONV
6854 data->state.crlf_conversions = 0; /* reset CRLF conversion counter */
6855 #endif /* CURL_DO_LINEEND_CONV */
6857 /* set start time here for timeout purposes in the connect procedure, it
6858 is later set again for the progress meter purpose */
6859 conn->now = Curl_tvnow();
6861 if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
6862 conn->bits.tcpconnect[FIRSTSOCKET] = FALSE;
6863 result = Curl_connecthost(conn, conn->dns_entry);
6868 Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */
6869 Curl_pgrsTime(data, TIMER_APPCONNECT); /* we're connected already */
6870 conn->bits.tcpconnect[FIRSTSOCKET] = TRUE;
6871 *protocol_done = TRUE;
6872 Curl_updateconninfo(conn, conn->sock[FIRSTSOCKET]);
6873 Curl_verboseconnect(conn);
6876 conn->now = Curl_tvnow(); /* time this *after* the connect is done, we
6877 set this here perhaps a second time */
6881 * This check is quite a hack. We're calling _fsetmode to fix the problem
6882 * with fwrite converting newline characters (you get mangled text files,
6883 * and corrupted binary files when you download to stdout and redirect it to
6887 if((data->set.out)->_handle == NULL) {
6888 _fsetmode(stdout, "b");
6895 CURLcode Curl_connect(struct Curl_easy *data,
6896 struct connectdata **in_connect,
6898 bool *protocol_done)
6902 *asyncp = FALSE; /* assume synchronous resolves by default */
6904 /* call the stuff that needs to be called */
6905 result = create_conn(data, in_connect, asyncp);
6909 if((*in_connect)->send_pipe->size || (*in_connect)->recv_pipe->size)
6911 *protocol_done = TRUE;
6913 /* DNS resolution is done: that's either because this is a reused
6914 connection, in which case DNS was unnecessary, or because DNS
6915 really did finish already (synch resolver/fast async resolve) */
6916 result = Curl_setup_conn(*in_connect, protocol_done);
6920 if(result == CURLE_NO_CONNECTION_AVAILABLE) {
6925 if(result && *in_connect) {
6926 /* We're not allowed to return failure with memory left allocated
6927 in the connectdata struct, free those here */
6928 Curl_disconnect(*in_connect, FALSE); /* close the connection */
6929 *in_connect = NULL; /* return a NULL */
6936 * Curl_init_do() inits the readwrite session. This is inited each time (in
6937 * the DO function before the protocol-specific DO functions are invoked) for
6938 * a transfer, sometimes multiple times on the same Curl_easy. Make sure
6939 * nothing in here depends on stuff that are setup dynamically for the
6942 * Allow this function to get called with 'conn' set to NULL.
6945 CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn)
6947 struct SingleRequest *k = &data->req;
6950 conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to
6953 data->state.done = FALSE; /* *_done() is not called yet */
6954 data->state.expect100header = FALSE;
6956 if(data->set.opt_no_body)
6957 /* in HTTP lingo, no body means using the HEAD request... */
6958 data->set.httpreq = HTTPREQ_HEAD;
6959 else if(HTTPREQ_HEAD == data->set.httpreq)
6960 /* ... but if unset there really is no perfect method that is the
6961 "opposite" of HEAD but in reality most people probably think GET
6962 then. The important thing is that we can't let it remain HEAD if the
6963 opt_no_body is set FALSE since then we'll behave wrong when getting
6965 data->set.httpreq = HTTPREQ_GET;
6967 k->start = Curl_tvnow(); /* start time */
6968 k->now = k->start; /* current time is now */
6969 k->header = TRUE; /* assume header */
6973 k->buf = data->state.buffer;
6974 k->uploadbuf = data->state.uploadbuffer;
6975 k->hbufp = data->state.headerbuff;
6976 k->ignorebody=FALSE;
6978 Curl_speedinit(data);
6980 Curl_pgrsSetUploadCounter(data, 0);
6981 Curl_pgrsSetDownloadCounter(data, 0);
6987 * get_protocol_family()
6989 * This is used to return the protocol family for a given protocol.
6993 * protocol [in] - A single bit protocol identifier such as HTTP or HTTPS.
6995 * Returns the family as a single bit protocol identifier.
6998 unsigned int get_protocol_family(unsigned int protocol)
7000 unsigned int family;
7003 case CURLPROTO_HTTP:
7004 case CURLPROTO_HTTPS:
7005 family = CURLPROTO_HTTP;
7009 case CURLPROTO_FTPS:
7010 family = CURLPROTO_FTP;
7014 family = CURLPROTO_SCP;
7017 case CURLPROTO_SFTP:
7018 family = CURLPROTO_SFTP;
7021 case CURLPROTO_TELNET:
7022 family = CURLPROTO_TELNET;
7025 case CURLPROTO_LDAP:
7026 case CURLPROTO_LDAPS:
7027 family = CURLPROTO_LDAP;
7030 case CURLPROTO_DICT:
7031 family = CURLPROTO_DICT;
7034 case CURLPROTO_FILE:
7035 family = CURLPROTO_FILE;
7038 case CURLPROTO_TFTP:
7039 family = CURLPROTO_TFTP;
7042 case CURLPROTO_IMAP:
7043 case CURLPROTO_IMAPS:
7044 family = CURLPROTO_IMAP;
7047 case CURLPROTO_POP3:
7048 case CURLPROTO_POP3S:
7049 family = CURLPROTO_POP3;
7052 case CURLPROTO_SMTP:
7053 case CURLPROTO_SMTPS:
7054 family = CURLPROTO_SMTP;
7057 case CURLPROTO_RTSP:
7058 family = CURLPROTO_RTSP;
7061 case CURLPROTO_RTMP:
7062 case CURLPROTO_RTMPS:
7063 family = CURLPROTO_RTMP;
7066 case CURLPROTO_RTMPT:
7067 case CURLPROTO_RTMPTS:
7068 family = CURLPROTO_RTMPT;
7071 case CURLPROTO_RTMPE:
7072 family = CURLPROTO_RTMPE;
7075 case CURLPROTO_RTMPTE:
7076 family = CURLPROTO_RTMPTE;
7079 case CURLPROTO_GOPHER:
7080 family = CURLPROTO_GOPHER;
7084 case CURLPROTO_SMBS:
7085 family = CURLPROTO_SMB;