1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2014, 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"
128 #include "conncache.h"
129 #include "multihandle.h"
130 #include "pipeline.h"
134 #define _MPRINTF_REPLACE /* use our functions only */
135 #include <curl/mprintf.h>
137 #include "curl_memory.h"
138 /* The last #include file should be: */
139 #include "memdebug.h"
141 /* Local static prototypes */
142 static struct connectdata *
143 find_oldest_idle_connection(struct SessionHandle *data);
144 static struct connectdata *
145 find_oldest_idle_connection_in_bundle(struct SessionHandle *data,
146 struct connectbundle *bundle);
147 static void conn_free(struct connectdata *conn);
148 static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke);
149 static CURLcode do_init(struct connectdata *conn);
150 static CURLcode parse_url_login(struct SessionHandle *data,
151 struct connectdata *conn,
152 char **userptr, char **passwdptr,
154 static CURLcode parse_login_details(const char *login, const size_t len,
155 char **userptr, char **passwdptr,
161 static const struct Curl_handler * const protocols[] = {
163 #ifndef CURL_DISABLE_HTTP
167 #if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)
171 #ifndef CURL_DISABLE_FTP
175 #if defined(USE_SSL) && !defined(CURL_DISABLE_FTP)
179 #ifndef CURL_DISABLE_TELNET
180 &Curl_handler_telnet,
183 #ifndef CURL_DISABLE_DICT
187 #ifndef CURL_DISABLE_LDAP
189 #if !defined(CURL_DISABLE_LDAPS) && \
190 ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \
191 (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)))
196 #ifndef CURL_DISABLE_FILE
200 #ifndef CURL_DISABLE_TFTP
209 #ifndef CURL_DISABLE_IMAP
216 #ifndef CURL_DISABLE_POP3
223 #if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
224 (CURL_SIZEOF_CURL_OFF_T > 4) && \
225 (!defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO))
232 #ifndef CURL_DISABLE_SMTP
239 #ifndef CURL_DISABLE_RTSP
243 #ifndef CURL_DISABLE_GOPHER
244 &Curl_handler_gopher,
251 &Curl_handler_rtmpte,
253 &Curl_handler_rtmpts,
256 (struct Curl_handler *) NULL
260 * Dummy handler for undefined protocol schemes.
263 static const struct Curl_handler Curl_handler_dummy = {
264 "<no protocol>", /* scheme */
265 ZERO_NULL, /* setup_connection */
266 ZERO_NULL, /* do_it */
267 ZERO_NULL, /* done */
268 ZERO_NULL, /* do_more */
269 ZERO_NULL, /* connect_it */
270 ZERO_NULL, /* connecting */
271 ZERO_NULL, /* doing */
272 ZERO_NULL, /* proto_getsock */
273 ZERO_NULL, /* doing_getsock */
274 ZERO_NULL, /* domore_getsock */
275 ZERO_NULL, /* perform_getsock */
276 ZERO_NULL, /* disconnect */
277 ZERO_NULL, /* readwrite */
280 PROTOPT_NONE /* flags */
283 void Curl_freeset(struct SessionHandle *data)
285 /* Free all dynamic strings stored in the data->set substructure. */
287 for(i=(enum dupstring)0; i < STRING_LAST; i++) {
288 Curl_safefree(data->set.str[i]);
291 if(data->change.referer_alloc) {
292 Curl_safefree(data->change.referer);
293 data->change.referer_alloc = FALSE;
295 data->change.referer = NULL;
296 if(data->change.url_alloc) {
297 Curl_safefree(data->change.url);
298 data->change.url_alloc = FALSE;
300 data->change.url = NULL;
303 static CURLcode setstropt(char **charp, char *s)
305 /* Release the previous storage at `charp' and replace by a dynamic storage
306 copy of `s'. Return CURLE_OK or CURLE_OUT_OF_MEMORY. */
308 Curl_safefree(*charp);
314 return CURLE_OUT_OF_MEMORY;
322 static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp)
324 CURLcode result = CURLE_OK;
328 /* Parse the login details if specified. It not then we treat NULL as a hint
329 to clear the existing data */
331 result = parse_login_details(option, strlen(option),
332 (userp ? &user : NULL),
333 (passwdp ? &passwd : NULL),
338 /* Store the username part of option if required */
340 if(!user && option && option[0] == ':') {
341 /* Allocate an empty string instead of returning NULL as user name */
344 result = CURLE_OUT_OF_MEMORY;
347 Curl_safefree(*userp);
351 /* Store the password part of option if required */
353 Curl_safefree(*passwdp);
361 CURLcode Curl_dupset(struct SessionHandle *dst, struct SessionHandle *src)
363 CURLcode result = CURLE_OK;
366 /* Copy src->set into dst->set first, then deal with the strings
370 /* clear all string pointers first */
371 memset(dst->set.str, 0, STRING_LAST * sizeof(char *));
373 /* duplicate all strings */
374 for(i=(enum dupstring)0; i< STRING_LASTZEROTERMINATED; i++) {
375 result = setstropt(&dst->set.str[i], src->set.str[i]);
380 /* duplicate memory areas pointed to */
381 i = STRING_COPYPOSTFIELDS;
382 if(src->set.postfieldsize && src->set.str[i]) {
383 /* postfieldsize is curl_off_t, Curl_memdup() takes a size_t ... */
384 dst->set.str[i] = Curl_memdup(src->set.str[i],
385 curlx_sotouz(src->set.postfieldsize));
387 return CURLE_OUT_OF_MEMORY;
388 /* point to the new copy */
389 dst->set.postfields = dst->set.str[i];
396 * This is the internal function curl_easy_cleanup() calls. This should
397 * cleanup and free all resources associated with this sessionhandle.
399 * NOTE: if we ever add something that attempts to write to a socket or
400 * similar here, we must ignore SIGPIPE first. It is currently only done
401 * when curl_easy_perform() is invoked.
404 CURLcode Curl_close(struct SessionHandle *data)
406 struct Curl_multi *m;
411 Curl_expire(data, 0); /* shut off timers */
416 /* This handle is still part of a multi handle, take care of this first
417 and detach this handle from there. */
418 curl_multi_remove_handle(data->multi, data);
421 /* when curl_easy_perform() is used, it creates its own multi handle to
422 use and this is the one */
423 curl_multi_cleanup(data->multi_easy);
425 /* Destroy the timeout list that is held in the easy handle. It is
426 /normally/ done by curl_multi_remove_handle() but this is "just in
428 if(data->state.timeoutlist) {
429 Curl_llist_destroy(data->state.timeoutlist, NULL);
430 data->state.timeoutlist = NULL;
433 data->magic = 0; /* force a clear AFTER the possibly enforced removal from
434 the multi handle, since that function uses the magic
437 if(data->state.rangestringalloc)
438 free(data->state.range);
440 /* Free the pathbuffer */
441 Curl_safefree(data->state.pathbuffer);
442 data->state.path = NULL;
444 /* freed here just in case DONE wasn't called */
445 Curl_free_request_state(data);
447 /* Close down all open SSL info and sessions */
448 Curl_ssl_close_all(data);
449 Curl_safefree(data->state.first_host);
450 Curl_safefree(data->state.scratch);
451 Curl_ssl_free_certinfo(data);
453 /* Cleanup possible redirect junk */
454 if(data->req.newurl) {
455 free(data->req.newurl);
456 data->req.newurl = NULL;
459 if(data->change.referer_alloc) {
460 Curl_safefree(data->change.referer);
461 data->change.referer_alloc = FALSE;
463 data->change.referer = NULL;
465 if(data->change.url_alloc) {
466 Curl_safefree(data->change.url);
467 data->change.url_alloc = FALSE;
469 data->change.url = NULL;
471 Curl_safefree(data->state.headerbuff);
473 Curl_flush_cookies(data, 1);
475 Curl_digest_cleanup(data);
477 Curl_safefree(data->info.contenttype);
478 Curl_safefree(data->info.wouldredirect);
480 /* this destroys the channel and we cannot use it anymore after this */
481 Curl_resolver_cleanup(data->state.resolver);
483 Curl_convert_close(data);
485 /* No longer a dirty share, if it exists */
487 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
488 data->share->dirty--;
489 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
498 * Initialize the UserDefined fields within a SessionHandle.
499 * This may be safely called on a new or existing SessionHandle.
501 CURLcode Curl_init_userdefined(struct UserDefined *set)
503 CURLcode result = CURLE_OK;
505 set->out = stdout; /* default output to stdout */
506 set->in = stdin; /* default input from stdin */
507 set->err = stderr; /* default stderr to stderr */
509 /* use fwrite as default function to store output */
510 set->fwrite_func = (curl_write_callback)fwrite;
512 /* use fread as default function to read input */
513 set->fread_func = (curl_read_callback)fread;
514 set->is_fread_set = 0;
515 set->is_fwrite_set = 0;
517 set->seek_func = ZERO_NULL;
518 set->seek_client = ZERO_NULL;
520 /* conversion callbacks for non-ASCII hosts */
521 set->convfromnetwork = ZERO_NULL;
522 set->convtonetwork = ZERO_NULL;
523 set->convfromutf8 = ZERO_NULL;
525 set->filesize = -1; /* we don't know the size */
526 set->postfieldsize = -1; /* unknown size */
527 set->maxredirs = -1; /* allow any amount by default */
529 set->httpreq = HTTPREQ_GET; /* Default HTTP request */
530 set->rtspreq = RTSPREQ_OPTIONS; /* Default RTSP request */
531 set->ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */
532 set->ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */
533 set->ftp_use_pret = FALSE; /* mainly useful for drftpd servers */
534 set->ftp_filemethod = FTPFILE_MULTICWD;
536 set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
538 /* Set the default size of the SSL session ID cache */
539 set->ssl.max_ssl_sessions = 5;
541 set->proxyport = CURL_DEFAULT_PROXY_PORT; /* from url.h */
542 set->proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
543 set->httpauth = CURLAUTH_BASIC; /* defaults to basic */
544 set->proxyauth = CURLAUTH_BASIC; /* defaults to basic */
546 /* make libcurl quiet by default: */
547 set->hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */
550 * libcurl 7.10 introduced SSL verification *by default*! This needs to be
551 * switched off unless wanted.
553 set->ssl.verifypeer = TRUE;
554 set->ssl.verifyhost = TRUE;
556 set->ssl.authtype = CURL_TLSAUTH_NONE;
558 set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
560 set->ssl.sessionid = TRUE; /* session ID caching enabled by default */
562 set->new_file_perms = 0644; /* Default permissions */
563 set->new_directory_perms = 0755; /* Default permissions */
565 /* for the *protocols fields we don't use the CURLPROTO_ALL convenience
566 define since we internally only use the lower 16 bits for the passed
567 in bitmask to not conflict with the private bits */
568 set->allowed_protocols = CURLPROTO_ALL;
569 set->redir_protocols = CURLPROTO_ALL & /* All except FILE, SCP and SMB */
570 ~(CURLPROTO_FILE | CURLPROTO_SCP | CURLPROTO_SMB |
573 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
575 * disallow unprotected protection negotiation NEC reference implementation
576 * seem not to follow rfc1961 section 4.3/4.4
578 set->socks5_gssapi_nec = FALSE;
579 /* set default GSS-API service name */
580 result = setstropt(&set->str[STRING_SOCKS5_GSSAPI_SERVICE],
581 (char *) CURL_DEFAULT_SOCKS5_GSSAPI_SERVICE);
586 /* This is our preferred CA cert bundle/path since install time */
587 #if defined(CURL_CA_BUNDLE)
588 result = setstropt(&set->str[STRING_SSL_CAFILE], (char *) CURL_CA_BUNDLE);
589 #elif defined(CURL_CA_PATH)
590 result = setstropt(&set->str[STRING_SSL_CAPATH], (char *) CURL_CA_PATH);
593 set->wildcardmatch = FALSE;
594 set->chunk_bgn = ZERO_NULL;
595 set->chunk_end = ZERO_NULL;
597 /* tcp keepalives are disabled by default, but provide reasonable values for
598 * the interval and idle times.
600 set->tcp_keepalive = FALSE;
601 set->tcp_keepintvl = 60;
602 set->tcp_keepidle = 60;
604 set->ssl_enable_npn = TRUE;
605 set->ssl_enable_alpn = TRUE;
607 set->expect_100_timeout = 1000L; /* Wait for a second by default. */
614 * @param curl is a pointer to a sessionhandle pointer that gets set by this
619 CURLcode Curl_open(struct SessionHandle **curl)
622 struct SessionHandle *data;
624 /* Very simple start-up: alloc the struct, init it with zeroes and return */
625 data = calloc(1, sizeof(struct SessionHandle));
627 /* this is a very serious error */
628 DEBUGF(fprintf(stderr, "Error: calloc of SessionHandle failed\n"));
629 return CURLE_OUT_OF_MEMORY;
632 data->magic = CURLEASY_MAGIC_NUMBER;
634 result = Curl_resolver_init(&data->state.resolver);
636 DEBUGF(fprintf(stderr, "Error: resolver_init failed\n"));
641 /* We do some initial setup here, all those fields that can't be just 0 */
643 data->state.headerbuff = malloc(HEADERSIZE);
644 if(!data->state.headerbuff) {
645 DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n"));
646 result = CURLE_OUT_OF_MEMORY;
649 result = Curl_init_userdefined(&data->set);
651 data->state.headersize=HEADERSIZE;
653 Curl_convert_init(data);
655 /* most recent connection is not yet defined */
656 data->state.lastconnect = NULL;
658 data->progress.flags |= PGRS_HIDE;
659 data->state.current_speed = -1; /* init to negative == impossible */
661 data->wildcard.state = CURLWC_INIT;
662 data->wildcard.filelist = NULL;
663 data->set.fnmatch = ZERO_NULL;
664 data->set.maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */
668 Curl_resolver_cleanup(data->state.resolver);
669 if(data->state.headerbuff)
670 free(data->state.headerbuff);
681 CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
685 CURLcode result = CURLE_OK;
687 #ifndef CURL_DISABLE_HTTP
692 case CURLOPT_DNS_CACHE_TIMEOUT:
693 data->set.dns_cache_timeout = va_arg(param, long);
695 case CURLOPT_DNS_USE_GLOBAL_CACHE:
696 /* remember we want this enabled */
697 arg = va_arg(param, long);
698 data->set.global_dns_cache = (0 != arg)?TRUE:FALSE;
700 case CURLOPT_SSL_CIPHER_LIST:
701 /* set a list of cipher we want to use in the SSL connection */
702 result = setstropt(&data->set.str[STRING_SSL_CIPHER_LIST],
703 va_arg(param, char *));
706 case CURLOPT_RANDOM_FILE:
708 * This is the path name to a file that contains random data to seed
709 * the random SSL stuff with. The file is only used for reading.
711 result = setstropt(&data->set.str[STRING_SSL_RANDOM_FILE],
712 va_arg(param, char *));
714 case CURLOPT_EGDSOCKET:
716 * The Entropy Gathering Daemon socket pathname
718 result = setstropt(&data->set.str[STRING_SSL_EGDSOCKET],
719 va_arg(param, char *));
721 case CURLOPT_MAXCONNECTS:
723 * Set the absolute number of maximum simultaneous alive connection that
724 * libcurl is allowed to have.
726 data->set.maxconnects = va_arg(param, long);
728 case CURLOPT_FORBID_REUSE:
730 * When this transfer is done, it must not be left to be reused by a
731 * subsequent transfer but shall be closed immediately.
733 data->set.reuse_forbid = (0 != va_arg(param, long))?TRUE:FALSE;
735 case CURLOPT_FRESH_CONNECT:
737 * This transfer shall not use a previously cached connection but
738 * should be made with a fresh new connect!
740 data->set.reuse_fresh = (0 != va_arg(param, long))?TRUE:FALSE;
742 case CURLOPT_VERBOSE:
744 * Verbose means infof() calls that give a lot of information about
745 * the connection and transfer procedures as well as internal choices.
747 data->set.verbose = (0 != va_arg(param, long))?TRUE:FALSE;
751 * Set to include the header in the general data output stream.
753 data->set.include_header = (0 != va_arg(param, long))?TRUE:FALSE;
755 case CURLOPT_NOPROGRESS:
757 * Shut off the internal supported progress meter
759 data->set.hide_progress = (0 != va_arg(param, long))?TRUE:FALSE;
760 if(data->set.hide_progress)
761 data->progress.flags |= PGRS_HIDE;
763 data->progress.flags &= ~PGRS_HIDE;
767 * Do not include the body part in the output data stream.
769 data->set.opt_no_body = (0 != va_arg(param, long))?TRUE:FALSE;
771 case CURLOPT_FAILONERROR:
773 * Don't output the >=400 error code HTML-page, but instead only
776 data->set.http_fail_on_error = (0 != va_arg(param, long))?TRUE:FALSE;
781 * We want to sent data to the remote host. If this is HTTP, that equals
782 * using the PUT request.
784 data->set.upload = (0 != va_arg(param, long))?TRUE:FALSE;
785 if(data->set.upload) {
786 /* If this is HTTP, PUT is what's needed to "upload" */
787 data->set.httpreq = HTTPREQ_PUT;
788 data->set.opt_no_body = FALSE; /* this is implied */
791 /* In HTTP, the opposite of upload is GET (unless NOBODY is true as
792 then this can be changed to HEAD later on) */
793 data->set.httpreq = HTTPREQ_GET;
795 case CURLOPT_FILETIME:
797 * Try to get the file time of the remote document. The time will
798 * later (possibly) become available using curl_easy_getinfo().
800 data->set.get_filetime = (0 != va_arg(param, long))?TRUE:FALSE;
802 case CURLOPT_FTP_CREATE_MISSING_DIRS:
804 * An FTP option that modifies an upload to create missing directories on
807 switch(va_arg(param, long)) {
809 data->set.ftp_create_missing_dirs = 0;
812 data->set.ftp_create_missing_dirs = 1;
815 data->set.ftp_create_missing_dirs = 2;
818 /* reserve other values for future use */
819 result = CURLE_UNKNOWN_OPTION;
823 case CURLOPT_SERVER_RESPONSE_TIMEOUT:
825 * Option that specifies how quickly an server response must be obtained
826 * before it is considered failure. For pingpong protocols.
828 data->set.server_response_timeout = va_arg( param , long ) * 1000;
830 case CURLOPT_TFTP_BLKSIZE:
832 * TFTP option that specifies the block size to use for data transmission
834 data->set.tftp_blksize = va_arg(param, long);
836 case CURLOPT_DIRLISTONLY:
838 * An option that changes the command to one that asks for a list
839 * only, no file info details.
841 data->set.ftp_list_only = (0 != va_arg(param, long))?TRUE:FALSE;
845 * We want to upload and append to an existing file.
847 data->set.ftp_append = (0 != va_arg(param, long))?TRUE:FALSE;
849 case CURLOPT_FTP_FILEMETHOD:
851 * How do access files over FTP.
853 data->set.ftp_filemethod = (curl_ftpfile)va_arg(param, long);
857 * Parse the $HOME/.netrc file
859 data->set.use_netrc = (enum CURL_NETRC_OPTION)va_arg(param, long);
861 case CURLOPT_NETRC_FILE:
863 * Use this file instead of the $HOME/.netrc file
865 result = setstropt(&data->set.str[STRING_NETRC_FILE],
866 va_arg(param, char *));
868 case CURLOPT_TRANSFERTEXT:
870 * This option was previously named 'FTPASCII'. Renamed to work with
871 * more protocols than merely FTP.
873 * Transfer using ASCII (instead of BINARY).
875 data->set.prefer_ascii = (0 != va_arg(param, long))?TRUE:FALSE;
877 case CURLOPT_TIMECONDITION:
879 * Set HTTP time condition. This must be one of the defines in the
880 * curl/curl.h header file.
882 data->set.timecondition = (curl_TimeCond)va_arg(param, long);
884 case CURLOPT_TIMEVALUE:
886 * This is the value to compare with the remote document with the
887 * method set with CURLOPT_TIMECONDITION
889 data->set.timevalue = (time_t)va_arg(param, long);
891 case CURLOPT_SSLVERSION:
893 * Set explicit SSL version to try to connect with, as some SSL
894 * implementations are lame.
896 data->set.ssl.version = va_arg(param, long);
899 #ifndef CURL_DISABLE_HTTP
900 case CURLOPT_AUTOREFERER:
902 * Switch on automatic referer that gets set if curl follows locations.
904 data->set.http_auto_referer = (0 != va_arg(param, long))?TRUE:FALSE;
907 case CURLOPT_ACCEPT_ENCODING:
909 * String to use at the value of Accept-Encoding header.
911 * If the encoding is set to "" we use an Accept-Encoding header that
912 * encompasses all the encodings we support.
913 * If the encoding is set to NULL we don't send an Accept-Encoding header
914 * and ignore an received Content-Encoding header.
917 argptr = va_arg(param, char *);
918 result = setstropt(&data->set.str[STRING_ENCODING],
919 (argptr && !*argptr)?
920 (char *) ALL_CONTENT_ENCODINGS: argptr);
923 case CURLOPT_TRANSFER_ENCODING:
924 data->set.http_transfer_encoding = (0 != va_arg(param, long))?TRUE:FALSE;
927 case CURLOPT_FOLLOWLOCATION:
929 * Follow Location: header hints on a HTTP-server.
931 data->set.http_follow_location = (0 != va_arg(param, long))?TRUE:FALSE;
934 case CURLOPT_UNRESTRICTED_AUTH:
936 * Send authentication (user+password) when following locations, even when
939 data->set.http_disable_hostname_check_before_authentication =
940 (0 != va_arg(param, long))?TRUE:FALSE;
943 case CURLOPT_MAXREDIRS:
945 * The maximum amount of hops you allow curl to follow Location:
946 * headers. This should mostly be used to detect never-ending loops.
948 data->set.maxredirs = va_arg(param, long);
951 case CURLOPT_POSTREDIR:
954 * Set the behaviour of POST when redirecting
955 * CURL_REDIR_GET_ALL - POST is changed to GET after 301 and 302
956 * CURL_REDIR_POST_301 - POST is kept as POST after 301
957 * CURL_REDIR_POST_302 - POST is kept as POST after 302
958 * CURL_REDIR_POST_303 - POST is kept as POST after 303
959 * CURL_REDIR_POST_ALL - POST is kept as POST after 301, 302 and 303
960 * other - POST is kept as POST after 301 and 302
962 int postRedir = curlx_sltosi(va_arg(param, long));
963 data->set.keep_post = postRedir & CURL_REDIR_POST_ALL;
968 /* Does this option serve a purpose anymore? Yes it does, when
969 CURLOPT_POSTFIELDS isn't used and the POST data is read off the
971 if(va_arg(param, long)) {
972 data->set.httpreq = HTTPREQ_POST;
973 data->set.opt_no_body = FALSE; /* this is implied */
976 data->set.httpreq = HTTPREQ_GET;
979 case CURLOPT_COPYPOSTFIELDS:
981 * A string with POST data. Makes curl HTTP POST. Even if it is NULL.
982 * If needed, CURLOPT_POSTFIELDSIZE must have been set prior to
983 * CURLOPT_COPYPOSTFIELDS and not altered later.
985 argptr = va_arg(param, char *);
987 if(!argptr || data->set.postfieldsize == -1)
988 result = setstropt(&data->set.str[STRING_COPYPOSTFIELDS], argptr);
991 * Check that requested length does not overflow the size_t type.
994 if((data->set.postfieldsize < 0) ||
995 ((sizeof(curl_off_t) != sizeof(size_t)) &&
996 (data->set.postfieldsize > (curl_off_t)((size_t)-1))))
997 result = CURLE_OUT_OF_MEMORY;
1001 (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1003 /* Allocate even when size == 0. This satisfies the need of possible
1004 later address compare to detect the COPYPOSTFIELDS mode, and
1005 to mark that postfields is used rather than read function or
1008 p = malloc((size_t)(data->set.postfieldsize?
1009 data->set.postfieldsize:1));
1012 result = CURLE_OUT_OF_MEMORY;
1014 if(data->set.postfieldsize)
1015 memcpy(p, argptr, (size_t)data->set.postfieldsize);
1017 data->set.str[STRING_COPYPOSTFIELDS] = p;
1022 data->set.postfields = data->set.str[STRING_COPYPOSTFIELDS];
1023 data->set.httpreq = HTTPREQ_POST;
1026 case CURLOPT_POSTFIELDS:
1028 * Like above, but use static data instead of copying it.
1030 data->set.postfields = va_arg(param, void *);
1031 /* Release old copied data. */
1032 (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1033 data->set.httpreq = HTTPREQ_POST;
1036 case CURLOPT_POSTFIELDSIZE:
1038 * The size of the POSTFIELD data to prevent libcurl to do strlen() to
1039 * figure it out. Enables binary posts.
1041 bigsize = va_arg(param, long);
1043 if(data->set.postfieldsize < bigsize &&
1044 data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
1045 /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */
1046 (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1047 data->set.postfields = NULL;
1050 data->set.postfieldsize = bigsize;
1053 case CURLOPT_POSTFIELDSIZE_LARGE:
1055 * The size of the POSTFIELD data to prevent libcurl to do strlen() to
1056 * figure it out. Enables binary posts.
1058 bigsize = va_arg(param, curl_off_t);
1060 if(data->set.postfieldsize < bigsize &&
1061 data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
1062 /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */
1063 (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1064 data->set.postfields = NULL;
1067 data->set.postfieldsize = bigsize;
1070 case CURLOPT_HTTPPOST:
1072 * Set to make us do HTTP POST
1074 data->set.httppost = va_arg(param, struct curl_httppost *);
1075 data->set.httpreq = HTTPREQ_POST_FORM;
1076 data->set.opt_no_body = FALSE; /* this is implied */
1079 case CURLOPT_REFERER:
1081 * String to set in the HTTP Referer: field.
1083 if(data->change.referer_alloc) {
1084 Curl_safefree(data->change.referer);
1085 data->change.referer_alloc = FALSE;
1087 result = setstropt(&data->set.str[STRING_SET_REFERER],
1088 va_arg(param, char *));
1089 data->change.referer = data->set.str[STRING_SET_REFERER];
1092 case CURLOPT_USERAGENT:
1094 * String to use in the HTTP User-Agent field
1096 result = setstropt(&data->set.str[STRING_USERAGENT],
1097 va_arg(param, char *));
1100 case CURLOPT_HTTPHEADER:
1102 * Set a list with HTTP headers to use (or replace internals with)
1104 data->set.headers = va_arg(param, struct curl_slist *);
1107 case CURLOPT_PROXYHEADER:
1109 * Set a list with proxy headers to use (or replace internals with)
1111 * Since CURLOPT_HTTPHEADER was the only way to set HTTP headers for a
1112 * long time we remain doing it this way until CURLOPT_PROXYHEADER is
1113 * used. As soon as this option has been used, if set to anything but
1114 * NULL, custom headers for proxies are only picked from this list.
1116 * Set this option to NULL to restore the previous behavior.
1118 data->set.proxyheaders = va_arg(param, struct curl_slist *);
1121 case CURLOPT_HEADEROPT:
1123 * Set header option.
1125 arg = va_arg(param, long);
1126 data->set.sep_headers = (arg & CURLHEADER_SEPARATE)? TRUE: FALSE;
1129 case CURLOPT_HTTP200ALIASES:
1131 * Set a list of aliases for HTTP 200 in response header
1133 data->set.http200aliases = va_arg(param, struct curl_slist *);
1136 #if !defined(CURL_DISABLE_COOKIES)
1137 case CURLOPT_COOKIE:
1139 * Cookie string to send to the remote server in the request.
1141 result = setstropt(&data->set.str[STRING_COOKIE],
1142 va_arg(param, char *));
1145 case CURLOPT_COOKIEFILE:
1147 * Set cookie file to read and parse. Can be used multiple times.
1149 argptr = (char *)va_arg(param, void *);
1151 struct curl_slist *cl;
1152 /* append the cookie file name to the list of file names, and deal with
1154 cl = curl_slist_append(data->change.cookielist, argptr);
1156 curl_slist_free_all(data->change.cookielist);
1157 data->change.cookielist = NULL;
1158 return CURLE_OUT_OF_MEMORY;
1160 data->change.cookielist = cl; /* store the list for later use */
1164 case CURLOPT_COOKIEJAR:
1166 * Set cookie file name to dump all cookies to when we're done.
1169 struct CookieInfo *newcookies;
1170 result = setstropt(&data->set.str[STRING_COOKIEJAR],
1171 va_arg(param, char *));
1174 * Activate the cookie parser. This may or may not already
1177 newcookies = Curl_cookie_init(data, NULL, data->cookies,
1178 data->set.cookiesession);
1180 result = CURLE_OUT_OF_MEMORY;
1181 data->cookies = newcookies;
1185 case CURLOPT_COOKIESESSION:
1187 * Set this option to TRUE to start a new "cookie session". It will
1188 * prevent the forthcoming read-cookies-from-file actions to accept
1189 * cookies that are marked as being session cookies, as they belong to a
1192 * In the original Netscape cookie spec, "session cookies" are cookies
1193 * with no expire date set. RFC2109 describes the same action if no
1194 * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds
1195 * a 'Discard' action that can enforce the discard even for cookies that
1198 * We run mostly with the original cookie spec, as hardly anyone implements
1201 data->set.cookiesession = (0 != va_arg(param, long))?TRUE:FALSE;
1204 case CURLOPT_COOKIELIST:
1205 argptr = va_arg(param, char *);
1210 if(Curl_raw_equal(argptr, "ALL")) {
1211 /* clear all cookies */
1212 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
1213 Curl_cookie_clearall(data->cookies);
1214 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
1216 else if(Curl_raw_equal(argptr, "SESS")) {
1217 /* clear session cookies */
1218 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
1219 Curl_cookie_clearsess(data->cookies);
1220 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
1222 else if(Curl_raw_equal(argptr, "FLUSH")) {
1223 /* flush cookies to file, takes care of the locking */
1224 Curl_flush_cookies(data, 0);
1226 else if(Curl_raw_equal(argptr, "RELOAD")) {
1227 /* reload cookies from file */
1228 Curl_cookie_loadfiles(data);
1233 /* if cookie engine was not running, activate it */
1234 data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE);
1236 argptr = strdup(argptr);
1237 if(!argptr || !data->cookies) {
1238 result = CURLE_OUT_OF_MEMORY;
1239 Curl_safefree(argptr);
1242 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
1244 if(checkprefix("Set-Cookie:", argptr))
1245 /* HTTP Header format line */
1246 Curl_cookie_add(data, data->cookies, TRUE, argptr + 11, NULL, NULL);
1249 /* Netscape format line */
1250 Curl_cookie_add(data, data->cookies, FALSE, argptr, NULL, NULL);
1252 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
1258 #endif /* CURL_DISABLE_COOKIES */
1260 case CURLOPT_HTTPGET:
1262 * Set to force us do HTTP GET
1264 if(va_arg(param, long)) {
1265 data->set.httpreq = HTTPREQ_GET;
1266 data->set.upload = FALSE; /* switch off upload */
1267 data->set.opt_no_body = FALSE; /* this is implied */
1271 case CURLOPT_HTTP_VERSION:
1273 * This sets a requested HTTP version to be used. The value is one of
1274 * the listed enums in curl/curl.h.
1276 arg = va_arg(param, long);
1278 if(arg == CURL_HTTP_VERSION_2_0)
1279 return CURLE_UNSUPPORTED_PROTOCOL;
1281 data->set.httpversion = arg;
1284 case CURLOPT_HTTPAUTH:
1286 * Set HTTP Authentication type BITMASK.
1291 unsigned long auth = va_arg(param, unsigned long);
1293 if(auth == CURLAUTH_NONE) {
1294 data->set.httpauth = auth;
1298 /* the DIGEST_IE bit is only used to set a special marker, for all the
1299 rest we need to handle it as normal DIGEST */
1300 data->state.authhost.iestyle = (auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE;
1302 if(auth & CURLAUTH_DIGEST_IE) {
1303 auth |= CURLAUTH_DIGEST; /* set standard digest bit */
1304 auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */
1307 /* switch off bits we can't support */
1309 auth &= ~CURLAUTH_NTLM; /* no NTLM support */
1310 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
1311 #elif !defined(NTLM_WB_ENABLED)
1312 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
1315 auth &= ~CURLAUTH_NEGOTIATE; /* no Negotiate (SPNEGO) auth without
1319 /* check if any auth bit lower than CURLAUTH_ONLY is still set */
1322 while(bitcheck < 31) {
1323 if(auth & (1UL << bitcheck++)) {
1329 return CURLE_NOT_BUILT_IN; /* no supported types left! */
1331 data->set.httpauth = auth;
1335 case CURLOPT_EXPECT_100_TIMEOUT_MS:
1337 * Time to wait for a response to a HTTP request containing an
1338 * Expect: 100-continue header before sending the data anyway.
1340 data->set.expect_100_timeout = va_arg(param, long);
1343 #endif /* CURL_DISABLE_HTTP */
1345 case CURLOPT_CUSTOMREQUEST:
1347 * Set a custom string to use as request
1349 result = setstropt(&data->set.str[STRING_CUSTOMREQUEST],
1350 va_arg(param, char *));
1353 data->set.httpreq = HTTPREQ_CUSTOM;
1354 here, we continue as if we were using the already set type
1355 and this just changes the actual request keyword */
1358 #ifndef CURL_DISABLE_PROXY
1359 case CURLOPT_HTTPPROXYTUNNEL:
1361 * Tunnel operations through the proxy instead of normal proxy use
1363 data->set.tunnel_thru_httpproxy = (0 != va_arg(param, long))?TRUE:FALSE;
1366 case CURLOPT_PROXYPORT:
1368 * Explicitly set HTTP proxy port number.
1370 data->set.proxyport = va_arg(param, long);
1373 case CURLOPT_PROXYAUTH:
1375 * Set HTTP Authentication type BITMASK.
1380 unsigned long auth = va_arg(param, unsigned long);
1382 if(auth == CURLAUTH_NONE) {
1383 data->set.proxyauth = auth;
1387 /* the DIGEST_IE bit is only used to set a special marker, for all the
1388 rest we need to handle it as normal DIGEST */
1389 data->state.authproxy.iestyle = (auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE;
1391 if(auth & CURLAUTH_DIGEST_IE) {
1392 auth |= CURLAUTH_DIGEST; /* set standard digest bit */
1393 auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */
1395 /* switch off bits we can't support */
1397 auth &= ~CURLAUTH_NTLM; /* no NTLM support */
1398 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
1399 #elif !defined(NTLM_WB_ENABLED)
1400 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
1403 auth &= ~CURLAUTH_NEGOTIATE; /* no Negotiate (SPNEGO) auth without
1407 /* check if any auth bit lower than CURLAUTH_ONLY is still set */
1410 while(bitcheck < 31) {
1411 if(auth & (1UL << bitcheck++)) {
1417 return CURLE_NOT_BUILT_IN; /* no supported types left! */
1419 data->set.proxyauth = auth;
1425 * Set proxy server:port to use as HTTP proxy.
1427 * If the proxy is set to "" we explicitly say that we don't want to use a
1428 * proxy (even though there might be environment variables saying so).
1430 * Setting it to NULL, means no proxy but allows the environment variables
1433 result = setstropt(&data->set.str[STRING_PROXY],
1434 va_arg(param, char *));
1437 case CURLOPT_PROXYTYPE:
1439 * Set proxy type. HTTP/HTTP_1_0/SOCKS4/SOCKS4a/SOCKS5/SOCKS5_HOSTNAME
1441 data->set.proxytype = (curl_proxytype)va_arg(param, long);
1444 case CURLOPT_PROXY_TRANSFER_MODE:
1446 * set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy
1448 switch (va_arg(param, long)) {
1450 data->set.proxy_transfer_mode = FALSE;
1453 data->set.proxy_transfer_mode = TRUE;
1456 /* reserve other values for future use */
1457 result = CURLE_UNKNOWN_OPTION;
1461 #endif /* CURL_DISABLE_PROXY */
1463 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
1464 case CURLOPT_SOCKS5_GSSAPI_SERVICE:
1466 * Set GSS-API service name
1468 result = setstropt(&data->set.str[STRING_SOCKS5_GSSAPI_SERVICE],
1469 va_arg(param, char *));
1472 case CURLOPT_SOCKS5_GSSAPI_NEC:
1474 * set flag for nec socks5 support
1476 data->set.socks5_gssapi_nec = (0 != va_arg(param, long))?TRUE:FALSE;
1480 case CURLOPT_HEADERDATA:
1482 * Custom pointer to pass the header write callback function
1484 data->set.writeheader = (void *)va_arg(param, void *);
1486 case CURLOPT_ERRORBUFFER:
1488 * Error buffer provided by the caller to get the human readable
1491 data->set.errorbuffer = va_arg(param, char *);
1493 case CURLOPT_WRITEDATA:
1495 * FILE pointer to write to. Or possibly
1496 * used as argument to the write callback.
1498 data->set.out = va_arg(param, void *);
1500 case CURLOPT_FTPPORT:
1502 * Use FTP PORT, this also specifies which IP address to use
1504 result = setstropt(&data->set.str[STRING_FTPPORT],
1505 va_arg(param, char *));
1506 data->set.ftp_use_port = (NULL != data->set.str[STRING_FTPPORT]) ?
1510 case CURLOPT_FTP_USE_EPRT:
1511 data->set.ftp_use_eprt = (0 != va_arg(param, long))?TRUE:FALSE;
1514 case CURLOPT_FTP_USE_EPSV:
1515 data->set.ftp_use_epsv = (0 != va_arg(param, long))?TRUE:FALSE;
1518 case CURLOPT_FTP_USE_PRET:
1519 data->set.ftp_use_pret = (0 != va_arg(param, long))?TRUE:FALSE;
1522 case CURLOPT_FTP_SSL_CCC:
1523 data->set.ftp_ccc = (curl_ftpccc)va_arg(param, long);
1526 case CURLOPT_FTP_SKIP_PASV_IP:
1528 * Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the
1529 * bypass of the IP address in PASV responses.
1531 data->set.ftp_skip_ip = (0 != va_arg(param, long))?TRUE:FALSE;
1534 case CURLOPT_READDATA:
1536 * FILE pointer to read the file to be uploaded from. Or possibly
1537 * used as argument to the read callback.
1539 data->set.in = va_arg(param, void *);
1541 case CURLOPT_INFILESIZE:
1543 * If known, this should inform curl about the file size of the
1544 * to-be-uploaded file.
1546 data->set.filesize = va_arg(param, long);
1548 case CURLOPT_INFILESIZE_LARGE:
1550 * If known, this should inform curl about the file size of the
1551 * to-be-uploaded file.
1553 data->set.filesize = va_arg(param, curl_off_t);
1555 case CURLOPT_LOW_SPEED_LIMIT:
1557 * The low speed limit that if transfers are below this for
1558 * CURLOPT_LOW_SPEED_TIME, the transfer is aborted.
1560 data->set.low_speed_limit=va_arg(param, long);
1562 case CURLOPT_MAX_SEND_SPEED_LARGE:
1564 * When transfer uploads are faster then CURLOPT_MAX_SEND_SPEED_LARGE
1565 * bytes per second the transfer is throttled..
1567 data->set.max_send_speed=va_arg(param, curl_off_t);
1569 case CURLOPT_MAX_RECV_SPEED_LARGE:
1571 * When receiving data faster than CURLOPT_MAX_RECV_SPEED_LARGE bytes per
1572 * second the transfer is throttled..
1574 data->set.max_recv_speed=va_arg(param, curl_off_t);
1576 case CURLOPT_LOW_SPEED_TIME:
1578 * The low speed time that if transfers are below the set
1579 * CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted.
1581 data->set.low_speed_time=va_arg(param, long);
1587 if(data->change.url_alloc) {
1588 /* the already set URL is allocated, free it first! */
1589 Curl_safefree(data->change.url);
1590 data->change.url_alloc = FALSE;
1592 result = setstropt(&data->set.str[STRING_SET_URL],
1593 va_arg(param, char *));
1594 data->change.url = data->set.str[STRING_SET_URL];
1598 * The port number to use when getting the URL
1600 data->set.use_port = va_arg(param, long);
1602 case CURLOPT_TIMEOUT:
1604 * The maximum time you allow curl to use for a single transfer
1607 data->set.timeout = va_arg(param, long) * 1000L;
1610 case CURLOPT_TIMEOUT_MS:
1611 data->set.timeout = va_arg(param, long);
1614 case CURLOPT_CONNECTTIMEOUT:
1616 * The maximum time you allow curl to use to connect.
1618 data->set.connecttimeout = va_arg(param, long) * 1000L;
1621 case CURLOPT_CONNECTTIMEOUT_MS:
1622 data->set.connecttimeout = va_arg(param, long);
1625 case CURLOPT_ACCEPTTIMEOUT_MS:
1627 * The maximum time you allow curl to wait for server connect
1629 data->set.accepttimeout = va_arg(param, long);
1632 case CURLOPT_USERPWD:
1634 * user:password to use in the operation
1636 result = setstropt_userpwd(va_arg(param, char *),
1637 &data->set.str[STRING_USERNAME],
1638 &data->set.str[STRING_PASSWORD]);
1641 case CURLOPT_USERNAME:
1643 * authentication user name to use in the operation
1645 result = setstropt(&data->set.str[STRING_USERNAME],
1646 va_arg(param, char *));
1649 case CURLOPT_PASSWORD:
1651 * authentication password to use in the operation
1653 result = setstropt(&data->set.str[STRING_PASSWORD],
1654 va_arg(param, char *));
1657 case CURLOPT_LOGIN_OPTIONS:
1659 * authentication options to use in the operation
1661 result = setstropt(&data->set.str[STRING_OPTIONS],
1662 va_arg(param, char *));
1665 case CURLOPT_XOAUTH2_BEARER:
1667 * XOAUTH2 bearer token to use in the operation
1669 result = setstropt(&data->set.str[STRING_BEARER],
1670 va_arg(param, char *));
1673 case CURLOPT_POSTQUOTE:
1675 * List of RAW FTP commands to use after a transfer
1677 data->set.postquote = va_arg(param, struct curl_slist *);
1679 case CURLOPT_PREQUOTE:
1681 * List of RAW FTP commands to use prior to RETR (Wesley Laxton)
1683 data->set.prequote = va_arg(param, struct curl_slist *);
1687 * List of RAW FTP commands to use before a transfer
1689 data->set.quote = va_arg(param, struct curl_slist *);
1691 case CURLOPT_RESOLVE:
1693 * List of NAME:[address] names to populate the DNS cache with
1694 * Prefix the NAME with dash (-) to _remove_ the name from the cache.
1696 * Names added with this API will remain in the cache until explicitly
1697 * removed or the handle is cleaned up.
1699 * This API can remove any name from the DNS cache, but only entries
1700 * that aren't actually in use right now will be pruned immediately.
1702 data->set.resolve = va_arg(param, struct curl_slist *);
1703 data->change.resolve = data->set.resolve;
1705 case CURLOPT_PROGRESSFUNCTION:
1707 * Progress callback function
1709 data->set.fprogress = va_arg(param, curl_progress_callback);
1710 if(data->set.fprogress)
1711 data->progress.callback = TRUE; /* no longer internal */
1713 data->progress.callback = FALSE; /* NULL enforces internal */
1716 case CURLOPT_XFERINFOFUNCTION:
1718 * Transfer info callback function
1720 data->set.fxferinfo = va_arg(param, curl_xferinfo_callback);
1721 if(data->set.fxferinfo)
1722 data->progress.callback = TRUE; /* no longer internal */
1724 data->progress.callback = FALSE; /* NULL enforces internal */
1728 case CURLOPT_PROGRESSDATA:
1730 * Custom client data to pass to the progress callback
1732 data->set.progress_client = va_arg(param, void *);
1735 #ifndef CURL_DISABLE_PROXY
1736 case CURLOPT_PROXYUSERPWD:
1738 * user:password needed to use the proxy
1740 result = setstropt_userpwd(va_arg(param, char *),
1741 &data->set.str[STRING_PROXYUSERNAME],
1742 &data->set.str[STRING_PROXYPASSWORD]);
1744 case CURLOPT_PROXYUSERNAME:
1746 * authentication user name to use in the operation
1748 result = setstropt(&data->set.str[STRING_PROXYUSERNAME],
1749 va_arg(param, char *));
1751 case CURLOPT_PROXYPASSWORD:
1753 * authentication password to use in the operation
1755 result = setstropt(&data->set.str[STRING_PROXYPASSWORD],
1756 va_arg(param, char *));
1758 case CURLOPT_NOPROXY:
1760 * proxy exception list
1762 result = setstropt(&data->set.str[STRING_NOPROXY],
1763 va_arg(param, char *));
1769 * What range of the file you want to transfer
1771 result = setstropt(&data->set.str[STRING_SET_RANGE],
1772 va_arg(param, char *));
1774 case CURLOPT_RESUME_FROM:
1776 * Resume transfer at the give file position
1778 data->set.set_resume_from = va_arg(param, long);
1780 case CURLOPT_RESUME_FROM_LARGE:
1782 * Resume transfer at the give file position
1784 data->set.set_resume_from = va_arg(param, curl_off_t);
1786 case CURLOPT_DEBUGFUNCTION:
1788 * stderr write callback.
1790 data->set.fdebug = va_arg(param, curl_debug_callback);
1792 * if the callback provided is NULL, it'll use the default callback
1795 case CURLOPT_DEBUGDATA:
1797 * Set to a void * that should receive all error writes. This
1798 * defaults to CURLOPT_STDERR for normal operations.
1800 data->set.debugdata = va_arg(param, void *);
1802 case CURLOPT_STDERR:
1804 * Set to a FILE * that should receive all error writes. This
1805 * defaults to stderr for normal operations.
1807 data->set.err = va_arg(param, FILE *);
1809 data->set.err = stderr;
1811 case CURLOPT_HEADERFUNCTION:
1813 * Set header write callback
1815 data->set.fwrite_header = va_arg(param, curl_write_callback);
1817 case CURLOPT_WRITEFUNCTION:
1819 * Set data write callback
1821 data->set.fwrite_func = va_arg(param, curl_write_callback);
1822 if(!data->set.fwrite_func) {
1823 data->set.is_fwrite_set = 0;
1824 /* When set to NULL, reset to our internal default function */
1825 data->set.fwrite_func = (curl_write_callback)fwrite;
1828 data->set.is_fwrite_set = 1;
1830 case CURLOPT_READFUNCTION:
1832 * Read data callback
1834 data->set.fread_func = va_arg(param, curl_read_callback);
1835 if(!data->set.fread_func) {
1836 data->set.is_fread_set = 0;
1837 /* When set to NULL, reset to our internal default function */
1838 data->set.fread_func = (curl_read_callback)fread;
1841 data->set.is_fread_set = 1;
1843 case CURLOPT_SEEKFUNCTION:
1845 * Seek callback. Might be NULL.
1847 data->set.seek_func = va_arg(param, curl_seek_callback);
1849 case CURLOPT_SEEKDATA:
1851 * Seek control callback. Might be NULL.
1853 data->set.seek_client = va_arg(param, void *);
1855 case CURLOPT_CONV_FROM_NETWORK_FUNCTION:
1857 * "Convert from network encoding" callback
1859 data->set.convfromnetwork = va_arg(param, curl_conv_callback);
1861 case CURLOPT_CONV_TO_NETWORK_FUNCTION:
1863 * "Convert to network encoding" callback
1865 data->set.convtonetwork = va_arg(param, curl_conv_callback);
1867 case CURLOPT_CONV_FROM_UTF8_FUNCTION:
1869 * "Convert from UTF-8 encoding" callback
1871 data->set.convfromutf8 = va_arg(param, curl_conv_callback);
1873 case CURLOPT_IOCTLFUNCTION:
1875 * I/O control callback. Might be NULL.
1877 data->set.ioctl_func = va_arg(param, curl_ioctl_callback);
1879 case CURLOPT_IOCTLDATA:
1881 * I/O control data pointer. Might be NULL.
1883 data->set.ioctl_client = va_arg(param, void *);
1885 case CURLOPT_SSLCERT:
1887 * String that holds file name of the SSL certificate to use
1889 result = setstropt(&data->set.str[STRING_CERT],
1890 va_arg(param, char *));
1892 case CURLOPT_SSLCERTTYPE:
1894 * String that holds file type of the SSL certificate to use
1896 result = setstropt(&data->set.str[STRING_CERT_TYPE],
1897 va_arg(param, char *));
1899 case CURLOPT_SSLKEY:
1901 * String that holds file name of the SSL key to use
1903 result = setstropt(&data->set.str[STRING_KEY],
1904 va_arg(param, char *));
1906 case CURLOPT_SSLKEYTYPE:
1908 * String that holds file type of the SSL key to use
1910 result = setstropt(&data->set.str[STRING_KEY_TYPE],
1911 va_arg(param, char *));
1913 case CURLOPT_KEYPASSWD:
1915 * String that holds the SSL or SSH private key password.
1917 result = setstropt(&data->set.str[STRING_KEY_PASSWD],
1918 va_arg(param, char *));
1920 case CURLOPT_SSLENGINE:
1922 * String that holds the SSL crypto engine.
1924 argptr = va_arg(param, char *);
1925 if(argptr && argptr[0])
1926 result = Curl_ssl_set_engine(data, argptr);
1929 case CURLOPT_SSLENGINE_DEFAULT:
1931 * flag to set engine as default.
1933 result = Curl_ssl_set_engine_default(data);
1937 * Kludgy option to enable CRLF conversions. Subject for removal.
1939 data->set.crlf = (0 != va_arg(param, long))?TRUE:FALSE;
1942 case CURLOPT_INTERFACE:
1944 * Set what interface or address/hostname to bind the socket to when
1945 * performing an operation and thus what from-IP your connection will use.
1947 result = setstropt(&data->set.str[STRING_DEVICE],
1948 va_arg(param, char *));
1950 case CURLOPT_LOCALPORT:
1952 * Set what local port to bind the socket to when performing an operation.
1954 data->set.localport = curlx_sltous(va_arg(param, long));
1956 case CURLOPT_LOCALPORTRANGE:
1958 * Set number of local ports to try, starting with CURLOPT_LOCALPORT.
1960 data->set.localportrange = curlx_sltosi(va_arg(param, long));
1962 case CURLOPT_KRBLEVEL:
1964 * A string that defines the kerberos security level.
1966 result = setstropt(&data->set.str[STRING_KRB_LEVEL],
1967 va_arg(param, char *));
1968 data->set.krb = (NULL != data->set.str[STRING_KRB_LEVEL])?TRUE:FALSE;
1970 case CURLOPT_GSSAPI_DELEGATION:
1972 * GSS-API credential delegation
1974 data->set.gssapi_delegation = va_arg(param, long);
1976 case CURLOPT_SSL_VERIFYPEER:
1978 * Enable peer SSL verifying.
1980 data->set.ssl.verifypeer = (0 != va_arg(param, long))?TRUE:FALSE;
1982 case CURLOPT_SSL_VERIFYHOST:
1984 * Enable verification of the host name in the peer certificate
1986 arg = va_arg(param, long);
1988 /* Obviously people are not reading documentation and too many thought
1989 this argument took a boolean when it wasn't and misused it. We thus ban
1990 1 as a sensible input and we warn about its use. Then we only have the
1991 2 action internally stored as TRUE. */
1994 failf(data, "CURLOPT_SSL_VERIFYHOST no longer supports 1 as value!");
1995 return CURLE_BAD_FUNCTION_ARGUMENT;
1998 data->set.ssl.verifyhost = (0 != arg)?TRUE:FALSE;
2000 case CURLOPT_SSL_VERIFYSTATUS:
2002 * Enable certificate status verifying.
2004 if(!Curl_ssl_cert_status_request()) {
2005 result = CURLE_NOT_BUILT_IN;
2009 data->set.ssl.verifystatus = (0 != va_arg(param, long))?TRUE:FALSE;
2011 case CURLOPT_SSL_CTX_FUNCTION:
2012 #ifdef have_curlssl_ssl_ctx
2014 * Set a SSL_CTX callback
2016 data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback);
2018 result = CURLE_NOT_BUILT_IN;
2021 case CURLOPT_SSL_CTX_DATA:
2022 #ifdef have_curlssl_ssl_ctx
2024 * Set a SSL_CTX callback parameter pointer
2026 data->set.ssl.fsslctxp = va_arg(param, void *);
2028 result = CURLE_NOT_BUILT_IN;
2031 case CURLOPT_CERTINFO:
2032 #ifdef have_curlssl_certinfo
2033 data->set.ssl.certinfo = (0 != va_arg(param, long))?TRUE:FALSE;
2035 result = CURLE_NOT_BUILT_IN;
2038 case CURLOPT_PINNEDPUBLICKEY:
2040 * Set pinned public key for SSL connection.
2041 * Specify file name of the public key in DER format.
2043 result = setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY],
2044 va_arg(param, char *));
2046 case CURLOPT_CAINFO:
2048 * Set CA info for SSL connection. Specify file name of the CA certificate
2050 result = setstropt(&data->set.str[STRING_SSL_CAFILE],
2051 va_arg(param, char *));
2053 case CURLOPT_CAPATH:
2054 #ifdef have_curlssl_ca_path /* not supported by all backends */
2056 * Set CA path info for SSL connection. Specify directory name of the CA
2057 * certificates which have been prepared using openssl c_rehash utility.
2059 /* This does not work on windows. */
2060 result = setstropt(&data->set.str[STRING_SSL_CAPATH],
2061 va_arg(param, char *));
2063 result = CURLE_NOT_BUILT_IN;
2066 case CURLOPT_CRLFILE:
2068 * Set CRL file info for SSL connection. Specify file name of the CRL
2069 * to check certificates revocation
2071 result = setstropt(&data->set.str[STRING_SSL_CRLFILE],
2072 va_arg(param, char *));
2074 case CURLOPT_ISSUERCERT:
2076 * Set Issuer certificate file
2077 * to check certificates issuer
2079 result = setstropt(&data->set.str[STRING_SSL_ISSUERCERT],
2080 va_arg(param, char *));
2082 case CURLOPT_TELNETOPTIONS:
2084 * Set a linked list of telnet options
2086 data->set.telnet_options = va_arg(param, struct curl_slist *);
2089 case CURLOPT_BUFFERSIZE:
2091 * The application kindly asks for a differently sized receive buffer.
2092 * If it seems reasonable, we'll use it.
2094 data->set.buffer_size = va_arg(param, long);
2096 if((data->set.buffer_size> (BUFSIZE -1 )) ||
2097 (data->set.buffer_size < 1))
2098 data->set.buffer_size = 0; /* huge internal default */
2102 case CURLOPT_NOSIGNAL:
2104 * The application asks not to set any signal() or alarm() handlers,
2105 * even when using a timeout.
2107 data->set.no_signal = (0 != va_arg(param, long))?TRUE:FALSE;
2112 struct Curl_share *set;
2113 set = va_arg(param, struct Curl_share *);
2115 /* disconnect from old share, if any */
2117 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
2119 if(data->dns.hostcachetype == HCACHE_SHARED) {
2120 data->dns.hostcache = NULL;
2121 data->dns.hostcachetype = HCACHE_NONE;
2124 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
2125 if(data->share->cookies == data->cookies)
2126 data->cookies = NULL;
2129 if(data->share->sslsession == data->state.session)
2130 data->state.session = NULL;
2132 data->share->dirty--;
2134 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
2138 /* use new share if it set */
2142 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
2144 data->share->dirty++;
2146 if(data->share->hostcache) {
2147 /* use shared host cache */
2148 data->dns.hostcache = data->share->hostcache;
2149 data->dns.hostcachetype = HCACHE_SHARED;
2151 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
2152 if(data->share->cookies) {
2153 /* use shared cookie list, first free own one if any */
2155 Curl_cookie_cleanup(data->cookies);
2156 /* enable cookies since we now use a share that uses cookies! */
2157 data->cookies = data->share->cookies;
2159 #endif /* CURL_DISABLE_HTTP */
2160 if(data->share->sslsession) {
2161 data->set.ssl.max_ssl_sessions = data->share->max_ssl_sessions;
2162 data->state.session = data->share->sslsession;
2164 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
2167 /* check for host cache not needed,
2168 * it will be done by curl_easy_perform */
2172 case CURLOPT_PRIVATE:
2174 * Set private data pointer.
2176 data->set.private_data = va_arg(param, void *);
2179 case CURLOPT_MAXFILESIZE:
2181 * Set the maximum size of a file to download.
2183 data->set.max_filesize = va_arg(param, long);
2187 case CURLOPT_USE_SSL:
2189 * Make transfers attempt to use SSL/TLS.
2191 data->set.use_ssl = (curl_usessl)va_arg(param, long);
2194 case CURLOPT_SSL_OPTIONS:
2195 arg = va_arg(param, long);
2196 data->set.ssl_enable_beast = arg&CURLSSLOPT_ALLOW_BEAST?TRUE:FALSE;
2200 case CURLOPT_FTPSSLAUTH:
2202 * Set a specific auth for FTP-SSL transfers.
2204 data->set.ftpsslauth = (curl_ftpauth)va_arg(param, long);
2207 case CURLOPT_IPRESOLVE:
2208 data->set.ipver = va_arg(param, long);
2211 case CURLOPT_MAXFILESIZE_LARGE:
2213 * Set the maximum size of a file to download.
2215 data->set.max_filesize = va_arg(param, curl_off_t);
2218 case CURLOPT_TCP_NODELAY:
2220 * Enable or disable TCP_NODELAY, which will disable/enable the Nagle
2223 data->set.tcp_nodelay = (0 != va_arg(param, long))?TRUE:FALSE;
2226 case CURLOPT_FTP_ACCOUNT:
2227 result = setstropt(&data->set.str[STRING_FTP_ACCOUNT],
2228 va_arg(param, char *));
2231 case CURLOPT_IGNORE_CONTENT_LENGTH:
2232 data->set.ignorecl = (0 != va_arg(param, long))?TRUE:FALSE;
2235 case CURLOPT_CONNECT_ONLY:
2237 * No data transfer, set up connection and let application use the socket
2239 data->set.connect_only = (0 != va_arg(param, long))?TRUE:FALSE;
2242 case CURLOPT_FTP_ALTERNATIVE_TO_USER:
2243 result = setstropt(&data->set.str[STRING_FTP_ALTERNATIVE_TO_USER],
2244 va_arg(param, char *));
2247 case CURLOPT_SOCKOPTFUNCTION:
2249 * socket callback function: called after socket() but before connect()
2251 data->set.fsockopt = va_arg(param, curl_sockopt_callback);
2254 case CURLOPT_SOCKOPTDATA:
2256 * socket callback data pointer. Might be NULL.
2258 data->set.sockopt_client = va_arg(param, void *);
2261 case CURLOPT_OPENSOCKETFUNCTION:
2263 * open/create socket callback function: called instead of socket(),
2266 data->set.fopensocket = va_arg(param, curl_opensocket_callback);
2269 case CURLOPT_OPENSOCKETDATA:
2271 * socket callback data pointer. Might be NULL.
2273 data->set.opensocket_client = va_arg(param, void *);
2276 case CURLOPT_CLOSESOCKETFUNCTION:
2278 * close socket callback function: called instead of close()
2279 * when shutting down a connection
2281 data->set.fclosesocket = va_arg(param, curl_closesocket_callback);
2284 case CURLOPT_CLOSESOCKETDATA:
2286 * socket callback data pointer. Might be NULL.
2288 data->set.closesocket_client = va_arg(param, void *);
2291 case CURLOPT_SSL_SESSIONID_CACHE:
2292 data->set.ssl.sessionid = (0 != va_arg(param, long))?TRUE:FALSE;
2296 /* we only include SSH options if explicitly built to support SSH */
2297 case CURLOPT_SSH_AUTH_TYPES:
2298 data->set.ssh_auth_types = va_arg(param, long);
2301 case CURLOPT_SSH_PUBLIC_KEYFILE:
2303 * Use this file instead of the $HOME/.ssh/id_dsa.pub file
2305 result = setstropt(&data->set.str[STRING_SSH_PUBLIC_KEY],
2306 va_arg(param, char *));
2309 case CURLOPT_SSH_PRIVATE_KEYFILE:
2311 * Use this file instead of the $HOME/.ssh/id_dsa file
2313 result = setstropt(&data->set.str[STRING_SSH_PRIVATE_KEY],
2314 va_arg(param, char *));
2316 case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5:
2318 * Option to allow for the MD5 of the host public key to be checked
2319 * for validation purposes.
2321 result = setstropt(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5],
2322 va_arg(param, char *));
2324 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2325 case CURLOPT_SSH_KNOWNHOSTS:
2327 * Store the file name to read known hosts from.
2329 result = setstropt(&data->set.str[STRING_SSH_KNOWNHOSTS],
2330 va_arg(param, char *));
2333 case CURLOPT_SSH_KEYFUNCTION:
2334 /* setting to NULL is fine since the ssh.c functions themselves will
2335 then rever to use the internal default */
2336 data->set.ssh_keyfunc = va_arg(param, curl_sshkeycallback);
2339 case CURLOPT_SSH_KEYDATA:
2341 * Custom client data to pass to the SSH keyfunc callback
2343 data->set.ssh_keyfunc_userp = va_arg(param, void *);
2345 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2347 #endif /* USE_LIBSSH2 */
2349 case CURLOPT_HTTP_TRANSFER_DECODING:
2351 * disable libcurl transfer encoding is used
2353 data->set.http_te_skip = (0 == va_arg(param, long))?TRUE:FALSE;
2356 case CURLOPT_HTTP_CONTENT_DECODING:
2358 * raw data passed to the application when content encoding is used
2360 data->set.http_ce_skip = (0 == va_arg(param, long))?TRUE:FALSE;
2363 case CURLOPT_NEW_FILE_PERMS:
2365 * Uses these permissions instead of 0644
2367 data->set.new_file_perms = va_arg(param, long);
2370 case CURLOPT_NEW_DIRECTORY_PERMS:
2372 * Uses these permissions instead of 0755
2374 data->set.new_directory_perms = va_arg(param, long);
2377 case CURLOPT_ADDRESS_SCOPE:
2379 * We always get longs when passed plain numericals, but for this value we
2380 * know that an unsigned int will always hold the value so we blindly
2381 * typecast to this type
2383 data->set.scope_id = curlx_sltoui(va_arg(param, long));
2386 case CURLOPT_PROTOCOLS:
2387 /* set the bitmask for the protocols that are allowed to be used for the
2388 transfer, which thus helps the app which takes URLs from users or other
2389 external inputs and want to restrict what protocol(s) to deal
2390 with. Defaults to CURLPROTO_ALL. */
2391 data->set.allowed_protocols = va_arg(param, long);
2394 case CURLOPT_REDIR_PROTOCOLS:
2395 /* set the bitmask for the protocols that libcurl is allowed to follow to,
2396 as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
2397 to be set in both bitmasks to be allowed to get redirected to. Defaults
2398 to all protocols except FILE and SCP. */
2399 data->set.redir_protocols = va_arg(param, long);
2402 case CURLOPT_MAIL_FROM:
2403 /* Set the SMTP mail originator */
2404 result = setstropt(&data->set.str[STRING_MAIL_FROM],
2405 va_arg(param, char *));
2408 case CURLOPT_MAIL_AUTH:
2409 /* Set the SMTP auth originator */
2410 result = setstropt(&data->set.str[STRING_MAIL_AUTH],
2411 va_arg(param, char *));
2414 case CURLOPT_MAIL_RCPT:
2415 /* Set the list of mail recipients */
2416 data->set.mail_rcpt = va_arg(param, struct curl_slist *);
2419 case CURLOPT_SASL_IR:
2420 /* Enable/disable SASL initial response */
2421 data->set.sasl_ir = (0 != va_arg(param, long)) ? TRUE : FALSE;
2424 case CURLOPT_RTSP_REQUEST:
2427 * Set the RTSP request method (OPTIONS, SETUP, PLAY, etc...)
2428 * Would this be better if the RTSPREQ_* were just moved into here?
2430 long curl_rtspreq = va_arg(param, long);
2431 Curl_RtspReq rtspreq = RTSPREQ_NONE;
2432 switch(curl_rtspreq) {
2433 case CURL_RTSPREQ_OPTIONS:
2434 rtspreq = RTSPREQ_OPTIONS;
2437 case CURL_RTSPREQ_DESCRIBE:
2438 rtspreq = RTSPREQ_DESCRIBE;
2441 case CURL_RTSPREQ_ANNOUNCE:
2442 rtspreq = RTSPREQ_ANNOUNCE;
2445 case CURL_RTSPREQ_SETUP:
2446 rtspreq = RTSPREQ_SETUP;
2449 case CURL_RTSPREQ_PLAY:
2450 rtspreq = RTSPREQ_PLAY;
2453 case CURL_RTSPREQ_PAUSE:
2454 rtspreq = RTSPREQ_PAUSE;
2457 case CURL_RTSPREQ_TEARDOWN:
2458 rtspreq = RTSPREQ_TEARDOWN;
2461 case CURL_RTSPREQ_GET_PARAMETER:
2462 rtspreq = RTSPREQ_GET_PARAMETER;
2465 case CURL_RTSPREQ_SET_PARAMETER:
2466 rtspreq = RTSPREQ_SET_PARAMETER;
2469 case CURL_RTSPREQ_RECORD:
2470 rtspreq = RTSPREQ_RECORD;
2473 case CURL_RTSPREQ_RECEIVE:
2474 rtspreq = RTSPREQ_RECEIVE;
2477 rtspreq = RTSPREQ_NONE;
2480 data->set.rtspreq = rtspreq;
2485 case CURLOPT_RTSP_SESSION_ID:
2487 * Set the RTSP Session ID manually. Useful if the application is
2488 * resuming a previously established RTSP session
2490 result = setstropt(&data->set.str[STRING_RTSP_SESSION_ID],
2491 va_arg(param, char *));
2494 case CURLOPT_RTSP_STREAM_URI:
2496 * Set the Stream URI for the RTSP request. Unless the request is
2497 * for generic server options, the application will need to set this.
2499 result = setstropt(&data->set.str[STRING_RTSP_STREAM_URI],
2500 va_arg(param, char *));
2503 case CURLOPT_RTSP_TRANSPORT:
2505 * The content of the Transport: header for the RTSP request
2507 result = setstropt(&data->set.str[STRING_RTSP_TRANSPORT],
2508 va_arg(param, char *));
2511 case CURLOPT_RTSP_CLIENT_CSEQ:
2513 * Set the CSEQ number to issue for the next RTSP request. Useful if the
2514 * application is resuming a previously broken connection. The CSEQ
2515 * will increment from this new number henceforth.
2517 data->state.rtsp_next_client_CSeq = va_arg(param, long);
2520 case CURLOPT_RTSP_SERVER_CSEQ:
2521 /* Same as the above, but for server-initiated requests */
2522 data->state.rtsp_next_client_CSeq = va_arg(param, long);
2525 case CURLOPT_INTERLEAVEDATA:
2526 data->set.rtp_out = va_arg(param, void *);
2528 case CURLOPT_INTERLEAVEFUNCTION:
2529 /* Set the user defined RTP write function */
2530 data->set.fwrite_rtp = va_arg(param, curl_write_callback);
2533 case CURLOPT_WILDCARDMATCH:
2534 data->set.wildcardmatch = (0 != va_arg(param, long))?TRUE:FALSE;
2536 case CURLOPT_CHUNK_BGN_FUNCTION:
2537 data->set.chunk_bgn = va_arg(param, curl_chunk_bgn_callback);
2539 case CURLOPT_CHUNK_END_FUNCTION:
2540 data->set.chunk_end = va_arg(param, curl_chunk_end_callback);
2542 case CURLOPT_FNMATCH_FUNCTION:
2543 data->set.fnmatch = va_arg(param, curl_fnmatch_callback);
2545 case CURLOPT_CHUNK_DATA:
2546 data->wildcard.customptr = va_arg(param, void *);
2548 case CURLOPT_FNMATCH_DATA:
2549 data->set.fnmatch_data = va_arg(param, void *);
2552 case CURLOPT_TLSAUTH_USERNAME:
2553 result = setstropt(&data->set.str[STRING_TLSAUTH_USERNAME],
2554 va_arg(param, char *));
2555 if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype)
2556 data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
2558 case CURLOPT_TLSAUTH_PASSWORD:
2559 result = setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD],
2560 va_arg(param, char *));
2561 if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype)
2562 data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
2564 case CURLOPT_TLSAUTH_TYPE:
2565 if(strnequal((char *)va_arg(param, char *), "SRP", strlen("SRP")))
2566 data->set.ssl.authtype = CURL_TLSAUTH_SRP;
2568 data->set.ssl.authtype = CURL_TLSAUTH_NONE;
2571 case CURLOPT_DNS_SERVERS:
2572 result = Curl_set_dns_servers(data, va_arg(param, char *));
2574 case CURLOPT_DNS_INTERFACE:
2575 result = Curl_set_dns_interface(data, va_arg(param, char *));
2577 case CURLOPT_DNS_LOCAL_IP4:
2578 result = Curl_set_dns_local_ip4(data, va_arg(param, char *));
2580 case CURLOPT_DNS_LOCAL_IP6:
2581 result = Curl_set_dns_local_ip6(data, va_arg(param, char *));
2584 case CURLOPT_TCP_KEEPALIVE:
2585 data->set.tcp_keepalive = (0 != va_arg(param, long))?TRUE:FALSE;
2587 case CURLOPT_TCP_KEEPIDLE:
2588 data->set.tcp_keepidle = va_arg(param, long);
2590 case CURLOPT_TCP_KEEPINTVL:
2591 data->set.tcp_keepintvl = va_arg(param, long);
2593 case CURLOPT_SSL_ENABLE_NPN:
2594 data->set.ssl_enable_npn = (0 != va_arg(param, long))?TRUE:FALSE;
2596 case CURLOPT_SSL_ENABLE_ALPN:
2597 data->set.ssl_enable_alpn = (0 != va_arg(param, long))?TRUE:FALSE;
2600 #ifdef USE_UNIX_SOCKETS
2601 case CURLOPT_UNIX_SOCKET_PATH:
2602 result = setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH],
2603 va_arg(param, char *));
2608 /* unknown tag and its companion, just ignore: */
2609 result = CURLE_UNKNOWN_OPTION;
2616 static void conn_free(struct connectdata *conn)
2621 /* possible left-overs from the async name resolvers */
2622 Curl_resolver_cancel(conn);
2624 /* close the SSL stuff before we close any sockets since they will/may
2625 write to the sockets */
2626 Curl_ssl_close(conn, FIRSTSOCKET);
2627 Curl_ssl_close(conn, SECONDARYSOCKET);
2629 /* close possibly still open sockets */
2630 if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
2631 Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
2632 if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET])
2633 Curl_closesocket(conn, conn->sock[FIRSTSOCKET]);
2634 if(CURL_SOCKET_BAD != conn->tempsock[0])
2635 Curl_closesocket(conn, conn->tempsock[0]);
2636 if(CURL_SOCKET_BAD != conn->tempsock[1])
2637 Curl_closesocket(conn, conn->tempsock[1]);
2639 #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
2640 defined(NTLM_WB_ENABLED)
2641 Curl_ntlm_wb_cleanup(conn);
2644 Curl_safefree(conn->user);
2645 Curl_safefree(conn->passwd);
2646 Curl_safefree(conn->xoauth2_bearer);
2647 Curl_safefree(conn->options);
2648 Curl_safefree(conn->proxyuser);
2649 Curl_safefree(conn->proxypasswd);
2650 Curl_safefree(conn->allocptr.proxyuserpwd);
2651 Curl_safefree(conn->allocptr.uagent);
2652 Curl_safefree(conn->allocptr.userpwd);
2653 Curl_safefree(conn->allocptr.accept_encoding);
2654 Curl_safefree(conn->allocptr.te);
2655 Curl_safefree(conn->allocptr.rangeline);
2656 Curl_safefree(conn->allocptr.ref);
2657 Curl_safefree(conn->allocptr.host);
2658 Curl_safefree(conn->allocptr.cookiehost);
2659 Curl_safefree(conn->allocptr.rtsp_transport);
2660 Curl_safefree(conn->trailer);
2661 Curl_safefree(conn->host.rawalloc); /* host name buffer */
2662 Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */
2663 Curl_safefree(conn->master_buffer);
2665 Curl_llist_destroy(conn->send_pipe, NULL);
2666 Curl_llist_destroy(conn->recv_pipe, NULL);
2668 conn->send_pipe = NULL;
2669 conn->recv_pipe = NULL;
2671 Curl_safefree(conn->localdev);
2672 Curl_free_ssl_config(&conn->ssl_config);
2674 free(conn); /* free all the connection oriented data */
2678 * Disconnects the given connection. Note the connection may not be the
2679 * primary connection, like when freeing room in the connection cache or
2680 * killing of a dead old connection.
2682 * This function MUST NOT reset state in the SessionHandle struct if that
2683 * isn't strictly bound to the life-time of *this* particular connection.
2687 CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
2689 struct SessionHandle *data;
2691 return CURLE_OK; /* this is closed and fine already */
2695 DEBUGF(fprintf(stderr, "DISCONNECT without easy handle, ignoring\n"));
2699 if(conn->dns_entry != NULL) {
2700 Curl_resolv_unlock(data, conn->dns_entry);
2701 conn->dns_entry = NULL;
2704 Curl_hostcache_prune(data); /* kill old DNS cache entries */
2706 #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM)
2707 /* Cleanup NTLM connection-related data */
2708 Curl_http_ntlm_cleanup(conn);
2711 if(conn->handler->disconnect)
2712 /* This is set if protocol-specific cleanups should be made */
2713 conn->handler->disconnect(conn, dead_connection);
2715 /* unlink ourselves! */
2716 infof(data, "Closing connection %ld\n", conn->connection_id);
2717 Curl_conncache_remove_conn(data->state.conn_cache, conn);
2719 #if defined(USE_LIBIDN)
2720 if(conn->host.encalloc)
2721 idn_free(conn->host.encalloc); /* encoded host name buffer, must be freed
2722 with idn_free() since this was allocated
2724 if(conn->proxy.encalloc)
2725 idn_free(conn->proxy.encalloc); /* encoded proxy name buffer, must be
2726 freed with idn_free() since this was
2727 allocated by libidn */
2728 #elif defined(USE_WIN32_IDN)
2729 free(conn->host.encalloc); /* encoded host name buffer, must be freed with
2730 idn_free() since this was allocated by
2731 curl_win32_idn_to_ascii */
2732 if(conn->proxy.encalloc)
2733 free(conn->proxy.encalloc); /* encoded proxy name buffer, must be freed
2734 with idn_free() since this was allocated by
2735 curl_win32_idn_to_ascii */
2738 Curl_ssl_close(conn, FIRSTSOCKET);
2740 /* Indicate to all handles on the pipe that we're dead */
2741 if(Curl_multi_pipeline_enabled(data->multi)) {
2742 signalPipeClose(conn->send_pipe, TRUE);
2743 signalPipeClose(conn->recv_pipe, TRUE);
2752 * This function should return TRUE if the socket is to be assumed to
2753 * be dead. Most commonly this happens when the server has closed the
2754 * connection due to inactivity.
2756 static bool SocketIsDead(curl_socket_t sock)
2759 bool ret_val = TRUE;
2761 sval = Curl_socket_ready(sock, CURL_SOCKET_BAD, 0);
2769 static bool IsPipeliningPossible(const struct SessionHandle *handle,
2770 const struct connectdata *conn)
2772 if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
2773 Curl_multi_pipeline_enabled(handle->multi) &&
2774 (handle->set.httpreq == HTTPREQ_GET ||
2775 handle->set.httpreq == HTTPREQ_HEAD) &&
2776 handle->set.httpversion != CURL_HTTP_VERSION_1_0)
2782 bool Curl_isPipeliningEnabled(const struct SessionHandle *handle)
2784 return Curl_multi_pipeline_enabled(handle->multi);
2787 CURLcode Curl_addHandleToPipeline(struct SessionHandle *data,
2788 struct curl_llist *pipeline)
2790 if(!Curl_llist_insert_next(pipeline, pipeline->tail, data))
2791 return CURLE_OUT_OF_MEMORY;
2795 int Curl_removeHandleFromPipeline(struct SessionHandle *handle,
2796 struct curl_llist *pipeline)
2798 struct curl_llist_element *curr;
2800 curr = pipeline->head;
2802 if(curr->ptr == handle) {
2803 Curl_llist_remove(pipeline, curr, NULL);
2804 return 1; /* we removed a handle */
2812 #if 0 /* this code is saved here as it is useful for debugging purposes */
2813 static void Curl_printPipeline(struct curl_llist *pipeline)
2815 struct curl_llist_element *curr;
2817 curr = pipeline->head;
2819 struct SessionHandle *data = (struct SessionHandle *) curr->ptr;
2820 infof(data, "Handle in pipeline: %s\n", data->state.path);
2826 static struct SessionHandle* gethandleathead(struct curl_llist *pipeline)
2828 struct curl_llist_element *curr = pipeline->head;
2830 return (struct SessionHandle *) curr->ptr;
2836 /* remove the specified connection from all (possible) pipelines and related
2838 void Curl_getoff_all_pipelines(struct SessionHandle *data,
2839 struct connectdata *conn)
2841 bool recv_head = (conn->readchannel_inuse &&
2842 (gethandleathead(conn->recv_pipe) == data)) ? TRUE : FALSE;
2844 bool send_head = (conn->writechannel_inuse &&
2845 (gethandleathead(conn->send_pipe) == data)) ? TRUE : FALSE;
2847 if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) && recv_head)
2848 conn->readchannel_inuse = FALSE;
2849 if(Curl_removeHandleFromPipeline(data, conn->send_pipe) && send_head)
2850 conn->writechannel_inuse = FALSE;
2853 static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke)
2855 struct curl_llist_element *curr;
2860 curr = pipeline->head;
2862 struct curl_llist_element *next = curr->next;
2863 struct SessionHandle *data = (struct SessionHandle *) curr->ptr;
2865 #ifdef DEBUGBUILD /* debug-only code */
2866 if(data->magic != CURLEASY_MAGIC_NUMBER) {
2868 infof(data, "signalPipeClose() found BAAD easy handle\n");
2873 data->state.pipe_broke = TRUE;
2874 Curl_multi_handlePipeBreak(data);
2875 Curl_llist_remove(pipeline, curr, NULL);
2881 * This function finds the connection in the connection
2882 * cache that has been unused for the longest time.
2884 * Returns the pointer to the oldest idle connection, or NULL if none was
2887 static struct connectdata *
2888 find_oldest_idle_connection(struct SessionHandle *data)
2890 struct conncache *bc = data->state.conn_cache;
2891 struct curl_hash_iterator iter;
2892 struct curl_llist_element *curr;
2893 struct curl_hash_element *he;
2897 struct connectdata *conn_candidate = NULL;
2898 struct connectbundle *bundle;
2902 Curl_hash_start_iterate(bc->hash, &iter);
2904 he = Curl_hash_next_element(&iter);
2906 struct connectdata *conn;
2910 curr = bundle->conn_list->head;
2915 /* Set higher score for the age passed since the connection was used */
2916 score = Curl_tvdiff(now, conn->now);
2918 if(score > highscore) {
2920 conn_candidate = conn;
2926 he = Curl_hash_next_element(&iter);
2929 return conn_candidate;
2933 * This function finds the connection in the connection
2934 * bundle that has been unused for the longest time.
2936 * Returns the pointer to the oldest idle connection, or NULL if none was
2939 static struct connectdata *
2940 find_oldest_idle_connection_in_bundle(struct SessionHandle *data,
2941 struct connectbundle *bundle)
2943 struct curl_llist_element *curr;
2947 struct connectdata *conn_candidate = NULL;
2948 struct connectdata *conn;
2954 curr = bundle->conn_list->head;
2959 /* Set higher score for the age passed since the connection was used */
2960 score = Curl_tvdiff(now, conn->now);
2962 if(score > highscore) {
2964 conn_candidate = conn;
2970 return conn_candidate;
2974 * This function checks if given connection is dead and disconnects if so.
2975 * (That also removes it from the connection cache.)
2977 * Returns TRUE if the connection actually was dead and disconnected.
2979 static bool disconnect_if_dead(struct connectdata *conn,
2980 struct SessionHandle *data)
2982 size_t pipeLen = conn->send_pipe->size + conn->recv_pipe->size;
2983 if(!pipeLen && !conn->inuse) {
2984 /* The check for a dead socket makes sense only if there are no
2985 handles in pipeline and the connection isn't already marked in
2988 if(conn->handler->protocol & CURLPROTO_RTSP)
2989 /* RTSP is a special case due to RTP interleaving */
2990 dead = Curl_rtsp_connisdead(conn);
2992 dead = SocketIsDead(conn->sock[FIRSTSOCKET]);
2996 infof(data, "Connection %ld seems to be dead!\n", conn->connection_id);
2998 /* disconnect resources */
2999 Curl_disconnect(conn, /* dead_connection */TRUE);
3007 * Wrapper to use disconnect_if_dead() function in Curl_conncache_foreach()
3011 static int call_disconnect_if_dead(struct connectdata *conn,
3014 struct SessionHandle* data = (struct SessionHandle*)param;
3015 disconnect_if_dead(conn, data);
3016 return 0; /* continue iteration */
3020 * This function scans the connection cache for half-open/dead connections,
3021 * closes and removes them.
3022 * The cleanup is done at most once per second.
3024 static void prune_dead_connections(struct SessionHandle *data)
3026 struct timeval now = Curl_tvnow();
3027 long elapsed = Curl_tvdiff(now, data->state.conn_cache->last_cleanup);
3029 if(elapsed >= 1000L) {
3030 Curl_conncache_foreach(data->state.conn_cache, data,
3031 call_disconnect_if_dead);
3032 data->state.conn_cache->last_cleanup = now;
3037 * Given one filled in connection struct (named needle), this function should
3038 * detect if there already is one that has all the significant details
3039 * exactly the same and thus should be used instead.
3041 * If there is a match, this function returns TRUE - and has marked the
3042 * connection as 'in-use'. It must later be called with ConnectionDone() to
3043 * return back to 'idle' (unused) state.
3045 * The force_reuse flag is set if the connection must be used, even if
3046 * the pipelining strategy wants to open a new connection instead of reusing.
3049 ConnectionExists(struct SessionHandle *data,
3050 struct connectdata *needle,
3051 struct connectdata **usethis,
3054 struct connectdata *check;
3055 struct connectdata *chosen = 0;
3056 bool canPipeline = IsPipeliningPossible(data, needle);
3057 bool wantNTLMhttp = ((data->state.authhost.want & CURLAUTH_NTLM) ||
3058 (data->state.authhost.want & CURLAUTH_NTLM_WB)) &&
3059 (needle->handler->protocol & PROTO_FAMILY_HTTP) ? TRUE : FALSE;
3060 struct connectbundle *bundle;
3062 *force_reuse = FALSE;
3064 /* We can't pipe if the site is blacklisted */
3065 if(canPipeline && Curl_pipeline_site_blacklisted(data, needle)) {
3066 canPipeline = FALSE;
3069 /* Look up the bundle with all the connections to this
3071 bundle = Curl_conncache_find_bundle(data->state.conn_cache,
3074 size_t max_pipe_len = Curl_multi_max_pipeline_length(data->multi);
3075 size_t best_pipe_len = max_pipe_len;
3076 struct curl_llist_element *curr;
3078 infof(data, "Found bundle for host %s: %p\n",
3079 needle->host.name, (void *)bundle);
3081 /* We can't pipe if we don't know anything about the server */
3082 if(canPipeline && !bundle->server_supports_pipelining) {
3083 infof(data, "Server doesn't support pipelining\n");
3084 canPipeline = FALSE;
3087 curr = bundle->conn_list->head;
3090 #if defined(USE_NTLM)
3091 bool credentialsMatch = FALSE;
3096 * Note that if we use a HTTP proxy, we check connections to that
3097 * proxy and not to the actual remote server.
3102 if(disconnect_if_dead(check, data))
3105 pipeLen = check->send_pipe->size + check->recv_pipe->size;
3108 /* Make sure the pipe has only GET requests */
3109 struct SessionHandle* sh = gethandleathead(check->send_pipe);
3110 struct SessionHandle* rh = gethandleathead(check->recv_pipe);
3112 if(!IsPipeliningPossible(sh, check))
3116 if(!IsPipeliningPossible(rh, check))
3122 /* can only happen within multi handles, and means that another easy
3123 handle is using this connection */
3127 if(Curl_resolver_asynch()) {
3128 /* ip_addr_str[0] is NUL only if the resolving of the name hasn't
3129 completed yet and until then we don't re-use this connection */
3130 if(!check->ip_addr_str[0]) {
3132 "Connection #%ld is still name resolving, can't reuse\n",
3133 check->connection_id);
3138 if((check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) ||
3139 check->bits.close) {
3140 /* Don't pick a connection that hasn't connected yet or that is going
3142 infof(data, "Connection #%ld isn't open enough, can't reuse\n",
3143 check->connection_id);
3145 if(check->recv_pipe->size > 0) {
3147 "BAD! Unconnected #%ld has a non-empty recv pipeline!\n",
3148 check->connection_id);
3155 if((needle->handler->flags&PROTOPT_SSL) !=
3156 (check->handler->flags&PROTOPT_SSL))
3157 /* don't do mixed SSL and non-SSL connections */
3158 if(!(needle->handler->protocol & check->handler->protocol))
3159 /* except protocols that have been upgraded via TLS */
3162 if(needle->handler->flags&PROTOPT_SSL) {
3163 if((data->set.ssl.verifypeer != check->verifypeer) ||
3164 (data->set.ssl.verifyhost != check->verifyhost))
3168 if(needle->bits.proxy != check->bits.proxy)
3169 /* don't do mixed proxy and non-proxy connections */
3172 if(!canPipeline && check->inuse)
3173 /* this request can't be pipelined but the checked connection is
3174 already in use so we skip it */
3177 if(needle->localdev || needle->localport) {
3178 /* If we are bound to a specific local end (IP+port), we must not
3179 re-use a random other one, although if we didn't ask for a
3180 particular one we can reuse one that was bound.
3182 This comparison is a bit rough and too strict. Since the input
3183 parameters can be specified in numerous ways and still end up the
3184 same it would take a lot of processing to make it really accurate.
3185 Instead, this matching will assume that re-uses of bound connections
3186 will most likely also re-use the exact same binding parameters and
3187 missing out a few edge cases shouldn't hurt anyone very much.
3189 if((check->localport != needle->localport) ||
3190 (check->localportrange != needle->localportrange) ||
3192 !needle->localdev ||
3193 strcmp(check->localdev, needle->localdev))
3197 if((!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) ||
3198 (wantNTLMhttp || check->ntlm.state != NTLMSTATE_NONE)) {
3199 /* This protocol requires credentials per connection or is HTTP+NTLM,
3200 so verify that we're using the same name and password as well */
3201 if(!strequal(needle->user, check->user) ||
3202 !strequal(needle->passwd, check->passwd)) {
3203 /* one of them was different */
3206 #if defined(USE_NTLM)
3207 credentialsMatch = TRUE;
3211 if(!needle->bits.httpproxy || needle->handler->flags&PROTOPT_SSL ||
3212 (needle->bits.httpproxy && check->bits.httpproxy &&
3213 needle->bits.tunnel_proxy && check->bits.tunnel_proxy &&
3214 Curl_raw_equal(needle->proxy.name, check->proxy.name) &&
3215 (needle->port == check->port))) {
3216 /* The requested connection does not use a HTTP proxy or it uses SSL or
3217 it is a non-SSL protocol tunneled over the same http proxy name and
3218 port number or it is a non-SSL protocol which is allowed to be
3221 if((Curl_raw_equal(needle->handler->scheme, check->handler->scheme) ||
3222 needle->handler->protocol & check->handler->protocol) &&
3223 Curl_raw_equal(needle->host.name, check->host.name) &&
3224 needle->remote_port == check->remote_port) {
3225 if(needle->handler->flags & PROTOPT_SSL) {
3226 /* This is a SSL connection so verify that we're using the same
3227 SSL options as well */
3228 if(!Curl_ssl_config_matches(&needle->ssl_config,
3229 &check->ssl_config)) {
3231 "Connection #%ld has different SSL parameters, "
3233 check->connection_id));
3236 else if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete) {
3238 "Connection #%ld has not started SSL connect, "
3240 check->connection_id));
3247 else { /* The requested needle connection is using a proxy,
3248 is the checked one using the same host, port and type? */
3249 if(check->bits.proxy &&
3250 (needle->proxytype == check->proxytype) &&
3251 (needle->bits.tunnel_proxy == check->bits.tunnel_proxy) &&
3252 Curl_raw_equal(needle->proxy.name, check->proxy.name) &&
3253 needle->port == check->port) {
3254 /* This is the same proxy connection, use it! */
3260 #if defined(USE_NTLM)
3261 /* If we are looking for an HTTP+NTLM connection, check if this is
3262 already authenticating with the right credentials. If not, keep
3263 looking so that we can reuse NTLM connections if
3264 possible. (Especially we must not reuse the same connection if
3265 partway through a handshake!) */
3267 if(credentialsMatch && check->ntlm.state != NTLMSTATE_NONE) {
3270 /* We must use this connection, no other */
3271 *force_reuse = TRUE;
3274 else if(credentialsMatch)
3275 /* this is a backup choice */
3282 /* We can pipeline if we want to. Let's continue looking for
3283 the optimal connection to use, i.e the shortest pipe that is not
3287 /* We have the optimal connection. Let's stop looking. */
3292 /* We can't use the connection if the pipe is full */
3293 if(pipeLen >= max_pipe_len)
3296 /* We can't use the connection if the pipe is penalized */
3297 if(Curl_pipeline_penalized(data, check))
3300 if(pipeLen < best_pipe_len) {
3301 /* This connection has a shorter pipe so far. We'll pick this
3302 and continue searching */
3304 best_pipe_len = pipeLen;
3309 /* We have found a connection. Let's stop searching. */
3319 return TRUE; /* yes, we found one to use! */
3322 return FALSE; /* no matching connecting exists */
3325 /* Mark the connection as 'idle', or close it if the cache is full.
3326 Returns TRUE if the connection is kept, or FALSE if it was closed. */
3328 ConnectionDone(struct SessionHandle *data, struct connectdata *conn)
3330 /* data->multi->maxconnects can be negative, deal with it. */
3331 size_t maxconnects =
3332 (data->multi->maxconnects < 0) ? data->multi->num_easy * 4:
3333 data->multi->maxconnects;
3334 struct connectdata *conn_candidate = NULL;
3336 /* Mark the current connection as 'unused' */
3337 conn->inuse = FALSE;
3339 if(maxconnects > 0 &&
3340 data->state.conn_cache->num_connections > maxconnects) {
3341 infof(data, "Connection cache is full, closing the oldest one.\n");
3343 conn_candidate = find_oldest_idle_connection(data);
3345 if(conn_candidate) {
3346 /* Set the connection's owner correctly */
3347 conn_candidate->data = data;
3349 /* the winner gets the honour of being disconnected */
3350 (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
3354 return (conn_candidate == conn) ? FALSE : TRUE;
3358 * The given input connection struct pointer is to be stored in the connection
3359 * cache. If the cache is already full, least interesting existing connection
3360 * (if any) gets closed.
3362 * The given connection should be unique. That must've been checked prior to
3365 static CURLcode ConnectionStore(struct SessionHandle *data,
3366 struct connectdata *conn)
3368 return Curl_conncache_add_conn(data->state.conn_cache, conn);
3371 /* after a TCP connection to the proxy has been verified, this function does
3372 the next magic step.
3374 Note: this function's sub-functions call failf()
3377 CURLcode Curl_connected_proxy(struct connectdata *conn,
3380 if(!conn->bits.proxy || sockindex)
3381 /* this magic only works for the primary socket as the secondary is used
3382 for FTP only and it has FTP specific magic in ftp.c */
3385 switch(conn->proxytype) {
3386 #ifndef CURL_DISABLE_PROXY
3387 case CURLPROXY_SOCKS5:
3388 case CURLPROXY_SOCKS5_HOSTNAME:
3389 return Curl_SOCKS5(conn->proxyuser, conn->proxypasswd,
3390 conn->host.name, conn->remote_port,
3393 case CURLPROXY_SOCKS4:
3394 return Curl_SOCKS4(conn->proxyuser, conn->host.name,
3395 conn->remote_port, FIRSTSOCKET, conn, FALSE);
3397 case CURLPROXY_SOCKS4A:
3398 return Curl_SOCKS4(conn->proxyuser, conn->host.name,
3399 conn->remote_port, FIRSTSOCKET, conn, TRUE);
3401 #endif /* CURL_DISABLE_PROXY */
3402 case CURLPROXY_HTTP:
3403 case CURLPROXY_HTTP_1_0:
3404 /* do nothing here. handled later. */
3408 } /* switch proxytype */
3414 * verboseconnect() displays verbose information after a connect
3416 #ifndef CURL_DISABLE_VERBOSE_STRINGS
3417 void Curl_verboseconnect(struct connectdata *conn)
3419 if(conn->data->set.verbose)
3420 infof(conn->data, "Connected to %s (%s) port %ld (#%ld)\n",
3421 conn->bits.proxy ? conn->proxy.dispname : conn->host.dispname,
3422 conn->ip_addr_str, conn->port, conn->connection_id);
3426 int Curl_protocol_getsock(struct connectdata *conn,
3427 curl_socket_t *socks,
3430 if(conn->handler->proto_getsock)
3431 return conn->handler->proto_getsock(conn, socks, numsocks);
3432 return GETSOCK_BLANK;
3435 int Curl_doing_getsock(struct connectdata *conn,
3436 curl_socket_t *socks,
3439 if(conn && conn->handler->doing_getsock)
3440 return conn->handler->doing_getsock(conn, socks, numsocks);
3441 return GETSOCK_BLANK;
3445 * We are doing protocol-specific connecting and this is being called over and
3446 * over from the multi interface until the connection phase is done on
3450 CURLcode Curl_protocol_connecting(struct connectdata *conn,
3453 CURLcode result=CURLE_OK;
3455 if(conn && conn->handler->connecting) {
3457 result = conn->handler->connecting(conn, done);
3466 * We are DOING this is being called over and over from the multi interface
3467 * until the DOING phase is done on protocol layer.
3470 CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done)
3472 CURLcode result=CURLE_OK;
3474 if(conn && conn->handler->doing) {
3476 result = conn->handler->doing(conn, done);
3485 * We have discovered that the TCP connection has been successful, we can now
3486 * proceed with some action.
3489 CURLcode Curl_protocol_connect(struct connectdata *conn,
3490 bool *protocol_done)
3492 CURLcode result=CURLE_OK;
3494 *protocol_done = FALSE;
3496 if(conn->bits.tcpconnect[FIRSTSOCKET] && conn->bits.protoconnstart) {
3497 /* We already are connected, get back. This may happen when the connect
3498 worked fine in the first call, like when we connect to a local server
3499 or proxy. Note that we don't know if the protocol is actually done.
3501 Unless this protocol doesn't have any protocol-connect callback, as
3502 then we know we're done. */
3503 if(!conn->handler->connecting)
3504 *protocol_done = TRUE;
3509 if(!conn->bits.protoconnstart) {
3511 result = Curl_proxy_connect(conn);
3515 if(conn->bits.tunnel_proxy && conn->bits.httpproxy &&
3516 (conn->tunnel_state[FIRSTSOCKET] != TUNNEL_COMPLETE))
3517 /* when using an HTTP tunnel proxy, await complete tunnel establishment
3518 before proceeding further. Return CURLE_OK so we'll be called again */
3521 if(conn->handler->connect_it) {
3522 /* is there a protocol-specific connect() procedure? */
3524 /* Call the protocol-specific connect function */
3525 result = conn->handler->connect_it(conn, protocol_done);
3528 *protocol_done = TRUE;
3530 /* it has started, possibly even completed but that knowledge isn't stored
3533 conn->bits.protoconnstart = TRUE;
3536 return result; /* pass back status */
3540 * Helpers for IDNA convertions.
3542 static bool is_ASCII_name(const char *hostname)
3544 const unsigned char *ch = (const unsigned char*)hostname;
3555 * Check if characters in hostname is allowed in Top Level Domain.
3557 static bool tld_check_name(struct SessionHandle *data,
3558 const char *ace_hostname)
3561 char *uc_name = NULL;
3563 #ifndef CURL_DISABLE_VERBOSE_STRINGS
3564 const char *tld_errmsg = "<no msg>";
3569 /* Convert (and downcase) ACE-name back into locale's character set */
3570 rc = idna_to_unicode_lzlz(ace_hostname, &uc_name, 0);
3571 if(rc != IDNA_SUCCESS)
3574 rc = tld_check_lz(uc_name, &err_pos, NULL);
3575 #ifndef CURL_DISABLE_VERBOSE_STRINGS
3576 #ifdef HAVE_TLD_STRERROR
3577 if(rc != TLD_SUCCESS)
3578 tld_errmsg = tld_strerror((Tld_rc)rc);
3580 if(rc == TLD_INVALID)
3581 infof(data, "WARNING: %s; pos %u = `%c'/0x%02X\n",
3582 tld_errmsg, err_pos, uc_name[err_pos],
3583 uc_name[err_pos] & 255);
3584 else if(rc != TLD_SUCCESS)
3585 infof(data, "WARNING: TLD check for %s failed; %s\n",
3586 uc_name, tld_errmsg);
3587 #endif /* CURL_DISABLE_VERBOSE_STRINGS */
3590 if(rc != TLD_SUCCESS)
3598 * Perform any necessary IDN conversion of hostname
3600 static void fix_hostname(struct SessionHandle *data,
3601 struct connectdata *conn, struct hostname *host)
3608 #elif defined(CURL_DISABLE_VERBOSE_STRINGS)
3612 /* set the name we use to display the host name */
3613 host->dispname = host->name;
3615 len = strlen(host->name);
3616 if(len && (host->name[len-1] == '.'))
3617 /* strip off a single trailing dot if present, primarily for SNI but
3618 there's no use for it */
3619 host->name[len-1]=0;
3621 if(!is_ASCII_name(host->name)) {
3623 /*************************************************************
3624 * Check name for non-ASCII and convert hostname to ACE form.
3625 *************************************************************/
3626 if(stringprep_check_version(LIBIDN_REQUIRED_VERSION)) {
3627 char *ace_hostname = NULL;
3628 int rc = idna_to_ascii_lz(host->name, &ace_hostname, 0);
3629 infof (data, "Input domain encoded as `%s'\n",
3630 stringprep_locale_charset ());
3631 if(rc != IDNA_SUCCESS)
3632 infof(data, "Failed to convert %s to ACE; %s\n",
3633 host->name, Curl_idn_strerror(conn,rc));
3635 /* tld_check_name() displays a warning if the host name contains
3636 "illegal" characters for this TLD */
3637 (void)tld_check_name(data, ace_hostname);
3639 host->encalloc = ace_hostname;
3640 /* change the name pointer to point to the encoded hostname */
3641 host->name = host->encalloc;
3644 #elif defined(USE_WIN32_IDN)
3645 /*************************************************************
3646 * Check name for non-ASCII and convert hostname to ACE form.
3647 *************************************************************/
3648 char *ace_hostname = NULL;
3649 int rc = curl_win32_idn_to_ascii(host->name, &ace_hostname);
3651 infof(data, "Failed to convert %s to ACE;\n",
3654 host->encalloc = ace_hostname;
3655 /* change the name pointer to point to the encoded hostname */
3656 host->name = host->encalloc;
3659 infof(data, "IDN support not present, can't parse Unicode domains\n");
3664 static void llist_dtor(void *user, void *element)
3672 * Allocate and initialize a new connectdata object.
3674 static struct connectdata *allocate_conn(struct SessionHandle *data)
3676 struct connectdata *conn = calloc(1, sizeof(struct connectdata));
3680 conn->handler = &Curl_handler_dummy; /* Be sure we have a handler defined
3681 already from start to avoid NULL
3682 situations and checks */
3684 /* and we setup a few fields in case we end up actually using this struct */
3686 conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
3687 conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
3688 conn->tempsock[0] = CURL_SOCKET_BAD; /* no file descriptor */
3689 conn->tempsock[1] = CURL_SOCKET_BAD; /* no file descriptor */
3690 conn->connection_id = -1; /* no ID */
3691 conn->port = -1; /* unknown at this point */
3692 conn->remote_port = -1; /* unknown */
3694 /* Default protocol-independent behavior doesn't support persistent
3695 connections, so we set this to force-close. Protocols that support
3696 this need to set this to FALSE in their "curl_do" functions. */
3697 connclose(conn, "Default to force-close");
3699 /* Store creation time to help future close decision making */
3700 conn->created = Curl_tvnow();
3702 conn->data = data; /* Setup the association between this connection
3703 and the SessionHandle */
3705 conn->proxytype = data->set.proxytype; /* type */
3707 #ifdef CURL_DISABLE_PROXY
3709 conn->bits.proxy = FALSE;
3710 conn->bits.httpproxy = FALSE;
3711 conn->bits.proxy_user_passwd = FALSE;
3712 conn->bits.tunnel_proxy = FALSE;
3714 #else /* CURL_DISABLE_PROXY */
3716 /* note that these two proxy bits are now just on what looks to be
3717 requested, they may be altered down the road */
3718 conn->bits.proxy = (data->set.str[STRING_PROXY] &&
3719 *data->set.str[STRING_PROXY])?TRUE:FALSE;
3720 conn->bits.httpproxy = (conn->bits.proxy &&
3721 (conn->proxytype == CURLPROXY_HTTP ||
3722 conn->proxytype == CURLPROXY_HTTP_1_0))?TRUE:FALSE;
3723 conn->bits.proxy_user_passwd =
3724 (NULL != data->set.str[STRING_PROXYUSERNAME])?TRUE:FALSE;
3725 conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy;
3727 #endif /* CURL_DISABLE_PROXY */
3729 conn->bits.user_passwd = (NULL != data->set.str[STRING_USERNAME])?TRUE:FALSE;
3730 conn->bits.ftp_use_epsv = data->set.ftp_use_epsv;
3731 conn->bits.ftp_use_eprt = data->set.ftp_use_eprt;
3733 conn->verifypeer = data->set.ssl.verifypeer;
3734 conn->verifyhost = data->set.ssl.verifyhost;
3736 conn->ip_version = data->set.ipver;
3738 #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
3739 defined(NTLM_WB_ENABLED)
3740 conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
3741 conn->ntlm_auth_hlpr_pid = 0;
3742 conn->challenge_header = NULL;
3743 conn->response_header = NULL;
3746 if(Curl_multi_pipeline_enabled(data->multi) &&
3747 !conn->master_buffer) {
3748 /* Allocate master_buffer to be used for pipelining */
3749 conn->master_buffer = calloc(BUFSIZE, sizeof (char));
3750 if(!conn->master_buffer)
3754 /* Initialize the pipeline lists */
3755 conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
3756 conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
3757 if(!conn->send_pipe || !conn->recv_pipe)
3761 conn->data_prot = PROT_CLEAR;
3764 /* Store the local bind parameters that will be used for this connection */
3765 if(data->set.str[STRING_DEVICE]) {
3766 conn->localdev = strdup(data->set.str[STRING_DEVICE]);
3770 conn->localportrange = data->set.localportrange;
3771 conn->localport = data->set.localport;
3773 /* the close socket stuff needs to be copied to the connection struct as
3774 it may live on without (this specific) SessionHandle */
3775 conn->fclosesocket = data->set.fclosesocket;
3776 conn->closesocket_client = data->set.closesocket_client;
3781 Curl_llist_destroy(conn->send_pipe, NULL);
3782 Curl_llist_destroy(conn->recv_pipe, NULL);
3784 conn->send_pipe = NULL;
3785 conn->recv_pipe = NULL;
3787 Curl_safefree(conn->master_buffer);
3788 Curl_safefree(conn->localdev);
3789 Curl_safefree(conn);
3793 static CURLcode findprotocol(struct SessionHandle *data,
3794 struct connectdata *conn,
3795 const char *protostr)
3797 const struct Curl_handler * const *pp;
3798 const struct Curl_handler *p;
3800 /* Scan protocol handler table and match against 'protostr' to set a few
3801 variables based on the URL. Now that the handler may be changed later
3802 when the protocol specific setup function is called. */
3803 for(pp = protocols; (p = *pp) != NULL; pp++) {
3804 if(Curl_raw_equal(p->scheme, protostr)) {
3805 /* Protocol found in table. Check if allowed */
3806 if(!(data->set.allowed_protocols & p->protocol))
3810 /* it is allowed for "normal" request, now do an extra check if this is
3811 the result of a redirect */
3812 if(data->state.this_is_a_follow &&
3813 !(data->set.redir_protocols & p->protocol))
3817 /* Perform setup complement if some. */
3818 conn->handler = conn->given = p;
3820 /* 'port' and 'remote_port' are set in setup_connection_internals() */
3826 /* The protocol was not found in the table, but we don't have to assign it
3827 to anything since it is already assigned to a dummy-struct in the
3828 create_conn() function when the connectdata struct is allocated. */
3829 failf(data, "Protocol \"%s\" not supported or disabled in " LIBCURL_NAME,
3832 return CURLE_UNSUPPORTED_PROTOCOL;
3836 * Parse URL and fill in the relevant members of the connection struct.
3838 static CURLcode parseurlandfillconn(struct SessionHandle *data,
3839 struct connectdata *conn,
3841 char **userp, char **passwdp,
3846 char *path = data->state.path;
3849 char protobuf[16] = "";
3850 const char *protop = "";
3852 bool rebuild_url = FALSE;
3854 *prot_missing = FALSE;
3856 /* We might pass the entire URL into the request so we need to make sure
3857 * there are no bad characters in there.*/
3858 if(strpbrk(data->change.url, "\r\n")) {
3859 failf(data, "Illegal characters found in URL");
3860 return CURLE_URL_MALFORMAT;
3863 /*************************************************************
3866 * We need to parse the url even when using the proxy, because we will need
3867 * the hostname and port in case we are trying to SSL connect through the
3868 * proxy -- and we don't know if we will need to use SSL until we parse the
3870 ************************************************************/
3871 if((2 == sscanf(data->change.url, "%15[^:]:%[^\n]",
3873 Curl_raw_equal(protobuf, "file")) {
3874 if(path[0] == '/' && path[1] == '/') {
3875 /* Allow omitted hostname (e.g. file:/<path>). This is not strictly
3876 * speaking a valid file: URL by RFC 1738, but treating file:/<path> as
3877 * file://localhost/<path> is similar to how other schemes treat missing
3878 * hostnames. See RFC 1808. */
3880 /* This cannot be done with strcpy() in a portable manner, since the
3881 memory areas overlap! */
3882 memmove(path, path + 2, strlen(path + 2)+1);
3885 * we deal with file://<host>/<path> differently since it supports no
3886 * hostname other than "localhost" and "127.0.0.1", which is unique among
3887 * the URL protocols specified in RFC 1738
3889 if(path[0] != '/') {
3890 /* the URL included a host name, we ignore host names in file:// URLs
3891 as the standards don't define what to do with them */
3892 char *ptr=strchr(path, '/');
3894 /* there was a slash present
3896 RFC1738 (section 3.1, page 5) says:
3898 The rest of the locator consists of data specific to the scheme,
3899 and is known as the "url-path". It supplies the details of how the
3900 specified resource can be accessed. Note that the "/" between the
3901 host (or port) and the url-path is NOT part of the url-path.
3903 As most agents use file://localhost/foo to get '/foo' although the
3904 slash preceding foo is a separator and not a slash for the path,
3905 a URL as file://localhost//foo must be valid as well, to refer to
3906 the same file with an absolute path.
3909 if(ptr[1] && ('/' == ptr[1]))
3910 /* if there was two slashes, we skip the first one as that is then
3911 used truly as a separator */
3914 /* This cannot be made with strcpy, as the memory chunks overlap! */
3915 memmove(path, ptr, strlen(ptr)+1);
3919 protop = "file"; /* protocol string */
3925 if(2 > sscanf(data->change.url,
3926 "%15[^\n:]://%[^\n/?]%[^\n]",
3928 conn->host.name, path)) {
3931 * The URL was badly formatted, let's try the browser-style _without_
3932 * protocol specified like 'http://'.
3934 rc = sscanf(data->change.url, "%[^\n/?]%[^\n]", conn->host.name, path);
3937 * We couldn't even get this format.
3938 * djgpp 2.04 has a sscanf() bug where 'conn->host.name' is
3939 * assigned, but the return value is EOF!
3941 #if defined(__DJGPP__) && (DJGPP_MINOR == 4)
3942 if(!(rc == -1 && *conn->host.name))
3945 failf(data, "<url> malformed");
3946 return CURLE_URL_MALFORMAT;
3951 * Since there was no protocol part specified, we guess what protocol it
3952 * is based on the first letters of the server name.
3955 /* Note: if you add a new protocol, please update the list in
3956 * lib/version.c too! */
3958 if(checkprefix("FTP.", conn->host.name))
3960 else if(checkprefix("DICT.", conn->host.name))
3962 else if(checkprefix("LDAP.", conn->host.name))
3964 else if(checkprefix("IMAP.", conn->host.name))
3966 else if(checkprefix("SMTP.", conn->host.name))
3968 else if(checkprefix("POP3.", conn->host.name))
3974 *prot_missing = TRUE; /* not given in URL */
3980 /* We search for '?' in the host name (but only on the right side of a
3981 * @-letter to allow ?-letters in username and password) to handle things
3982 * like http://example.com?param= (notice the missing '/').
3984 at = strchr(conn->host.name, '@');
3986 query = strchr(at+1, '?');
3988 query = strchr(conn->host.name, '?');
3991 /* We must insert a slash before the '?'-letter in the URL. If the URL had
3992 a slash after the '?', that is where the path currently begins and the
3993 '?string' is still part of the host name.
3995 We must move the trailing part from the host name and put it first in
3996 the path. And have it all prefixed with a slash.
3999 size_t hostlen = strlen(query);
4000 size_t pathlen = strlen(path);
4002 /* move the existing path plus the zero byte forward, to make room for
4003 the host-name part */
4004 memmove(path+hostlen+1, path, pathlen+1);
4006 /* now copy the trailing host part in front of the existing path */
4007 memcpy(path+1, query, hostlen);
4009 path[0]='/'; /* prepend the missing slash */
4012 *query=0; /* now cut off the hostname at the ? */
4015 /* if there's no path set, use a single slash */
4020 /* If the URL is malformatted (missing a '/' after hostname before path) we
4021 * insert a slash here. The only letter except '/' we accept to start a path
4024 if(path[0] == '?') {
4025 /* We need this function to deal with overlapping memory areas. We know
4026 that the memory area 'path' points to is 'urllen' bytes big and that
4027 is bigger than the path. Use +1 to move the zero byte too. */
4028 memmove(&path[1], path, strlen(path)+1);
4033 /* sanitise paths and remove ../ and ./ sequences according to RFC3986 */
4034 char *newp = Curl_dedotdotify(path);
4036 return CURLE_OUT_OF_MEMORY;
4038 if(strcmp(newp, path)) {
4040 free(data->state.pathbuffer);
4041 data->state.pathbuffer = newp;
4042 data->state.path = newp;
4050 * "rebuild_url" means that one or more URL components have been modified so
4051 * we need to generate an updated full version. We need the corrected URL
4052 * when communicating over HTTP proxy and we don't know at this point if
4053 * we're using a proxy or not.
4058 size_t plen = strlen(path); /* new path, should be 1 byte longer than
4060 size_t urllen = strlen(data->change.url); /* original URL length */
4062 size_t prefixlen = strlen(conn->host.name);
4065 prefixlen += strlen(protop) + strlen("://");
4067 reurl = malloc(urllen + 2); /* 2 for zerobyte + slash */
4069 return CURLE_OUT_OF_MEMORY;
4071 /* copy the prefix */
4072 memcpy(reurl, data->change.url, prefixlen);
4074 /* append the trailing piece + zerobyte */
4075 memcpy(&reurl[prefixlen], path, plen + 1);
4077 /* possible free the old one */
4078 if(data->change.url_alloc) {
4079 Curl_safefree(data->change.url);
4080 data->change.url_alloc = FALSE;
4083 infof(data, "Rebuilt URL to: %s\n", reurl);
4085 data->change.url = reurl;
4086 data->change.url_alloc = TRUE; /* free this later */
4090 * Parse the login details from the URL and strip them out of
4093 result = parse_url_login(data, conn, userp, passwdp, optionsp);
4097 if(conn->host.name[0] == '[') {
4098 /* This looks like an IPv6 address literal. See if there is an address
4099 scope if there is no location header */
4100 char *percent = strchr(conn->host.name, '%');
4102 unsigned int identifier_offset = 3;
4104 unsigned long scope;
4105 if(strncmp("%25", percent, 3) != 0) {
4107 "Please URL encode %% as %%25, see RFC 6874.\n");
4108 identifier_offset = 1;
4110 scope = strtoul(percent + identifier_offset, &endp, 10);
4112 /* The address scope was well formed. Knock it out of the
4114 memmove(percent, endp, strlen(endp)+1);
4115 conn->scope_id = (unsigned int)scope;
4118 /* Zone identifier is not numeric */
4119 #if defined(HAVE_NET_IF_H) && defined(IFNAMSIZ) && defined(HAVE_IF_NAMETOINDEX)
4120 char ifname[IFNAMSIZ + 2];
4121 char *square_bracket;
4122 unsigned int scopeidx = 0;
4123 strncpy(ifname, percent + identifier_offset, IFNAMSIZ + 2);
4124 /* Ensure nullbyte termination */
4125 ifname[IFNAMSIZ + 1] = '\0';
4126 square_bracket = strchr(ifname, ']');
4127 if(square_bracket) {
4129 *square_bracket = '\0';
4130 scopeidx = if_nametoindex(ifname);
4132 infof(data, "Invalid network interface: %s; %s\n", ifname,
4137 char *p = percent + identifier_offset + strlen(ifname);
4139 /* Remove zone identifier from hostname */
4140 memmove(percent, p, strlen(p) + 1);
4141 conn->scope_id = scopeidx;
4144 #endif /* HAVE_NET_IF_H && IFNAMSIZ */
4145 infof(data, "Invalid IPv6 address format\n");
4150 if(data->set.scope_id)
4151 /* Override any scope that was set above. */
4152 conn->scope_id = data->set.scope_id;
4154 /* Remove the fragment part of the path. Per RFC 2396, this is always the
4155 last part of the URI. We are looking for the first '#' so that we deal
4156 gracefully with non conformant URI such as http://example.com#foo#bar. */
4157 fragment = strchr(path, '#');
4161 /* we know the path part ended with a fragment, so we know the full URL
4162 string does too and we need to cut it off from there so it isn't used
4164 fragment = strchr(data->change.url, '#');
4170 * So if the URL was A://B/C#D,
4172 * conn->host.name is B
4173 * data->state.path is /C
4176 return findprotocol(data, conn, protop);
4180 * If we're doing a resumed transfer, we need to setup our stuff
4183 static CURLcode setup_range(struct SessionHandle *data)
4185 struct UrlState *s = &data->state;
4186 s->resume_from = data->set.set_resume_from;
4187 if(s->resume_from || data->set.str[STRING_SET_RANGE]) {
4188 if(s->rangestringalloc)
4192 s->range = aprintf("%" CURL_FORMAT_CURL_OFF_TU "-", s->resume_from);
4194 s->range = strdup(data->set.str[STRING_SET_RANGE]);
4196 s->rangestringalloc = (s->range)?TRUE:FALSE;
4199 return CURLE_OUT_OF_MEMORY;
4201 /* tell ourselves to fetch this range */
4202 s->use_range = TRUE; /* enable range download */
4205 s->use_range = FALSE; /* disable range download */
4212 * setup_connection_internals() -
4214 * Setup connection internals specific to the requested protocol in the
4215 * SessionHandle. This is inited and setup before the connection is made but
4216 * is about the particular protocol that is to be used.
4218 * This MUST get called after proxy magic has been figured out.
4220 static CURLcode setup_connection_internals(struct connectdata *conn)
4222 const struct Curl_handler * p;
4224 struct SessionHandle *data = conn->data;
4226 /* in some case in the multi state-machine, we go back to the CONNECT state
4227 and then a second (or third or...) call to this function will be made
4228 without doing a DISCONNECT or DONE in between (since the connection is
4229 yet in place) and therefore this function needs to first make sure
4230 there's no lingering previous data allocated. */
4231 Curl_free_request_state(data);
4233 memset(&data->req, 0, sizeof(struct SingleRequest));
4234 data->req.maxdownload = -1;
4236 conn->socktype = SOCK_STREAM; /* most of them are TCP streams */
4238 /* Perform setup complement if some. */
4241 if(p->setup_connection) {
4242 result = (*p->setup_connection)(conn);
4247 p = conn->handler; /* May have changed. */
4251 /* we check for -1 here since if proxy was detected already, this
4252 was very likely already set to the proxy port */
4253 conn->port = p->defport;
4255 /* only if remote_port was not already parsed off the URL we use the
4256 default port number */
4257 if(conn->remote_port < 0)
4258 conn->remote_port = (unsigned short)conn->given->defport;
4264 * Curl_free_request_state() should free temp data that was allocated in the
4265 * SessionHandle for this single request.
4268 void Curl_free_request_state(struct SessionHandle *data)
4270 Curl_safefree(data->req.protop);
4271 Curl_safefree(data->req.newurl);
4275 #ifndef CURL_DISABLE_PROXY
4276 /****************************************************************
4277 * Checks if the host is in the noproxy list. returns true if it matches
4278 * and therefore the proxy should NOT be used.
4279 ****************************************************************/
4280 static bool check_noproxy(const char* name, const char* no_proxy)
4282 /* no_proxy=domain1.dom,host.domain2.dom
4283 * (a comma-separated list of hosts which should
4284 * not be proxied, or an asterisk to override
4285 * all proxy variables)
4289 const char* separator = ", ";
4290 size_t no_proxy_len;
4294 if(no_proxy && no_proxy[0]) {
4295 if(Curl_raw_equal("*", no_proxy)) {
4299 /* NO_PROXY was specified and it wasn't just an asterisk */
4301 no_proxy_len = strlen(no_proxy);
4302 endptr = strchr(name, ':');
4304 namelen = endptr - name;
4306 namelen = strlen(name);
4308 for(tok_start = 0; tok_start < no_proxy_len; tok_start = tok_end + 1) {
4309 while(tok_start < no_proxy_len &&
4310 strchr(separator, no_proxy[tok_start]) != NULL) {
4311 /* Look for the beginning of the token. */
4315 if(tok_start == no_proxy_len)
4316 break; /* It was all trailing separator chars, no more tokens. */
4318 for(tok_end = tok_start; tok_end < no_proxy_len &&
4319 strchr(separator, no_proxy[tok_end]) == NULL; ++tok_end)
4320 /* Look for the end of the token. */
4323 /* To match previous behaviour, where it was necessary to specify
4324 * ".local.com" to prevent matching "notlocal.com", we will leave
4327 if(no_proxy[tok_start] == '.')
4330 if((tok_end - tok_start) <= namelen) {
4331 /* Match the last part of the name to the domain we are checking. */
4332 const char *checkn = name + namelen - (tok_end - tok_start);
4333 if(Curl_raw_nequal(no_proxy + tok_start, checkn,
4334 tok_end - tok_start)) {
4335 if((tok_end - tok_start) == namelen || *(checkn - 1) == '.') {
4336 /* We either have an exact match, or the previous character is a .
4337 * so it is within the same domain, so no proxy for this host.
4342 } /* if((tok_end - tok_start) <= namelen) */
4343 } /* for(tok_start = 0; tok_start < no_proxy_len;
4344 tok_start = tok_end + 1) */
4345 } /* NO_PROXY was specified and it wasn't just an asterisk */
4350 /****************************************************************
4351 * Detect what (if any) proxy to use. Remember that this selects a host
4352 * name and is not limited to HTTP proxies only.
4353 * The returned pointer must be freed by the caller (unless NULL)
4354 ****************************************************************/
4355 static char *detect_proxy(struct connectdata *conn)
4359 #ifndef CURL_DISABLE_HTTP
4360 /* If proxy was not specified, we check for default proxy environment
4361 * variables, to enable i.e Lynx compliance:
4363 * http_proxy=http://some.server.dom:port/
4364 * https_proxy=http://some.server.dom:port/
4365 * ftp_proxy=http://some.server.dom:port/
4366 * no_proxy=domain1.dom,host.domain2.dom
4367 * (a comma-separated list of hosts which should
4368 * not be proxied, or an asterisk to override
4369 * all proxy variables)
4370 * all_proxy=http://some.server.dom:port/
4371 * (seems to exist for the CERN www lib. Probably
4372 * the first to check for.)
4374 * For compatibility, the all-uppercase versions of these variables are
4375 * checked if the lowercase versions don't exist.
4377 char *no_proxy=NULL;
4378 char proxy_env[128];
4380 no_proxy=curl_getenv("no_proxy");
4382 no_proxy=curl_getenv("NO_PROXY");
4384 if(!check_noproxy(conn->host.name, no_proxy)) {
4385 /* It was not listed as without proxy */
4386 const char *protop = conn->handler->scheme;
4387 char *envp = proxy_env;
4390 /* Now, build <protocol>_proxy and check for such a one to use */
4392 *envp++ = (char)tolower((int)*protop++);
4395 strcpy(envp, "_proxy");
4397 /* read the protocol proxy: */
4398 prox=curl_getenv(proxy_env);
4401 * We don't try the uppercase version of HTTP_PROXY because of
4404 * When curl is used in a webserver application
4405 * environment (cgi or php), this environment variable can
4406 * be controlled by the web server user by setting the
4407 * http header 'Proxy:' to some value.
4409 * This can cause 'internal' http/ftp requests to be
4410 * arbitrarily redirected by any external attacker.
4412 if(!prox && !Curl_raw_equal("http_proxy", proxy_env)) {
4413 /* There was no lowercase variable, try the uppercase version: */
4414 Curl_strntoupper(proxy_env, proxy_env, sizeof(proxy_env));
4415 prox=curl_getenv(proxy_env);
4419 proxy = prox; /* use this */
4421 proxy = curl_getenv("all_proxy"); /* default proxy to use */
4423 proxy=curl_getenv("ALL_PROXY");
4425 } /* if(!check_noproxy(conn->host.name, no_proxy)) - it wasn't specified
4430 #else /* !CURL_DISABLE_HTTP */
4433 #endif /* CURL_DISABLE_HTTP */
4439 * If this is supposed to use a proxy, we need to figure out the proxy
4440 * host name, so that we can re-use an existing connection
4441 * that may exist registered to the same proxy host.
4442 * proxy will be freed before this function returns.
4444 static CURLcode parse_proxy(struct SessionHandle *data,
4445 struct connectdata *conn, char *proxy)
4450 /* We use 'proxyptr' to point to the proxy name from now on... */
4455 /* We do the proxy host string parsing here. We want the host name and the
4456 * port name. Accept a protocol:// prefix
4459 /* Parse the protocol part if present */
4460 endofprot = strstr(proxy, "://");
4462 proxyptr = endofprot+3;
4463 if(checkprefix("socks5h", proxy))
4464 conn->proxytype = CURLPROXY_SOCKS5_HOSTNAME;
4465 else if(checkprefix("socks5", proxy))
4466 conn->proxytype = CURLPROXY_SOCKS5;
4467 else if(checkprefix("socks4a", proxy))
4468 conn->proxytype = CURLPROXY_SOCKS4A;
4469 else if(checkprefix("socks4", proxy) || checkprefix("socks", proxy))
4470 conn->proxytype = CURLPROXY_SOCKS4;
4471 /* Any other xxx:// : change to http proxy */
4474 proxyptr = proxy; /* No xxx:// head: It's a HTTP proxy */
4476 /* Is there a username and password given in this proxy url? */
4477 atsign = strchr(proxyptr, '@');
4479 char *proxyuser = NULL;
4480 char *proxypasswd = NULL;
4482 parse_login_details(proxyptr, atsign - proxyptr,
4483 &proxyuser, &proxypasswd, NULL);
4485 /* found user and password, rip them out. note that we are
4486 unescaping them, as there is otherwise no way to have a
4487 username or password with reserved characters like ':' in
4489 Curl_safefree(conn->proxyuser);
4490 if(proxyuser && strlen(proxyuser) < MAX_CURL_USER_LENGTH)
4491 conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
4493 conn->proxyuser = strdup("");
4495 if(!conn->proxyuser)
4496 result = CURLE_OUT_OF_MEMORY;
4498 Curl_safefree(conn->proxypasswd);
4499 if(proxypasswd && strlen(proxypasswd) < MAX_CURL_PASSWORD_LENGTH)
4500 conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL);
4502 conn->proxypasswd = strdup("");
4504 if(!conn->proxypasswd)
4505 result = CURLE_OUT_OF_MEMORY;
4509 conn->bits.proxy_user_passwd = TRUE; /* enable it */
4510 atsign++; /* the right side of the @-letter */
4512 proxyptr = atsign; /* now use this instead */
4516 Curl_safefree(proxyuser);
4517 Curl_safefree(proxypasswd);
4523 /* start scanning for port number at this point */
4526 /* detect and extract RFC6874-style IPv6-addresses */
4527 if(*proxyptr == '[') {
4528 char *ptr = ++proxyptr; /* advance beyond the initial bracket */
4529 while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '.')))
4532 /* There might be a zone identifier */
4533 if(strncmp("%25", ptr, 3))
4534 infof(data, "Please URL encode %% as %%25, see RFC 6874.\n");
4536 /* Allow unresered characters as defined in RFC 3986 */
4537 while(*ptr && (ISALPHA(*ptr) || ISXDIGIT(*ptr) || (*ptr == '-') ||
4538 (*ptr == '.') || (*ptr == '_') || (*ptr == '~')))
4542 /* yeps, it ended nicely with a bracket as well */
4545 infof(data, "Invalid IPv6 address format\n");
4547 /* Note that if this didn't end with a bracket, we still advanced the
4548 * proxyptr first, but I can't see anything wrong with that as no host
4549 * name nor a numeric can legally start with a bracket.
4553 /* Get port number off proxy.server.com:1080 */
4554 prox_portno = strchr(portptr, ':');
4556 *prox_portno = 0x0; /* cut off number from host name */
4558 /* now set the local port number */
4559 conn->port = strtol(prox_portno, NULL, 10);
4562 if(proxyptr[0]=='/')
4563 /* If the first character in the proxy string is a slash, fail
4564 immediately. The following code will otherwise clear the string which
4565 will lead to code running as if no proxy was set! */
4566 return CURLE_COULDNT_RESOLVE_PROXY;
4568 /* without a port number after the host name, some people seem to use
4569 a slash so we strip everything from the first slash */
4570 atsign = strchr(proxyptr, '/');
4572 *atsign = 0x0; /* cut off path part from host name */
4574 if(data->set.proxyport)
4575 /* None given in the proxy string, then get the default one if it is
4577 conn->port = data->set.proxyport;
4580 /* now, clone the cleaned proxy host name */
4581 conn->proxy.rawalloc = strdup(proxyptr);
4582 conn->proxy.name = conn->proxy.rawalloc;
4584 if(!conn->proxy.rawalloc)
4585 return CURLE_OUT_OF_MEMORY;
4591 * Extract the user and password from the authentication string
4593 static CURLcode parse_proxy_auth(struct SessionHandle *data,
4594 struct connectdata *conn)
4596 char proxyuser[MAX_CURL_USER_LENGTH]="";
4597 char proxypasswd[MAX_CURL_PASSWORD_LENGTH]="";
4599 if(data->set.str[STRING_PROXYUSERNAME] != NULL) {
4600 strncpy(proxyuser, data->set.str[STRING_PROXYUSERNAME],
4601 MAX_CURL_USER_LENGTH);
4602 proxyuser[MAX_CURL_USER_LENGTH-1] = '\0'; /*To be on safe side*/
4604 if(data->set.str[STRING_PROXYPASSWORD] != NULL) {
4605 strncpy(proxypasswd, data->set.str[STRING_PROXYPASSWORD],
4606 MAX_CURL_PASSWORD_LENGTH);
4607 proxypasswd[MAX_CURL_PASSWORD_LENGTH-1] = '\0'; /*To be on safe side*/
4610 conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
4611 if(!conn->proxyuser)
4612 return CURLE_OUT_OF_MEMORY;
4614 conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL);
4615 if(!conn->proxypasswd)
4616 return CURLE_OUT_OF_MEMORY;
4620 #endif /* CURL_DISABLE_PROXY */
4625 * Parse the login details (user name, password and options) from the URL and
4626 * strip them out of the host name
4628 * Inputs: data->set.use_netrc (CURLOPT_NETRC)
4631 * Outputs: (almost :- all currently undefined)
4632 * conn->bits.user_passwd - non-zero if non-default passwords exist
4633 * user - non-zero length if defined
4634 * passwd - non-zero length if defined
4635 * options - non-zero length if defined
4636 * conn->host.name - remove user name and password
4638 static CURLcode parse_url_login(struct SessionHandle *data,
4639 struct connectdata *conn,
4640 char **user, char **passwd, char **options)
4642 CURLcode result = CURLE_OK;
4644 char *passwdp = NULL;
4645 char *optionsp = NULL;
4647 /* At this point, we're hoping all the other special cases have
4648 * been taken care of, so conn->host.name is at most
4649 * [user[:password][;options]]@]hostname
4651 * We need somewhere to put the embedded details, so do that first.
4654 char *ptr = strchr(conn->host.name, '@');
4655 char *login = conn->host.name;
4657 DEBUGASSERT(!**user);
4658 DEBUGASSERT(!**passwd);
4659 DEBUGASSERT(!**options);
4664 /* We will now try to extract the
4665 * possible login information in a string like:
4666 * ftp://user:password@ftp.my.site:8021/README */
4667 conn->host.name = ++ptr;
4669 /* So the hostname is sane. Only bother interpreting the
4670 * results if we could care. It could still be wasted
4671 * work because it might be overtaken by the programmatically
4672 * set user/passwd, but doing that first adds more cases here :-(
4675 if(data->set.use_netrc == CURL_NETRC_REQUIRED)
4678 /* We could use the login information in the URL so extract it */
4679 result = parse_login_details(login, ptr - login - 1,
4680 &userp, &passwdp, &optionsp);
4687 /* We have a user in the URL */
4688 conn->bits.userpwd_in_url = TRUE;
4689 conn->bits.user_passwd = TRUE; /* enable user+password */
4691 /* Decode the user */
4692 newname = curl_easy_unescape(data, userp, 0, NULL);
4694 result = CURLE_OUT_OF_MEMORY;
4703 /* We have a password in the URL so decode it */
4704 char *newpasswd = curl_easy_unescape(data, passwdp, 0, NULL);
4706 result = CURLE_OUT_OF_MEMORY;
4711 *passwd = newpasswd;
4715 /* We have an options list in the URL so decode it */
4716 char *newoptions = curl_easy_unescape(data, optionsp, 0, NULL);
4718 result = CURLE_OUT_OF_MEMORY;
4723 *options = newoptions;
4729 Curl_safefree(userp);
4730 Curl_safefree(passwdp);
4731 Curl_safefree(optionsp);
4737 * parse_login_details()
4739 * This is used to parse a login string for user name, password and options in
4740 * the following formats:
4744 * user:password;options
4746 * user;options:password
4754 * login [in] - The login string.
4755 * len [in] - The length of the login string.
4756 * userp [in/out] - The address where a pointer to newly allocated memory
4757 * holding the user will be stored upon completion.
4758 * passdwp [in/out] - The address where a pointer to newly allocated memory
4759 * holding the password will be stored upon completion.
4760 * optionsp [in/out] - The address where a pointer to newly allocated memory
4761 * holding the options will be stored upon completion.
4763 * Returns CURLE_OK on success.
4765 static CURLcode parse_login_details(const char *login, const size_t len,
4766 char **userp, char **passwdp,
4769 CURLcode result = CURLE_OK;
4773 const char *psep = NULL;
4774 const char *osep = NULL;
4779 /* Attempt to find the password separator */
4781 psep = strchr(login, ':');
4783 /* Within the constraint of the login string */
4784 if(psep >= login + len)
4788 /* Attempt to find the options separator */
4790 osep = strchr(login, ';');
4792 /* Within the constraint of the login string */
4793 if(osep >= login + len)
4797 /* Calculate the portion lengths */
4799 (size_t)(osep && psep > osep ? osep - login : psep - login) :
4800 (osep ? (size_t)(osep - login) : len));
4802 (osep && osep > psep ? (size_t)(osep - psep) :
4803 (size_t)(login + len - psep)) - 1 : 0);
4805 (psep && psep > osep ? (size_t)(psep - osep) :
4806 (size_t)(login + len - osep)) - 1 : 0);
4808 /* Allocate the user portion buffer */
4810 ubuf = malloc(ulen + 1);
4812 result = CURLE_OUT_OF_MEMORY;
4815 /* Allocate the password portion buffer */
4816 if(!result && passwdp && plen) {
4817 pbuf = malloc(plen + 1);
4819 Curl_safefree(ubuf);
4820 result = CURLE_OUT_OF_MEMORY;
4824 /* Allocate the options portion buffer */
4825 if(!result && optionsp && olen) {
4826 obuf = malloc(olen + 1);
4828 Curl_safefree(pbuf);
4829 Curl_safefree(ubuf);
4830 result = CURLE_OUT_OF_MEMORY;
4835 /* Store the user portion if necessary */
4837 memcpy(ubuf, login, ulen);
4839 Curl_safefree(*userp);
4843 /* Store the password portion if necessary */
4845 memcpy(pbuf, psep + 1, plen);
4847 Curl_safefree(*passwdp);
4851 /* Store the options portion if necessary */
4853 memcpy(obuf, osep + 1, olen);
4855 Curl_safefree(*optionsp);
4863 /*************************************************************
4864 * Figure out the remote port number and fix it in the URL
4866 * No matter if we use a proxy or not, we have to figure out the remote
4867 * port number of various reasons.
4869 * To be able to detect port number flawlessly, we must not confuse them
4870 * IPv6-specified addresses in the [0::1] style. (RFC2732)
4872 * The conn->host.name is currently [user:passwd@]host[:port] where host
4873 * could be a hostname, IPv4 address or IPv6 address.
4875 * The port number embedded in the URL is replaced, if necessary.
4876 *************************************************************/
4877 static CURLcode parse_remote_port(struct SessionHandle *data,
4878 struct connectdata *conn)
4883 /* Note that at this point, the IPv6 address cannot contain any scope
4884 suffix as that has already been removed in the parseurlandfillconn()
4886 if((1 == sscanf(conn->host.name, "[%*45[0123456789abcdefABCDEF:.]%c",
4888 (']' == endbracket)) {
4889 /* this is a RFC2732-style specified IP-address */
4890 conn->bits.ipv6_ip = TRUE;
4892 conn->host.name++; /* skip over the starting bracket */
4893 portptr = strchr(conn->host.name, ']');
4895 *portptr++ = '\0'; /* zero terminate, killing the bracket */
4897 portptr = NULL; /* no port number available */
4902 struct in6_addr in6;
4903 if(Curl_inet_pton(AF_INET6, conn->host.name, &in6) > 0) {
4904 /* This is a numerical IPv6 address, meaning this is a wrongly formatted
4906 failf(data, "IPv6 numerical address used in URL without brackets");
4907 return CURLE_URL_MALFORMAT;
4911 portptr = strrchr(conn->host.name, ':');
4914 if(data->set.use_port && data->state.allow_port) {
4915 /* if set, we use this and ignore the port possibly given in the URL */
4916 conn->remote_port = (unsigned short)data->set.use_port;
4918 *portptr = '\0'; /* cut off the name there anyway - if there was a port
4919 number - since the port number is to be ignored! */
4920 if(conn->bits.httpproxy) {
4921 /* we need to create new URL with the new port number */
4925 if(conn->bits.type_set)
4926 snprintf(type, sizeof(type), ";type=%c",
4927 data->set.prefer_ascii?'A':
4928 (data->set.ftp_list_only?'D':'I'));
4931 * This synthesized URL isn't always right--suffixes like ;type=A are
4932 * stripped off. It would be better to work directly from the original
4933 * URL and simply replace the port part of it.
4935 url = aprintf("%s://%s%s%s:%hu%s%s%s", conn->given->scheme,
4936 conn->bits.ipv6_ip?"[":"", conn->host.name,
4937 conn->bits.ipv6_ip?"]":"", conn->remote_port,
4938 data->state.slash_removed?"/":"", data->state.path,
4941 return CURLE_OUT_OF_MEMORY;
4943 if(data->change.url_alloc) {
4944 Curl_safefree(data->change.url);
4945 data->change.url_alloc = FALSE;
4948 data->change.url = url;
4949 data->change.url_alloc = TRUE;
4953 /* no CURLOPT_PORT given, extract the one from the URL */
4958 port=strtol(portptr+1, &rest, 10); /* Port number must be decimal */
4960 if((port < 0) || (port > 0xffff)) {
4961 /* Single unix standard says port numbers are 16 bits long */
4962 failf(data, "Port number out of range");
4963 return CURLE_URL_MALFORMAT;
4966 else if(rest != &portptr[1]) {
4967 *portptr = '\0'; /* cut off the name there */
4968 conn->remote_port = curlx_ultous(port);
4971 /* Browser behavior adaptation. If there's a colon with no digits after,
4972 just cut off the name there which makes us ignore the colon and just
4973 use the default port. Firefox and Chrome both do that. */
4980 * Override the login details from the URL with that in the CURLOPT_USERPWD
4981 * option or a .netrc file, if applicable.
4983 static CURLcode override_login(struct SessionHandle *data,
4984 struct connectdata *conn,
4985 char **userp, char **passwdp, char **optionsp)
4987 if(data->set.str[STRING_USERNAME]) {
4989 *userp = strdup(data->set.str[STRING_USERNAME]);
4991 return CURLE_OUT_OF_MEMORY;
4994 if(data->set.str[STRING_PASSWORD]) {
4996 *passwdp = strdup(data->set.str[STRING_PASSWORD]);
4998 return CURLE_OUT_OF_MEMORY;
5001 if(data->set.str[STRING_OPTIONS]) {
5003 *optionsp = strdup(data->set.str[STRING_OPTIONS]);
5005 return CURLE_OUT_OF_MEMORY;
5008 conn->bits.netrc = FALSE;
5009 if(data->set.use_netrc != CURL_NETRC_IGNORED) {
5010 int ret = Curl_parsenetrc(conn->host.name,
5012 data->set.str[STRING_NETRC_FILE]);
5014 infof(data, "Couldn't find host %s in the "
5015 DOT_CHAR "netrc file; using defaults\n",
5019 return CURLE_OUT_OF_MEMORY;
5022 /* set bits.netrc TRUE to remember that we got the name from a .netrc
5023 file, so that it is safe to use even if we followed a Location: to a
5024 different host or similar. */
5025 conn->bits.netrc = TRUE;
5027 conn->bits.user_passwd = TRUE; /* enable user+password */
5035 * Set the login details so they're available in the connection
5037 static CURLcode set_login(struct connectdata *conn,
5038 const char *user, const char *passwd,
5039 const char *options)
5041 CURLcode result = CURLE_OK;
5043 /* If our protocol needs a password and we have none, use the defaults */
5044 if((conn->handler->flags & PROTOPT_NEEDSPWD) && !conn->bits.user_passwd) {
5045 /* Store the default user */
5046 conn->user = strdup(CURL_DEFAULT_USER);
5048 /* Store the default password */
5050 conn->passwd = strdup(CURL_DEFAULT_PASSWORD);
5052 conn->passwd = NULL;
5054 /* This is the default password, so DON'T set conn->bits.user_passwd */
5057 /* Store the user, zero-length if not set */
5058 conn->user = strdup(user);
5060 /* Store the password (only if user is present), zero-length if not set */
5062 conn->passwd = strdup(passwd);
5064 conn->passwd = NULL;
5067 if(!conn->user || !conn->passwd)
5068 result = CURLE_OUT_OF_MEMORY;
5070 /* Store the options, null if not set */
5071 if(!result && options[0]) {
5072 conn->options = strdup(options);
5075 result = CURLE_OUT_OF_MEMORY;
5081 /*************************************************************
5082 * Resolve the address of the server or proxy
5083 *************************************************************/
5084 static CURLcode resolve_server(struct SessionHandle *data,
5085 struct connectdata *conn,
5088 CURLcode result=CURLE_OK;
5089 long timeout_ms = Curl_timeleft(data, NULL, TRUE);
5091 /*************************************************************
5092 * Resolve the name of the server or proxy
5093 *************************************************************/
5094 if(conn->bits.reuse)
5095 /* We're reusing the connection - no need to resolve anything, and
5096 fix_hostname() was called already in create_conn() for the re-use
5101 /* this is a fresh connect */
5103 struct Curl_dns_entry *hostaddr;
5105 /* set a pointer to the hostname we display */
5106 fix_hostname(data, conn, &conn->host);
5108 #ifdef USE_UNIX_SOCKETS
5109 if(data->set.str[STRING_UNIX_SOCKET_PATH]) {
5110 /* Unix domain sockets are local. The host gets ignored, just use the
5111 * specified domain socket address. Do not cache "DNS entries". There is
5112 * no DNS involved and we already have the filesystem path available */
5113 const char *path = data->set.str[STRING_UNIX_SOCKET_PATH];
5115 hostaddr = calloc(1, sizeof(struct Curl_dns_entry));
5117 result = CURLE_OUT_OF_MEMORY;
5118 else if((hostaddr->addr = Curl_unix2addr(path)) != NULL)
5121 /* Long paths are not supported for now */
5122 if(strlen(path) >= sizeof(((struct sockaddr_un *)0)->sun_path)) {
5123 failf(data, "Unix socket path too long: '%s'", path);
5124 result = CURLE_COULDNT_RESOLVE_HOST;
5127 result = CURLE_OUT_OF_MEMORY;
5134 if(!conn->proxy.name || !*conn->proxy.name) {
5135 /* If not connecting via a proxy, extract the port from the URL, if it is
5136 * there, thus overriding any defaults that might have been set above. */
5137 conn->port = conn->remote_port; /* it is the same port */
5139 /* Resolve target host right on */
5140 rc = Curl_resolv_timeout(conn, conn->host.name, (int)conn->port,
5141 &hostaddr, timeout_ms);
5142 if(rc == CURLRESOLV_PENDING)
5145 else if(rc == CURLRESOLV_TIMEDOUT)
5146 result = CURLE_OPERATION_TIMEDOUT;
5148 else if(!hostaddr) {
5149 failf(data, "Couldn't resolve host '%s'", conn->host.dispname);
5150 result = CURLE_COULDNT_RESOLVE_HOST;
5151 /* don't return yet, we need to clean up the timeout first */
5155 /* This is a proxy that hasn't been resolved yet. */
5157 /* IDN-fix the proxy name */
5158 fix_hostname(data, conn, &conn->proxy);
5161 rc = Curl_resolv_timeout(conn, conn->proxy.name, (int)conn->port,
5162 &hostaddr, timeout_ms);
5164 if(rc == CURLRESOLV_PENDING)
5167 else if(rc == CURLRESOLV_TIMEDOUT)
5168 result = CURLE_OPERATION_TIMEDOUT;
5170 else if(!hostaddr) {
5171 failf(data, "Couldn't resolve proxy '%s'", conn->proxy.dispname);
5172 result = CURLE_COULDNT_RESOLVE_PROXY;
5173 /* don't return yet, we need to clean up the timeout first */
5176 DEBUGASSERT(conn->dns_entry == NULL);
5177 conn->dns_entry = hostaddr;
5184 * Cleanup the connection just allocated before we can move along and use the
5185 * previously existing one. All relevant data is copied over and old_conn is
5186 * ready for freeing once this function returns.
5188 static void reuse_conn(struct connectdata *old_conn,
5189 struct connectdata *conn)
5191 if(old_conn->proxy.rawalloc)
5192 free(old_conn->proxy.rawalloc);
5194 /* free the SSL config struct from this connection struct as this was
5195 allocated in vain and is targeted for destruction */
5196 Curl_free_ssl_config(&old_conn->ssl_config);
5198 conn->data = old_conn->data;
5200 /* get the user+password information from the old_conn struct since it may
5201 * be new for this request even when we re-use an existing connection */
5202 conn->bits.user_passwd = old_conn->bits.user_passwd;
5203 if(conn->bits.user_passwd) {
5204 /* use the new user name and password though */
5205 Curl_safefree(conn->user);
5206 Curl_safefree(conn->passwd);
5207 conn->user = old_conn->user;
5208 conn->passwd = old_conn->passwd;
5209 old_conn->user = NULL;
5210 old_conn->passwd = NULL;
5213 conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd;
5214 if(conn->bits.proxy_user_passwd) {
5215 /* use the new proxy user name and proxy password though */
5216 Curl_safefree(conn->proxyuser);
5217 Curl_safefree(conn->proxypasswd);
5218 conn->proxyuser = old_conn->proxyuser;
5219 conn->proxypasswd = old_conn->proxypasswd;
5220 old_conn->proxyuser = NULL;
5221 old_conn->proxypasswd = NULL;
5224 /* host can change, when doing keepalive with a proxy or if the case is
5225 different this time etc */
5226 Curl_safefree(conn->host.rawalloc);
5227 conn->host=old_conn->host;
5229 /* persist connection info in session handle */
5230 Curl_persistconninfo(conn);
5233 conn->bits.reuse = TRUE; /* yes, we're re-using here */
5235 Curl_safefree(old_conn->user);
5236 Curl_safefree(old_conn->passwd);
5237 Curl_safefree(old_conn->proxyuser);
5238 Curl_safefree(old_conn->proxypasswd);
5239 Curl_safefree(old_conn->localdev);
5241 Curl_llist_destroy(old_conn->send_pipe, NULL);
5242 Curl_llist_destroy(old_conn->recv_pipe, NULL);
5244 old_conn->send_pipe = NULL;
5245 old_conn->recv_pipe = NULL;
5247 Curl_safefree(old_conn->master_buffer);
5251 * create_conn() sets up a new connectdata struct, or re-uses an already
5252 * existing one, and resolves host name.
5254 * if this function returns CURLE_OK and *async is set to TRUE, the resolve
5255 * response will be coming asynchronously. If *async is FALSE, the name is
5258 * @param data The sessionhandle pointer
5259 * @param in_connect is set to the next connection data pointer
5260 * @param async is set TRUE when an async DNS resolution is pending
5261 * @see Curl_setup_conn()
5263 * *NOTE* this function assigns the conn->data pointer!
5266 static CURLcode create_conn(struct SessionHandle *data,
5267 struct connectdata **in_connect,
5270 CURLcode result = CURLE_OK;
5271 struct connectdata *conn;
5272 struct connectdata *conn_temp = NULL;
5275 char *passwd = NULL;
5276 char *options = NULL;
5279 bool prot_missing = FALSE;
5280 bool no_connections_available = FALSE;
5281 bool force_reuse = FALSE;
5282 size_t max_host_connections = Curl_multi_max_host_connections(data->multi);
5283 size_t max_total_connections = Curl_multi_max_total_connections(data->multi);
5287 /*************************************************************
5289 *************************************************************/
5291 if(!data->change.url) {
5292 result = CURLE_URL_MALFORMAT;
5296 /* First, split up the current URL in parts so that we can use the
5297 parts for checking against the already present connections. In order
5298 to not have to modify everything at once, we allocate a temporary
5299 connection data struct and fill in for comparison purposes. */
5300 conn = allocate_conn(data);
5303 result = CURLE_OUT_OF_MEMORY;
5307 /* We must set the return variable as soon as possible, so that our
5308 parent can cleanup any possible allocs we may have done before
5312 /* This initing continues below, see the comment "Continue connectdata
5313 * initialization here" */
5315 /***********************************************************
5316 * We need to allocate memory to store the path in. We get the size of the
5317 * full URL to be sure, and we need to make it at least 256 bytes since
5318 * other parts of the code will rely on this fact
5319 ***********************************************************/
5320 #define LEAST_PATH_ALLOC 256
5321 urllen=strlen(data->change.url);
5322 if(urllen < LEAST_PATH_ALLOC)
5323 urllen=LEAST_PATH_ALLOC;
5326 * We malloc() the buffers below urllen+2 to make room for 2 possibilities:
5327 * 1 - an extra terminating zero
5328 * 2 - an extra slash (in case a syntax like "www.host.com?moo" is used)
5331 Curl_safefree(data->state.pathbuffer);
5332 data->state.path = NULL;
5334 data->state.pathbuffer = malloc(urllen+2);
5335 if(NULL == data->state.pathbuffer) {
5336 result = CURLE_OUT_OF_MEMORY; /* really bad error */
5339 data->state.path = data->state.pathbuffer;
5341 conn->host.rawalloc = malloc(urllen+2);
5342 if(NULL == conn->host.rawalloc) {
5343 Curl_safefree(data->state.pathbuffer);
5344 data->state.path = NULL;
5345 result = CURLE_OUT_OF_MEMORY;
5349 conn->host.name = conn->host.rawalloc;
5350 conn->host.name[0] = 0;
5353 passwd = strdup("");
5354 options = strdup("");
5355 if(!user || !passwd || !options) {
5356 result = CURLE_OUT_OF_MEMORY;
5360 result = parseurlandfillconn(data, conn, &prot_missing, &user, &passwd,
5365 /*************************************************************
5366 * No protocol part in URL was used, add it!
5367 *************************************************************/
5369 /* We're guessing prefixes here and if we're told to use a proxy or if
5370 we're gonna follow a Location: later or... then we need the protocol
5371 part added so that we have a valid URL. */
5374 reurl = aprintf("%s://%s", conn->handler->scheme, data->change.url);
5377 result = CURLE_OUT_OF_MEMORY;
5381 if(data->change.url_alloc) {
5382 Curl_safefree(data->change.url);
5383 data->change.url_alloc = FALSE;
5386 data->change.url = reurl;
5387 data->change.url_alloc = TRUE; /* free this later */
5390 /*************************************************************
5391 * If the protocol can't handle url query strings, then cut
5392 * off the unhandable part
5393 *************************************************************/
5394 if((conn->given->flags&PROTOPT_NOURLQUERY)) {
5395 char *path_q_sep = strchr(conn->data->state.path, '?');
5397 /* according to rfc3986, allow the query (?foo=bar)
5398 also on protocols that can't handle it.
5400 cut the string-part after '?'
5403 /* terminate the string */
5408 if(data->set.str[STRING_BEARER]) {
5409 conn->xoauth2_bearer = strdup(data->set.str[STRING_BEARER]);
5410 if(!conn->xoauth2_bearer) {
5411 result = CURLE_OUT_OF_MEMORY;
5416 #ifndef CURL_DISABLE_PROXY
5417 /*************************************************************
5418 * Extract the user and password from the authentication string
5419 *************************************************************/
5420 if(conn->bits.proxy_user_passwd) {
5421 result = parse_proxy_auth(data, conn);
5426 /*************************************************************
5427 * Detect what (if any) proxy to use
5428 *************************************************************/
5429 if(data->set.str[STRING_PROXY]) {
5430 proxy = strdup(data->set.str[STRING_PROXY]);
5431 /* if global proxy is set, this is it */
5433 failf(data, "memory shortage");
5434 result = CURLE_OUT_OF_MEMORY;
5439 if(data->set.str[STRING_NOPROXY] &&
5440 check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY])) {
5442 free(proxy); /* proxy is in exception list */
5447 proxy = detect_proxy(conn);
5449 #ifdef USE_UNIX_SOCKETS
5450 if(proxy && data->set.str[STRING_UNIX_SOCKET_PATH]) {
5451 free(proxy); /* Unix domain sockets cannot be proxied, so disable it */
5456 if(proxy && (!*proxy || (conn->handler->flags & PROTOPT_NONETWORK))) {
5457 free(proxy); /* Don't bother with an empty proxy string or if the
5458 protocol doesn't work with network */
5462 /***********************************************************************
5463 * If this is supposed to use a proxy, we need to figure out the proxy host
5464 * name, proxy type and port number, so that we can re-use an existing
5465 * connection that may exist registered to the same proxy host.
5466 ***********************************************************************/
5468 result = parse_proxy(data, conn, proxy);
5470 Curl_safefree(proxy); /* parse_proxy copies the proxy string */
5475 if((conn->proxytype == CURLPROXY_HTTP) ||
5476 (conn->proxytype == CURLPROXY_HTTP_1_0)) {
5477 #ifdef CURL_DISABLE_HTTP
5478 /* asking for a HTTP proxy is a bit funny when HTTP is disabled... */
5479 result = CURLE_UNSUPPORTED_PROTOCOL;
5482 /* force this connection's protocol to become HTTP if not already
5483 compatible - if it isn't tunneling through */
5484 if(!(conn->handler->protocol & PROTO_FAMILY_HTTP) &&
5485 !conn->bits.tunnel_proxy)
5486 conn->handler = &Curl_handler_http;
5488 conn->bits.httpproxy = TRUE;
5492 conn->bits.httpproxy = FALSE; /* not a HTTP proxy */
5493 conn->bits.proxy = TRUE;
5496 /* we aren't using the proxy after all... */
5497 conn->bits.proxy = FALSE;
5498 conn->bits.httpproxy = FALSE;
5499 conn->bits.proxy_user_passwd = FALSE;
5500 conn->bits.tunnel_proxy = FALSE;
5503 #endif /* CURL_DISABLE_PROXY */
5505 /*************************************************************
5506 * If the protocol is using SSL and HTTP proxy is used, we set
5507 * the tunnel_proxy bit.
5508 *************************************************************/
5509 if((conn->given->flags&PROTOPT_SSL) && conn->bits.httpproxy)
5510 conn->bits.tunnel_proxy = TRUE;
5512 /*************************************************************
5513 * Figure out the remote port number and fix it in the URL
5514 *************************************************************/
5515 result = parse_remote_port(data, conn);
5519 /* Check for overridden login details and set them accordingly so they
5520 they are known when protocol->setup_connection is called! */
5521 result = override_login(data, conn, &user, &passwd, &options);
5524 result = set_login(conn, user, passwd, options);
5528 /*************************************************************
5529 * Setup internals depending on protocol. Needs to be done after
5530 * we figured out what/if proxy to use.
5531 *************************************************************/
5532 result = setup_connection_internals(conn);
5536 conn->recv[FIRSTSOCKET] = Curl_recv_plain;
5537 conn->send[FIRSTSOCKET] = Curl_send_plain;
5538 conn->recv[SECONDARYSOCKET] = Curl_recv_plain;
5539 conn->send[SECONDARYSOCKET] = Curl_send_plain;
5541 /***********************************************************************
5542 * file: is a special case in that it doesn't need a network connection
5543 ***********************************************************************/
5544 #ifndef CURL_DISABLE_FILE
5545 if(conn->handler->flags & PROTOPT_NONETWORK) {
5547 /* this is supposed to be the connect function so we better at least check
5548 that the file is present here! */
5549 DEBUGASSERT(conn->handler->connect_it);
5550 result = conn->handler->connect_it(conn, &done);
5552 /* Setup a "faked" transfer that'll do nothing */
5555 conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; /* we are "connected */
5557 ConnectionStore(data, conn);
5560 * Setup whatever necessary for a resumed transfer
5562 result = setup_range(data);
5564 DEBUGASSERT(conn->handler->done);
5565 /* we ignore the return code for the protocol-specific DONE */
5566 (void)conn->handler->done(conn, result, FALSE);
5570 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */
5571 -1, NULL); /* no upload */
5574 /* since we skip do_init() */
5581 /* Get a cloned copy of the SSL config situation stored in the
5582 connection struct. But to get this going nicely, we must first make
5583 sure that the strings in the master copy are pointing to the correct
5584 strings in the session handle strings array!
5586 Keep in mind that the pointers in the master copy are pointing to strings
5587 that will be freed as part of the SessionHandle struct, but all cloned
5588 copies will be separately allocated.
5590 data->set.ssl.CApath = data->set.str[STRING_SSL_CAPATH];
5591 data->set.ssl.CAfile = data->set.str[STRING_SSL_CAFILE];
5592 data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE];
5593 data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT];
5594 data->set.ssl.random_file = data->set.str[STRING_SSL_RANDOM_FILE];
5595 data->set.ssl.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
5596 data->set.ssl.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST];
5598 data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME];
5599 data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD];
5602 if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config)) {
5603 result = CURLE_OUT_OF_MEMORY;
5607 prune_dead_connections(data);
5609 /*************************************************************
5610 * Check the current list of connections to see if we can
5611 * re-use an already existing one or if we have to create a
5613 *************************************************************/
5615 /* reuse_fresh is TRUE if we are told to use a new connection by force, but
5616 we only acknowledge this option if this is not a re-used connection
5617 already (which happens due to follow-location or during a HTTP
5618 authentication phase). */
5619 if(data->set.reuse_fresh && !data->state.this_is_a_follow)
5622 reuse = ConnectionExists(data, conn, &conn_temp, &force_reuse);
5624 /* If we found a reusable connection, we may still want to
5625 open a new connection if we are pipelining. */
5626 if(reuse && !force_reuse && IsPipeliningPossible(data, conn_temp)) {
5627 size_t pipelen = conn_temp->send_pipe->size + conn_temp->recv_pipe->size;
5629 infof(data, "Found connection %ld, with requests in the pipe (%zu)\n",
5630 conn_temp->connection_id, pipelen);
5632 if(conn_temp->bundle->num_connections < max_host_connections &&
5633 data->state.conn_cache->num_connections < max_total_connections) {
5634 /* We want a new connection anyway */
5637 infof(data, "We can reuse, but we want a new connection anyway\n");
5644 * We already have a connection for this, we got the former connection
5645 * in the conn_temp variable and thus we need to cleanup the one we
5646 * just allocated before we can move along and use the previously
5649 conn_temp->inuse = TRUE; /* mark this as being in use so that no other
5650 handle in a multi stack may nick it */
5651 reuse_conn(conn, conn_temp);
5652 free(conn); /* we don't need this anymore */
5656 /* set a pointer to the hostname we display */
5657 fix_hostname(data, conn, &conn->host);
5659 infof(data, "Re-using existing connection! (#%ld) with host %s\n",
5660 conn->connection_id,
5661 conn->proxy.name?conn->proxy.dispname:conn->host.dispname);
5664 /* We have decided that we want a new connection. However, we may not
5665 be able to do that if we have reached the limit of how many
5666 connections we are allowed to open. */
5667 struct connectbundle *bundle;
5669 bundle = Curl_conncache_find_bundle(data->state.conn_cache,
5671 if(max_host_connections > 0 && bundle &&
5672 (bundle->num_connections >= max_host_connections)) {
5673 struct connectdata *conn_candidate;
5675 /* The bundle is full. Let's see if we can kill a connection. */
5676 conn_candidate = find_oldest_idle_connection_in_bundle(data, bundle);
5678 if(conn_candidate) {
5679 /* Set the connection's owner correctly, then kill it */
5680 conn_candidate->data = data;
5681 (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
5684 no_connections_available = TRUE;
5687 if(max_total_connections > 0 &&
5688 (data->state.conn_cache->num_connections >= max_total_connections)) {
5689 struct connectdata *conn_candidate;
5691 /* The cache is full. Let's see if we can kill a connection. */
5692 conn_candidate = find_oldest_idle_connection(data);
5694 if(conn_candidate) {
5695 /* Set the connection's owner correctly, then kill it */
5696 conn_candidate->data = data;
5697 (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
5700 no_connections_available = TRUE;
5704 if(no_connections_available) {
5705 infof(data, "No connections available.\n");
5710 result = CURLE_NO_CONNECTION_AVAILABLE;
5715 * This is a brand new connection, so let's store it in the connection
5718 ConnectionStore(data, conn);
5721 #if defined(USE_NTLM)
5722 /* If NTLM is requested in a part of this connection, make sure we don't
5723 assume the state is fine as this is a fresh connection and NTLM is
5724 connection based. */
5725 if((data->state.authhost.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
5726 data->state.authhost.done) {
5727 infof(data, "NTLM picked AND auth done set, clear picked!\n");
5728 data->state.authhost.picked = CURLAUTH_NONE;
5731 if((data->state.authproxy.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
5732 data->state.authproxy.done) {
5733 infof(data, "NTLM-proxy picked AND auth done set, clear picked!\n");
5734 data->state.authproxy.picked = CURLAUTH_NONE;
5739 /* Mark the connection as used */
5742 /* Setup and init stuff before DO starts, in preparing for the transfer. */
5746 * Setup whatever necessary for a resumed transfer
5748 result = setup_range(data);
5752 /* Continue connectdata initialization here. */
5755 * Inherit the proper values from the urldata struct AFTER we have arranged
5756 * the persistent connection stuff
5758 conn->fread_func = data->set.fread_func;
5759 conn->fread_in = data->set.in;
5760 conn->seek_func = data->set.seek_func;
5761 conn->seek_client = data->set.seek_client;
5763 /*************************************************************
5764 * Resolve the address of the server or proxy
5765 *************************************************************/
5766 result = resolve_server(data, conn, async);
5770 Curl_safefree(options);
5771 Curl_safefree(passwd);
5772 Curl_safefree(user);
5773 Curl_safefree(proxy);
5777 /* Curl_setup_conn() is called after the name resolve initiated in
5778 * create_conn() is all done.
5780 * Curl_setup_conn() also handles reused connections
5782 * conn->data MUST already have been setup fine (in create_conn)
5785 CURLcode Curl_setup_conn(struct connectdata *conn,
5786 bool *protocol_done)
5788 CURLcode result = CURLE_OK;
5789 struct SessionHandle *data = conn->data;
5791 Curl_pgrsTime(data, TIMER_NAMELOOKUP);
5793 if(conn->handler->flags & PROTOPT_NONETWORK) {
5794 /* nothing to setup when not using a network */
5795 *protocol_done = TRUE;
5798 *protocol_done = FALSE; /* default to not done */
5800 /* set proxy_connect_closed to false unconditionally already here since it
5801 is used strictly to provide extra information to a parent function in the
5802 case of proxy CONNECT failures and we must make sure we don't have it
5803 lingering set from a previous invoke */
5804 conn->bits.proxy_connect_closed = FALSE;
5807 * Set user-agent. Used for HTTP, but since we can attempt to tunnel
5808 * basically anything through a http proxy we can't limit this based on
5811 if(data->set.str[STRING_USERAGENT]) {
5812 Curl_safefree(conn->allocptr.uagent);
5813 conn->allocptr.uagent =
5814 aprintf("User-Agent: %s\r\n", data->set.str[STRING_USERAGENT]);
5815 if(!conn->allocptr.uagent)
5816 return CURLE_OUT_OF_MEMORY;
5819 data->req.headerbytecount = 0;
5821 #ifdef CURL_DO_LINEEND_CONV
5822 data->state.crlf_conversions = 0; /* reset CRLF conversion counter */
5823 #endif /* CURL_DO_LINEEND_CONV */
5825 /* set start time here for timeout purposes in the connect procedure, it
5826 is later set again for the progress meter purpose */
5827 conn->now = Curl_tvnow();
5829 if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
5830 conn->bits.tcpconnect[FIRSTSOCKET] = FALSE;
5831 result = Curl_connecthost(conn, conn->dns_entry);
5836 Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */
5837 Curl_pgrsTime(data, TIMER_APPCONNECT); /* we're connected already */
5838 conn->bits.tcpconnect[FIRSTSOCKET] = TRUE;
5839 *protocol_done = TRUE;
5840 Curl_updateconninfo(conn, conn->sock[FIRSTSOCKET]);
5841 Curl_verboseconnect(conn);
5844 conn->now = Curl_tvnow(); /* time this *after* the connect is done, we
5845 set this here perhaps a second time */
5849 * This check is quite a hack. We're calling _fsetmode to fix the problem
5850 * with fwrite converting newline characters (you get mangled text files,
5851 * and corrupted binary files when you download to stdout and redirect it to
5855 if((data->set.out)->_handle == NULL) {
5856 _fsetmode(stdout, "b");
5863 CURLcode Curl_connect(struct SessionHandle *data,
5864 struct connectdata **in_connect,
5866 bool *protocol_done)
5870 *asyncp = FALSE; /* assume synchronous resolves by default */
5872 /* call the stuff that needs to be called */
5873 result = create_conn(data, in_connect, asyncp);
5877 if((*in_connect)->send_pipe->size || (*in_connect)->recv_pipe->size)
5879 *protocol_done = TRUE;
5881 /* DNS resolution is done: that's either because this is a reused
5882 connection, in which case DNS was unnecessary, or because DNS
5883 really did finish already (synch resolver/fast async resolve) */
5884 result = Curl_setup_conn(*in_connect, protocol_done);
5888 if(result == CURLE_NO_CONNECTION_AVAILABLE) {
5893 if(result && *in_connect) {
5894 /* We're not allowed to return failure with memory left allocated
5895 in the connectdata struct, free those here */
5896 Curl_disconnect(*in_connect, FALSE); /* close the connection */
5897 *in_connect = NULL; /* return a NULL */
5903 CURLcode Curl_done(struct connectdata **connp,
5904 CURLcode status, /* an error if this is called after an
5905 error was detected */
5909 struct connectdata *conn;
5910 struct SessionHandle *data;
5912 DEBUGASSERT(*connp);
5918 /* Stop if Curl_done() has already been called */
5921 Curl_getoff_all_pipelines(data, conn);
5923 if((conn->send_pipe->size + conn->recv_pipe->size != 0 &&
5924 !data->set.reuse_forbid &&
5926 /* Stop if pipeline is not empty and we do not have to close
5930 conn->bits.done = TRUE; /* called just now! */
5932 /* Cleanup possible redirect junk */
5933 if(data->req.newurl) {
5934 free(data->req.newurl);
5935 data->req.newurl = NULL;
5937 if(data->req.location) {
5938 free(data->req.location);
5939 data->req.location = NULL;
5942 Curl_resolver_cancel(conn);
5944 if(conn->dns_entry) {
5945 Curl_resolv_unlock(data, conn->dns_entry); /* done with this */
5946 conn->dns_entry = NULL;
5950 case CURLE_ABORTED_BY_CALLBACK:
5951 case CURLE_READ_ERROR:
5952 case CURLE_WRITE_ERROR:
5953 /* When we're aborted due to a callback return code it basically have to
5954 be counted as premature as there is trouble ahead if we don't. We have
5955 many callbacks and protocols work differently, we could potentially do
5956 this more fine-grained in the future. */
5962 /* this calls the protocol-specific function pointer previously set */
5963 if(conn->handler->done)
5964 result = conn->handler->done(conn, status, premature);
5968 if(!result && Curl_pgrsDone(conn))
5969 result = CURLE_ABORTED_BY_CALLBACK;
5971 /* if the transfer was completed in a paused state there can be buffered
5972 data left to write and then kill */
5973 if(data->state.tempwrite) {
5974 free(data->state.tempwrite);
5975 data->state.tempwrite = NULL;
5978 /* if data->set.reuse_forbid is TRUE, it means the libcurl client has
5979 forced us to close this connection. This is ignored for requests taking
5980 place in a NTLM authentication handshake
5982 if conn->bits.close is TRUE, it means that the connection should be
5983 closed in spite of all our efforts to be nice, due to protocol
5984 restrictions in our or the server's end
5986 if premature is TRUE, it means this connection was said to be DONE before
5987 the entire request operation is complete and thus we can't know in what
5988 state it is for re-using, so we're forced to close it. In a perfect world
5989 we can add code that keep track of if we really must close it here or not,
5990 but currently we have no such detail knowledge.
5993 if((data->set.reuse_forbid
5994 #if defined(USE_NTLM)
5995 && !(conn->ntlm.state == NTLMSTATE_TYPE2 ||
5996 conn->proxyntlm.state == NTLMSTATE_TYPE2)
5998 ) || conn->bits.close || premature) {
5999 CURLcode res2 = Curl_disconnect(conn, premature); /* close connection */
6001 /* If we had an error already, make sure we return that one. But
6002 if we got a new error, return that. */
6007 /* the connection is no longer in use */
6008 if(ConnectionDone(data, conn)) {
6009 /* remember the most recently used connection */
6010 data->state.lastconnect = conn;
6012 infof(data, "Connection #%ld to host %s left intact\n",
6013 conn->connection_id,
6014 conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname);
6017 data->state.lastconnect = NULL;
6020 *connp = NULL; /* to make the caller of this function better detect that
6021 this was either closed or handed over to the connection
6022 cache here, and therefore cannot be used from this point on
6024 Curl_free_request_state(data);
6030 * do_init() inits the readwrite session. This is inited each time (in the DO
6031 * function before the protocol-specific DO functions are invoked) for a
6032 * transfer, sometimes multiple times on the same SessionHandle. Make sure
6033 * nothing in here depends on stuff that are setup dynamically for the
6037 static CURLcode do_init(struct connectdata *conn)
6039 struct SessionHandle *data = conn->data;
6040 struct SingleRequest *k = &data->req;
6042 conn->bits.done = FALSE; /* Curl_done() is not called yet */
6043 conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */
6044 data->state.expect100header = FALSE;
6046 if(data->set.opt_no_body)
6047 /* in HTTP lingo, no body means using the HEAD request... */
6048 data->set.httpreq = HTTPREQ_HEAD;
6049 else if(HTTPREQ_HEAD == data->set.httpreq)
6050 /* ... but if unset there really is no perfect method that is the
6051 "opposite" of HEAD but in reality most people probably think GET
6052 then. The important thing is that we can't let it remain HEAD if the
6053 opt_no_body is set FALSE since then we'll behave wrong when getting
6055 data->set.httpreq = HTTPREQ_GET;
6057 k->start = Curl_tvnow(); /* start time */
6058 k->now = k->start; /* current time is now */
6059 k->header = TRUE; /* assume header */
6063 k->buf = data->state.buffer;
6064 k->uploadbuf = data->state.uploadbuffer;
6065 k->hbufp = data->state.headerbuff;
6066 k->ignorebody=FALSE;
6068 Curl_speedinit(data);
6070 Curl_pgrsSetUploadCounter(data, 0);
6071 Curl_pgrsSetDownloadCounter(data, 0);
6077 * do_complete is called when the DO actions are complete.
6079 * We init chunking and trailer bits to their default values here immediately
6080 * before receiving any header data for the current request in the pipeline.
6082 static void do_complete(struct connectdata *conn)
6084 conn->data->req.chunk=FALSE;
6085 conn->data->req.maxfd = (conn->sockfd>conn->writesockfd?
6086 conn->sockfd:conn->writesockfd)+1;
6087 Curl_pgrsTime(conn->data, TIMER_PRETRANSFER);
6090 CURLcode Curl_do(struct connectdata **connp, bool *done)
6092 CURLcode result=CURLE_OK;
6093 struct connectdata *conn = *connp;
6094 struct SessionHandle *data = conn->data;
6096 if(conn->handler->do_it) {
6097 /* generic protocol-specific function pointer set in curl_connect() */
6098 result = conn->handler->do_it(conn, done);
6100 /* This was formerly done in transfer.c, but we better do it here */
6101 if((CURLE_SEND_ERROR == result) && conn->bits.reuse) {
6103 * If the connection is using an easy handle, call reconnect
6104 * to re-establish the connection. Otherwise, let the multi logic
6105 * figure out how to re-establish the connection.
6108 result = Curl_reconnect_request(connp);
6111 /* ... finally back to actually retry the DO phase */
6112 conn = *connp; /* re-assign conn since Curl_reconnect_request
6113 creates a new connection */
6114 result = conn->handler->do_it(conn, done);
6121 if(!result && *done)
6122 /* do_complete must be called after the protocol-specific DO function */
6129 * Curl_do_more() is called during the DO_MORE multi state. It is basically a
6130 * second stage DO state which (wrongly) was introduced to support FTP's
6131 * second connection.
6133 * TODO: A future libcurl should be able to work away this state.
6135 * 'complete' can return 0 for incomplete, 1 for done and -1 for go back to
6136 * DOING state there's more work to do!
6139 CURLcode Curl_do_more(struct connectdata *conn, int *complete)
6141 CURLcode result=CURLE_OK;
6145 if(conn->handler->do_more)
6146 result = conn->handler->do_more(conn, complete);
6148 if(!result && (*complete == 1))
6149 /* do_complete must be called after the protocol-specific DO function */