1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at http://curl.haxx.se/docs/copyright.html.
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ***************************************************************************/
23 #include "curl_setup.h"
25 #ifdef HAVE_NETINET_IN_H
26 #include <netinet/in.h>
31 #ifdef HAVE_ARPA_INET_H
32 #include <arpa/inet.h>
37 #ifdef HAVE_SYS_IOCTL_H
38 #include <sys/ioctl.h>
41 #ifdef HAVE_SYS_PARAM_H
42 #include <sys/param.h>
55 #error "We can't compile without socket() support!"
65 #include <stringprep.h>
66 #ifdef HAVE_IDN_FREE_H
69 /* prototype from idn-free.h, not provided by libidn 0.4.5's make install! */
70 void idn_free (void *ptr);
73 /* if idn_free() was not found in this version of libidn use free() instead */
74 #define idn_free(x) (free)(x)
76 #elif defined(USE_WIN32_IDN)
77 /* prototype for curl_win32_idn_to_ascii() */
78 int curl_win32_idn_to_ascii(const char *in, char **out);
79 #endif /* USE_LIBIDN */
85 #include "vtls/vtls.h"
96 #include "content_encoding.h"
97 #include "http_digest.h"
98 #include "http_negotiate.h"
102 #include "speedcheck.h"
104 #include "warnless.h"
105 #include "non-ascii.h"
106 #include "inet_pton.h"
108 /* And now for the protocols */
115 #include "curl_ldap.h"
120 #include "inet_ntop.h"
121 #include "curl_ntlm.h"
122 #include "curl_ntlm_wb.h"
124 #include "curl_rtmp.h"
126 #include "http_proxy.h"
127 #include "conncache.h"
128 #include "multihandle.h"
129 #include "pipeline.h"
132 #include "curl_printf.h"
133 #include "curl_memory.h"
134 /* The last #include file should be: */
135 #include "memdebug.h"
137 /* Local static prototypes */
138 static struct connectdata *
139 find_oldest_idle_connection(struct SessionHandle *data);
140 static struct connectdata *
141 find_oldest_idle_connection_in_bundle(struct SessionHandle *data,
142 struct connectbundle *bundle);
143 static void conn_free(struct connectdata *conn);
144 static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke);
145 static CURLcode parse_url_login(struct SessionHandle *data,
146 struct connectdata *conn,
147 char **userptr, char **passwdptr,
149 static CURLcode parse_login_details(const char *login, const size_t len,
150 char **userptr, char **passwdptr,
156 static const struct Curl_handler * const protocols[] = {
158 #ifndef CURL_DISABLE_HTTP
162 #if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)
166 #ifndef CURL_DISABLE_FTP
170 #if defined(USE_SSL) && !defined(CURL_DISABLE_FTP)
174 #ifndef CURL_DISABLE_TELNET
175 &Curl_handler_telnet,
178 #ifndef CURL_DISABLE_DICT
182 #ifndef CURL_DISABLE_LDAP
184 #if !defined(CURL_DISABLE_LDAPS) && \
185 ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \
186 (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)))
191 #ifndef CURL_DISABLE_FILE
195 #ifndef CURL_DISABLE_TFTP
204 #ifndef CURL_DISABLE_IMAP
211 #ifndef CURL_DISABLE_POP3
218 #if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
219 (CURL_SIZEOF_CURL_OFF_T > 4) && \
220 (!defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO))
227 #ifndef CURL_DISABLE_SMTP
234 #ifndef CURL_DISABLE_RTSP
238 #ifndef CURL_DISABLE_GOPHER
239 &Curl_handler_gopher,
246 &Curl_handler_rtmpte,
248 &Curl_handler_rtmpts,
251 (struct Curl_handler *) NULL
255 * Dummy handler for undefined protocol schemes.
258 static const struct Curl_handler Curl_handler_dummy = {
259 "<no protocol>", /* scheme */
260 ZERO_NULL, /* setup_connection */
261 ZERO_NULL, /* do_it */
262 ZERO_NULL, /* done */
263 ZERO_NULL, /* do_more */
264 ZERO_NULL, /* connect_it */
265 ZERO_NULL, /* connecting */
266 ZERO_NULL, /* doing */
267 ZERO_NULL, /* proto_getsock */
268 ZERO_NULL, /* doing_getsock */
269 ZERO_NULL, /* domore_getsock */
270 ZERO_NULL, /* perform_getsock */
271 ZERO_NULL, /* disconnect */
272 ZERO_NULL, /* readwrite */
275 PROTOPT_NONE /* flags */
278 void Curl_freeset(struct SessionHandle *data)
280 /* Free all dynamic strings stored in the data->set substructure. */
282 for(i=(enum dupstring)0; i < STRING_LAST; i++) {
283 Curl_safefree(data->set.str[i]);
286 if(data->change.referer_alloc) {
287 Curl_safefree(data->change.referer);
288 data->change.referer_alloc = FALSE;
290 data->change.referer = NULL;
291 if(data->change.url_alloc) {
292 Curl_safefree(data->change.url);
293 data->change.url_alloc = FALSE;
295 data->change.url = NULL;
298 static CURLcode setstropt(char **charp, char *s)
300 /* Release the previous storage at `charp' and replace by a dynamic storage
301 copy of `s'. Return CURLE_OK or CURLE_OUT_OF_MEMORY. */
303 Curl_safefree(*charp);
309 return CURLE_OUT_OF_MEMORY;
317 static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp)
319 CURLcode result = CURLE_OK;
323 /* Parse the login details if specified. It not then we treat NULL as a hint
324 to clear the existing data */
326 result = parse_login_details(option, strlen(option),
327 (userp ? &user : NULL),
328 (passwdp ? &passwd : NULL),
333 /* Store the username part of option if required */
335 if(!user && option && option[0] == ':') {
336 /* Allocate an empty string instead of returning NULL as user name */
339 result = CURLE_OUT_OF_MEMORY;
342 Curl_safefree(*userp);
346 /* Store the password part of option if required */
348 Curl_safefree(*passwdp);
356 CURLcode Curl_dupset(struct SessionHandle *dst, struct SessionHandle *src)
358 CURLcode result = CURLE_OK;
361 /* Copy src->set into dst->set first, then deal with the strings
365 /* clear all string pointers first */
366 memset(dst->set.str, 0, STRING_LAST * sizeof(char *));
368 /* duplicate all strings */
369 for(i=(enum dupstring)0; i< STRING_LASTZEROTERMINATED; i++) {
370 result = setstropt(&dst->set.str[i], src->set.str[i]);
375 /* duplicate memory areas pointed to */
376 i = STRING_COPYPOSTFIELDS;
377 if(src->set.postfieldsize && src->set.str[i]) {
378 /* postfieldsize is curl_off_t, Curl_memdup() takes a size_t ... */
379 dst->set.str[i] = Curl_memdup(src->set.str[i],
380 curlx_sotouz(src->set.postfieldsize));
382 return CURLE_OUT_OF_MEMORY;
383 /* point to the new copy */
384 dst->set.postfields = dst->set.str[i];
391 * This is the internal function curl_easy_cleanup() calls. This should
392 * cleanup and free all resources associated with this sessionhandle.
394 * NOTE: if we ever add something that attempts to write to a socket or
395 * similar here, we must ignore SIGPIPE first. It is currently only done
396 * when curl_easy_perform() is invoked.
399 CURLcode Curl_close(struct SessionHandle *data)
401 struct Curl_multi *m;
406 Curl_expire(data, 0); /* shut off timers */
411 /* This handle is still part of a multi handle, take care of this first
412 and detach this handle from there. */
413 curl_multi_remove_handle(data->multi, data);
416 /* when curl_easy_perform() is used, it creates its own multi handle to
417 use and this is the one */
418 curl_multi_cleanup(data->multi_easy);
420 /* Destroy the timeout list that is held in the easy handle. It is
421 /normally/ done by curl_multi_remove_handle() but this is "just in
423 if(data->state.timeoutlist) {
424 Curl_llist_destroy(data->state.timeoutlist, NULL);
425 data->state.timeoutlist = NULL;
428 data->magic = 0; /* force a clear AFTER the possibly enforced removal from
429 the multi handle, since that function uses the magic
432 if(data->state.rangestringalloc)
433 free(data->state.range);
435 /* Free the pathbuffer */
436 Curl_safefree(data->state.pathbuffer);
437 data->state.path = NULL;
439 /* freed here just in case DONE wasn't called */
440 Curl_free_request_state(data);
442 /* Close down all open SSL info and sessions */
443 Curl_ssl_close_all(data);
444 Curl_safefree(data->state.first_host);
445 Curl_safefree(data->state.scratch);
446 Curl_ssl_free_certinfo(data);
448 /* Cleanup possible redirect junk */
449 free(data->req.newurl);
450 data->req.newurl = NULL;
452 if(data->change.referer_alloc) {
453 Curl_safefree(data->change.referer);
454 data->change.referer_alloc = FALSE;
456 data->change.referer = NULL;
458 if(data->change.url_alloc) {
459 Curl_safefree(data->change.url);
460 data->change.url_alloc = FALSE;
462 data->change.url = NULL;
464 Curl_safefree(data->state.headerbuff);
466 Curl_flush_cookies(data, 1);
468 Curl_digest_cleanup(data);
470 Curl_safefree(data->info.contenttype);
471 Curl_safefree(data->info.wouldredirect);
473 /* this destroys the channel and we cannot use it anymore after this */
474 Curl_resolver_cleanup(data->state.resolver);
476 Curl_convert_close(data);
478 /* No longer a dirty share, if it exists */
480 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
481 data->share->dirty--;
482 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
491 * Initialize the UserDefined fields within a SessionHandle.
492 * This may be safely called on a new or existing SessionHandle.
494 CURLcode Curl_init_userdefined(struct UserDefined *set)
496 CURLcode result = CURLE_OK;
498 set->out = stdout; /* default output to stdout */
499 set->in = stdin; /* default input from stdin */
500 set->err = stderr; /* default stderr to stderr */
502 /* use fwrite as default function to store output */
503 set->fwrite_func = (curl_write_callback)fwrite;
505 /* use fread as default function to read input */
506 set->fread_func = (curl_read_callback)fread;
507 set->is_fread_set = 0;
508 set->is_fwrite_set = 0;
510 set->seek_func = ZERO_NULL;
511 set->seek_client = ZERO_NULL;
513 /* conversion callbacks for non-ASCII hosts */
514 set->convfromnetwork = ZERO_NULL;
515 set->convtonetwork = ZERO_NULL;
516 set->convfromutf8 = ZERO_NULL;
518 set->filesize = -1; /* we don't know the size */
519 set->postfieldsize = -1; /* unknown size */
520 set->maxredirs = -1; /* allow any amount by default */
522 set->httpreq = HTTPREQ_GET; /* Default HTTP request */
523 set->rtspreq = RTSPREQ_OPTIONS; /* Default RTSP request */
524 set->ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */
525 set->ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */
526 set->ftp_use_pret = FALSE; /* mainly useful for drftpd servers */
527 set->ftp_filemethod = FTPFILE_MULTICWD;
529 set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
531 /* Set the default size of the SSL session ID cache */
532 set->ssl.max_ssl_sessions = 5;
534 set->proxyport = CURL_DEFAULT_PROXY_PORT; /* from url.h */
535 set->proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
536 set->httpauth = CURLAUTH_BASIC; /* defaults to basic */
537 set->proxyauth = CURLAUTH_BASIC; /* defaults to basic */
539 /* make libcurl quiet by default: */
540 set->hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */
543 * libcurl 7.10 introduced SSL verification *by default*! This needs to be
544 * switched off unless wanted.
546 set->ssl.verifypeer = TRUE;
547 set->ssl.verifyhost = TRUE;
549 set->ssl.authtype = CURL_TLSAUTH_NONE;
551 set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
553 set->ssl.sessionid = TRUE; /* session ID caching enabled by default */
555 set->new_file_perms = 0644; /* Default permissions */
556 set->new_directory_perms = 0755; /* Default permissions */
558 /* for the *protocols fields we don't use the CURLPROTO_ALL convenience
559 define since we internally only use the lower 16 bits for the passed
560 in bitmask to not conflict with the private bits */
561 set->allowed_protocols = CURLPROTO_ALL;
562 set->redir_protocols = CURLPROTO_ALL & /* All except FILE, SCP and SMB */
563 ~(CURLPROTO_FILE | CURLPROTO_SCP | CURLPROTO_SMB |
566 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
568 * disallow unprotected protection negotiation NEC reference implementation
569 * seem not to follow rfc1961 section 4.3/4.4
571 set->socks5_gssapi_nec = FALSE;
572 /* set default GSS-API service name */
573 result = setstropt(&set->str[STRING_SOCKS5_GSSAPI_SERVICE],
574 (char *) CURL_DEFAULT_SOCKS5_GSSAPI_SERVICE);
578 /* set default negotiate proxy service name */
579 result = setstropt(&set->str[STRING_PROXY_SERVICE_NAME],
580 (char *) CURL_DEFAULT_PROXY_SERVICE_NAME);
584 /* set default negotiate service name */
585 result = setstropt(&set->str[STRING_SERVICE_NAME],
586 (char *) CURL_DEFAULT_SERVICE_NAME);
591 /* This is our preferred CA cert bundle/path since install time */
592 #if defined(CURL_CA_BUNDLE)
593 result = setstropt(&set->str[STRING_SSL_CAFILE], (char *) CURL_CA_BUNDLE);
597 #if defined(CURL_CA_PATH)
598 result = setstropt(&set->str[STRING_SSL_CAPATH], (char *) CURL_CA_PATH);
603 set->wildcardmatch = FALSE;
604 set->chunk_bgn = ZERO_NULL;
605 set->chunk_end = ZERO_NULL;
607 /* tcp keepalives are disabled by default, but provide reasonable values for
608 * the interval and idle times.
610 set->tcp_keepalive = FALSE;
611 set->tcp_keepintvl = 60;
612 set->tcp_keepidle = 60;
614 set->ssl_enable_npn = TRUE;
615 set->ssl_enable_alpn = TRUE;
617 set->expect_100_timeout = 1000L; /* Wait for a second by default. */
618 set->sep_headers = TRUE; /* separated header lists by default */
625 * @param curl is a pointer to a sessionhandle pointer that gets set by this
630 CURLcode Curl_open(struct SessionHandle **curl)
633 struct SessionHandle *data;
635 /* Very simple start-up: alloc the struct, init it with zeroes and return */
636 data = calloc(1, sizeof(struct SessionHandle));
638 /* this is a very serious error */
639 DEBUGF(fprintf(stderr, "Error: calloc of SessionHandle failed\n"));
640 return CURLE_OUT_OF_MEMORY;
643 data->magic = CURLEASY_MAGIC_NUMBER;
645 result = Curl_resolver_init(&data->state.resolver);
647 DEBUGF(fprintf(stderr, "Error: resolver_init failed\n"));
652 /* We do some initial setup here, all those fields that can't be just 0 */
654 data->state.headerbuff = malloc(HEADERSIZE);
655 if(!data->state.headerbuff) {
656 DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n"));
657 result = CURLE_OUT_OF_MEMORY;
660 result = Curl_init_userdefined(&data->set);
662 data->state.headersize=HEADERSIZE;
664 Curl_convert_init(data);
666 /* most recent connection is not yet defined */
667 data->state.lastconnect = NULL;
669 data->progress.flags |= PGRS_HIDE;
670 data->state.current_speed = -1; /* init to negative == impossible */
672 data->wildcard.state = CURLWC_INIT;
673 data->wildcard.filelist = NULL;
674 data->set.fnmatch = ZERO_NULL;
675 data->set.maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */
679 Curl_resolver_cleanup(data->state.resolver);
680 free(data->state.headerbuff);
691 CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
695 CURLcode result = CURLE_OK;
697 #ifndef CURL_DISABLE_HTTP
702 case CURLOPT_DNS_CACHE_TIMEOUT:
703 data->set.dns_cache_timeout = va_arg(param, long);
705 case CURLOPT_DNS_USE_GLOBAL_CACHE:
706 /* remember we want this enabled */
707 arg = va_arg(param, long);
708 data->set.global_dns_cache = (0 != arg)?TRUE:FALSE;
710 case CURLOPT_SSL_CIPHER_LIST:
711 /* set a list of cipher we want to use in the SSL connection */
712 result = setstropt(&data->set.str[STRING_SSL_CIPHER_LIST],
713 va_arg(param, char *));
716 case CURLOPT_RANDOM_FILE:
718 * This is the path name to a file that contains random data to seed
719 * the random SSL stuff with. The file is only used for reading.
721 result = setstropt(&data->set.str[STRING_SSL_RANDOM_FILE],
722 va_arg(param, char *));
724 case CURLOPT_EGDSOCKET:
726 * The Entropy Gathering Daemon socket pathname
728 result = setstropt(&data->set.str[STRING_SSL_EGDSOCKET],
729 va_arg(param, char *));
731 case CURLOPT_MAXCONNECTS:
733 * Set the absolute number of maximum simultaneous alive connection that
734 * libcurl is allowed to have.
736 data->set.maxconnects = va_arg(param, long);
738 case CURLOPT_FORBID_REUSE:
740 * When this transfer is done, it must not be left to be reused by a
741 * subsequent transfer but shall be closed immediately.
743 data->set.reuse_forbid = (0 != va_arg(param, long))?TRUE:FALSE;
745 case CURLOPT_FRESH_CONNECT:
747 * This transfer shall not use a previously cached connection but
748 * should be made with a fresh new connect!
750 data->set.reuse_fresh = (0 != va_arg(param, long))?TRUE:FALSE;
752 case CURLOPT_VERBOSE:
754 * Verbose means infof() calls that give a lot of information about
755 * the connection and transfer procedures as well as internal choices.
757 data->set.verbose = (0 != va_arg(param, long))?TRUE:FALSE;
761 * Set to include the header in the general data output stream.
763 data->set.include_header = (0 != va_arg(param, long))?TRUE:FALSE;
765 case CURLOPT_NOPROGRESS:
767 * Shut off the internal supported progress meter
769 data->set.hide_progress = (0 != va_arg(param, long))?TRUE:FALSE;
770 if(data->set.hide_progress)
771 data->progress.flags |= PGRS_HIDE;
773 data->progress.flags &= ~PGRS_HIDE;
777 * Do not include the body part in the output data stream.
779 data->set.opt_no_body = (0 != va_arg(param, long))?TRUE:FALSE;
781 case CURLOPT_FAILONERROR:
783 * Don't output the >=400 error code HTML-page, but instead only
786 data->set.http_fail_on_error = (0 != va_arg(param, long))?TRUE:FALSE;
791 * We want to sent data to the remote host. If this is HTTP, that equals
792 * using the PUT request.
794 data->set.upload = (0 != va_arg(param, long))?TRUE:FALSE;
795 if(data->set.upload) {
796 /* If this is HTTP, PUT is what's needed to "upload" */
797 data->set.httpreq = HTTPREQ_PUT;
798 data->set.opt_no_body = FALSE; /* this is implied */
801 /* In HTTP, the opposite of upload is GET (unless NOBODY is true as
802 then this can be changed to HEAD later on) */
803 data->set.httpreq = HTTPREQ_GET;
805 case CURLOPT_FILETIME:
807 * Try to get the file time of the remote document. The time will
808 * later (possibly) become available using curl_easy_getinfo().
810 data->set.get_filetime = (0 != va_arg(param, long))?TRUE:FALSE;
812 case CURLOPT_FTP_CREATE_MISSING_DIRS:
814 * An FTP option that modifies an upload to create missing directories on
817 switch(va_arg(param, long)) {
819 data->set.ftp_create_missing_dirs = 0;
822 data->set.ftp_create_missing_dirs = 1;
825 data->set.ftp_create_missing_dirs = 2;
828 /* reserve other values for future use */
829 result = CURLE_UNKNOWN_OPTION;
833 case CURLOPT_SERVER_RESPONSE_TIMEOUT:
835 * Option that specifies how quickly an server response must be obtained
836 * before it is considered failure. For pingpong protocols.
838 data->set.server_response_timeout = va_arg( param , long ) * 1000;
840 case CURLOPT_TFTP_BLKSIZE:
842 * TFTP option that specifies the block size to use for data transmission
844 data->set.tftp_blksize = va_arg(param, long);
846 case CURLOPT_DIRLISTONLY:
848 * An option that changes the command to one that asks for a list
849 * only, no file info details.
851 data->set.ftp_list_only = (0 != va_arg(param, long))?TRUE:FALSE;
855 * We want to upload and append to an existing file.
857 data->set.ftp_append = (0 != va_arg(param, long))?TRUE:FALSE;
859 case CURLOPT_FTP_FILEMETHOD:
861 * How do access files over FTP.
863 data->set.ftp_filemethod = (curl_ftpfile)va_arg(param, long);
867 * Parse the $HOME/.netrc file
869 data->set.use_netrc = (enum CURL_NETRC_OPTION)va_arg(param, long);
871 case CURLOPT_NETRC_FILE:
873 * Use this file instead of the $HOME/.netrc file
875 result = setstropt(&data->set.str[STRING_NETRC_FILE],
876 va_arg(param, char *));
878 case CURLOPT_TRANSFERTEXT:
880 * This option was previously named 'FTPASCII'. Renamed to work with
881 * more protocols than merely FTP.
883 * Transfer using ASCII (instead of BINARY).
885 data->set.prefer_ascii = (0 != va_arg(param, long))?TRUE:FALSE;
887 case CURLOPT_TIMECONDITION:
889 * Set HTTP time condition. This must be one of the defines in the
890 * curl/curl.h header file.
892 data->set.timecondition = (curl_TimeCond)va_arg(param, long);
894 case CURLOPT_TIMEVALUE:
896 * This is the value to compare with the remote document with the
897 * method set with CURLOPT_TIMECONDITION
899 data->set.timevalue = (time_t)va_arg(param, long);
901 case CURLOPT_SSLVERSION:
903 * Set explicit SSL version to try to connect with, as some SSL
904 * implementations are lame.
907 data->set.ssl.version = va_arg(param, long);
909 result = CURLE_UNKNOWN_OPTION;
913 #ifndef CURL_DISABLE_HTTP
914 case CURLOPT_AUTOREFERER:
916 * Switch on automatic referer that gets set if curl follows locations.
918 data->set.http_auto_referer = (0 != va_arg(param, long))?TRUE:FALSE;
921 case CURLOPT_ACCEPT_ENCODING:
923 * String to use at the value of Accept-Encoding header.
925 * If the encoding is set to "" we use an Accept-Encoding header that
926 * encompasses all the encodings we support.
927 * If the encoding is set to NULL we don't send an Accept-Encoding header
928 * and ignore an received Content-Encoding header.
931 argptr = va_arg(param, char *);
932 result = setstropt(&data->set.str[STRING_ENCODING],
933 (argptr && !*argptr)?
934 (char *) ALL_CONTENT_ENCODINGS: argptr);
937 case CURLOPT_TRANSFER_ENCODING:
938 data->set.http_transfer_encoding = (0 != va_arg(param, long))?TRUE:FALSE;
941 case CURLOPT_FOLLOWLOCATION:
943 * Follow Location: header hints on a HTTP-server.
945 data->set.http_follow_location = (0 != va_arg(param, long))?TRUE:FALSE;
948 case CURLOPT_UNRESTRICTED_AUTH:
950 * Send authentication (user+password) when following locations, even when
953 data->set.http_disable_hostname_check_before_authentication =
954 (0 != va_arg(param, long))?TRUE:FALSE;
957 case CURLOPT_MAXREDIRS:
959 * The maximum amount of hops you allow curl to follow Location:
960 * headers. This should mostly be used to detect never-ending loops.
962 data->set.maxredirs = va_arg(param, long);
965 case CURLOPT_POSTREDIR:
968 * Set the behaviour of POST when redirecting
969 * CURL_REDIR_GET_ALL - POST is changed to GET after 301 and 302
970 * CURL_REDIR_POST_301 - POST is kept as POST after 301
971 * CURL_REDIR_POST_302 - POST is kept as POST after 302
972 * CURL_REDIR_POST_303 - POST is kept as POST after 303
973 * CURL_REDIR_POST_ALL - POST is kept as POST after 301, 302 and 303
974 * other - POST is kept as POST after 301 and 302
976 int postRedir = curlx_sltosi(va_arg(param, long));
977 data->set.keep_post = postRedir & CURL_REDIR_POST_ALL;
982 /* Does this option serve a purpose anymore? Yes it does, when
983 CURLOPT_POSTFIELDS isn't used and the POST data is read off the
985 if(va_arg(param, long)) {
986 data->set.httpreq = HTTPREQ_POST;
987 data->set.opt_no_body = FALSE; /* this is implied */
990 data->set.httpreq = HTTPREQ_GET;
993 case CURLOPT_COPYPOSTFIELDS:
995 * A string with POST data. Makes curl HTTP POST. Even if it is NULL.
996 * If needed, CURLOPT_POSTFIELDSIZE must have been set prior to
997 * CURLOPT_COPYPOSTFIELDS and not altered later.
999 argptr = va_arg(param, char *);
1001 if(!argptr || data->set.postfieldsize == -1)
1002 result = setstropt(&data->set.str[STRING_COPYPOSTFIELDS], argptr);
1005 * Check that requested length does not overflow the size_t type.
1008 if((data->set.postfieldsize < 0) ||
1009 ((sizeof(curl_off_t) != sizeof(size_t)) &&
1010 (data->set.postfieldsize > (curl_off_t)((size_t)-1))))
1011 result = CURLE_OUT_OF_MEMORY;
1015 (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1017 /* Allocate even when size == 0. This satisfies the need of possible
1018 later address compare to detect the COPYPOSTFIELDS mode, and
1019 to mark that postfields is used rather than read function or
1022 p = malloc((size_t)(data->set.postfieldsize?
1023 data->set.postfieldsize:1));
1026 result = CURLE_OUT_OF_MEMORY;
1028 if(data->set.postfieldsize)
1029 memcpy(p, argptr, (size_t)data->set.postfieldsize);
1031 data->set.str[STRING_COPYPOSTFIELDS] = p;
1036 data->set.postfields = data->set.str[STRING_COPYPOSTFIELDS];
1037 data->set.httpreq = HTTPREQ_POST;
1040 case CURLOPT_POSTFIELDS:
1042 * Like above, but use static data instead of copying it.
1044 data->set.postfields = va_arg(param, void *);
1045 /* Release old copied data. */
1046 (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1047 data->set.httpreq = HTTPREQ_POST;
1050 case CURLOPT_POSTFIELDSIZE:
1052 * The size of the POSTFIELD data to prevent libcurl to do strlen() to
1053 * figure it out. Enables binary posts.
1055 bigsize = va_arg(param, long);
1057 if(data->set.postfieldsize < bigsize &&
1058 data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
1059 /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */
1060 (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1061 data->set.postfields = NULL;
1064 data->set.postfieldsize = bigsize;
1067 case CURLOPT_POSTFIELDSIZE_LARGE:
1069 * The size of the POSTFIELD data to prevent libcurl to do strlen() to
1070 * figure it out. Enables binary posts.
1072 bigsize = va_arg(param, curl_off_t);
1074 if(data->set.postfieldsize < bigsize &&
1075 data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
1076 /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */
1077 (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1078 data->set.postfields = NULL;
1081 data->set.postfieldsize = bigsize;
1084 case CURLOPT_HTTPPOST:
1086 * Set to make us do HTTP POST
1088 data->set.httppost = va_arg(param, struct curl_httppost *);
1089 data->set.httpreq = HTTPREQ_POST_FORM;
1090 data->set.opt_no_body = FALSE; /* this is implied */
1093 case CURLOPT_REFERER:
1095 * String to set in the HTTP Referer: field.
1097 if(data->change.referer_alloc) {
1098 Curl_safefree(data->change.referer);
1099 data->change.referer_alloc = FALSE;
1101 result = setstropt(&data->set.str[STRING_SET_REFERER],
1102 va_arg(param, char *));
1103 data->change.referer = data->set.str[STRING_SET_REFERER];
1106 case CURLOPT_USERAGENT:
1108 * String to use in the HTTP User-Agent field
1110 result = setstropt(&data->set.str[STRING_USERAGENT],
1111 va_arg(param, char *));
1114 case CURLOPT_HTTPHEADER:
1116 * Set a list with HTTP headers to use (or replace internals with)
1118 data->set.headers = va_arg(param, struct curl_slist *);
1121 case CURLOPT_PROXYHEADER:
1123 * Set a list with proxy headers to use (or replace internals with)
1125 * Since CURLOPT_HTTPHEADER was the only way to set HTTP headers for a
1126 * long time we remain doing it this way until CURLOPT_PROXYHEADER is
1127 * used. As soon as this option has been used, if set to anything but
1128 * NULL, custom headers for proxies are only picked from this list.
1130 * Set this option to NULL to restore the previous behavior.
1132 data->set.proxyheaders = va_arg(param, struct curl_slist *);
1135 case CURLOPT_HEADEROPT:
1137 * Set header option.
1139 arg = va_arg(param, long);
1140 data->set.sep_headers = (arg & CURLHEADER_SEPARATE)? TRUE: FALSE;
1143 case CURLOPT_HTTP200ALIASES:
1145 * Set a list of aliases for HTTP 200 in response header
1147 data->set.http200aliases = va_arg(param, struct curl_slist *);
1150 #if !defined(CURL_DISABLE_COOKIES)
1151 case CURLOPT_COOKIE:
1153 * Cookie string to send to the remote server in the request.
1155 result = setstropt(&data->set.str[STRING_COOKIE],
1156 va_arg(param, char *));
1159 case CURLOPT_COOKIEFILE:
1161 * Set cookie file to read and parse. Can be used multiple times.
1163 argptr = (char *)va_arg(param, void *);
1165 struct curl_slist *cl;
1166 /* append the cookie file name to the list of file names, and deal with
1168 cl = curl_slist_append(data->change.cookielist, argptr);
1170 curl_slist_free_all(data->change.cookielist);
1171 data->change.cookielist = NULL;
1172 return CURLE_OUT_OF_MEMORY;
1174 data->change.cookielist = cl; /* store the list for later use */
1178 case CURLOPT_COOKIEJAR:
1180 * Set cookie file name to dump all cookies to when we're done.
1183 struct CookieInfo *newcookies;
1184 result = setstropt(&data->set.str[STRING_COOKIEJAR],
1185 va_arg(param, char *));
1188 * Activate the cookie parser. This may or may not already
1191 newcookies = Curl_cookie_init(data, NULL, data->cookies,
1192 data->set.cookiesession);
1194 result = CURLE_OUT_OF_MEMORY;
1195 data->cookies = newcookies;
1199 case CURLOPT_COOKIESESSION:
1201 * Set this option to TRUE to start a new "cookie session". It will
1202 * prevent the forthcoming read-cookies-from-file actions to accept
1203 * cookies that are marked as being session cookies, as they belong to a
1206 * In the original Netscape cookie spec, "session cookies" are cookies
1207 * with no expire date set. RFC2109 describes the same action if no
1208 * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds
1209 * a 'Discard' action that can enforce the discard even for cookies that
1212 * We run mostly with the original cookie spec, as hardly anyone implements
1215 data->set.cookiesession = (0 != va_arg(param, long))?TRUE:FALSE;
1218 case CURLOPT_COOKIELIST:
1219 argptr = va_arg(param, char *);
1224 if(Curl_raw_equal(argptr, "ALL")) {
1225 /* clear all cookies */
1226 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
1227 Curl_cookie_clearall(data->cookies);
1228 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
1230 else if(Curl_raw_equal(argptr, "SESS")) {
1231 /* clear session cookies */
1232 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
1233 Curl_cookie_clearsess(data->cookies);
1234 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
1236 else if(Curl_raw_equal(argptr, "FLUSH")) {
1237 /* flush cookies to file, takes care of the locking */
1238 Curl_flush_cookies(data, 0);
1240 else if(Curl_raw_equal(argptr, "RELOAD")) {
1241 /* reload cookies from file */
1242 Curl_cookie_loadfiles(data);
1247 /* if cookie engine was not running, activate it */
1248 data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE);
1250 argptr = strdup(argptr);
1251 if(!argptr || !data->cookies) {
1252 result = CURLE_OUT_OF_MEMORY;
1256 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
1258 if(checkprefix("Set-Cookie:", argptr))
1259 /* HTTP Header format line */
1260 Curl_cookie_add(data, data->cookies, TRUE, argptr + 11, NULL, NULL);
1263 /* Netscape format line */
1264 Curl_cookie_add(data, data->cookies, FALSE, argptr, NULL, NULL);
1266 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
1272 #endif /* CURL_DISABLE_COOKIES */
1274 case CURLOPT_HTTPGET:
1276 * Set to force us do HTTP GET
1278 if(va_arg(param, long)) {
1279 data->set.httpreq = HTTPREQ_GET;
1280 data->set.upload = FALSE; /* switch off upload */
1281 data->set.opt_no_body = FALSE; /* this is implied */
1285 case CURLOPT_HTTP_VERSION:
1287 * This sets a requested HTTP version to be used. The value is one of
1288 * the listed enums in curl/curl.h.
1290 arg = va_arg(param, long);
1292 if(arg == CURL_HTTP_VERSION_2_0)
1293 return CURLE_UNSUPPORTED_PROTOCOL;
1295 data->set.httpversion = arg;
1298 case CURLOPT_HTTPAUTH:
1300 * Set HTTP Authentication type BITMASK.
1305 unsigned long auth = va_arg(param, unsigned long);
1307 if(auth == CURLAUTH_NONE) {
1308 data->set.httpauth = auth;
1312 /* the DIGEST_IE bit is only used to set a special marker, for all the
1313 rest we need to handle it as normal DIGEST */
1314 data->state.authhost.iestyle = (auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE;
1316 if(auth & CURLAUTH_DIGEST_IE) {
1317 auth |= CURLAUTH_DIGEST; /* set standard digest bit */
1318 auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */
1321 /* switch off bits we can't support */
1323 auth &= ~CURLAUTH_NTLM; /* no NTLM support */
1324 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
1325 #elif !defined(NTLM_WB_ENABLED)
1326 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
1329 auth &= ~CURLAUTH_NEGOTIATE; /* no Negotiate (SPNEGO) auth without
1333 /* check if any auth bit lower than CURLAUTH_ONLY is still set */
1336 while(bitcheck < 31) {
1337 if(auth & (1UL << bitcheck++)) {
1343 return CURLE_NOT_BUILT_IN; /* no supported types left! */
1345 data->set.httpauth = auth;
1349 case CURLOPT_EXPECT_100_TIMEOUT_MS:
1351 * Time to wait for a response to a HTTP request containing an
1352 * Expect: 100-continue header before sending the data anyway.
1354 data->set.expect_100_timeout = va_arg(param, long);
1357 #endif /* CURL_DISABLE_HTTP */
1359 case CURLOPT_CUSTOMREQUEST:
1361 * Set a custom string to use as request
1363 result = setstropt(&data->set.str[STRING_CUSTOMREQUEST],
1364 va_arg(param, char *));
1367 data->set.httpreq = HTTPREQ_CUSTOM;
1368 here, we continue as if we were using the already set type
1369 and this just changes the actual request keyword */
1372 #ifndef CURL_DISABLE_PROXY
1373 case CURLOPT_HTTPPROXYTUNNEL:
1375 * Tunnel operations through the proxy instead of normal proxy use
1377 data->set.tunnel_thru_httpproxy = (0 != va_arg(param, long))?TRUE:FALSE;
1380 case CURLOPT_PROXYPORT:
1382 * Explicitly set HTTP proxy port number.
1384 data->set.proxyport = va_arg(param, long);
1387 case CURLOPT_PROXYAUTH:
1389 * Set HTTP Authentication type BITMASK.
1394 unsigned long auth = va_arg(param, unsigned long);
1396 if(auth == CURLAUTH_NONE) {
1397 data->set.proxyauth = auth;
1401 /* the DIGEST_IE bit is only used to set a special marker, for all the
1402 rest we need to handle it as normal DIGEST */
1403 data->state.authproxy.iestyle = (auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE;
1405 if(auth & CURLAUTH_DIGEST_IE) {
1406 auth |= CURLAUTH_DIGEST; /* set standard digest bit */
1407 auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */
1409 /* switch off bits we can't support */
1411 auth &= ~CURLAUTH_NTLM; /* no NTLM support */
1412 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
1413 #elif !defined(NTLM_WB_ENABLED)
1414 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
1417 auth &= ~CURLAUTH_NEGOTIATE; /* no Negotiate (SPNEGO) auth without
1421 /* check if any auth bit lower than CURLAUTH_ONLY is still set */
1424 while(bitcheck < 31) {
1425 if(auth & (1UL << bitcheck++)) {
1431 return CURLE_NOT_BUILT_IN; /* no supported types left! */
1433 data->set.proxyauth = auth;
1439 * Set proxy server:port to use as HTTP proxy.
1441 * If the proxy is set to "" we explicitly say that we don't want to use a
1442 * proxy (even though there might be environment variables saying so).
1444 * Setting it to NULL, means no proxy but allows the environment variables
1447 result = setstropt(&data->set.str[STRING_PROXY],
1448 va_arg(param, char *));
1451 case CURLOPT_PROXYTYPE:
1453 * Set proxy type. HTTP/HTTP_1_0/SOCKS4/SOCKS4a/SOCKS5/SOCKS5_HOSTNAME
1455 data->set.proxytype = (curl_proxytype)va_arg(param, long);
1458 case CURLOPT_PROXY_TRANSFER_MODE:
1460 * set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy
1462 switch (va_arg(param, long)) {
1464 data->set.proxy_transfer_mode = FALSE;
1467 data->set.proxy_transfer_mode = TRUE;
1470 /* reserve other values for future use */
1471 result = CURLE_UNKNOWN_OPTION;
1475 #endif /* CURL_DISABLE_PROXY */
1477 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
1478 case CURLOPT_SOCKS5_GSSAPI_SERVICE:
1480 * Set GSS-API service name
1482 result = setstropt(&data->set.str[STRING_SOCKS5_GSSAPI_SERVICE],
1483 va_arg(param, char *));
1486 case CURLOPT_PROXY_SERVICE_NAME:
1488 * Set negotiate proxy service name
1490 result = setstropt(&data->set.str[STRING_PROXY_SERVICE_NAME],
1491 va_arg(param, char *));
1494 case CURLOPT_SOCKS5_GSSAPI_NEC:
1496 * set flag for nec socks5 support
1498 data->set.socks5_gssapi_nec = (0 != va_arg(param, long))?TRUE:FALSE;
1501 case CURLOPT_SERVICE_NAME:
1503 * Set negotiate service identity
1505 result = setstropt(&data->set.str[STRING_SERVICE_NAME],
1506 va_arg(param, char *));
1511 case CURLOPT_HEADERDATA:
1513 * Custom pointer to pass the header write callback function
1515 data->set.writeheader = (void *)va_arg(param, void *);
1517 case CURLOPT_ERRORBUFFER:
1519 * Error buffer provided by the caller to get the human readable
1522 data->set.errorbuffer = va_arg(param, char *);
1524 case CURLOPT_WRITEDATA:
1526 * FILE pointer to write to. Or possibly
1527 * used as argument to the write callback.
1529 data->set.out = va_arg(param, void *);
1531 case CURLOPT_FTPPORT:
1533 * Use FTP PORT, this also specifies which IP address to use
1535 result = setstropt(&data->set.str[STRING_FTPPORT],
1536 va_arg(param, char *));
1537 data->set.ftp_use_port = (NULL != data->set.str[STRING_FTPPORT]) ?
1541 case CURLOPT_FTP_USE_EPRT:
1542 data->set.ftp_use_eprt = (0 != va_arg(param, long))?TRUE:FALSE;
1545 case CURLOPT_FTP_USE_EPSV:
1546 data->set.ftp_use_epsv = (0 != va_arg(param, long))?TRUE:FALSE;
1549 case CURLOPT_FTP_USE_PRET:
1550 data->set.ftp_use_pret = (0 != va_arg(param, long))?TRUE:FALSE;
1553 case CURLOPT_FTP_SSL_CCC:
1554 data->set.ftp_ccc = (curl_ftpccc)va_arg(param, long);
1557 case CURLOPT_FTP_SKIP_PASV_IP:
1559 * Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the
1560 * bypass of the IP address in PASV responses.
1562 data->set.ftp_skip_ip = (0 != va_arg(param, long))?TRUE:FALSE;
1565 case CURLOPT_READDATA:
1567 * FILE pointer to read the file to be uploaded from. Or possibly
1568 * used as argument to the read callback.
1570 data->set.in = va_arg(param, void *);
1572 case CURLOPT_INFILESIZE:
1574 * If known, this should inform curl about the file size of the
1575 * to-be-uploaded file.
1577 data->set.filesize = va_arg(param, long);
1579 case CURLOPT_INFILESIZE_LARGE:
1581 * If known, this should inform curl about the file size of the
1582 * to-be-uploaded file.
1584 data->set.filesize = va_arg(param, curl_off_t);
1586 case CURLOPT_LOW_SPEED_LIMIT:
1588 * The low speed limit that if transfers are below this for
1589 * CURLOPT_LOW_SPEED_TIME, the transfer is aborted.
1591 data->set.low_speed_limit=va_arg(param, long);
1593 case CURLOPT_MAX_SEND_SPEED_LARGE:
1595 * When transfer uploads are faster then CURLOPT_MAX_SEND_SPEED_LARGE
1596 * bytes per second the transfer is throttled..
1598 data->set.max_send_speed=va_arg(param, curl_off_t);
1600 case CURLOPT_MAX_RECV_SPEED_LARGE:
1602 * When receiving data faster than CURLOPT_MAX_RECV_SPEED_LARGE bytes per
1603 * second the transfer is throttled..
1605 data->set.max_recv_speed=va_arg(param, curl_off_t);
1607 case CURLOPT_LOW_SPEED_TIME:
1609 * The low speed time that if transfers are below the set
1610 * CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted.
1612 data->set.low_speed_time=va_arg(param, long);
1618 if(data->change.url_alloc) {
1619 /* the already set URL is allocated, free it first! */
1620 Curl_safefree(data->change.url);
1621 data->change.url_alloc = FALSE;
1623 result = setstropt(&data->set.str[STRING_SET_URL],
1624 va_arg(param, char *));
1625 data->change.url = data->set.str[STRING_SET_URL];
1629 * The port number to use when getting the URL
1631 data->set.use_port = va_arg(param, long);
1633 case CURLOPT_TIMEOUT:
1635 * The maximum time you allow curl to use for a single transfer
1638 data->set.timeout = va_arg(param, long) * 1000L;
1641 case CURLOPT_TIMEOUT_MS:
1642 data->set.timeout = va_arg(param, long);
1645 case CURLOPT_CONNECTTIMEOUT:
1647 * The maximum time you allow curl to use to connect.
1649 data->set.connecttimeout = va_arg(param, long) * 1000L;
1652 case CURLOPT_CONNECTTIMEOUT_MS:
1653 data->set.connecttimeout = va_arg(param, long);
1656 case CURLOPT_ACCEPTTIMEOUT_MS:
1658 * The maximum time you allow curl to wait for server connect
1660 data->set.accepttimeout = va_arg(param, long);
1663 case CURLOPT_USERPWD:
1665 * user:password to use in the operation
1667 result = setstropt_userpwd(va_arg(param, char *),
1668 &data->set.str[STRING_USERNAME],
1669 &data->set.str[STRING_PASSWORD]);
1672 case CURLOPT_USERNAME:
1674 * authentication user name to use in the operation
1676 result = setstropt(&data->set.str[STRING_USERNAME],
1677 va_arg(param, char *));
1680 case CURLOPT_PASSWORD:
1682 * authentication password to use in the operation
1684 result = setstropt(&data->set.str[STRING_PASSWORD],
1685 va_arg(param, char *));
1688 case CURLOPT_LOGIN_OPTIONS:
1690 * authentication options to use in the operation
1692 result = setstropt(&data->set.str[STRING_OPTIONS],
1693 va_arg(param, char *));
1696 case CURLOPT_XOAUTH2_BEARER:
1698 * XOAUTH2 bearer token to use in the operation
1700 result = setstropt(&data->set.str[STRING_BEARER],
1701 va_arg(param, char *));
1704 case CURLOPT_POSTQUOTE:
1706 * List of RAW FTP commands to use after a transfer
1708 data->set.postquote = va_arg(param, struct curl_slist *);
1710 case CURLOPT_PREQUOTE:
1712 * List of RAW FTP commands to use prior to RETR (Wesley Laxton)
1714 data->set.prequote = va_arg(param, struct curl_slist *);
1718 * List of RAW FTP commands to use before a transfer
1720 data->set.quote = va_arg(param, struct curl_slist *);
1722 case CURLOPT_RESOLVE:
1724 * List of NAME:[address] names to populate the DNS cache with
1725 * Prefix the NAME with dash (-) to _remove_ the name from the cache.
1727 * Names added with this API will remain in the cache until explicitly
1728 * removed or the handle is cleaned up.
1730 * This API can remove any name from the DNS cache, but only entries
1731 * that aren't actually in use right now will be pruned immediately.
1733 data->set.resolve = va_arg(param, struct curl_slist *);
1734 data->change.resolve = data->set.resolve;
1736 case CURLOPT_PROGRESSFUNCTION:
1738 * Progress callback function
1740 data->set.fprogress = va_arg(param, curl_progress_callback);
1741 if(data->set.fprogress)
1742 data->progress.callback = TRUE; /* no longer internal */
1744 data->progress.callback = FALSE; /* NULL enforces internal */
1747 case CURLOPT_XFERINFOFUNCTION:
1749 * Transfer info callback function
1751 data->set.fxferinfo = va_arg(param, curl_xferinfo_callback);
1752 if(data->set.fxferinfo)
1753 data->progress.callback = TRUE; /* no longer internal */
1755 data->progress.callback = FALSE; /* NULL enforces internal */
1759 case CURLOPT_PROGRESSDATA:
1761 * Custom client data to pass to the progress callback
1763 data->set.progress_client = va_arg(param, void *);
1766 #ifndef CURL_DISABLE_PROXY
1767 case CURLOPT_PROXYUSERPWD:
1769 * user:password needed to use the proxy
1771 result = setstropt_userpwd(va_arg(param, char *),
1772 &data->set.str[STRING_PROXYUSERNAME],
1773 &data->set.str[STRING_PROXYPASSWORD]);
1775 case CURLOPT_PROXYUSERNAME:
1777 * authentication user name to use in the operation
1779 result = setstropt(&data->set.str[STRING_PROXYUSERNAME],
1780 va_arg(param, char *));
1782 case CURLOPT_PROXYPASSWORD:
1784 * authentication password to use in the operation
1786 result = setstropt(&data->set.str[STRING_PROXYPASSWORD],
1787 va_arg(param, char *));
1789 case CURLOPT_NOPROXY:
1791 * proxy exception list
1793 result = setstropt(&data->set.str[STRING_NOPROXY],
1794 va_arg(param, char *));
1800 * What range of the file you want to transfer
1802 result = setstropt(&data->set.str[STRING_SET_RANGE],
1803 va_arg(param, char *));
1805 case CURLOPT_RESUME_FROM:
1807 * Resume transfer at the give file position
1809 data->set.set_resume_from = va_arg(param, long);
1811 case CURLOPT_RESUME_FROM_LARGE:
1813 * Resume transfer at the give file position
1815 data->set.set_resume_from = va_arg(param, curl_off_t);
1817 case CURLOPT_DEBUGFUNCTION:
1819 * stderr write callback.
1821 data->set.fdebug = va_arg(param, curl_debug_callback);
1823 * if the callback provided is NULL, it'll use the default callback
1826 case CURLOPT_DEBUGDATA:
1828 * Set to a void * that should receive all error writes. This
1829 * defaults to CURLOPT_STDERR for normal operations.
1831 data->set.debugdata = va_arg(param, void *);
1833 case CURLOPT_STDERR:
1835 * Set to a FILE * that should receive all error writes. This
1836 * defaults to stderr for normal operations.
1838 data->set.err = va_arg(param, FILE *);
1840 data->set.err = stderr;
1842 case CURLOPT_HEADERFUNCTION:
1844 * Set header write callback
1846 data->set.fwrite_header = va_arg(param, curl_write_callback);
1848 case CURLOPT_WRITEFUNCTION:
1850 * Set data write callback
1852 data->set.fwrite_func = va_arg(param, curl_write_callback);
1853 if(!data->set.fwrite_func) {
1854 data->set.is_fwrite_set = 0;
1855 /* When set to NULL, reset to our internal default function */
1856 data->set.fwrite_func = (curl_write_callback)fwrite;
1859 data->set.is_fwrite_set = 1;
1861 case CURLOPT_READFUNCTION:
1863 * Read data callback
1865 data->set.fread_func = va_arg(param, curl_read_callback);
1866 if(!data->set.fread_func) {
1867 data->set.is_fread_set = 0;
1868 /* When set to NULL, reset to our internal default function */
1869 data->set.fread_func = (curl_read_callback)fread;
1872 data->set.is_fread_set = 1;
1874 case CURLOPT_SEEKFUNCTION:
1876 * Seek callback. Might be NULL.
1878 data->set.seek_func = va_arg(param, curl_seek_callback);
1880 case CURLOPT_SEEKDATA:
1882 * Seek control callback. Might be NULL.
1884 data->set.seek_client = va_arg(param, void *);
1886 case CURLOPT_CONV_FROM_NETWORK_FUNCTION:
1888 * "Convert from network encoding" callback
1890 data->set.convfromnetwork = va_arg(param, curl_conv_callback);
1892 case CURLOPT_CONV_TO_NETWORK_FUNCTION:
1894 * "Convert to network encoding" callback
1896 data->set.convtonetwork = va_arg(param, curl_conv_callback);
1898 case CURLOPT_CONV_FROM_UTF8_FUNCTION:
1900 * "Convert from UTF-8 encoding" callback
1902 data->set.convfromutf8 = va_arg(param, curl_conv_callback);
1904 case CURLOPT_IOCTLFUNCTION:
1906 * I/O control callback. Might be NULL.
1908 data->set.ioctl_func = va_arg(param, curl_ioctl_callback);
1910 case CURLOPT_IOCTLDATA:
1912 * I/O control data pointer. Might be NULL.
1914 data->set.ioctl_client = va_arg(param, void *);
1916 case CURLOPT_SSLCERT:
1918 * String that holds file name of the SSL certificate to use
1920 result = setstropt(&data->set.str[STRING_CERT],
1921 va_arg(param, char *));
1923 case CURLOPT_SSLCERTTYPE:
1925 * String that holds file type of the SSL certificate to use
1927 result = setstropt(&data->set.str[STRING_CERT_TYPE],
1928 va_arg(param, char *));
1930 case CURLOPT_SSLKEY:
1932 * String that holds file name of the SSL key to use
1934 result = setstropt(&data->set.str[STRING_KEY],
1935 va_arg(param, char *));
1937 case CURLOPT_SSLKEYTYPE:
1939 * String that holds file type of the SSL key to use
1941 result = setstropt(&data->set.str[STRING_KEY_TYPE],
1942 va_arg(param, char *));
1944 case CURLOPT_KEYPASSWD:
1946 * String that holds the SSL or SSH private key password.
1948 result = setstropt(&data->set.str[STRING_KEY_PASSWD],
1949 va_arg(param, char *));
1951 case CURLOPT_SSLENGINE:
1953 * String that holds the SSL crypto engine.
1955 argptr = va_arg(param, char *);
1956 if(argptr && argptr[0])
1957 result = Curl_ssl_set_engine(data, argptr);
1960 case CURLOPT_SSLENGINE_DEFAULT:
1962 * flag to set engine as default.
1964 result = Curl_ssl_set_engine_default(data);
1968 * Kludgy option to enable CRLF conversions. Subject for removal.
1970 data->set.crlf = (0 != va_arg(param, long))?TRUE:FALSE;
1973 case CURLOPT_INTERFACE:
1975 * Set what interface or address/hostname to bind the socket to when
1976 * performing an operation and thus what from-IP your connection will use.
1978 result = setstropt(&data->set.str[STRING_DEVICE],
1979 va_arg(param, char *));
1981 case CURLOPT_LOCALPORT:
1983 * Set what local port to bind the socket to when performing an operation.
1985 data->set.localport = curlx_sltous(va_arg(param, long));
1987 case CURLOPT_LOCALPORTRANGE:
1989 * Set number of local ports to try, starting with CURLOPT_LOCALPORT.
1991 data->set.localportrange = curlx_sltosi(va_arg(param, long));
1993 case CURLOPT_KRBLEVEL:
1995 * A string that defines the kerberos security level.
1997 result = setstropt(&data->set.str[STRING_KRB_LEVEL],
1998 va_arg(param, char *));
1999 data->set.krb = (NULL != data->set.str[STRING_KRB_LEVEL])?TRUE:FALSE;
2001 case CURLOPT_GSSAPI_DELEGATION:
2003 * GSS-API credential delegation
2005 data->set.gssapi_delegation = va_arg(param, long);
2007 case CURLOPT_SSL_VERIFYPEER:
2009 * Enable peer SSL verifying.
2011 data->set.ssl.verifypeer = (0 != va_arg(param, long))?TRUE:FALSE;
2013 case CURLOPT_SSL_VERIFYHOST:
2015 * Enable verification of the host name in the peer certificate
2017 arg = va_arg(param, long);
2019 /* Obviously people are not reading documentation and too many thought
2020 this argument took a boolean when it wasn't and misused it. We thus ban
2021 1 as a sensible input and we warn about its use. Then we only have the
2022 2 action internally stored as TRUE. */
2025 failf(data, "CURLOPT_SSL_VERIFYHOST no longer supports 1 as value!");
2026 return CURLE_BAD_FUNCTION_ARGUMENT;
2029 data->set.ssl.verifyhost = (0 != arg)?TRUE:FALSE;
2031 case CURLOPT_SSL_VERIFYSTATUS:
2033 * Enable certificate status verifying.
2035 if(!Curl_ssl_cert_status_request()) {
2036 result = CURLE_NOT_BUILT_IN;
2040 data->set.ssl.verifystatus = (0 != va_arg(param, long))?TRUE:FALSE;
2042 case CURLOPT_SSL_CTX_FUNCTION:
2043 #ifdef have_curlssl_ssl_ctx
2045 * Set a SSL_CTX callback
2047 data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback);
2049 result = CURLE_NOT_BUILT_IN;
2052 case CURLOPT_SSL_CTX_DATA:
2053 #ifdef have_curlssl_ssl_ctx
2055 * Set a SSL_CTX callback parameter pointer
2057 data->set.ssl.fsslctxp = va_arg(param, void *);
2059 result = CURLE_NOT_BUILT_IN;
2062 case CURLOPT_SSL_FALSESTART:
2064 * Enable TLS false start.
2066 if(!Curl_ssl_false_start()) {
2067 result = CURLE_NOT_BUILT_IN;
2071 data->set.ssl.falsestart = (0 != va_arg(param, long))?TRUE:FALSE;
2073 case CURLOPT_CERTINFO:
2074 #ifdef have_curlssl_certinfo
2075 data->set.ssl.certinfo = (0 != va_arg(param, long))?TRUE:FALSE;
2077 result = CURLE_NOT_BUILT_IN;
2080 case CURLOPT_PINNEDPUBLICKEY:
2082 * Set pinned public key for SSL connection.
2083 * Specify file name of the public key in DER format.
2085 result = setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY],
2086 va_arg(param, char *));
2088 case CURLOPT_CAINFO:
2090 * Set CA info for SSL connection. Specify file name of the CA certificate
2092 result = setstropt(&data->set.str[STRING_SSL_CAFILE],
2093 va_arg(param, char *));
2095 case CURLOPT_CAPATH:
2096 #ifdef have_curlssl_ca_path /* not supported by all backends */
2098 * Set CA path info for SSL connection. Specify directory name of the CA
2099 * certificates which have been prepared using openssl c_rehash utility.
2101 /* This does not work on windows. */
2102 result = setstropt(&data->set.str[STRING_SSL_CAPATH],
2103 va_arg(param, char *));
2105 result = CURLE_NOT_BUILT_IN;
2108 case CURLOPT_CRLFILE:
2110 * Set CRL file info for SSL connection. Specify file name of the CRL
2111 * to check certificates revocation
2113 result = setstropt(&data->set.str[STRING_SSL_CRLFILE],
2114 va_arg(param, char *));
2116 case CURLOPT_ISSUERCERT:
2118 * Set Issuer certificate file
2119 * to check certificates issuer
2121 result = setstropt(&data->set.str[STRING_SSL_ISSUERCERT],
2122 va_arg(param, char *));
2124 case CURLOPT_TELNETOPTIONS:
2126 * Set a linked list of telnet options
2128 data->set.telnet_options = va_arg(param, struct curl_slist *);
2131 case CURLOPT_BUFFERSIZE:
2133 * The application kindly asks for a differently sized receive buffer.
2134 * If it seems reasonable, we'll use it.
2136 data->set.buffer_size = va_arg(param, long);
2138 if((data->set.buffer_size> (BUFSIZE -1 )) ||
2139 (data->set.buffer_size < 1))
2140 data->set.buffer_size = 0; /* huge internal default */
2144 case CURLOPT_NOSIGNAL:
2146 * The application asks not to set any signal() or alarm() handlers,
2147 * even when using a timeout.
2149 data->set.no_signal = (0 != va_arg(param, long))?TRUE:FALSE;
2154 struct Curl_share *set;
2155 set = va_arg(param, struct Curl_share *);
2157 /* disconnect from old share, if any */
2159 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
2161 if(data->dns.hostcachetype == HCACHE_SHARED) {
2162 data->dns.hostcache = NULL;
2163 data->dns.hostcachetype = HCACHE_NONE;
2166 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
2167 if(data->share->cookies == data->cookies)
2168 data->cookies = NULL;
2171 if(data->share->sslsession == data->state.session)
2172 data->state.session = NULL;
2174 data->share->dirty--;
2176 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
2180 /* use new share if it set */
2184 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
2186 data->share->dirty++;
2188 if(data->share->specifier & (1<< CURL_LOCK_DATA_DNS)) {
2189 /* use shared host cache */
2190 data->dns.hostcache = &data->share->hostcache;
2191 data->dns.hostcachetype = HCACHE_SHARED;
2193 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
2194 if(data->share->cookies) {
2195 /* use shared cookie list, first free own one if any */
2196 Curl_cookie_cleanup(data->cookies);
2197 /* enable cookies since we now use a share that uses cookies! */
2198 data->cookies = data->share->cookies;
2200 #endif /* CURL_DISABLE_HTTP */
2201 if(data->share->sslsession) {
2202 data->set.ssl.max_ssl_sessions = data->share->max_ssl_sessions;
2203 data->state.session = data->share->sslsession;
2205 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
2208 /* check for host cache not needed,
2209 * it will be done by curl_easy_perform */
2213 case CURLOPT_PRIVATE:
2215 * Set private data pointer.
2217 data->set.private_data = va_arg(param, void *);
2220 case CURLOPT_MAXFILESIZE:
2222 * Set the maximum size of a file to download.
2224 data->set.max_filesize = va_arg(param, long);
2228 case CURLOPT_USE_SSL:
2230 * Make transfers attempt to use SSL/TLS.
2232 data->set.use_ssl = (curl_usessl)va_arg(param, long);
2235 case CURLOPT_SSL_OPTIONS:
2236 arg = va_arg(param, long);
2237 data->set.ssl_enable_beast = !!(arg & CURLSSLOPT_ALLOW_BEAST);
2238 data->set.ssl_no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
2242 case CURLOPT_FTPSSLAUTH:
2244 * Set a specific auth for FTP-SSL transfers.
2246 data->set.ftpsslauth = (curl_ftpauth)va_arg(param, long);
2249 case CURLOPT_IPRESOLVE:
2250 data->set.ipver = va_arg(param, long);
2253 case CURLOPT_MAXFILESIZE_LARGE:
2255 * Set the maximum size of a file to download.
2257 data->set.max_filesize = va_arg(param, curl_off_t);
2260 case CURLOPT_TCP_NODELAY:
2262 * Enable or disable TCP_NODELAY, which will disable/enable the Nagle
2265 data->set.tcp_nodelay = (0 != va_arg(param, long))?TRUE:FALSE;
2268 case CURLOPT_FTP_ACCOUNT:
2269 result = setstropt(&data->set.str[STRING_FTP_ACCOUNT],
2270 va_arg(param, char *));
2273 case CURLOPT_IGNORE_CONTENT_LENGTH:
2274 data->set.ignorecl = (0 != va_arg(param, long))?TRUE:FALSE;
2277 case CURLOPT_CONNECT_ONLY:
2279 * No data transfer, set up connection and let application use the socket
2281 data->set.connect_only = (0 != va_arg(param, long))?TRUE:FALSE;
2284 case CURLOPT_FTP_ALTERNATIVE_TO_USER:
2285 result = setstropt(&data->set.str[STRING_FTP_ALTERNATIVE_TO_USER],
2286 va_arg(param, char *));
2289 case CURLOPT_SOCKOPTFUNCTION:
2291 * socket callback function: called after socket() but before connect()
2293 data->set.fsockopt = va_arg(param, curl_sockopt_callback);
2296 case CURLOPT_SOCKOPTDATA:
2298 * socket callback data pointer. Might be NULL.
2300 data->set.sockopt_client = va_arg(param, void *);
2303 case CURLOPT_OPENSOCKETFUNCTION:
2305 * open/create socket callback function: called instead of socket(),
2308 data->set.fopensocket = va_arg(param, curl_opensocket_callback);
2311 case CURLOPT_OPENSOCKETDATA:
2313 * socket callback data pointer. Might be NULL.
2315 data->set.opensocket_client = va_arg(param, void *);
2318 case CURLOPT_CLOSESOCKETFUNCTION:
2320 * close socket callback function: called instead of close()
2321 * when shutting down a connection
2323 data->set.fclosesocket = va_arg(param, curl_closesocket_callback);
2326 case CURLOPT_CLOSESOCKETDATA:
2328 * socket callback data pointer. Might be NULL.
2330 data->set.closesocket_client = va_arg(param, void *);
2333 case CURLOPT_SSL_SESSIONID_CACHE:
2334 data->set.ssl.sessionid = (0 != va_arg(param, long))?TRUE:FALSE;
2338 /* we only include SSH options if explicitly built to support SSH */
2339 case CURLOPT_SSH_AUTH_TYPES:
2340 data->set.ssh_auth_types = va_arg(param, long);
2343 case CURLOPT_SSH_PUBLIC_KEYFILE:
2345 * Use this file instead of the $HOME/.ssh/id_dsa.pub file
2347 result = setstropt(&data->set.str[STRING_SSH_PUBLIC_KEY],
2348 va_arg(param, char *));
2351 case CURLOPT_SSH_PRIVATE_KEYFILE:
2353 * Use this file instead of the $HOME/.ssh/id_dsa file
2355 result = setstropt(&data->set.str[STRING_SSH_PRIVATE_KEY],
2356 va_arg(param, char *));
2358 case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5:
2360 * Option to allow for the MD5 of the host public key to be checked
2361 * for validation purposes.
2363 result = setstropt(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5],
2364 va_arg(param, char *));
2366 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2367 case CURLOPT_SSH_KNOWNHOSTS:
2369 * Store the file name to read known hosts from.
2371 result = setstropt(&data->set.str[STRING_SSH_KNOWNHOSTS],
2372 va_arg(param, char *));
2375 case CURLOPT_SSH_KEYFUNCTION:
2376 /* setting to NULL is fine since the ssh.c functions themselves will
2377 then rever to use the internal default */
2378 data->set.ssh_keyfunc = va_arg(param, curl_sshkeycallback);
2381 case CURLOPT_SSH_KEYDATA:
2383 * Custom client data to pass to the SSH keyfunc callback
2385 data->set.ssh_keyfunc_userp = va_arg(param, void *);
2387 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2389 #endif /* USE_LIBSSH2 */
2391 case CURLOPT_HTTP_TRANSFER_DECODING:
2393 * disable libcurl transfer encoding is used
2395 data->set.http_te_skip = (0 == va_arg(param, long))?TRUE:FALSE;
2398 case CURLOPT_HTTP_CONTENT_DECODING:
2400 * raw data passed to the application when content encoding is used
2402 data->set.http_ce_skip = (0 == va_arg(param, long))?TRUE:FALSE;
2405 case CURLOPT_NEW_FILE_PERMS:
2407 * Uses these permissions instead of 0644
2409 data->set.new_file_perms = va_arg(param, long);
2412 case CURLOPT_NEW_DIRECTORY_PERMS:
2414 * Uses these permissions instead of 0755
2416 data->set.new_directory_perms = va_arg(param, long);
2419 case CURLOPT_ADDRESS_SCOPE:
2421 * We always get longs when passed plain numericals, but for this value we
2422 * know that an unsigned int will always hold the value so we blindly
2423 * typecast to this type
2425 data->set.scope_id = curlx_sltoui(va_arg(param, long));
2428 case CURLOPT_PROTOCOLS:
2429 /* set the bitmask for the protocols that are allowed to be used for the
2430 transfer, which thus helps the app which takes URLs from users or other
2431 external inputs and want to restrict what protocol(s) to deal
2432 with. Defaults to CURLPROTO_ALL. */
2433 data->set.allowed_protocols = va_arg(param, long);
2436 case CURLOPT_REDIR_PROTOCOLS:
2437 /* set the bitmask for the protocols that libcurl is allowed to follow to,
2438 as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
2439 to be set in both bitmasks to be allowed to get redirected to. Defaults
2440 to all protocols except FILE and SCP. */
2441 data->set.redir_protocols = va_arg(param, long);
2444 case CURLOPT_MAIL_FROM:
2445 /* Set the SMTP mail originator */
2446 result = setstropt(&data->set.str[STRING_MAIL_FROM],
2447 va_arg(param, char *));
2450 case CURLOPT_MAIL_AUTH:
2451 /* Set the SMTP auth originator */
2452 result = setstropt(&data->set.str[STRING_MAIL_AUTH],
2453 va_arg(param, char *));
2456 case CURLOPT_MAIL_RCPT:
2457 /* Set the list of mail recipients */
2458 data->set.mail_rcpt = va_arg(param, struct curl_slist *);
2461 case CURLOPT_SASL_IR:
2462 /* Enable/disable SASL initial response */
2463 data->set.sasl_ir = (0 != va_arg(param, long)) ? TRUE : FALSE;
2466 case CURLOPT_RTSP_REQUEST:
2469 * Set the RTSP request method (OPTIONS, SETUP, PLAY, etc...)
2470 * Would this be better if the RTSPREQ_* were just moved into here?
2472 long curl_rtspreq = va_arg(param, long);
2473 Curl_RtspReq rtspreq = RTSPREQ_NONE;
2474 switch(curl_rtspreq) {
2475 case CURL_RTSPREQ_OPTIONS:
2476 rtspreq = RTSPREQ_OPTIONS;
2479 case CURL_RTSPREQ_DESCRIBE:
2480 rtspreq = RTSPREQ_DESCRIBE;
2483 case CURL_RTSPREQ_ANNOUNCE:
2484 rtspreq = RTSPREQ_ANNOUNCE;
2487 case CURL_RTSPREQ_SETUP:
2488 rtspreq = RTSPREQ_SETUP;
2491 case CURL_RTSPREQ_PLAY:
2492 rtspreq = RTSPREQ_PLAY;
2495 case CURL_RTSPREQ_PAUSE:
2496 rtspreq = RTSPREQ_PAUSE;
2499 case CURL_RTSPREQ_TEARDOWN:
2500 rtspreq = RTSPREQ_TEARDOWN;
2503 case CURL_RTSPREQ_GET_PARAMETER:
2504 rtspreq = RTSPREQ_GET_PARAMETER;
2507 case CURL_RTSPREQ_SET_PARAMETER:
2508 rtspreq = RTSPREQ_SET_PARAMETER;
2511 case CURL_RTSPREQ_RECORD:
2512 rtspreq = RTSPREQ_RECORD;
2515 case CURL_RTSPREQ_RECEIVE:
2516 rtspreq = RTSPREQ_RECEIVE;
2519 rtspreq = RTSPREQ_NONE;
2522 data->set.rtspreq = rtspreq;
2527 case CURLOPT_RTSP_SESSION_ID:
2529 * Set the RTSP Session ID manually. Useful if the application is
2530 * resuming a previously established RTSP session
2532 result = setstropt(&data->set.str[STRING_RTSP_SESSION_ID],
2533 va_arg(param, char *));
2536 case CURLOPT_RTSP_STREAM_URI:
2538 * Set the Stream URI for the RTSP request. Unless the request is
2539 * for generic server options, the application will need to set this.
2541 result = setstropt(&data->set.str[STRING_RTSP_STREAM_URI],
2542 va_arg(param, char *));
2545 case CURLOPT_RTSP_TRANSPORT:
2547 * The content of the Transport: header for the RTSP request
2549 result = setstropt(&data->set.str[STRING_RTSP_TRANSPORT],
2550 va_arg(param, char *));
2553 case CURLOPT_RTSP_CLIENT_CSEQ:
2555 * Set the CSEQ number to issue for the next RTSP request. Useful if the
2556 * application is resuming a previously broken connection. The CSEQ
2557 * will increment from this new number henceforth.
2559 data->state.rtsp_next_client_CSeq = va_arg(param, long);
2562 case CURLOPT_RTSP_SERVER_CSEQ:
2563 /* Same as the above, but for server-initiated requests */
2564 data->state.rtsp_next_client_CSeq = va_arg(param, long);
2567 case CURLOPT_INTERLEAVEDATA:
2568 data->set.rtp_out = va_arg(param, void *);
2570 case CURLOPT_INTERLEAVEFUNCTION:
2571 /* Set the user defined RTP write function */
2572 data->set.fwrite_rtp = va_arg(param, curl_write_callback);
2575 case CURLOPT_WILDCARDMATCH:
2576 data->set.wildcardmatch = (0 != va_arg(param, long))?TRUE:FALSE;
2578 case CURLOPT_CHUNK_BGN_FUNCTION:
2579 data->set.chunk_bgn = va_arg(param, curl_chunk_bgn_callback);
2581 case CURLOPT_CHUNK_END_FUNCTION:
2582 data->set.chunk_end = va_arg(param, curl_chunk_end_callback);
2584 case CURLOPT_FNMATCH_FUNCTION:
2585 data->set.fnmatch = va_arg(param, curl_fnmatch_callback);
2587 case CURLOPT_CHUNK_DATA:
2588 data->wildcard.customptr = va_arg(param, void *);
2590 case CURLOPT_FNMATCH_DATA:
2591 data->set.fnmatch_data = va_arg(param, void *);
2594 case CURLOPT_TLSAUTH_USERNAME:
2595 result = setstropt(&data->set.str[STRING_TLSAUTH_USERNAME],
2596 va_arg(param, char *));
2597 if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype)
2598 data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
2600 case CURLOPT_TLSAUTH_PASSWORD:
2601 result = setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD],
2602 va_arg(param, char *));
2603 if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype)
2604 data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
2606 case CURLOPT_TLSAUTH_TYPE:
2607 if(strnequal((char *)va_arg(param, char *), "SRP", strlen("SRP")))
2608 data->set.ssl.authtype = CURL_TLSAUTH_SRP;
2610 data->set.ssl.authtype = CURL_TLSAUTH_NONE;
2613 case CURLOPT_DNS_SERVERS:
2614 result = Curl_set_dns_servers(data, va_arg(param, char *));
2616 case CURLOPT_DNS_INTERFACE:
2617 result = Curl_set_dns_interface(data, va_arg(param, char *));
2619 case CURLOPT_DNS_LOCAL_IP4:
2620 result = Curl_set_dns_local_ip4(data, va_arg(param, char *));
2622 case CURLOPT_DNS_LOCAL_IP6:
2623 result = Curl_set_dns_local_ip6(data, va_arg(param, char *));
2626 case CURLOPT_TCP_KEEPALIVE:
2627 data->set.tcp_keepalive = (0 != va_arg(param, long))?TRUE:FALSE;
2629 case CURLOPT_TCP_KEEPIDLE:
2630 data->set.tcp_keepidle = va_arg(param, long);
2632 case CURLOPT_TCP_KEEPINTVL:
2633 data->set.tcp_keepintvl = va_arg(param, long);
2635 case CURLOPT_SSL_ENABLE_NPN:
2636 data->set.ssl_enable_npn = (0 != va_arg(param, long))?TRUE:FALSE;
2638 case CURLOPT_SSL_ENABLE_ALPN:
2639 data->set.ssl_enable_alpn = (0 != va_arg(param, long))?TRUE:FALSE;
2642 #ifdef USE_UNIX_SOCKETS
2643 case CURLOPT_UNIX_SOCKET_PATH:
2644 result = setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH],
2645 va_arg(param, char *));
2649 case CURLOPT_PATH_AS_IS:
2650 data->set.path_as_is = (0 != va_arg(param, long))?TRUE:FALSE;
2652 case CURLOPT_PIPEWAIT:
2653 data->set.pipewait = (0 != va_arg(param, long))?TRUE:FALSE;
2656 /* unknown tag and its companion, just ignore: */
2657 result = CURLE_UNKNOWN_OPTION;
2664 static void conn_free(struct connectdata *conn)
2669 /* possible left-overs from the async name resolvers */
2670 Curl_resolver_cancel(conn);
2672 /* close the SSL stuff before we close any sockets since they will/may
2673 write to the sockets */
2674 Curl_ssl_close(conn, FIRSTSOCKET);
2675 Curl_ssl_close(conn, SECONDARYSOCKET);
2677 /* close possibly still open sockets */
2678 if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
2679 Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
2680 if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET])
2681 Curl_closesocket(conn, conn->sock[FIRSTSOCKET]);
2682 if(CURL_SOCKET_BAD != conn->tempsock[0])
2683 Curl_closesocket(conn, conn->tempsock[0]);
2684 if(CURL_SOCKET_BAD != conn->tempsock[1])
2685 Curl_closesocket(conn, conn->tempsock[1]);
2687 #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
2688 defined(NTLM_WB_ENABLED)
2689 Curl_ntlm_wb_cleanup(conn);
2692 Curl_safefree(conn->user);
2693 Curl_safefree(conn->passwd);
2694 Curl_safefree(conn->xoauth2_bearer);
2695 Curl_safefree(conn->options);
2696 Curl_safefree(conn->proxyuser);
2697 Curl_safefree(conn->proxypasswd);
2698 Curl_safefree(conn->allocptr.proxyuserpwd);
2699 Curl_safefree(conn->allocptr.uagent);
2700 Curl_safefree(conn->allocptr.userpwd);
2701 Curl_safefree(conn->allocptr.accept_encoding);
2702 Curl_safefree(conn->allocptr.te);
2703 Curl_safefree(conn->allocptr.rangeline);
2704 Curl_safefree(conn->allocptr.ref);
2705 Curl_safefree(conn->allocptr.host);
2706 Curl_safefree(conn->allocptr.cookiehost);
2707 Curl_safefree(conn->allocptr.rtsp_transport);
2708 Curl_safefree(conn->trailer);
2709 Curl_safefree(conn->host.rawalloc); /* host name buffer */
2710 Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */
2711 Curl_safefree(conn->master_buffer);
2713 Curl_llist_destroy(conn->send_pipe, NULL);
2714 Curl_llist_destroy(conn->recv_pipe, NULL);
2716 conn->send_pipe = NULL;
2717 conn->recv_pipe = NULL;
2719 Curl_safefree(conn->localdev);
2720 Curl_free_ssl_config(&conn->ssl_config);
2722 free(conn); /* free all the connection oriented data */
2726 * Disconnects the given connection. Note the connection may not be the
2727 * primary connection, like when freeing room in the connection cache or
2728 * killing of a dead old connection.
2730 * This function MUST NOT reset state in the SessionHandle struct if that
2731 * isn't strictly bound to the life-time of *this* particular connection.
2735 CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
2737 struct SessionHandle *data;
2739 return CURLE_OK; /* this is closed and fine already */
2743 DEBUGF(fprintf(stderr, "DISCONNECT without easy handle, ignoring\n"));
2747 if(conn->dns_entry != NULL) {
2748 Curl_resolv_unlock(data, conn->dns_entry);
2749 conn->dns_entry = NULL;
2752 Curl_hostcache_prune(data); /* kill old DNS cache entries */
2754 #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM)
2755 /* Cleanup NTLM connection-related data */
2756 Curl_http_ntlm_cleanup(conn);
2759 if(conn->handler->disconnect)
2760 /* This is set if protocol-specific cleanups should be made */
2761 conn->handler->disconnect(conn, dead_connection);
2763 /* unlink ourselves! */
2764 infof(data, "Closing connection %ld\n", conn->connection_id);
2765 Curl_conncache_remove_conn(data->state.conn_cache, conn);
2767 #if defined(USE_LIBIDN)
2768 if(conn->host.encalloc)
2769 idn_free(conn->host.encalloc); /* encoded host name buffer, must be freed
2770 with idn_free() since this was allocated
2772 if(conn->proxy.encalloc)
2773 idn_free(conn->proxy.encalloc); /* encoded proxy name buffer, must be
2774 freed with idn_free() since this was
2775 allocated by libidn */
2776 #elif defined(USE_WIN32_IDN)
2777 free(conn->host.encalloc); /* encoded host name buffer, must be freed with
2778 idn_free() since this was allocated by
2779 curl_win32_idn_to_ascii */
2780 free(conn->proxy.encalloc); /* encoded proxy name buffer, must be freed
2781 with idn_free() since this was allocated by
2782 curl_win32_idn_to_ascii */
2785 Curl_ssl_close(conn, FIRSTSOCKET);
2787 /* Indicate to all handles on the pipe that we're dead */
2788 if(Curl_pipeline_wanted(data->multi, CURLPIPE_ANY)) {
2789 signalPipeClose(conn->send_pipe, TRUE);
2790 signalPipeClose(conn->recv_pipe, TRUE);
2799 * This function should return TRUE if the socket is to be assumed to
2800 * be dead. Most commonly this happens when the server has closed the
2801 * connection due to inactivity.
2803 static bool SocketIsDead(curl_socket_t sock)
2806 bool ret_val = TRUE;
2808 sval = Curl_socket_ready(sock, CURL_SOCKET_BAD, 0);
2817 * IsPipeliningPossible() returns TRUE if the options set would allow
2818 * pipelining/multiplexing and the connection is using a HTTP protocol.
2820 static bool IsPipeliningPossible(const struct SessionHandle *handle,
2821 const struct connectdata *conn)
2823 /* If a HTTP protocol and pipelining is enabled */
2824 if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
2826 if(Curl_pipeline_wanted(handle->multi, CURLPIPE_HTTP1) &&
2827 (handle->set.httpversion != CURL_HTTP_VERSION_1_0) &&
2828 (handle->set.httpreq == HTTPREQ_GET ||
2829 handle->set.httpreq == HTTPREQ_HEAD))
2830 /* didn't ask for HTTP/1.0 and a GET or HEAD */
2833 if(Curl_pipeline_wanted(handle->multi, CURLPIPE_MULTIPLEX) &&
2834 (handle->set.httpversion == CURL_HTTP_VERSION_2_0))
2841 int Curl_removeHandleFromPipeline(struct SessionHandle *handle,
2842 struct curl_llist *pipeline)
2844 struct curl_llist_element *curr;
2846 curr = pipeline->head;
2848 if(curr->ptr == handle) {
2849 Curl_llist_remove(pipeline, curr, NULL);
2850 return 1; /* we removed a handle */
2858 #if 0 /* this code is saved here as it is useful for debugging purposes */
2859 static void Curl_printPipeline(struct curl_llist *pipeline)
2861 struct curl_llist_element *curr;
2863 curr = pipeline->head;
2865 struct SessionHandle *data = (struct SessionHandle *) curr->ptr;
2866 infof(data, "Handle in pipeline: %s\n", data->state.path);
2872 static struct SessionHandle* gethandleathead(struct curl_llist *pipeline)
2874 struct curl_llist_element *curr = pipeline->head;
2876 return (struct SessionHandle *) curr->ptr;
2882 /* remove the specified connection from all (possible) pipelines and related
2884 void Curl_getoff_all_pipelines(struct SessionHandle *data,
2885 struct connectdata *conn)
2887 bool recv_head = (conn->readchannel_inuse &&
2888 Curl_recvpipe_head(data, conn));
2889 bool send_head = (conn->writechannel_inuse &&
2890 Curl_sendpipe_head(data, conn));
2892 if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) && recv_head)
2893 Curl_pipeline_leave_read(conn);
2894 if(Curl_removeHandleFromPipeline(data, conn->send_pipe) && send_head)
2895 Curl_pipeline_leave_write(conn);
2898 static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke)
2900 struct curl_llist_element *curr;
2905 curr = pipeline->head;
2907 struct curl_llist_element *next = curr->next;
2908 struct SessionHandle *data = (struct SessionHandle *) curr->ptr;
2910 #ifdef DEBUGBUILD /* debug-only code */
2911 if(data->magic != CURLEASY_MAGIC_NUMBER) {
2913 infof(data, "signalPipeClose() found BAAD easy handle\n");
2918 data->state.pipe_broke = TRUE;
2919 Curl_multi_handlePipeBreak(data);
2920 Curl_llist_remove(pipeline, curr, NULL);
2926 * This function finds the connection in the connection
2927 * cache that has been unused for the longest time.
2929 * Returns the pointer to the oldest idle connection, or NULL if none was
2932 static struct connectdata *
2933 find_oldest_idle_connection(struct SessionHandle *data)
2935 struct conncache *bc = data->state.conn_cache;
2936 struct curl_hash_iterator iter;
2937 struct curl_llist_element *curr;
2938 struct curl_hash_element *he;
2942 struct connectdata *conn_candidate = NULL;
2943 struct connectbundle *bundle;
2947 Curl_hash_start_iterate(&bc->hash, &iter);
2949 he = Curl_hash_next_element(&iter);
2951 struct connectdata *conn;
2955 curr = bundle->conn_list->head;
2960 /* Set higher score for the age passed since the connection was used */
2961 score = Curl_tvdiff(now, conn->now);
2963 if(score > highscore) {
2965 conn_candidate = conn;
2971 he = Curl_hash_next_element(&iter);
2974 return conn_candidate;
2978 * This function finds the connection in the connection
2979 * bundle that has been unused for the longest time.
2981 * Returns the pointer to the oldest idle connection, or NULL if none was
2984 static struct connectdata *
2985 find_oldest_idle_connection_in_bundle(struct SessionHandle *data,
2986 struct connectbundle *bundle)
2988 struct curl_llist_element *curr;
2992 struct connectdata *conn_candidate = NULL;
2993 struct connectdata *conn;
2999 curr = bundle->conn_list->head;
3004 /* Set higher score for the age passed since the connection was used */
3005 score = Curl_tvdiff(now, conn->now);
3007 if(score > highscore) {
3009 conn_candidate = conn;
3015 return conn_candidate;
3019 * This function checks if given connection is dead and disconnects if so.
3020 * (That also removes it from the connection cache.)
3022 * Returns TRUE if the connection actually was dead and disconnected.
3024 static bool disconnect_if_dead(struct connectdata *conn,
3025 struct SessionHandle *data)
3027 size_t pipeLen = conn->send_pipe->size + conn->recv_pipe->size;
3028 if(!pipeLen && !conn->inuse) {
3029 /* The check for a dead socket makes sense only if there are no
3030 handles in pipeline and the connection isn't already marked in
3033 if(conn->handler->protocol & CURLPROTO_RTSP)
3034 /* RTSP is a special case due to RTP interleaving */
3035 dead = Curl_rtsp_connisdead(conn);
3037 dead = SocketIsDead(conn->sock[FIRSTSOCKET]);
3041 infof(data, "Connection %ld seems to be dead!\n", conn->connection_id);
3043 /* disconnect resources */
3044 Curl_disconnect(conn, /* dead_connection */TRUE);
3052 * Wrapper to use disconnect_if_dead() function in Curl_conncache_foreach()
3056 static int call_disconnect_if_dead(struct connectdata *conn,
3059 struct SessionHandle* data = (struct SessionHandle*)param;
3060 disconnect_if_dead(conn, data);
3061 return 0; /* continue iteration */
3065 * This function scans the connection cache for half-open/dead connections,
3066 * closes and removes them.
3067 * The cleanup is done at most once per second.
3069 static void prune_dead_connections(struct SessionHandle *data)
3071 struct timeval now = Curl_tvnow();
3072 long elapsed = Curl_tvdiff(now, data->state.conn_cache->last_cleanup);
3074 if(elapsed >= 1000L) {
3075 Curl_conncache_foreach(data->state.conn_cache, data,
3076 call_disconnect_if_dead);
3077 data->state.conn_cache->last_cleanup = now;
3082 static size_t max_pipeline_length(struct Curl_multi *multi)
3084 return multi ? multi->max_pipeline_length : 0;
3089 * Given one filled in connection struct (named needle), this function should
3090 * detect if there already is one that has all the significant details
3091 * exactly the same and thus should be used instead.
3093 * If there is a match, this function returns TRUE - and has marked the
3094 * connection as 'in-use'. It must later be called with ConnectionDone() to
3095 * return back to 'idle' (unused) state.
3097 * The force_reuse flag is set if the connection must be used, even if
3098 * the pipelining strategy wants to open a new connection instead of reusing.
3101 ConnectionExists(struct SessionHandle *data,
3102 struct connectdata *needle,
3103 struct connectdata **usethis,
3107 struct connectdata *check;
3108 struct connectdata *chosen = 0;
3109 bool canPipeline = IsPipeliningPossible(data, needle);
3111 bool wantNTLMhttp = ((data->state.authhost.want & CURLAUTH_NTLM) ||
3112 (data->state.authhost.want & CURLAUTH_NTLM_WB)) &&
3113 (needle->handler->protocol & PROTO_FAMILY_HTTP) ? TRUE : FALSE;
3115 struct connectbundle *bundle;
3117 *force_reuse = FALSE;
3120 /* We can't pipe if the site is blacklisted */
3121 if(canPipeline && Curl_pipeline_site_blacklisted(data, needle)) {
3122 canPipeline = FALSE;
3125 /* Look up the bundle with all the connections to this
3127 bundle = Curl_conncache_find_bundle(needle, data->state.conn_cache);
3129 /* Max pipe length is zero (unlimited) for multiplexed connections */
3130 size_t max_pipe_len = (bundle->multiuse != BUNDLE_MULTIPLEX)?
3131 max_pipeline_length(data->multi):0;
3132 size_t best_pipe_len = max_pipe_len;
3133 struct curl_llist_element *curr;
3135 infof(data, "Found bundle for host %s: %p\n",
3136 needle->host.name, (void *)bundle);
3138 /* We can't pipe if we don't know anything about the server */
3140 if(bundle->multiuse <= BUNDLE_UNKNOWN) {
3141 if((bundle->multiuse == BUNDLE_UNKNOWN) && data->set.pipewait) {
3142 infof(data, "Server doesn't support multi-use yet, wait\n");
3144 return FALSE; /* no re-use */
3147 infof(data, "Server doesn't support multi-use (yet)\n");
3148 canPipeline = FALSE;
3152 curr = bundle->conn_list->head;
3155 #if defined(USE_NTLM)
3156 bool credentialsMatch = FALSE;
3161 * Note that if we use a HTTP proxy, we check connections to that
3162 * proxy and not to the actual remote server.
3167 if(disconnect_if_dead(check, data))
3170 pipeLen = check->send_pipe->size + check->recv_pipe->size;
3174 if(!check->bits.multiplex) {
3175 /* If not multiplexing, make sure the pipe has only GET requests */
3176 struct SessionHandle* sh = gethandleathead(check->send_pipe);
3177 struct SessionHandle* rh = gethandleathead(check->recv_pipe);
3179 if(!IsPipeliningPossible(sh, check))
3183 if(!IsPipeliningPossible(rh, check))
3190 /* can only happen within multi handles, and means that another easy
3191 handle is using this connection */
3195 if(Curl_resolver_asynch()) {
3196 /* ip_addr_str[0] is NUL only if the resolving of the name hasn't
3197 completed yet and until then we don't re-use this connection */
3198 if(!check->ip_addr_str[0]) {
3200 "Connection #%ld is still name resolving, can't reuse\n",
3201 check->connection_id);
3206 if((check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) ||
3207 check->bits.close) {
3208 /* Don't pick a connection that hasn't connected yet or that is going
3210 infof(data, "Connection #%ld isn't open enough, can't reuse\n",
3211 check->connection_id);
3213 if(check->recv_pipe->size > 0) {
3215 "BAD! Unconnected #%ld has a non-empty recv pipeline!\n",
3216 check->connection_id);
3223 if((needle->handler->flags&PROTOPT_SSL) !=
3224 (check->handler->flags&PROTOPT_SSL))
3225 /* don't do mixed SSL and non-SSL connections */
3226 if(!(needle->handler->protocol & check->handler->protocol))
3227 /* except protocols that have been upgraded via TLS */
3230 if(needle->handler->flags&PROTOPT_SSL) {
3231 if((data->set.ssl.verifypeer != check->verifypeer) ||
3232 (data->set.ssl.verifyhost != check->verifyhost))
3236 if(needle->bits.proxy != check->bits.proxy)
3237 /* don't do mixed proxy and non-proxy connections */
3240 if(!canPipeline && check->inuse)
3241 /* this request can't be pipelined but the checked connection is
3242 already in use so we skip it */
3245 if(needle->localdev || needle->localport) {
3246 /* If we are bound to a specific local end (IP+port), we must not
3247 re-use a random other one, although if we didn't ask for a
3248 particular one we can reuse one that was bound.
3250 This comparison is a bit rough and too strict. Since the input
3251 parameters can be specified in numerous ways and still end up the
3252 same it would take a lot of processing to make it really accurate.
3253 Instead, this matching will assume that re-uses of bound connections
3254 will most likely also re-use the exact same binding parameters and
3255 missing out a few edge cases shouldn't hurt anyone very much.
3257 if((check->localport != needle->localport) ||
3258 (check->localportrange != needle->localportrange) ||
3260 !needle->localdev ||
3261 strcmp(check->localdev, needle->localdev))
3265 if((!(needle->handler->flags & PROTOPT_CREDSPERREQUEST))
3267 || (wantNTLMhttp || check->ntlm.state != NTLMSTATE_NONE)
3270 /* This protocol requires credentials per connection or is HTTP+NTLM,
3271 so verify that we're using the same name and password as well */
3272 if(!strequal(needle->user, check->user) ||
3273 !strequal(needle->passwd, check->passwd)) {
3274 /* one of them was different */
3277 #if defined(USE_NTLM)
3278 credentialsMatch = TRUE;
3282 if(!needle->bits.httpproxy || needle->handler->flags&PROTOPT_SSL ||
3283 (needle->bits.httpproxy && check->bits.httpproxy &&
3284 needle->bits.tunnel_proxy && check->bits.tunnel_proxy &&
3285 Curl_raw_equal(needle->proxy.name, check->proxy.name) &&
3286 (needle->port == check->port))) {
3287 /* The requested connection does not use a HTTP proxy or it uses SSL or
3288 it is a non-SSL protocol tunneled over the same http proxy name and
3289 port number or it is a non-SSL protocol which is allowed to be
3292 if((Curl_raw_equal(needle->handler->scheme, check->handler->scheme) ||
3293 needle->handler->protocol & check->handler->protocol) &&
3294 Curl_raw_equal(needle->host.name, check->host.name) &&
3295 needle->remote_port == check->remote_port) {
3296 if(needle->handler->flags & PROTOPT_SSL) {
3297 /* This is a SSL connection so verify that we're using the same
3298 SSL options as well */
3299 if(!Curl_ssl_config_matches(&needle->ssl_config,
3300 &check->ssl_config)) {
3302 "Connection #%ld has different SSL parameters, "
3304 check->connection_id));
3307 else if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete) {
3309 "Connection #%ld has not started SSL connect, "
3311 check->connection_id));
3318 else { /* The requested needle connection is using a proxy,
3319 is the checked one using the same host, port and type? */
3320 if(check->bits.proxy &&
3321 (needle->proxytype == check->proxytype) &&
3322 (needle->bits.tunnel_proxy == check->bits.tunnel_proxy) &&
3323 Curl_raw_equal(needle->proxy.name, check->proxy.name) &&
3324 needle->port == check->port) {
3325 /* This is the same proxy connection, use it! */
3331 #if defined(USE_NTLM)
3332 /* If we are looking for an HTTP+NTLM connection, check if this is
3333 already authenticating with the right credentials. If not, keep
3334 looking so that we can reuse NTLM connections if
3335 possible. (Especially we must not reuse the same connection if
3336 partway through a handshake!) */
3338 if(credentialsMatch && check->ntlm.state != NTLMSTATE_NONE) {
3341 /* We must use this connection, no other */
3342 *force_reuse = TRUE;
3345 else if(credentialsMatch)
3346 /* this is a backup choice */
3353 /* We can pipeline if we want to. Let's continue looking for
3354 the optimal connection to use, i.e the shortest pipe that is not
3358 /* We have the optimal connection. Let's stop looking. */
3363 /* We can't use the connection if the pipe is full */
3364 if(max_pipe_len && (pipeLen >= max_pipe_len)) {
3365 infof(data, "Pipe is full, skip (%zu)\n", pipeLen);
3369 /* If multiplexed, make sure we don't go over concurrency limit */
3370 if(check->bits.multiplex) {
3371 /* Multiplexed connections can only be HTTP/2 for now */
3372 struct http_conn *httpc = &check->proto.httpc;
3373 if(pipeLen >= httpc->settings.max_concurrent_streams) {
3374 infof(data, "MAX_CONCURRENT_STREAMS reached, skip (%zu)\n",
3380 /* We can't use the connection if the pipe is penalized */
3381 if(Curl_pipeline_penalized(data, check)) {
3382 infof(data, "Penalized, skip\n");
3387 if(pipeLen < best_pipe_len) {
3388 /* This connection has a shorter pipe so far. We'll pick this
3389 and continue searching */
3391 best_pipe_len = pipeLen;
3396 /* When not pipelining (== multiplexed), we have a match here! */
3398 infof(data, "Multiplexed connection found!\n");
3403 /* We have found a connection. Let's stop searching. */
3413 return TRUE; /* yes, we found one to use! */
3416 return FALSE; /* no matching connecting exists */
3419 /* Mark the connection as 'idle', or close it if the cache is full.
3420 Returns TRUE if the connection is kept, or FALSE if it was closed. */
3422 ConnectionDone(struct SessionHandle *data, struct connectdata *conn)
3424 /* data->multi->maxconnects can be negative, deal with it. */
3425 size_t maxconnects =
3426 (data->multi->maxconnects < 0) ? data->multi->num_easy * 4:
3427 data->multi->maxconnects;
3428 struct connectdata *conn_candidate = NULL;
3430 /* Mark the current connection as 'unused' */
3431 conn->inuse = FALSE;
3433 if(maxconnects > 0 &&
3434 data->state.conn_cache->num_connections > maxconnects) {
3435 infof(data, "Connection cache is full, closing the oldest one.\n");
3437 conn_candidate = find_oldest_idle_connection(data);
3439 if(conn_candidate) {
3440 /* Set the connection's owner correctly */
3441 conn_candidate->data = data;
3443 /* the winner gets the honour of being disconnected */
3444 (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
3448 return (conn_candidate == conn) ? FALSE : TRUE;
3451 /* after a TCP connection to the proxy has been verified, this function does
3452 the next magic step.
3454 Note: this function's sub-functions call failf()
3457 CURLcode Curl_connected_proxy(struct connectdata *conn,
3460 if(!conn->bits.proxy || sockindex)
3461 /* this magic only works for the primary socket as the secondary is used
3462 for FTP only and it has FTP specific magic in ftp.c */
3465 switch(conn->proxytype) {
3466 #ifndef CURL_DISABLE_PROXY
3467 case CURLPROXY_SOCKS5:
3468 case CURLPROXY_SOCKS5_HOSTNAME:
3469 return Curl_SOCKS5(conn->proxyuser, conn->proxypasswd,
3470 conn->host.name, conn->remote_port,
3473 case CURLPROXY_SOCKS4:
3474 return Curl_SOCKS4(conn->proxyuser, conn->host.name,
3475 conn->remote_port, FIRSTSOCKET, conn, FALSE);
3477 case CURLPROXY_SOCKS4A:
3478 return Curl_SOCKS4(conn->proxyuser, conn->host.name,
3479 conn->remote_port, FIRSTSOCKET, conn, TRUE);
3481 #endif /* CURL_DISABLE_PROXY */
3482 case CURLPROXY_HTTP:
3483 case CURLPROXY_HTTP_1_0:
3484 /* do nothing here. handled later. */
3488 } /* switch proxytype */
3494 * verboseconnect() displays verbose information after a connect
3496 #ifndef CURL_DISABLE_VERBOSE_STRINGS
3497 void Curl_verboseconnect(struct connectdata *conn)
3499 if(conn->data->set.verbose)
3500 infof(conn->data, "Connected to %s (%s) port %ld (#%ld)\n",
3501 conn->bits.proxy ? conn->proxy.dispname : conn->host.dispname,
3502 conn->ip_addr_str, conn->port, conn->connection_id);
3506 int Curl_protocol_getsock(struct connectdata *conn,
3507 curl_socket_t *socks,
3510 if(conn->handler->proto_getsock)
3511 return conn->handler->proto_getsock(conn, socks, numsocks);
3512 return GETSOCK_BLANK;
3515 int Curl_doing_getsock(struct connectdata *conn,
3516 curl_socket_t *socks,
3519 if(conn && conn->handler->doing_getsock)
3520 return conn->handler->doing_getsock(conn, socks, numsocks);
3521 return GETSOCK_BLANK;
3525 * We are doing protocol-specific connecting and this is being called over and
3526 * over from the multi interface until the connection phase is done on
3530 CURLcode Curl_protocol_connecting(struct connectdata *conn,
3533 CURLcode result=CURLE_OK;
3535 if(conn && conn->handler->connecting) {
3537 result = conn->handler->connecting(conn, done);
3546 * We are DOING this is being called over and over from the multi interface
3547 * until the DOING phase is done on protocol layer.
3550 CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done)
3552 CURLcode result=CURLE_OK;
3554 if(conn && conn->handler->doing) {
3556 result = conn->handler->doing(conn, done);
3565 * We have discovered that the TCP connection has been successful, we can now
3566 * proceed with some action.
3569 CURLcode Curl_protocol_connect(struct connectdata *conn,
3570 bool *protocol_done)
3572 CURLcode result=CURLE_OK;
3574 *protocol_done = FALSE;
3576 if(conn->bits.tcpconnect[FIRSTSOCKET] && conn->bits.protoconnstart) {
3577 /* We already are connected, get back. This may happen when the connect
3578 worked fine in the first call, like when we connect to a local server
3579 or proxy. Note that we don't know if the protocol is actually done.
3581 Unless this protocol doesn't have any protocol-connect callback, as
3582 then we know we're done. */
3583 if(!conn->handler->connecting)
3584 *protocol_done = TRUE;
3589 if(!conn->bits.protoconnstart) {
3591 result = Curl_proxy_connect(conn);
3595 if(conn->bits.tunnel_proxy && conn->bits.httpproxy &&
3596 (conn->tunnel_state[FIRSTSOCKET] != TUNNEL_COMPLETE))
3597 /* when using an HTTP tunnel proxy, await complete tunnel establishment
3598 before proceeding further. Return CURLE_OK so we'll be called again */
3601 if(conn->handler->connect_it) {
3602 /* is there a protocol-specific connect() procedure? */
3604 /* Call the protocol-specific connect function */
3605 result = conn->handler->connect_it(conn, protocol_done);
3608 *protocol_done = TRUE;
3610 /* it has started, possibly even completed but that knowledge isn't stored
3613 conn->bits.protoconnstart = TRUE;
3616 return result; /* pass back status */
3620 * Helpers for IDNA convertions.
3622 static bool is_ASCII_name(const char *hostname)
3624 const unsigned char *ch = (const unsigned char*)hostname;
3635 * Check if characters in hostname is allowed in Top Level Domain.
3637 static bool tld_check_name(struct SessionHandle *data,
3638 const char *ace_hostname)
3641 char *uc_name = NULL;
3643 #ifndef CURL_DISABLE_VERBOSE_STRINGS
3644 const char *tld_errmsg = "<no msg>";
3649 /* Convert (and downcase) ACE-name back into locale's character set */
3650 rc = idna_to_unicode_lzlz(ace_hostname, &uc_name, 0);
3651 if(rc != IDNA_SUCCESS)
3654 rc = tld_check_lz(uc_name, &err_pos, NULL);
3655 #ifndef CURL_DISABLE_VERBOSE_STRINGS
3656 #ifdef HAVE_TLD_STRERROR
3657 if(rc != TLD_SUCCESS)
3658 tld_errmsg = tld_strerror((Tld_rc)rc);
3660 if(rc == TLD_INVALID)
3661 infof(data, "WARNING: %s; pos %u = `%c'/0x%02X\n",
3662 tld_errmsg, err_pos, uc_name[err_pos],
3663 uc_name[err_pos] & 255);
3664 else if(rc != TLD_SUCCESS)
3665 infof(data, "WARNING: TLD check for %s failed; %s\n",
3666 uc_name, tld_errmsg);
3667 #endif /* CURL_DISABLE_VERBOSE_STRINGS */
3670 if(rc != TLD_SUCCESS)
3678 * Perform any necessary IDN conversion of hostname
3680 static void fix_hostname(struct SessionHandle *data,
3681 struct connectdata *conn, struct hostname *host)
3688 #elif defined(CURL_DISABLE_VERBOSE_STRINGS)
3692 /* set the name we use to display the host name */
3693 host->dispname = host->name;
3695 len = strlen(host->name);
3696 if(len && (host->name[len-1] == '.'))
3697 /* strip off a single trailing dot if present, primarily for SNI but
3698 there's no use for it */
3699 host->name[len-1]=0;
3701 if(!is_ASCII_name(host->name)) {
3703 /*************************************************************
3704 * Check name for non-ASCII and convert hostname to ACE form.
3705 *************************************************************/
3706 if(stringprep_check_version(LIBIDN_REQUIRED_VERSION)) {
3707 char *ace_hostname = NULL;
3708 int rc = idna_to_ascii_lz(host->name, &ace_hostname, 0);
3709 infof (data, "Input domain encoded as `%s'\n",
3710 stringprep_locale_charset ());
3711 if(rc != IDNA_SUCCESS)
3712 infof(data, "Failed to convert %s to ACE; %s\n",
3713 host->name, Curl_idn_strerror(conn, rc));
3715 /* tld_check_name() displays a warning if the host name contains
3716 "illegal" characters for this TLD */
3717 (void)tld_check_name(data, ace_hostname);
3719 host->encalloc = ace_hostname;
3720 /* change the name pointer to point to the encoded hostname */
3721 host->name = host->encalloc;
3724 #elif defined(USE_WIN32_IDN)
3725 /*************************************************************
3726 * Check name for non-ASCII and convert hostname to ACE form.
3727 *************************************************************/
3728 char *ace_hostname = NULL;
3729 int rc = curl_win32_idn_to_ascii(host->name, &ace_hostname);
3731 infof(data, "Failed to convert %s to ACE;\n",
3734 host->encalloc = ace_hostname;
3735 /* change the name pointer to point to the encoded hostname */
3736 host->name = host->encalloc;
3739 infof(data, "IDN support not present, can't parse Unicode domains\n");
3744 static void llist_dtor(void *user, void *element)
3752 * Allocate and initialize a new connectdata object.
3754 static struct connectdata *allocate_conn(struct SessionHandle *data)
3756 struct connectdata *conn = calloc(1, sizeof(struct connectdata));
3760 conn->handler = &Curl_handler_dummy; /* Be sure we have a handler defined
3761 already from start to avoid NULL
3762 situations and checks */
3764 /* and we setup a few fields in case we end up actually using this struct */
3766 conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
3767 conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
3768 conn->tempsock[0] = CURL_SOCKET_BAD; /* no file descriptor */
3769 conn->tempsock[1] = CURL_SOCKET_BAD; /* no file descriptor */
3770 conn->connection_id = -1; /* no ID */
3771 conn->port = -1; /* unknown at this point */
3772 conn->remote_port = -1; /* unknown */
3774 /* Default protocol-independent behavior doesn't support persistent
3775 connections, so we set this to force-close. Protocols that support
3776 this need to set this to FALSE in their "curl_do" functions. */
3777 connclose(conn, "Default to force-close");
3779 /* Store creation time to help future close decision making */
3780 conn->created = Curl_tvnow();
3782 conn->data = data; /* Setup the association between this connection
3783 and the SessionHandle */
3785 conn->proxytype = data->set.proxytype; /* type */
3787 #ifdef CURL_DISABLE_PROXY
3789 conn->bits.proxy = FALSE;
3790 conn->bits.httpproxy = FALSE;
3791 conn->bits.proxy_user_passwd = FALSE;
3792 conn->bits.tunnel_proxy = FALSE;
3794 #else /* CURL_DISABLE_PROXY */
3796 /* note that these two proxy bits are now just on what looks to be
3797 requested, they may be altered down the road */
3798 conn->bits.proxy = (data->set.str[STRING_PROXY] &&
3799 *data->set.str[STRING_PROXY])?TRUE:FALSE;
3800 conn->bits.httpproxy = (conn->bits.proxy &&
3801 (conn->proxytype == CURLPROXY_HTTP ||
3802 conn->proxytype == CURLPROXY_HTTP_1_0))?TRUE:FALSE;
3803 conn->bits.proxy_user_passwd =
3804 (NULL != data->set.str[STRING_PROXYUSERNAME])?TRUE:FALSE;
3805 conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy;
3807 #endif /* CURL_DISABLE_PROXY */
3809 conn->bits.user_passwd = (NULL != data->set.str[STRING_USERNAME])?TRUE:FALSE;
3810 conn->bits.ftp_use_epsv = data->set.ftp_use_epsv;
3811 conn->bits.ftp_use_eprt = data->set.ftp_use_eprt;
3813 conn->verifypeer = data->set.ssl.verifypeer;
3814 conn->verifyhost = data->set.ssl.verifyhost;
3816 conn->ip_version = data->set.ipver;
3818 #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
3819 defined(NTLM_WB_ENABLED)
3820 conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
3821 conn->ntlm_auth_hlpr_pid = 0;
3822 conn->challenge_header = NULL;
3823 conn->response_header = NULL;
3826 if(Curl_pipeline_wanted(data->multi, CURLPIPE_HTTP1) &&
3827 !conn->master_buffer) {
3828 /* Allocate master_buffer to be used for HTTP/1 pipelining */
3829 conn->master_buffer = calloc(BUFSIZE, sizeof (char));
3830 if(!conn->master_buffer)
3834 /* Initialize the pipeline lists */
3835 conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
3836 conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
3837 if(!conn->send_pipe || !conn->recv_pipe)
3841 conn->data_prot = PROT_CLEAR;
3844 /* Store the local bind parameters that will be used for this connection */
3845 if(data->set.str[STRING_DEVICE]) {
3846 conn->localdev = strdup(data->set.str[STRING_DEVICE]);
3850 conn->localportrange = data->set.localportrange;
3851 conn->localport = data->set.localport;
3853 /* the close socket stuff needs to be copied to the connection struct as
3854 it may live on without (this specific) SessionHandle */
3855 conn->fclosesocket = data->set.fclosesocket;
3856 conn->closesocket_client = data->set.closesocket_client;
3861 Curl_llist_destroy(conn->send_pipe, NULL);
3862 Curl_llist_destroy(conn->recv_pipe, NULL);
3864 conn->send_pipe = NULL;
3865 conn->recv_pipe = NULL;
3867 free(conn->master_buffer);
3868 free(conn->localdev);
3873 static CURLcode findprotocol(struct SessionHandle *data,
3874 struct connectdata *conn,
3875 const char *protostr)
3877 const struct Curl_handler * const *pp;
3878 const struct Curl_handler *p;
3880 /* Scan protocol handler table and match against 'protostr' to set a few
3881 variables based on the URL. Now that the handler may be changed later
3882 when the protocol specific setup function is called. */
3883 for(pp = protocols; (p = *pp) != NULL; pp++) {
3884 if(Curl_raw_equal(p->scheme, protostr)) {
3885 /* Protocol found in table. Check if allowed */
3886 if(!(data->set.allowed_protocols & p->protocol))
3890 /* it is allowed for "normal" request, now do an extra check if this is
3891 the result of a redirect */
3892 if(data->state.this_is_a_follow &&
3893 !(data->set.redir_protocols & p->protocol))
3897 /* Perform setup complement if some. */
3898 conn->handler = conn->given = p;
3900 /* 'port' and 'remote_port' are set in setup_connection_internals() */
3906 /* The protocol was not found in the table, but we don't have to assign it
3907 to anything since it is already assigned to a dummy-struct in the
3908 create_conn() function when the connectdata struct is allocated. */
3909 failf(data, "Protocol \"%s\" not supported or disabled in " LIBCURL_NAME,
3912 return CURLE_UNSUPPORTED_PROTOCOL;
3916 * Parse URL and fill in the relevant members of the connection struct.
3918 static CURLcode parseurlandfillconn(struct SessionHandle *data,
3919 struct connectdata *conn,
3921 char **userp, char **passwdp,
3926 char *path = data->state.path;
3929 char protobuf[16] = "";
3930 const char *protop = "";
3932 bool rebuild_url = FALSE;
3934 *prot_missing = FALSE;
3936 /* We might pass the entire URL into the request so we need to make sure
3937 * there are no bad characters in there.*/
3938 if(strpbrk(data->change.url, "\r\n")) {
3939 failf(data, "Illegal characters found in URL");
3940 return CURLE_URL_MALFORMAT;
3943 /*************************************************************
3946 * We need to parse the url even when using the proxy, because we will need
3947 * the hostname and port in case we are trying to SSL connect through the
3948 * proxy -- and we don't know if we will need to use SSL until we parse the
3950 ************************************************************/
3951 if((2 == sscanf(data->change.url, "%15[^:]:%[^\n]",
3953 Curl_raw_equal(protobuf, "file")) {
3954 if(path[0] == '/' && path[1] == '/') {
3955 /* Allow omitted hostname (e.g. file:/<path>). This is not strictly
3956 * speaking a valid file: URL by RFC 1738, but treating file:/<path> as
3957 * file://localhost/<path> is similar to how other schemes treat missing
3958 * hostnames. See RFC 1808. */
3960 /* This cannot be done with strcpy() in a portable manner, since the
3961 memory areas overlap! */
3962 memmove(path, path + 2, strlen(path + 2)+1);
3965 * we deal with file://<host>/<path> differently since it supports no
3966 * hostname other than "localhost" and "127.0.0.1", which is unique among
3967 * the URL protocols specified in RFC 1738
3969 if(path[0] != '/') {
3970 /* the URL included a host name, we ignore host names in file:// URLs
3971 as the standards don't define what to do with them */
3972 char *ptr=strchr(path, '/');
3974 /* there was a slash present
3976 RFC1738 (section 3.1, page 5) says:
3978 The rest of the locator consists of data specific to the scheme,
3979 and is known as the "url-path". It supplies the details of how the
3980 specified resource can be accessed. Note that the "/" between the
3981 host (or port) and the url-path is NOT part of the url-path.
3983 As most agents use file://localhost/foo to get '/foo' although the
3984 slash preceding foo is a separator and not a slash for the path,
3985 a URL as file://localhost//foo must be valid as well, to refer to
3986 the same file with an absolute path.
3989 if(ptr[1] && ('/' == ptr[1]))
3990 /* if there was two slashes, we skip the first one as that is then
3991 used truly as a separator */
3994 /* This cannot be made with strcpy, as the memory chunks overlap! */
3995 memmove(path, ptr, strlen(ptr)+1);
3999 protop = "file"; /* protocol string */
4005 if(2 > sscanf(data->change.url,
4006 "%15[^\n:]://%[^\n/?]%[^\n]",
4008 conn->host.name, path)) {
4011 * The URL was badly formatted, let's try the browser-style _without_
4012 * protocol specified like 'http://'.
4014 rc = sscanf(data->change.url, "%[^\n/?]%[^\n]", conn->host.name, path);
4017 * We couldn't even get this format.
4018 * djgpp 2.04 has a sscanf() bug where 'conn->host.name' is
4019 * assigned, but the return value is EOF!
4021 #if defined(__DJGPP__) && (DJGPP_MINOR == 4)
4022 if(!(rc == -1 && *conn->host.name))
4025 failf(data, "<url> malformed");
4026 return CURLE_URL_MALFORMAT;
4031 * Since there was no protocol part specified, we guess what protocol it
4032 * is based on the first letters of the server name.
4035 /* Note: if you add a new protocol, please update the list in
4036 * lib/version.c too! */
4038 if(checkprefix("FTP.", conn->host.name))
4040 else if(checkprefix("DICT.", conn->host.name))
4042 else if(checkprefix("LDAP.", conn->host.name))
4044 else if(checkprefix("IMAP.", conn->host.name))
4046 else if(checkprefix("SMTP.", conn->host.name))
4048 else if(checkprefix("POP3.", conn->host.name))
4054 *prot_missing = TRUE; /* not given in URL */
4060 /* We search for '?' in the host name (but only on the right side of a
4061 * @-letter to allow ?-letters in username and password) to handle things
4062 * like http://example.com?param= (notice the missing '/').
4064 at = strchr(conn->host.name, '@');
4066 query = strchr(at+1, '?');
4068 query = strchr(conn->host.name, '?');
4071 /* We must insert a slash before the '?'-letter in the URL. If the URL had
4072 a slash after the '?', that is where the path currently begins and the
4073 '?string' is still part of the host name.
4075 We must move the trailing part from the host name and put it first in
4076 the path. And have it all prefixed with a slash.
4079 size_t hostlen = strlen(query);
4080 size_t pathlen = strlen(path);
4082 /* move the existing path plus the zero byte forward, to make room for
4083 the host-name part */
4084 memmove(path+hostlen+1, path, pathlen+1);
4086 /* now copy the trailing host part in front of the existing path */
4087 memcpy(path+1, query, hostlen);
4089 path[0]='/'; /* prepend the missing slash */
4092 *query=0; /* now cut off the hostname at the ? */
4095 /* if there's no path set, use a single slash */
4100 /* If the URL is malformatted (missing a '/' after hostname before path) we
4101 * insert a slash here. The only letter except '/' we accept to start a path
4104 if(path[0] == '?') {
4105 /* We need this function to deal with overlapping memory areas. We know
4106 that the memory area 'path' points to is 'urllen' bytes big and that
4107 is bigger than the path. Use +1 to move the zero byte too. */
4108 memmove(&path[1], path, strlen(path)+1);
4112 else if(!data->set.path_as_is) {
4113 /* sanitise paths and remove ../ and ./ sequences according to RFC3986 */
4114 char *newp = Curl_dedotdotify(path);
4116 return CURLE_OUT_OF_MEMORY;
4118 if(strcmp(newp, path)) {
4120 free(data->state.pathbuffer);
4121 data->state.pathbuffer = newp;
4122 data->state.path = newp;
4130 * "rebuild_url" means that one or more URL components have been modified so
4131 * we need to generate an updated full version. We need the corrected URL
4132 * when communicating over HTTP proxy and we don't know at this point if
4133 * we're using a proxy or not.
4138 size_t plen = strlen(path); /* new path, should be 1 byte longer than
4140 size_t urllen = strlen(data->change.url); /* original URL length */
4142 size_t prefixlen = strlen(conn->host.name);
4145 prefixlen += strlen(protop) + strlen("://");
4147 reurl = malloc(urllen + 2); /* 2 for zerobyte + slash */
4149 return CURLE_OUT_OF_MEMORY;
4151 /* copy the prefix */
4152 memcpy(reurl, data->change.url, prefixlen);
4154 /* append the trailing piece + zerobyte */
4155 memcpy(&reurl[prefixlen], path, plen + 1);
4157 /* possible free the old one */
4158 if(data->change.url_alloc) {
4159 Curl_safefree(data->change.url);
4160 data->change.url_alloc = FALSE;
4163 infof(data, "Rebuilt URL to: %s\n", reurl);
4165 data->change.url = reurl;
4166 data->change.url_alloc = TRUE; /* free this later */
4170 * Parse the login details from the URL and strip them out of
4173 result = parse_url_login(data, conn, userp, passwdp, optionsp);
4177 if(conn->host.name[0] == '[') {
4178 /* This looks like an IPv6 address literal. See if there is an address
4179 scope if there is no location header */
4180 char *percent = strchr(conn->host.name, '%');
4182 unsigned int identifier_offset = 3;
4184 unsigned long scope;
4185 if(strncmp("%25", percent, 3) != 0) {
4187 "Please URL encode %% as %%25, see RFC 6874.\n");
4188 identifier_offset = 1;
4190 scope = strtoul(percent + identifier_offset, &endp, 10);
4192 /* The address scope was well formed. Knock it out of the
4194 memmove(percent, endp, strlen(endp)+1);
4195 conn->scope_id = (unsigned int)scope;
4198 /* Zone identifier is not numeric */
4199 #if defined(HAVE_NET_IF_H) && defined(IFNAMSIZ) && defined(HAVE_IF_NAMETOINDEX)
4200 char ifname[IFNAMSIZ + 2];
4201 char *square_bracket;
4202 unsigned int scopeidx = 0;
4203 strncpy(ifname, percent + identifier_offset, IFNAMSIZ + 2);
4204 /* Ensure nullbyte termination */
4205 ifname[IFNAMSIZ + 1] = '\0';
4206 square_bracket = strchr(ifname, ']');
4207 if(square_bracket) {
4209 *square_bracket = '\0';
4210 scopeidx = if_nametoindex(ifname);
4212 infof(data, "Invalid network interface: %s; %s\n", ifname,
4217 char *p = percent + identifier_offset + strlen(ifname);
4219 /* Remove zone identifier from hostname */
4220 memmove(percent, p, strlen(p) + 1);
4221 conn->scope_id = scopeidx;
4224 #endif /* HAVE_NET_IF_H && IFNAMSIZ */
4225 infof(data, "Invalid IPv6 address format\n");
4230 if(data->set.scope_id)
4231 /* Override any scope that was set above. */
4232 conn->scope_id = data->set.scope_id;
4234 /* Remove the fragment part of the path. Per RFC 2396, this is always the
4235 last part of the URI. We are looking for the first '#' so that we deal
4236 gracefully with non conformant URI such as http://example.com#foo#bar. */
4237 fragment = strchr(path, '#');
4241 /* we know the path part ended with a fragment, so we know the full URL
4242 string does too and we need to cut it off from there so it isn't used
4244 fragment = strchr(data->change.url, '#');
4250 * So if the URL was A://B/C#D,
4252 * conn->host.name is B
4253 * data->state.path is /C
4256 return findprotocol(data, conn, protop);
4260 * If we're doing a resumed transfer, we need to setup our stuff
4263 static CURLcode setup_range(struct SessionHandle *data)
4265 struct UrlState *s = &data->state;
4266 s->resume_from = data->set.set_resume_from;
4267 if(s->resume_from || data->set.str[STRING_SET_RANGE]) {
4268 if(s->rangestringalloc)
4272 s->range = aprintf("%" CURL_FORMAT_CURL_OFF_TU "-", s->resume_from);
4274 s->range = strdup(data->set.str[STRING_SET_RANGE]);
4276 s->rangestringalloc = (s->range)?TRUE:FALSE;
4279 return CURLE_OUT_OF_MEMORY;
4281 /* tell ourselves to fetch this range */
4282 s->use_range = TRUE; /* enable range download */
4285 s->use_range = FALSE; /* disable range download */
4292 * setup_connection_internals() -
4294 * Setup connection internals specific to the requested protocol in the
4295 * SessionHandle. This is inited and setup before the connection is made but
4296 * is about the particular protocol that is to be used.
4298 * This MUST get called after proxy magic has been figured out.
4300 static CURLcode setup_connection_internals(struct connectdata *conn)
4302 const struct Curl_handler * p;
4304 struct SessionHandle *data = conn->data;
4306 /* in some case in the multi state-machine, we go back to the CONNECT state
4307 and then a second (or third or...) call to this function will be made
4308 without doing a DISCONNECT or DONE in between (since the connection is
4309 yet in place) and therefore this function needs to first make sure
4310 there's no lingering previous data allocated. */
4311 Curl_free_request_state(data);
4313 memset(&data->req, 0, sizeof(struct SingleRequest));
4314 data->req.maxdownload = -1;
4316 conn->socktype = SOCK_STREAM; /* most of them are TCP streams */
4318 /* Perform setup complement if some. */
4321 if(p->setup_connection) {
4322 result = (*p->setup_connection)(conn);
4327 p = conn->handler; /* May have changed. */
4331 /* we check for -1 here since if proxy was detected already, this
4332 was very likely already set to the proxy port */
4333 conn->port = p->defport;
4335 /* only if remote_port was not already parsed off the URL we use the
4336 default port number */
4337 if(conn->remote_port < 0)
4338 conn->remote_port = (unsigned short)conn->given->defport;
4344 * Curl_free_request_state() should free temp data that was allocated in the
4345 * SessionHandle for this single request.
4348 void Curl_free_request_state(struct SessionHandle *data)
4350 Curl_safefree(data->req.protop);
4351 Curl_safefree(data->req.newurl);
4355 #ifndef CURL_DISABLE_PROXY
4356 /****************************************************************
4357 * Checks if the host is in the noproxy list. returns true if it matches
4358 * and therefore the proxy should NOT be used.
4359 ****************************************************************/
4360 static bool check_noproxy(const char* name, const char* no_proxy)
4362 /* no_proxy=domain1.dom,host.domain2.dom
4363 * (a comma-separated list of hosts which should
4364 * not be proxied, or an asterisk to override
4365 * all proxy variables)
4369 const char* separator = ", ";
4370 size_t no_proxy_len;
4374 if(no_proxy && no_proxy[0]) {
4375 if(Curl_raw_equal("*", no_proxy)) {
4379 /* NO_PROXY was specified and it wasn't just an asterisk */
4381 no_proxy_len = strlen(no_proxy);
4382 endptr = strchr(name, ':');
4384 namelen = endptr - name;
4386 namelen = strlen(name);
4388 for(tok_start = 0; tok_start < no_proxy_len; tok_start = tok_end + 1) {
4389 while(tok_start < no_proxy_len &&
4390 strchr(separator, no_proxy[tok_start]) != NULL) {
4391 /* Look for the beginning of the token. */
4395 if(tok_start == no_proxy_len)
4396 break; /* It was all trailing separator chars, no more tokens. */
4398 for(tok_end = tok_start; tok_end < no_proxy_len &&
4399 strchr(separator, no_proxy[tok_end]) == NULL; ++tok_end)
4400 /* Look for the end of the token. */
4403 /* To match previous behaviour, where it was necessary to specify
4404 * ".local.com" to prevent matching "notlocal.com", we will leave
4407 if(no_proxy[tok_start] == '.')
4410 if((tok_end - tok_start) <= namelen) {
4411 /* Match the last part of the name to the domain we are checking. */
4412 const char *checkn = name + namelen - (tok_end - tok_start);
4413 if(Curl_raw_nequal(no_proxy + tok_start, checkn,
4414 tok_end - tok_start)) {
4415 if((tok_end - tok_start) == namelen || *(checkn - 1) == '.') {
4416 /* We either have an exact match, or the previous character is a .
4417 * so it is within the same domain, so no proxy for this host.
4422 } /* if((tok_end - tok_start) <= namelen) */
4423 } /* for(tok_start = 0; tok_start < no_proxy_len;
4424 tok_start = tok_end + 1) */
4425 } /* NO_PROXY was specified and it wasn't just an asterisk */
4430 /****************************************************************
4431 * Detect what (if any) proxy to use. Remember that this selects a host
4432 * name and is not limited to HTTP proxies only.
4433 * The returned pointer must be freed by the caller (unless NULL)
4434 ****************************************************************/
4435 static char *detect_proxy(struct connectdata *conn)
4439 #ifndef CURL_DISABLE_HTTP
4440 /* If proxy was not specified, we check for default proxy environment
4441 * variables, to enable i.e Lynx compliance:
4443 * http_proxy=http://some.server.dom:port/
4444 * https_proxy=http://some.server.dom:port/
4445 * ftp_proxy=http://some.server.dom:port/
4446 * no_proxy=domain1.dom,host.domain2.dom
4447 * (a comma-separated list of hosts which should
4448 * not be proxied, or an asterisk to override
4449 * all proxy variables)
4450 * all_proxy=http://some.server.dom:port/
4451 * (seems to exist for the CERN www lib. Probably
4452 * the first to check for.)
4454 * For compatibility, the all-uppercase versions of these variables are
4455 * checked if the lowercase versions don't exist.
4457 char *no_proxy=NULL;
4458 char proxy_env[128];
4460 no_proxy=curl_getenv("no_proxy");
4462 no_proxy=curl_getenv("NO_PROXY");
4464 if(!check_noproxy(conn->host.name, no_proxy)) {
4465 /* It was not listed as without proxy */
4466 const char *protop = conn->handler->scheme;
4467 char *envp = proxy_env;
4470 /* Now, build <protocol>_proxy and check for such a one to use */
4472 *envp++ = (char)tolower((int)*protop++);
4475 strcpy(envp, "_proxy");
4477 /* read the protocol proxy: */
4478 prox=curl_getenv(proxy_env);
4481 * We don't try the uppercase version of HTTP_PROXY because of
4484 * When curl is used in a webserver application
4485 * environment (cgi or php), this environment variable can
4486 * be controlled by the web server user by setting the
4487 * http header 'Proxy:' to some value.
4489 * This can cause 'internal' http/ftp requests to be
4490 * arbitrarily redirected by any external attacker.
4492 if(!prox && !Curl_raw_equal("http_proxy", proxy_env)) {
4493 /* There was no lowercase variable, try the uppercase version: */
4494 Curl_strntoupper(proxy_env, proxy_env, sizeof(proxy_env));
4495 prox=curl_getenv(proxy_env);
4499 proxy = prox; /* use this */
4501 proxy = curl_getenv("all_proxy"); /* default proxy to use */
4503 proxy=curl_getenv("ALL_PROXY");
4505 } /* if(!check_noproxy(conn->host.name, no_proxy)) - it wasn't specified
4509 #else /* !CURL_DISABLE_HTTP */
4512 #endif /* CURL_DISABLE_HTTP */
4518 * If this is supposed to use a proxy, we need to figure out the proxy
4519 * host name, so that we can re-use an existing connection
4520 * that may exist registered to the same proxy host.
4522 static CURLcode parse_proxy(struct SessionHandle *data,
4523 struct connectdata *conn, char *proxy)
4528 /* We use 'proxyptr' to point to the proxy name from now on... */
4533 /* We do the proxy host string parsing here. We want the host name and the
4534 * port name. Accept a protocol:// prefix
4537 /* Parse the protocol part if present */
4538 endofprot = strstr(proxy, "://");
4540 proxyptr = endofprot+3;
4541 if(checkprefix("socks5h", proxy))
4542 conn->proxytype = CURLPROXY_SOCKS5_HOSTNAME;
4543 else if(checkprefix("socks5", proxy))
4544 conn->proxytype = CURLPROXY_SOCKS5;
4545 else if(checkprefix("socks4a", proxy))
4546 conn->proxytype = CURLPROXY_SOCKS4A;
4547 else if(checkprefix("socks4", proxy) || checkprefix("socks", proxy))
4548 conn->proxytype = CURLPROXY_SOCKS4;
4549 /* Any other xxx:// : change to http proxy */
4552 proxyptr = proxy; /* No xxx:// head: It's a HTTP proxy */
4554 /* Is there a username and password given in this proxy url? */
4555 atsign = strchr(proxyptr, '@');
4557 char *proxyuser = NULL;
4558 char *proxypasswd = NULL;
4560 parse_login_details(proxyptr, atsign - proxyptr,
4561 &proxyuser, &proxypasswd, NULL);
4563 /* found user and password, rip them out. note that we are
4564 unescaping them, as there is otherwise no way to have a
4565 username or password with reserved characters like ':' in
4567 Curl_safefree(conn->proxyuser);
4568 if(proxyuser && strlen(proxyuser) < MAX_CURL_USER_LENGTH)
4569 conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
4571 conn->proxyuser = strdup("");
4573 if(!conn->proxyuser)
4574 result = CURLE_OUT_OF_MEMORY;
4576 Curl_safefree(conn->proxypasswd);
4577 if(proxypasswd && strlen(proxypasswd) < MAX_CURL_PASSWORD_LENGTH)
4578 conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL);
4580 conn->proxypasswd = strdup("");
4582 if(!conn->proxypasswd)
4583 result = CURLE_OUT_OF_MEMORY;
4587 conn->bits.proxy_user_passwd = TRUE; /* enable it */
4588 atsign++; /* the right side of the @-letter */
4590 proxyptr = atsign; /* now use this instead */
4601 /* start scanning for port number at this point */
4604 /* detect and extract RFC6874-style IPv6-addresses */
4605 if(*proxyptr == '[') {
4606 char *ptr = ++proxyptr; /* advance beyond the initial bracket */
4607 while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '.')))
4610 /* There might be a zone identifier */
4611 if(strncmp("%25", ptr, 3))
4612 infof(data, "Please URL encode %% as %%25, see RFC 6874.\n");
4614 /* Allow unresered characters as defined in RFC 3986 */
4615 while(*ptr && (ISALPHA(*ptr) || ISXDIGIT(*ptr) || (*ptr == '-') ||
4616 (*ptr == '.') || (*ptr == '_') || (*ptr == '~')))
4620 /* yeps, it ended nicely with a bracket as well */
4623 infof(data, "Invalid IPv6 address format\n");
4625 /* Note that if this didn't end with a bracket, we still advanced the
4626 * proxyptr first, but I can't see anything wrong with that as no host
4627 * name nor a numeric can legally start with a bracket.
4631 /* Get port number off proxy.server.com:1080 */
4632 prox_portno = strchr(portptr, ':');
4634 *prox_portno = 0x0; /* cut off number from host name */
4636 /* now set the local port number */
4637 conn->port = strtol(prox_portno, NULL, 10);
4640 if(proxyptr[0]=='/')
4641 /* If the first character in the proxy string is a slash, fail
4642 immediately. The following code will otherwise clear the string which
4643 will lead to code running as if no proxy was set! */
4644 return CURLE_COULDNT_RESOLVE_PROXY;
4646 /* without a port number after the host name, some people seem to use
4647 a slash so we strip everything from the first slash */
4648 atsign = strchr(proxyptr, '/');
4650 *atsign = 0x0; /* cut off path part from host name */
4652 if(data->set.proxyport)
4653 /* None given in the proxy string, then get the default one if it is
4655 conn->port = data->set.proxyport;
4658 /* now, clone the cleaned proxy host name */
4659 conn->proxy.rawalloc = strdup(proxyptr);
4660 conn->proxy.name = conn->proxy.rawalloc;
4662 if(!conn->proxy.rawalloc)
4663 return CURLE_OUT_OF_MEMORY;
4669 * Extract the user and password from the authentication string
4671 static CURLcode parse_proxy_auth(struct SessionHandle *data,
4672 struct connectdata *conn)
4674 char proxyuser[MAX_CURL_USER_LENGTH]="";
4675 char proxypasswd[MAX_CURL_PASSWORD_LENGTH]="";
4677 if(data->set.str[STRING_PROXYUSERNAME] != NULL) {
4678 strncpy(proxyuser, data->set.str[STRING_PROXYUSERNAME],
4679 MAX_CURL_USER_LENGTH);
4680 proxyuser[MAX_CURL_USER_LENGTH-1] = '\0'; /*To be on safe side*/
4682 if(data->set.str[STRING_PROXYPASSWORD] != NULL) {
4683 strncpy(proxypasswd, data->set.str[STRING_PROXYPASSWORD],
4684 MAX_CURL_PASSWORD_LENGTH);
4685 proxypasswd[MAX_CURL_PASSWORD_LENGTH-1] = '\0'; /*To be on safe side*/
4688 conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
4689 if(!conn->proxyuser)
4690 return CURLE_OUT_OF_MEMORY;
4692 conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL);
4693 if(!conn->proxypasswd)
4694 return CURLE_OUT_OF_MEMORY;
4698 #endif /* CURL_DISABLE_PROXY */
4703 * Parse the login details (user name, password and options) from the URL and
4704 * strip them out of the host name
4706 * Inputs: data->set.use_netrc (CURLOPT_NETRC)
4709 * Outputs: (almost :- all currently undefined)
4710 * conn->bits.user_passwd - non-zero if non-default passwords exist
4711 * user - non-zero length if defined
4712 * passwd - non-zero length if defined
4713 * options - non-zero length if defined
4714 * conn->host.name - remove user name and password
4716 static CURLcode parse_url_login(struct SessionHandle *data,
4717 struct connectdata *conn,
4718 char **user, char **passwd, char **options)
4720 CURLcode result = CURLE_OK;
4722 char *passwdp = NULL;
4723 char *optionsp = NULL;
4725 /* At this point, we're hoping all the other special cases have
4726 * been taken care of, so conn->host.name is at most
4727 * [user[:password][;options]]@]hostname
4729 * We need somewhere to put the embedded details, so do that first.
4732 char *ptr = strchr(conn->host.name, '@');
4733 char *login = conn->host.name;
4735 DEBUGASSERT(!**user);
4736 DEBUGASSERT(!**passwd);
4737 DEBUGASSERT(!**options);
4742 /* We will now try to extract the
4743 * possible login information in a string like:
4744 * ftp://user:password@ftp.my.site:8021/README */
4745 conn->host.name = ++ptr;
4747 /* So the hostname is sane. Only bother interpreting the
4748 * results if we could care. It could still be wasted
4749 * work because it might be overtaken by the programmatically
4750 * set user/passwd, but doing that first adds more cases here :-(
4753 if(data->set.use_netrc == CURL_NETRC_REQUIRED)
4756 /* We could use the login information in the URL so extract it */
4757 result = parse_login_details(login, ptr - login - 1,
4758 &userp, &passwdp, &optionsp);
4765 /* We have a user in the URL */
4766 conn->bits.userpwd_in_url = TRUE;
4767 conn->bits.user_passwd = TRUE; /* enable user+password */
4769 /* Decode the user */
4770 newname = curl_easy_unescape(data, userp, 0, NULL);
4772 result = CURLE_OUT_OF_MEMORY;
4781 /* We have a password in the URL so decode it */
4782 char *newpasswd = curl_easy_unescape(data, passwdp, 0, NULL);
4784 result = CURLE_OUT_OF_MEMORY;
4789 *passwd = newpasswd;
4793 /* We have an options list in the URL so decode it */
4794 char *newoptions = curl_easy_unescape(data, optionsp, 0, NULL);
4796 result = CURLE_OUT_OF_MEMORY;
4801 *options = newoptions;
4815 * parse_login_details()
4817 * This is used to parse a login string for user name, password and options in
4818 * the following formats:
4822 * user:password;options
4824 * user;options:password
4832 * login [in] - The login string.
4833 * len [in] - The length of the login string.
4834 * userp [in/out] - The address where a pointer to newly allocated memory
4835 * holding the user will be stored upon completion.
4836 * passdwp [in/out] - The address where a pointer to newly allocated memory
4837 * holding the password will be stored upon completion.
4838 * optionsp [in/out] - The address where a pointer to newly allocated memory
4839 * holding the options will be stored upon completion.
4841 * Returns CURLE_OK on success.
4843 static CURLcode parse_login_details(const char *login, const size_t len,
4844 char **userp, char **passwdp,
4847 CURLcode result = CURLE_OK;
4851 const char *psep = NULL;
4852 const char *osep = NULL;
4857 /* Attempt to find the password separator */
4859 psep = strchr(login, ':');
4861 /* Within the constraint of the login string */
4862 if(psep >= login + len)
4866 /* Attempt to find the options separator */
4868 osep = strchr(login, ';');
4870 /* Within the constraint of the login string */
4871 if(osep >= login + len)
4875 /* Calculate the portion lengths */
4877 (size_t)(osep && psep > osep ? osep - login : psep - login) :
4878 (osep ? (size_t)(osep - login) : len));
4880 (osep && osep > psep ? (size_t)(osep - psep) :
4881 (size_t)(login + len - psep)) - 1 : 0);
4883 (psep && psep > osep ? (size_t)(psep - osep) :
4884 (size_t)(login + len - osep)) - 1 : 0);
4886 /* Allocate the user portion buffer */
4888 ubuf = malloc(ulen + 1);
4890 result = CURLE_OUT_OF_MEMORY;
4893 /* Allocate the password portion buffer */
4894 if(!result && passwdp && plen) {
4895 pbuf = malloc(plen + 1);
4898 result = CURLE_OUT_OF_MEMORY;
4902 /* Allocate the options portion buffer */
4903 if(!result && optionsp && olen) {
4904 obuf = malloc(olen + 1);
4908 result = CURLE_OUT_OF_MEMORY;
4913 /* Store the user portion if necessary */
4915 memcpy(ubuf, login, ulen);
4917 Curl_safefree(*userp);
4921 /* Store the password portion if necessary */
4923 memcpy(pbuf, psep + 1, plen);
4925 Curl_safefree(*passwdp);
4929 /* Store the options portion if necessary */
4931 memcpy(obuf, osep + 1, olen);
4933 Curl_safefree(*optionsp);
4941 /*************************************************************
4942 * Figure out the remote port number and fix it in the URL
4944 * No matter if we use a proxy or not, we have to figure out the remote
4945 * port number of various reasons.
4947 * To be able to detect port number flawlessly, we must not confuse them
4948 * IPv6-specified addresses in the [0::1] style. (RFC2732)
4950 * The conn->host.name is currently [user:passwd@]host[:port] where host
4951 * could be a hostname, IPv4 address or IPv6 address.
4953 * The port number embedded in the URL is replaced, if necessary.
4954 *************************************************************/
4955 static CURLcode parse_remote_port(struct SessionHandle *data,
4956 struct connectdata *conn)
4961 /* Note that at this point, the IPv6 address cannot contain any scope
4962 suffix as that has already been removed in the parseurlandfillconn()
4964 if((1 == sscanf(conn->host.name, "[%*45[0123456789abcdefABCDEF:.]%c",
4966 (']' == endbracket)) {
4967 /* this is a RFC2732-style specified IP-address */
4968 conn->bits.ipv6_ip = TRUE;
4970 conn->host.name++; /* skip over the starting bracket */
4971 portptr = strchr(conn->host.name, ']');
4973 *portptr++ = '\0'; /* zero terminate, killing the bracket */
4975 portptr = NULL; /* no port number available */
4980 struct in6_addr in6;
4981 if(Curl_inet_pton(AF_INET6, conn->host.name, &in6) > 0) {
4982 /* This is a numerical IPv6 address, meaning this is a wrongly formatted
4984 failf(data, "IPv6 numerical address used in URL without brackets");
4985 return CURLE_URL_MALFORMAT;
4989 portptr = strrchr(conn->host.name, ':');
4992 if(data->set.use_port && data->state.allow_port) {
4993 /* if set, we use this and ignore the port possibly given in the URL */
4994 conn->remote_port = (unsigned short)data->set.use_port;
4996 *portptr = '\0'; /* cut off the name there anyway - if there was a port
4997 number - since the port number is to be ignored! */
4998 if(conn->bits.httpproxy) {
4999 /* we need to create new URL with the new port number */
5003 if(conn->bits.type_set)
5004 snprintf(type, sizeof(type), ";type=%c",
5005 data->set.prefer_ascii?'A':
5006 (data->set.ftp_list_only?'D':'I'));
5009 * This synthesized URL isn't always right--suffixes like ;type=A are
5010 * stripped off. It would be better to work directly from the original
5011 * URL and simply replace the port part of it.
5013 url = aprintf("%s://%s%s%s:%hu%s%s%s", conn->given->scheme,
5014 conn->bits.ipv6_ip?"[":"", conn->host.name,
5015 conn->bits.ipv6_ip?"]":"", conn->remote_port,
5016 data->state.slash_removed?"/":"", data->state.path,
5019 return CURLE_OUT_OF_MEMORY;
5021 if(data->change.url_alloc) {
5022 Curl_safefree(data->change.url);
5023 data->change.url_alloc = FALSE;
5026 data->change.url = url;
5027 data->change.url_alloc = TRUE;
5031 /* no CURLOPT_PORT given, extract the one from the URL */
5036 port=strtol(portptr+1, &rest, 10); /* Port number must be decimal */
5038 if((port < 0) || (port > 0xffff)) {
5039 /* Single unix standard says port numbers are 16 bits long */
5040 failf(data, "Port number out of range");
5041 return CURLE_URL_MALFORMAT;
5044 else if(rest != &portptr[1]) {
5045 *portptr = '\0'; /* cut off the name there */
5046 conn->remote_port = curlx_ultous(port);
5049 /* Browser behavior adaptation. If there's a colon with no digits after,
5050 just cut off the name there which makes us ignore the colon and just
5051 use the default port. Firefox and Chrome both do that. */
5058 * Override the login details from the URL with that in the CURLOPT_USERPWD
5059 * option or a .netrc file, if applicable.
5061 static CURLcode override_login(struct SessionHandle *data,
5062 struct connectdata *conn,
5063 char **userp, char **passwdp, char **optionsp)
5065 if(data->set.str[STRING_USERNAME]) {
5067 *userp = strdup(data->set.str[STRING_USERNAME]);
5069 return CURLE_OUT_OF_MEMORY;
5072 if(data->set.str[STRING_PASSWORD]) {
5074 *passwdp = strdup(data->set.str[STRING_PASSWORD]);
5076 return CURLE_OUT_OF_MEMORY;
5079 if(data->set.str[STRING_OPTIONS]) {
5081 *optionsp = strdup(data->set.str[STRING_OPTIONS]);
5083 return CURLE_OUT_OF_MEMORY;
5086 conn->bits.netrc = FALSE;
5087 if(data->set.use_netrc != CURL_NETRC_IGNORED) {
5088 int ret = Curl_parsenetrc(conn->host.name,
5090 data->set.str[STRING_NETRC_FILE]);
5092 infof(data, "Couldn't find host %s in the "
5093 DOT_CHAR "netrc file; using defaults\n",
5097 return CURLE_OUT_OF_MEMORY;
5100 /* set bits.netrc TRUE to remember that we got the name from a .netrc
5101 file, so that it is safe to use even if we followed a Location: to a
5102 different host or similar. */
5103 conn->bits.netrc = TRUE;
5105 conn->bits.user_passwd = TRUE; /* enable user+password */
5113 * Set the login details so they're available in the connection
5115 static CURLcode set_login(struct connectdata *conn,
5116 const char *user, const char *passwd,
5117 const char *options)
5119 CURLcode result = CURLE_OK;
5121 /* If our protocol needs a password and we have none, use the defaults */
5122 if((conn->handler->flags & PROTOPT_NEEDSPWD) && !conn->bits.user_passwd) {
5123 /* Store the default user */
5124 conn->user = strdup(CURL_DEFAULT_USER);
5126 /* Store the default password */
5128 conn->passwd = strdup(CURL_DEFAULT_PASSWORD);
5130 conn->passwd = NULL;
5132 /* This is the default password, so DON'T set conn->bits.user_passwd */
5135 /* Store the user, zero-length if not set */
5136 conn->user = strdup(user);
5138 /* Store the password (only if user is present), zero-length if not set */
5140 conn->passwd = strdup(passwd);
5142 conn->passwd = NULL;
5145 if(!conn->user || !conn->passwd)
5146 result = CURLE_OUT_OF_MEMORY;
5148 /* Store the options, null if not set */
5149 if(!result && options[0]) {
5150 conn->options = strdup(options);
5153 result = CURLE_OUT_OF_MEMORY;
5159 /*************************************************************
5160 * Resolve the address of the server or proxy
5161 *************************************************************/
5162 static CURLcode resolve_server(struct SessionHandle *data,
5163 struct connectdata *conn,
5166 CURLcode result=CURLE_OK;
5167 long timeout_ms = Curl_timeleft(data, NULL, TRUE);
5169 /*************************************************************
5170 * Resolve the name of the server or proxy
5171 *************************************************************/
5172 if(conn->bits.reuse)
5173 /* We're reusing the connection - no need to resolve anything, and
5174 fix_hostname() was called already in create_conn() for the re-use
5179 /* this is a fresh connect */
5181 struct Curl_dns_entry *hostaddr;
5183 /* set a pointer to the hostname we display */
5184 fix_hostname(data, conn, &conn->host);
5186 #ifdef USE_UNIX_SOCKETS
5187 if(data->set.str[STRING_UNIX_SOCKET_PATH]) {
5188 /* Unix domain sockets are local. The host gets ignored, just use the
5189 * specified domain socket address. Do not cache "DNS entries". There is
5190 * no DNS involved and we already have the filesystem path available */
5191 const char *path = data->set.str[STRING_UNIX_SOCKET_PATH];
5193 hostaddr = calloc(1, sizeof(struct Curl_dns_entry));
5195 result = CURLE_OUT_OF_MEMORY;
5196 else if((hostaddr->addr = Curl_unix2addr(path)) != NULL)
5199 /* Long paths are not supported for now */
5200 if(strlen(path) >= sizeof(((struct sockaddr_un *)0)->sun_path)) {
5201 failf(data, "Unix socket path too long: '%s'", path);
5202 result = CURLE_COULDNT_RESOLVE_HOST;
5205 result = CURLE_OUT_OF_MEMORY;
5212 if(!conn->proxy.name || !*conn->proxy.name) {
5213 /* If not connecting via a proxy, extract the port from the URL, if it is
5214 * there, thus overriding any defaults that might have been set above. */
5215 conn->port = conn->remote_port; /* it is the same port */
5217 /* Resolve target host right on */
5218 rc = Curl_resolv_timeout(conn, conn->host.name, (int)conn->port,
5219 &hostaddr, timeout_ms);
5220 if(rc == CURLRESOLV_PENDING)
5223 else if(rc == CURLRESOLV_TIMEDOUT)
5224 result = CURLE_OPERATION_TIMEDOUT;
5226 else if(!hostaddr) {
5227 failf(data, "Couldn't resolve host '%s'", conn->host.dispname);
5228 result = CURLE_COULDNT_RESOLVE_HOST;
5229 /* don't return yet, we need to clean up the timeout first */
5233 /* This is a proxy that hasn't been resolved yet. */
5235 /* IDN-fix the proxy name */
5236 fix_hostname(data, conn, &conn->proxy);
5239 rc = Curl_resolv_timeout(conn, conn->proxy.name, (int)conn->port,
5240 &hostaddr, timeout_ms);
5242 if(rc == CURLRESOLV_PENDING)
5245 else if(rc == CURLRESOLV_TIMEDOUT)
5246 result = CURLE_OPERATION_TIMEDOUT;
5248 else if(!hostaddr) {
5249 failf(data, "Couldn't resolve proxy '%s'", conn->proxy.dispname);
5250 result = CURLE_COULDNT_RESOLVE_PROXY;
5251 /* don't return yet, we need to clean up the timeout first */
5254 DEBUGASSERT(conn->dns_entry == NULL);
5255 conn->dns_entry = hostaddr;
5262 * Cleanup the connection just allocated before we can move along and use the
5263 * previously existing one. All relevant data is copied over and old_conn is
5264 * ready for freeing once this function returns.
5266 static void reuse_conn(struct connectdata *old_conn,
5267 struct connectdata *conn)
5269 free(old_conn->proxy.rawalloc);
5271 /* free the SSL config struct from this connection struct as this was
5272 allocated in vain and is targeted for destruction */
5273 Curl_free_ssl_config(&old_conn->ssl_config);
5275 conn->data = old_conn->data;
5277 /* get the user+password information from the old_conn struct since it may
5278 * be new for this request even when we re-use an existing connection */
5279 conn->bits.user_passwd = old_conn->bits.user_passwd;
5280 if(conn->bits.user_passwd) {
5281 /* use the new user name and password though */
5282 Curl_safefree(conn->user);
5283 Curl_safefree(conn->passwd);
5284 conn->user = old_conn->user;
5285 conn->passwd = old_conn->passwd;
5286 old_conn->user = NULL;
5287 old_conn->passwd = NULL;
5290 conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd;
5291 if(conn->bits.proxy_user_passwd) {
5292 /* use the new proxy user name and proxy password though */
5293 Curl_safefree(conn->proxyuser);
5294 Curl_safefree(conn->proxypasswd);
5295 conn->proxyuser = old_conn->proxyuser;
5296 conn->proxypasswd = old_conn->proxypasswd;
5297 old_conn->proxyuser = NULL;
5298 old_conn->proxypasswd = NULL;
5301 /* host can change, when doing keepalive with a proxy or if the case is
5302 different this time etc */
5303 Curl_safefree(conn->host.rawalloc);
5304 conn->host=old_conn->host;
5306 /* persist connection info in session handle */
5307 Curl_persistconninfo(conn);
5310 conn->bits.reuse = TRUE; /* yes, we're re-using here */
5312 Curl_safefree(old_conn->user);
5313 Curl_safefree(old_conn->passwd);
5314 Curl_safefree(old_conn->proxyuser);
5315 Curl_safefree(old_conn->proxypasswd);
5316 Curl_safefree(old_conn->localdev);
5318 Curl_llist_destroy(old_conn->send_pipe, NULL);
5319 Curl_llist_destroy(old_conn->recv_pipe, NULL);
5321 old_conn->send_pipe = NULL;
5322 old_conn->recv_pipe = NULL;
5324 Curl_safefree(old_conn->master_buffer);
5328 * create_conn() sets up a new connectdata struct, or re-uses an already
5329 * existing one, and resolves host name.
5331 * if this function returns CURLE_OK and *async is set to TRUE, the resolve
5332 * response will be coming asynchronously. If *async is FALSE, the name is
5335 * @param data The sessionhandle pointer
5336 * @param in_connect is set to the next connection data pointer
5337 * @param async is set TRUE when an async DNS resolution is pending
5338 * @see Curl_setup_conn()
5340 * *NOTE* this function assigns the conn->data pointer!
5343 static CURLcode create_conn(struct SessionHandle *data,
5344 struct connectdata **in_connect,
5347 CURLcode result = CURLE_OK;
5348 struct connectdata *conn;
5349 struct connectdata *conn_temp = NULL;
5352 char *passwd = NULL;
5353 char *options = NULL;
5356 bool prot_missing = FALSE;
5357 bool connections_available = TRUE;
5358 bool force_reuse = FALSE;
5359 bool waitpipe = FALSE;
5360 size_t max_host_connections = Curl_multi_max_host_connections(data->multi);
5361 size_t max_total_connections = Curl_multi_max_total_connections(data->multi);
5365 /*************************************************************
5367 *************************************************************/
5369 if(!data->change.url) {
5370 result = CURLE_URL_MALFORMAT;
5374 /* First, split up the current URL in parts so that we can use the
5375 parts for checking against the already present connections. In order
5376 to not have to modify everything at once, we allocate a temporary
5377 connection data struct and fill in for comparison purposes. */
5378 conn = allocate_conn(data);
5381 result = CURLE_OUT_OF_MEMORY;
5385 /* We must set the return variable as soon as possible, so that our
5386 parent can cleanup any possible allocs we may have done before
5390 /* This initing continues below, see the comment "Continue connectdata
5391 * initialization here" */
5393 /***********************************************************
5394 * We need to allocate memory to store the path in. We get the size of the
5395 * full URL to be sure, and we need to make it at least 256 bytes since
5396 * other parts of the code will rely on this fact
5397 ***********************************************************/
5398 #define LEAST_PATH_ALLOC 256
5399 urllen=strlen(data->change.url);
5400 if(urllen < LEAST_PATH_ALLOC)
5401 urllen=LEAST_PATH_ALLOC;
5404 * We malloc() the buffers below urllen+2 to make room for 2 possibilities:
5405 * 1 - an extra terminating zero
5406 * 2 - an extra slash (in case a syntax like "www.host.com?moo" is used)
5409 Curl_safefree(data->state.pathbuffer);
5410 data->state.path = NULL;
5412 data->state.pathbuffer = malloc(urllen+2);
5413 if(NULL == data->state.pathbuffer) {
5414 result = CURLE_OUT_OF_MEMORY; /* really bad error */
5417 data->state.path = data->state.pathbuffer;
5419 conn->host.rawalloc = malloc(urllen+2);
5420 if(NULL == conn->host.rawalloc) {
5421 Curl_safefree(data->state.pathbuffer);
5422 data->state.path = NULL;
5423 result = CURLE_OUT_OF_MEMORY;
5427 conn->host.name = conn->host.rawalloc;
5428 conn->host.name[0] = 0;
5431 passwd = strdup("");
5432 options = strdup("");
5433 if(!user || !passwd || !options) {
5434 result = CURLE_OUT_OF_MEMORY;
5438 result = parseurlandfillconn(data, conn, &prot_missing, &user, &passwd,
5443 /*************************************************************
5444 * No protocol part in URL was used, add it!
5445 *************************************************************/
5447 /* We're guessing prefixes here and if we're told to use a proxy or if
5448 we're gonna follow a Location: later or... then we need the protocol
5449 part added so that we have a valid URL. */
5452 reurl = aprintf("%s://%s", conn->handler->scheme, data->change.url);
5455 result = CURLE_OUT_OF_MEMORY;
5459 if(data->change.url_alloc) {
5460 Curl_safefree(data->change.url);
5461 data->change.url_alloc = FALSE;
5464 data->change.url = reurl;
5465 data->change.url_alloc = TRUE; /* free this later */
5468 /*************************************************************
5469 * If the protocol can't handle url query strings, then cut
5470 * off the unhandable part
5471 *************************************************************/
5472 if((conn->given->flags&PROTOPT_NOURLQUERY)) {
5473 char *path_q_sep = strchr(conn->data->state.path, '?');
5475 /* according to rfc3986, allow the query (?foo=bar)
5476 also on protocols that can't handle it.
5478 cut the string-part after '?'
5481 /* terminate the string */
5486 if(data->set.str[STRING_BEARER]) {
5487 conn->xoauth2_bearer = strdup(data->set.str[STRING_BEARER]);
5488 if(!conn->xoauth2_bearer) {
5489 result = CURLE_OUT_OF_MEMORY;
5494 #ifndef CURL_DISABLE_PROXY
5495 /*************************************************************
5496 * Extract the user and password from the authentication string
5497 *************************************************************/
5498 if(conn->bits.proxy_user_passwd) {
5499 result = parse_proxy_auth(data, conn);
5504 /*************************************************************
5505 * Detect what (if any) proxy to use
5506 *************************************************************/
5507 if(data->set.str[STRING_PROXY]) {
5508 proxy = strdup(data->set.str[STRING_PROXY]);
5509 /* if global proxy is set, this is it */
5511 failf(data, "memory shortage");
5512 result = CURLE_OUT_OF_MEMORY;
5517 if(data->set.str[STRING_NOPROXY] &&
5518 check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY])) {
5519 free(proxy); /* proxy is in exception list */
5523 proxy = detect_proxy(conn);
5525 #ifdef USE_UNIX_SOCKETS
5526 if(proxy && data->set.str[STRING_UNIX_SOCKET_PATH]) {
5527 free(proxy); /* Unix domain sockets cannot be proxied, so disable it */
5532 if(proxy && (!*proxy || (conn->handler->flags & PROTOPT_NONETWORK))) {
5533 free(proxy); /* Don't bother with an empty proxy string or if the
5534 protocol doesn't work with network */
5538 /***********************************************************************
5539 * If this is supposed to use a proxy, we need to figure out the proxy host
5540 * name, proxy type and port number, so that we can re-use an existing
5541 * connection that may exist registered to the same proxy host.
5542 ***********************************************************************/
5544 result = parse_proxy(data, conn, proxy);
5546 free(proxy); /* parse_proxy copies the proxy string */
5552 if((conn->proxytype == CURLPROXY_HTTP) ||
5553 (conn->proxytype == CURLPROXY_HTTP_1_0)) {
5554 #ifdef CURL_DISABLE_HTTP
5555 /* asking for a HTTP proxy is a bit funny when HTTP is disabled... */
5556 result = CURLE_UNSUPPORTED_PROTOCOL;
5559 /* force this connection's protocol to become HTTP if not already
5560 compatible - if it isn't tunneling through */
5561 if(!(conn->handler->protocol & PROTO_FAMILY_HTTP) &&
5562 !conn->bits.tunnel_proxy)
5563 conn->handler = &Curl_handler_http;
5565 conn->bits.httpproxy = TRUE;
5569 conn->bits.httpproxy = FALSE; /* not a HTTP proxy */
5570 conn->bits.tunnel_proxy = FALSE; /* no tunneling if not HTTP */
5572 conn->bits.proxy = TRUE;
5575 /* we aren't using the proxy after all... */
5576 conn->bits.proxy = FALSE;
5577 conn->bits.httpproxy = FALSE;
5578 conn->bits.proxy_user_passwd = FALSE;
5579 conn->bits.tunnel_proxy = FALSE;
5582 #endif /* CURL_DISABLE_PROXY */
5584 /*************************************************************
5585 * If the protocol is using SSL and HTTP proxy is used, we set
5586 * the tunnel_proxy bit.
5587 *************************************************************/
5588 if((conn->given->flags&PROTOPT_SSL) && conn->bits.httpproxy)
5589 conn->bits.tunnel_proxy = TRUE;
5591 /*************************************************************
5592 * Figure out the remote port number and fix it in the URL
5593 *************************************************************/
5594 result = parse_remote_port(data, conn);
5598 /* Check for overridden login details and set them accordingly so they
5599 they are known when protocol->setup_connection is called! */
5600 result = override_login(data, conn, &user, &passwd, &options);
5603 result = set_login(conn, user, passwd, options);
5607 /*************************************************************
5608 * Setup internals depending on protocol. Needs to be done after
5609 * we figured out what/if proxy to use.
5610 *************************************************************/
5611 result = setup_connection_internals(conn);
5615 conn->recv[FIRSTSOCKET] = Curl_recv_plain;
5616 conn->send[FIRSTSOCKET] = Curl_send_plain;
5617 conn->recv[SECONDARYSOCKET] = Curl_recv_plain;
5618 conn->send[SECONDARYSOCKET] = Curl_send_plain;
5620 /***********************************************************************
5621 * file: is a special case in that it doesn't need a network connection
5622 ***********************************************************************/
5623 #ifndef CURL_DISABLE_FILE
5624 if(conn->handler->flags & PROTOPT_NONETWORK) {
5626 /* this is supposed to be the connect function so we better at least check
5627 that the file is present here! */
5628 DEBUGASSERT(conn->handler->connect_it);
5629 result = conn->handler->connect_it(conn, &done);
5631 /* Setup a "faked" transfer that'll do nothing */
5634 conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; /* we are "connected */
5636 Curl_conncache_add_conn(data->state.conn_cache, conn);
5639 * Setup whatever necessary for a resumed transfer
5641 result = setup_range(data);
5643 DEBUGASSERT(conn->handler->done);
5644 /* we ignore the return code for the protocol-specific DONE */
5645 (void)conn->handler->done(conn, result, FALSE);
5649 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */
5650 -1, NULL); /* no upload */
5653 /* since we skip do_init() */
5654 Curl_init_do(data, conn);
5660 /* Get a cloned copy of the SSL config situation stored in the
5661 connection struct. But to get this going nicely, we must first make
5662 sure that the strings in the master copy are pointing to the correct
5663 strings in the session handle strings array!
5665 Keep in mind that the pointers in the master copy are pointing to strings
5666 that will be freed as part of the SessionHandle struct, but all cloned
5667 copies will be separately allocated.
5669 data->set.ssl.CApath = data->set.str[STRING_SSL_CAPATH];
5670 data->set.ssl.CAfile = data->set.str[STRING_SSL_CAFILE];
5671 data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE];
5672 data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT];
5673 data->set.ssl.random_file = data->set.str[STRING_SSL_RANDOM_FILE];
5674 data->set.ssl.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
5675 data->set.ssl.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST];
5677 data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME];
5678 data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD];
5681 if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config)) {
5682 result = CURLE_OUT_OF_MEMORY;
5686 prune_dead_connections(data);
5688 /*************************************************************
5689 * Check the current list of connections to see if we can
5690 * re-use an already existing one or if we have to create a
5692 *************************************************************/
5694 /* reuse_fresh is TRUE if we are told to use a new connection by force, but
5695 we only acknowledge this option if this is not a re-used connection
5696 already (which happens due to follow-location or during a HTTP
5697 authentication phase). */
5698 if(data->set.reuse_fresh && !data->state.this_is_a_follow)
5701 reuse = ConnectionExists(data, conn, &conn_temp, &force_reuse, &waitpipe);
5703 /* If we found a reusable connection, we may still want to
5704 open a new connection if we are pipelining. */
5705 if(reuse && !force_reuse && IsPipeliningPossible(data, conn_temp)) {
5706 size_t pipelen = conn_temp->send_pipe->size + conn_temp->recv_pipe->size;
5708 infof(data, "Found connection %ld, with requests in the pipe (%zu)\n",
5709 conn_temp->connection_id, pipelen);
5711 if(conn_temp->bundle->num_connections < max_host_connections &&
5712 data->state.conn_cache->num_connections < max_total_connections) {
5713 /* We want a new connection anyway */
5716 infof(data, "We can reuse, but we want a new connection anyway\n");
5723 * We already have a connection for this, we got the former connection
5724 * in the conn_temp variable and thus we need to cleanup the one we
5725 * just allocated before we can move along and use the previously
5728 conn_temp->inuse = TRUE; /* mark this as being in use so that no other
5729 handle in a multi stack may nick it */
5730 reuse_conn(conn, conn_temp);
5731 free(conn); /* we don't need this anymore */
5735 /* set a pointer to the hostname we display */
5736 fix_hostname(data, conn, &conn->host);
5738 infof(data, "Re-using existing connection! (#%ld) with %s %s\n",
5739 conn->connection_id,
5740 conn->bits.proxy?"proxy":"host",
5741 conn->proxy.name?conn->proxy.dispname:conn->host.dispname);
5744 /* We have decided that we want a new connection. However, we may not
5745 be able to do that if we have reached the limit of how many
5746 connections we are allowed to open. */
5747 struct connectbundle *bundle = NULL;
5750 /* There is a connection that *might* become usable for pipelining
5751 "soon", and we wait for that */
5752 connections_available = FALSE;
5754 bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache);
5756 if(max_host_connections > 0 && bundle &&
5757 (bundle->num_connections >= max_host_connections)) {
5758 struct connectdata *conn_candidate;
5760 /* The bundle is full. Let's see if we can kill a connection. */
5761 conn_candidate = find_oldest_idle_connection_in_bundle(data, bundle);
5763 if(conn_candidate) {
5764 /* Set the connection's owner correctly, then kill it */
5765 conn_candidate->data = data;
5766 (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
5769 infof(data, "No more connections allowed to host: %d\n",
5770 max_host_connections);
5771 connections_available = FALSE;
5775 if(connections_available &&
5776 (max_total_connections > 0) &&
5777 (data->state.conn_cache->num_connections >= max_total_connections)) {
5778 struct connectdata *conn_candidate;
5780 /* The cache is full. Let's see if we can kill a connection. */
5781 conn_candidate = find_oldest_idle_connection(data);
5783 if(conn_candidate) {
5784 /* Set the connection's owner correctly, then kill it */
5785 conn_candidate->data = data;
5786 (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
5789 infof(data, "No connections available in cache\n");
5790 connections_available = FALSE;
5794 if(!connections_available) {
5795 infof(data, "No connections available.\n");
5800 result = CURLE_NO_CONNECTION_AVAILABLE;
5805 * This is a brand new connection, so let's store it in the connection
5808 Curl_conncache_add_conn(data->state.conn_cache, conn);
5811 #if defined(USE_NTLM)
5812 /* If NTLM is requested in a part of this connection, make sure we don't
5813 assume the state is fine as this is a fresh connection and NTLM is
5814 connection based. */
5815 if((data->state.authhost.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
5816 data->state.authhost.done) {
5817 infof(data, "NTLM picked AND auth done set, clear picked!\n");
5818 data->state.authhost.picked = CURLAUTH_NONE;
5821 if((data->state.authproxy.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
5822 data->state.authproxy.done) {
5823 infof(data, "NTLM-proxy picked AND auth done set, clear picked!\n");
5824 data->state.authproxy.picked = CURLAUTH_NONE;
5829 /* Mark the connection as used */
5832 /* Setup and init stuff before DO starts, in preparing for the transfer. */
5833 Curl_init_do(data, conn);
5836 * Setup whatever necessary for a resumed transfer
5838 result = setup_range(data);
5842 /* Continue connectdata initialization here. */
5845 * Inherit the proper values from the urldata struct AFTER we have arranged
5846 * the persistent connection stuff
5848 conn->seek_func = data->set.seek_func;
5849 conn->seek_client = data->set.seek_client;
5851 /*************************************************************
5852 * Resolve the address of the server or proxy
5853 *************************************************************/
5854 result = resolve_server(data, conn, async);
5865 /* Curl_setup_conn() is called after the name resolve initiated in
5866 * create_conn() is all done.
5868 * Curl_setup_conn() also handles reused connections
5870 * conn->data MUST already have been setup fine (in create_conn)
5873 CURLcode Curl_setup_conn(struct connectdata *conn,
5874 bool *protocol_done)
5876 CURLcode result = CURLE_OK;
5877 struct SessionHandle *data = conn->data;
5879 Curl_pgrsTime(data, TIMER_NAMELOOKUP);
5881 if(conn->handler->flags & PROTOPT_NONETWORK) {
5882 /* nothing to setup when not using a network */
5883 *protocol_done = TRUE;
5886 *protocol_done = FALSE; /* default to not done */
5888 /* set proxy_connect_closed to false unconditionally already here since it
5889 is used strictly to provide extra information to a parent function in the
5890 case of proxy CONNECT failures and we must make sure we don't have it
5891 lingering set from a previous invoke */
5892 conn->bits.proxy_connect_closed = FALSE;
5895 * Set user-agent. Used for HTTP, but since we can attempt to tunnel
5896 * basically anything through a http proxy we can't limit this based on
5899 if(data->set.str[STRING_USERAGENT]) {
5900 Curl_safefree(conn->allocptr.uagent);
5901 conn->allocptr.uagent =
5902 aprintf("User-Agent: %s\r\n", data->set.str[STRING_USERAGENT]);
5903 if(!conn->allocptr.uagent)
5904 return CURLE_OUT_OF_MEMORY;
5907 data->req.headerbytecount = 0;
5909 #ifdef CURL_DO_LINEEND_CONV
5910 data->state.crlf_conversions = 0; /* reset CRLF conversion counter */
5911 #endif /* CURL_DO_LINEEND_CONV */
5913 /* set start time here for timeout purposes in the connect procedure, it
5914 is later set again for the progress meter purpose */
5915 conn->now = Curl_tvnow();
5917 if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
5918 conn->bits.tcpconnect[FIRSTSOCKET] = FALSE;
5919 result = Curl_connecthost(conn, conn->dns_entry);
5924 Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */
5925 Curl_pgrsTime(data, TIMER_APPCONNECT); /* we're connected already */
5926 conn->bits.tcpconnect[FIRSTSOCKET] = TRUE;
5927 *protocol_done = TRUE;
5928 Curl_updateconninfo(conn, conn->sock[FIRSTSOCKET]);
5929 Curl_verboseconnect(conn);
5932 conn->now = Curl_tvnow(); /* time this *after* the connect is done, we
5933 set this here perhaps a second time */
5937 * This check is quite a hack. We're calling _fsetmode to fix the problem
5938 * with fwrite converting newline characters (you get mangled text files,
5939 * and corrupted binary files when you download to stdout and redirect it to
5943 if((data->set.out)->_handle == NULL) {
5944 _fsetmode(stdout, "b");
5951 CURLcode Curl_connect(struct SessionHandle *data,
5952 struct connectdata **in_connect,
5954 bool *protocol_done)
5958 *asyncp = FALSE; /* assume synchronous resolves by default */
5960 /* call the stuff that needs to be called */
5961 result = create_conn(data, in_connect, asyncp);
5965 if((*in_connect)->send_pipe->size || (*in_connect)->recv_pipe->size)
5967 *protocol_done = TRUE;
5969 /* DNS resolution is done: that's either because this is a reused
5970 connection, in which case DNS was unnecessary, or because DNS
5971 really did finish already (synch resolver/fast async resolve) */
5972 result = Curl_setup_conn(*in_connect, protocol_done);
5976 if(result == CURLE_NO_CONNECTION_AVAILABLE) {
5981 if(result && *in_connect) {
5982 /* We're not allowed to return failure with memory left allocated
5983 in the connectdata struct, free those here */
5984 Curl_disconnect(*in_connect, FALSE); /* close the connection */
5985 *in_connect = NULL; /* return a NULL */
5991 CURLcode Curl_done(struct connectdata **connp,
5992 CURLcode status, /* an error if this is called after an
5993 error was detected */
5997 struct connectdata *conn;
5998 struct SessionHandle *data;
6000 DEBUGASSERT(*connp);
6005 DEBUGF(infof(data, "Curl_done\n"));
6007 if(data->state.done)
6008 /* Stop if Curl_done() has already been called */
6011 Curl_getoff_all_pipelines(data, conn);
6013 /* Cleanup possible redirect junk */
6014 free(data->req.newurl);
6015 data->req.newurl = NULL;
6016 free(data->req.location);
6017 data->req.location = NULL;
6020 case CURLE_ABORTED_BY_CALLBACK:
6021 case CURLE_READ_ERROR:
6022 case CURLE_WRITE_ERROR:
6023 /* When we're aborted due to a callback return code it basically have to
6024 be counted as premature as there is trouble ahead if we don't. We have
6025 many callbacks and protocols work differently, we could potentially do
6026 this more fine-grained in the future. */
6032 /* this calls the protocol-specific function pointer previously set */
6033 if(conn->handler->done)
6034 result = conn->handler->done(conn, status, premature);
6038 if(!result && Curl_pgrsDone(conn))
6039 result = CURLE_ABORTED_BY_CALLBACK;
6041 if((conn->send_pipe->size + conn->recv_pipe->size != 0 &&
6042 !data->set.reuse_forbid &&
6043 !conn->bits.close)) {
6044 /* Stop if pipeline is not empty and we do not have to close
6046 DEBUGF(infof(data, "Connection still in use, no more Curl_done now!\n"));
6050 data->state.done = TRUE; /* called just now! */
6051 Curl_resolver_cancel(conn);
6053 if(conn->dns_entry) {
6054 Curl_resolv_unlock(data, conn->dns_entry); /* done with this */
6055 conn->dns_entry = NULL;
6058 /* if the transfer was completed in a paused state there can be buffered
6059 data left to write and then kill */
6060 free(data->state.tempwrite);
6061 data->state.tempwrite = NULL;
6063 /* if data->set.reuse_forbid is TRUE, it means the libcurl client has
6064 forced us to close this connection. This is ignored for requests taking
6065 place in a NTLM authentication handshake
6067 if conn->bits.close is TRUE, it means that the connection should be
6068 closed in spite of all our efforts to be nice, due to protocol
6069 restrictions in our or the server's end
6071 if premature is TRUE, it means this connection was said to be DONE before
6072 the entire request operation is complete and thus we can't know in what
6073 state it is for re-using, so we're forced to close it. In a perfect world
6074 we can add code that keep track of if we really must close it here or not,
6075 but currently we have no such detail knowledge.
6078 if((data->set.reuse_forbid
6079 #if defined(USE_NTLM)
6080 && !(conn->ntlm.state == NTLMSTATE_TYPE2 ||
6081 conn->proxyntlm.state == NTLMSTATE_TYPE2)
6083 ) || conn->bits.close || premature) {
6084 CURLcode res2 = Curl_disconnect(conn, premature); /* close connection */
6086 /* If we had an error already, make sure we return that one. But
6087 if we got a new error, return that. */
6092 /* the connection is no longer in use */
6093 if(ConnectionDone(data, conn)) {
6094 /* remember the most recently used connection */
6095 data->state.lastconnect = conn;
6097 infof(data, "Connection #%ld to host %s left intact\n",
6098 conn->connection_id,
6099 conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname);
6102 data->state.lastconnect = NULL;
6105 *connp = NULL; /* to make the caller of this function better detect that
6106 this was either closed or handed over to the connection
6107 cache here, and therefore cannot be used from this point on
6109 Curl_free_request_state(data);
6115 * Curl_init_do() inits the readwrite session. This is inited each time (in
6116 * the DO function before the protocol-specific DO functions are invoked) for
6117 * a transfer, sometimes multiple times on the same SessionHandle. Make sure
6118 * nothing in here depends on stuff that are setup dynamically for the
6121 * Allow this function to get called with 'conn' set to NULL.
6124 CURLcode Curl_init_do(struct SessionHandle *data, struct connectdata *conn)
6126 struct SingleRequest *k = &data->req;
6129 conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to
6132 data->state.done = FALSE; /* Curl_done() is not called yet */
6133 data->state.expect100header = FALSE;
6135 if(data->set.opt_no_body)
6136 /* in HTTP lingo, no body means using the HEAD request... */
6137 data->set.httpreq = HTTPREQ_HEAD;
6138 else if(HTTPREQ_HEAD == data->set.httpreq)
6139 /* ... but if unset there really is no perfect method that is the
6140 "opposite" of HEAD but in reality most people probably think GET
6141 then. The important thing is that we can't let it remain HEAD if the
6142 opt_no_body is set FALSE since then we'll behave wrong when getting
6144 data->set.httpreq = HTTPREQ_GET;
6146 k->start = Curl_tvnow(); /* start time */
6147 k->now = k->start; /* current time is now */
6148 k->header = TRUE; /* assume header */
6152 k->buf = data->state.buffer;
6153 k->uploadbuf = data->state.uploadbuffer;
6154 k->hbufp = data->state.headerbuff;
6155 k->ignorebody=FALSE;
6157 Curl_speedinit(data);
6159 Curl_pgrsSetUploadCounter(data, 0);
6160 Curl_pgrsSetDownloadCounter(data, 0);
6166 * do_complete is called when the DO actions are complete.
6168 * We init chunking and trailer bits to their default values here immediately
6169 * before receiving any header data for the current request in the pipeline.
6171 static void do_complete(struct connectdata *conn)
6173 conn->data->req.chunk=FALSE;
6174 conn->data->req.maxfd = (conn->sockfd>conn->writesockfd?
6175 conn->sockfd:conn->writesockfd)+1;
6176 Curl_pgrsTime(conn->data, TIMER_PRETRANSFER);
6179 CURLcode Curl_do(struct connectdata **connp, bool *done)
6181 CURLcode result=CURLE_OK;
6182 struct connectdata *conn = *connp;
6183 struct SessionHandle *data = conn->data;
6185 if(conn->handler->do_it) {
6186 /* generic protocol-specific function pointer set in curl_connect() */
6187 result = conn->handler->do_it(conn, done);
6189 /* This was formerly done in transfer.c, but we better do it here */
6190 if((CURLE_SEND_ERROR == result) && conn->bits.reuse) {
6192 * If the connection is using an easy handle, call reconnect
6193 * to re-establish the connection. Otherwise, let the multi logic
6194 * figure out how to re-establish the connection.
6197 result = Curl_reconnect_request(connp);
6200 /* ... finally back to actually retry the DO phase */
6201 conn = *connp; /* re-assign conn since Curl_reconnect_request
6202 creates a new connection */
6203 result = conn->handler->do_it(conn, done);
6210 if(!result && *done)
6211 /* do_complete must be called after the protocol-specific DO function */
6218 * Curl_do_more() is called during the DO_MORE multi state. It is basically a
6219 * second stage DO state which (wrongly) was introduced to support FTP's
6220 * second connection.
6222 * TODO: A future libcurl should be able to work away this state.
6224 * 'complete' can return 0 for incomplete, 1 for done and -1 for go back to
6225 * DOING state there's more work to do!
6228 CURLcode Curl_do_more(struct connectdata *conn, int *complete)
6230 CURLcode result=CURLE_OK;
6234 if(conn->handler->do_more)
6235 result = conn->handler->do_more(conn, complete);
6237 if(!result && (*complete == 1))
6238 /* do_complete must be called after the protocol-specific DO function */