url.c revision e3149cc1cf501b46caba8d47652ac90b95c78eac
1/*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. 9 * 10 * This software is licensed as described in the file COPYING, which 11 * you should have received as part of this distribution. The terms 12 * are also available at https://curl.haxx.se/docs/copyright.html. 13 * 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. 17 * 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 * KIND, either express or implied. 20 * 21 ***************************************************************************/ 22 23#include "curl_setup.h" 24 25#ifdef HAVE_NETINET_IN_H 26#include <netinet/in.h> 27#endif 28#ifdef HAVE_NETDB_H 29#include <netdb.h> 30#endif 31#ifdef HAVE_ARPA_INET_H 32#include <arpa/inet.h> 33#endif 34#ifdef HAVE_NET_IF_H 35#include <net/if.h> 36#endif 37#ifdef HAVE_SYS_IOCTL_H 38#include <sys/ioctl.h> 39#endif 40 41#ifdef HAVE_SYS_PARAM_H 42#include <sys/param.h> 43#endif 44 45#ifdef __VMS 46#include <in.h> 47#include <inet.h> 48#endif 49 50#ifdef HAVE_SYS_UN_H 51#include <sys/un.h> 52#endif 53 54#ifndef HAVE_SOCKET 55#error "We can't compile without socket() support!" 56#endif 57 58#ifdef HAVE_LIMITS_H 59#include <limits.h> 60#endif 61 62#ifdef USE_LIBIDN 63#include <idna.h> 64#include <tld.h> 65#include <stringprep.h> 66#ifdef HAVE_IDN_FREE_H 67#include <idn-free.h> 68#else 69/* prototype from idn-free.h, not provided by libidn 0.4.5's make install! */ 70void idn_free (void *ptr); 71#endif 72#ifndef HAVE_IDN_FREE 73/* if idn_free() was not found in this version of libidn use free() instead */ 74#define idn_free(x) (free)(x) 75#endif 76#elif defined(USE_WIN32_IDN) 77/* prototype for curl_win32_idn_to_ascii() */ 78bool curl_win32_idn_to_ascii(const char *in, char **out); 79#endif /* USE_LIBIDN */ 80 81#include "urldata.h" 82#include "netrc.h" 83 84#include "formdata.h" 85#include "vtls/vtls.h" 86#include "hostip.h" 87#include "transfer.h" 88#include "sendf.h" 89#include "progress.h" 90#include "cookie.h" 91#include "strequal.h" 92#include "strerror.h" 93#include "escape.h" 94#include "strtok.h" 95#include "share.h" 96#include "content_encoding.h" 97#include "http_digest.h" 98#include "http_negotiate.h" 99#include "select.h" 100#include "multiif.h" 101#include "easyif.h" 102#include "speedcheck.h" 103#include "rawstr.h" 104#include "warnless.h" 105#include "non-ascii.h" 106#include "inet_pton.h" 107 108/* And now for the protocols */ 109#include "ftp.h" 110#include "dict.h" 111#include "telnet.h" 112#include "tftp.h" 113#include "http.h" 114#include "http2.h" 115#include "file.h" 116#include "curl_ldap.h" 117#include "ssh.h" 118#include "imap.h" 119#include "url.h" 120#include "connect.h" 121#include "inet_ntop.h" 122#include "http_ntlm.h" 123#include "curl_ntlm_wb.h" 124#include "socks.h" 125#include "curl_rtmp.h" 126#include "gopher.h" 127#include "http_proxy.h" 128#include "conncache.h" 129#include "multihandle.h" 130#include "pipeline.h" 131#include "dotdot.h" 132#include "strdup.h" 133/* The last 3 #include files should be in this order */ 134#include "curl_printf.h" 135#include "curl_memory.h" 136#include "memdebug.h" 137 138/* Local static prototypes */ 139static struct connectdata * 140find_oldest_idle_connection_in_bundle(struct Curl_easy *data, 141 struct connectbundle *bundle); 142static void conn_free(struct connectdata *conn); 143static void free_fixed_hostname(struct hostname *host); 144static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke); 145static CURLcode parse_url_login(struct Curl_easy *data, 146 struct connectdata *conn, 147 char **userptr, char **passwdptr, 148 char **optionsptr); 149static CURLcode parse_login_details(const char *login, const size_t len, 150 char **userptr, char **passwdptr, 151 char **optionsptr); 152static unsigned int get_protocol_family(unsigned int protocol); 153 154/* 155 * Protocol table. 156 */ 157 158static const struct Curl_handler * const protocols[] = { 159 160#ifndef CURL_DISABLE_HTTP 161 &Curl_handler_http, 162#endif 163 164#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP) 165 &Curl_handler_https, 166#endif 167 168#ifndef CURL_DISABLE_FTP 169 &Curl_handler_ftp, 170#endif 171 172#if defined(USE_SSL) && !defined(CURL_DISABLE_FTP) 173 &Curl_handler_ftps, 174#endif 175 176#ifndef CURL_DISABLE_TELNET 177 &Curl_handler_telnet, 178#endif 179 180#ifndef CURL_DISABLE_DICT 181 &Curl_handler_dict, 182#endif 183 184#ifndef CURL_DISABLE_LDAP 185 &Curl_handler_ldap, 186#if !defined(CURL_DISABLE_LDAPS) && \ 187 ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \ 188 (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL))) 189 &Curl_handler_ldaps, 190#endif 191#endif 192 193#ifndef CURL_DISABLE_FILE 194 &Curl_handler_file, 195#endif 196 197#ifndef CURL_DISABLE_TFTP 198 &Curl_handler_tftp, 199#endif 200 201#ifdef USE_LIBSSH2 202 &Curl_handler_scp, 203 &Curl_handler_sftp, 204#endif 205 206#ifndef CURL_DISABLE_IMAP 207 &Curl_handler_imap, 208#ifdef USE_SSL 209 &Curl_handler_imaps, 210#endif 211#endif 212 213#ifndef CURL_DISABLE_POP3 214 &Curl_handler_pop3, 215#ifdef USE_SSL 216 &Curl_handler_pop3s, 217#endif 218#endif 219 220#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \ 221 (CURL_SIZEOF_CURL_OFF_T > 4) && \ 222 (!defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)) 223 &Curl_handler_smb, 224#ifdef USE_SSL 225 &Curl_handler_smbs, 226#endif 227#endif 228 229#ifndef CURL_DISABLE_SMTP 230 &Curl_handler_smtp, 231#ifdef USE_SSL 232 &Curl_handler_smtps, 233#endif 234#endif 235 236#ifndef CURL_DISABLE_RTSP 237 &Curl_handler_rtsp, 238#endif 239 240#ifndef CURL_DISABLE_GOPHER 241 &Curl_handler_gopher, 242#endif 243 244#ifdef USE_LIBRTMP 245 &Curl_handler_rtmp, 246 &Curl_handler_rtmpt, 247 &Curl_handler_rtmpe, 248 &Curl_handler_rtmpte, 249 &Curl_handler_rtmps, 250 &Curl_handler_rtmpts, 251#endif 252 253 (struct Curl_handler *) NULL 254}; 255 256/* 257 * Dummy handler for undefined protocol schemes. 258 */ 259 260static const struct Curl_handler Curl_handler_dummy = { 261 "<no protocol>", /* scheme */ 262 ZERO_NULL, /* setup_connection */ 263 ZERO_NULL, /* do_it */ 264 ZERO_NULL, /* done */ 265 ZERO_NULL, /* do_more */ 266 ZERO_NULL, /* connect_it */ 267 ZERO_NULL, /* connecting */ 268 ZERO_NULL, /* doing */ 269 ZERO_NULL, /* proto_getsock */ 270 ZERO_NULL, /* doing_getsock */ 271 ZERO_NULL, /* domore_getsock */ 272 ZERO_NULL, /* perform_getsock */ 273 ZERO_NULL, /* disconnect */ 274 ZERO_NULL, /* readwrite */ 275 0, /* defport */ 276 0, /* protocol */ 277 PROTOPT_NONE /* flags */ 278}; 279 280void Curl_freeset(struct Curl_easy *data) 281{ 282 /* Free all dynamic strings stored in the data->set substructure. */ 283 enum dupstring i; 284 for(i=(enum dupstring)0; i < STRING_LAST; i++) { 285 Curl_safefree(data->set.str[i]); 286 } 287 288 if(data->change.referer_alloc) { 289 Curl_safefree(data->change.referer); 290 data->change.referer_alloc = FALSE; 291 } 292 data->change.referer = NULL; 293 if(data->change.url_alloc) { 294 Curl_safefree(data->change.url); 295 data->change.url_alloc = FALSE; 296 } 297 data->change.url = NULL; 298} 299 300static CURLcode setstropt(char **charp, const char *s) 301{ 302 /* Release the previous storage at `charp' and replace by a dynamic storage 303 copy of `s'. Return CURLE_OK or CURLE_OUT_OF_MEMORY. */ 304 305 Curl_safefree(*charp); 306 307 if(s) { 308 char *str = strdup(s); 309 310 if(!str) 311 return CURLE_OUT_OF_MEMORY; 312 313 *charp = str; 314 } 315 316 return CURLE_OK; 317} 318 319static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp) 320{ 321 CURLcode result = CURLE_OK; 322 char *user = NULL; 323 char *passwd = NULL; 324 325 /* Parse the login details if specified. It not then we treat NULL as a hint 326 to clear the existing data */ 327 if(option) { 328 result = parse_login_details(option, strlen(option), 329 (userp ? &user : NULL), 330 (passwdp ? &passwd : NULL), 331 NULL); 332 } 333 334 if(!result) { 335 /* Store the username part of option if required */ 336 if(userp) { 337 if(!user && option && option[0] == ':') { 338 /* Allocate an empty string instead of returning NULL as user name */ 339 user = strdup(""); 340 if(!user) 341 result = CURLE_OUT_OF_MEMORY; 342 } 343 344 Curl_safefree(*userp); 345 *userp = user; 346 } 347 348 /* Store the password part of option if required */ 349 if(passwdp) { 350 Curl_safefree(*passwdp); 351 *passwdp = passwd; 352 } 353 } 354 355 return result; 356} 357 358CURLcode Curl_dupset(struct Curl_easy *dst, struct Curl_easy *src) 359{ 360 CURLcode result = CURLE_OK; 361 enum dupstring i; 362 363 /* Copy src->set into dst->set first, then deal with the strings 364 afterwards */ 365 dst->set = src->set; 366 367 /* clear all string pointers first */ 368 memset(dst->set.str, 0, STRING_LAST * sizeof(char *)); 369 370 /* duplicate all strings */ 371 for(i=(enum dupstring)0; i< STRING_LASTZEROTERMINATED; i++) { 372 result = setstropt(&dst->set.str[i], src->set.str[i]); 373 if(result) 374 return result; 375 } 376 377 /* duplicate memory areas pointed to */ 378 i = STRING_COPYPOSTFIELDS; 379 if(src->set.postfieldsize && src->set.str[i]) { 380 /* postfieldsize is curl_off_t, Curl_memdup() takes a size_t ... */ 381 dst->set.str[i] = Curl_memdup(src->set.str[i], 382 curlx_sotouz(src->set.postfieldsize)); 383 if(!dst->set.str[i]) 384 return CURLE_OUT_OF_MEMORY; 385 /* point to the new copy */ 386 dst->set.postfields = dst->set.str[i]; 387 } 388 389 return CURLE_OK; 390} 391 392/* 393 * This is the internal function curl_easy_cleanup() calls. This should 394 * cleanup and free all resources associated with this sessionhandle. 395 * 396 * NOTE: if we ever add something that attempts to write to a socket or 397 * similar here, we must ignore SIGPIPE first. It is currently only done 398 * when curl_easy_perform() is invoked. 399 */ 400 401CURLcode Curl_close(struct Curl_easy *data) 402{ 403 struct Curl_multi *m; 404 405 if(!data) 406 return CURLE_OK; 407 408 Curl_expire(data, 0); /* shut off timers */ 409 410 m = data->multi; 411 412 if(m) 413 /* This handle is still part of a multi handle, take care of this first 414 and detach this handle from there. */ 415 curl_multi_remove_handle(data->multi, data); 416 417 if(data->multi_easy) 418 /* when curl_easy_perform() is used, it creates its own multi handle to 419 use and this is the one */ 420 curl_multi_cleanup(data->multi_easy); 421 422 /* Destroy the timeout list that is held in the easy handle. It is 423 /normally/ done by curl_multi_remove_handle() but this is "just in 424 case" */ 425 if(data->state.timeoutlist) { 426 Curl_llist_destroy(data->state.timeoutlist, NULL); 427 data->state.timeoutlist = NULL; 428 } 429 430 data->magic = 0; /* force a clear AFTER the possibly enforced removal from 431 the multi handle, since that function uses the magic 432 field! */ 433 434 if(data->state.rangestringalloc) 435 free(data->state.range); 436 437 /* Free the pathbuffer */ 438 Curl_safefree(data->state.pathbuffer); 439 data->state.path = NULL; 440 441 /* freed here just in case DONE wasn't called */ 442 Curl_free_request_state(data); 443 444 /* Close down all open SSL info and sessions */ 445 Curl_ssl_close_all(data); 446 Curl_safefree(data->state.first_host); 447 Curl_safefree(data->state.scratch); 448 Curl_ssl_free_certinfo(data); 449 450 /* Cleanup possible redirect junk */ 451 free(data->req.newurl); 452 data->req.newurl = NULL; 453 454 if(data->change.referer_alloc) { 455 Curl_safefree(data->change.referer); 456 data->change.referer_alloc = FALSE; 457 } 458 data->change.referer = NULL; 459 460 if(data->change.url_alloc) { 461 Curl_safefree(data->change.url); 462 data->change.url_alloc = FALSE; 463 } 464 data->change.url = NULL; 465 466 Curl_safefree(data->state.headerbuff); 467 468 Curl_flush_cookies(data, 1); 469 470 Curl_digest_cleanup(data); 471 472 Curl_safefree(data->info.contenttype); 473 Curl_safefree(data->info.wouldredirect); 474 475 /* this destroys the channel and we cannot use it anymore after this */ 476 Curl_resolver_cleanup(data->state.resolver); 477 478 Curl_convert_close(data); 479 480 /* No longer a dirty share, if it exists */ 481 if(data->share) { 482 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); 483 data->share->dirty--; 484 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); 485 } 486 487 if(data->set.wildcardmatch) { 488 /* destruct wildcard structures if it is needed */ 489 struct WildcardData *wc = &data->wildcard; 490 Curl_wildcard_dtor(wc); 491 } 492 493 Curl_freeset(data); 494 free(data); 495 return CURLE_OK; 496} 497 498/* 499 * Initialize the UserDefined fields within a Curl_easy. 500 * This may be safely called on a new or existing Curl_easy. 501 */ 502CURLcode Curl_init_userdefined(struct UserDefined *set) 503{ 504 CURLcode result = CURLE_OK; 505 506 set->out = stdout; /* default output to stdout */ 507 set->in_set = stdin; /* default input from stdin */ 508 set->err = stderr; /* default stderr to stderr */ 509 510 /* use fwrite as default function to store output */ 511 set->fwrite_func = (curl_write_callback)fwrite; 512 513 /* use fread as default function to read input */ 514 set->fread_func_set = (curl_read_callback)fread; 515 set->is_fread_set = 0; 516 set->is_fwrite_set = 0; 517 518 set->seek_func = ZERO_NULL; 519 set->seek_client = ZERO_NULL; 520 521 /* conversion callbacks for non-ASCII hosts */ 522 set->convfromnetwork = ZERO_NULL; 523 set->convtonetwork = ZERO_NULL; 524 set->convfromutf8 = ZERO_NULL; 525 526 set->filesize = -1; /* we don't know the size */ 527 set->postfieldsize = -1; /* unknown size */ 528 set->maxredirs = -1; /* allow any amount by default */ 529 530 set->httpreq = HTTPREQ_GET; /* Default HTTP request */ 531 set->rtspreq = RTSPREQ_OPTIONS; /* Default RTSP request */ 532 set->ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */ 533 set->ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */ 534 set->ftp_use_pret = FALSE; /* mainly useful for drftpd servers */ 535 set->ftp_filemethod = FTPFILE_MULTICWD; 536 537 set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */ 538 539 /* Set the default size of the SSL session ID cache */ 540 set->ssl.max_ssl_sessions = 5; 541 542 set->proxyport = CURL_DEFAULT_PROXY_PORT; /* from url.h */ 543 set->proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */ 544 set->httpauth = CURLAUTH_BASIC; /* defaults to basic */ 545 set->proxyauth = CURLAUTH_BASIC; /* defaults to basic */ 546 547 /* make libcurl quiet by default: */ 548 set->hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */ 549 550 /* 551 * libcurl 7.10 introduced SSL verification *by default*! This needs to be 552 * switched off unless wanted. 553 */ 554 set->ssl.verifypeer = TRUE; 555 set->ssl.verifyhost = TRUE; 556#ifdef USE_TLS_SRP 557 set->ssl.authtype = CURL_TLSAUTH_NONE; 558#endif 559 set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth 560 type */ 561 set->ssl.sessionid = TRUE; /* session ID caching enabled by default */ 562 563 set->new_file_perms = 0644; /* Default permissions */ 564 set->new_directory_perms = 0755; /* Default permissions */ 565 566 /* for the *protocols fields we don't use the CURLPROTO_ALL convenience 567 define since we internally only use the lower 16 bits for the passed 568 in bitmask to not conflict with the private bits */ 569 set->allowed_protocols = CURLPROTO_ALL; 570 set->redir_protocols = CURLPROTO_ALL & /* All except FILE, SCP and SMB */ 571 ~(CURLPROTO_FILE | CURLPROTO_SCP | CURLPROTO_SMB | 572 CURLPROTO_SMBS); 573 574#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) 575 /* 576 * disallow unprotected protection negotiation NEC reference implementation 577 * seem not to follow rfc1961 section 4.3/4.4 578 */ 579 set->socks5_gssapi_nec = FALSE; 580#endif 581 582 /* This is our preferred CA cert bundle/path since install time */ 583#if defined(CURL_CA_BUNDLE) 584 result = setstropt(&set->str[STRING_SSL_CAFILE], CURL_CA_BUNDLE); 585 if(result) 586 return result; 587#endif 588#if defined(CURL_CA_PATH) 589 result = setstropt(&set->str[STRING_SSL_CAPATH], CURL_CA_PATH); 590 if(result) 591 return result; 592#endif 593 594 set->wildcardmatch = FALSE; 595 set->chunk_bgn = ZERO_NULL; 596 set->chunk_end = ZERO_NULL; 597 598 /* tcp keepalives are disabled by default, but provide reasonable values for 599 * the interval and idle times. 600 */ 601 set->tcp_keepalive = FALSE; 602 set->tcp_keepintvl = 60; 603 set->tcp_keepidle = 60; 604 set->tcp_fastopen = FALSE; 605 606 set->ssl_enable_npn = TRUE; 607 set->ssl_enable_alpn = TRUE; 608 609 set->expect_100_timeout = 1000L; /* Wait for a second by default. */ 610 set->sep_headers = TRUE; /* separated header lists by default */ 611 612 Curl_http2_init_userset(set); 613 return result; 614} 615 616/** 617 * Curl_open() 618 * 619 * @param curl is a pointer to a sessionhandle pointer that gets set by this 620 * function. 621 * @return CURLcode 622 */ 623 624CURLcode Curl_open(struct Curl_easy **curl) 625{ 626 CURLcode result; 627 struct Curl_easy *data; 628 629 /* Very simple start-up: alloc the struct, init it with zeroes and return */ 630 data = calloc(1, sizeof(struct Curl_easy)); 631 if(!data) { 632 /* this is a very serious error */ 633 DEBUGF(fprintf(stderr, "Error: calloc of Curl_easy failed\n")); 634 return CURLE_OUT_OF_MEMORY; 635 } 636 637 data->magic = CURLEASY_MAGIC_NUMBER; 638 639 result = Curl_resolver_init(&data->state.resolver); 640 if(result) { 641 DEBUGF(fprintf(stderr, "Error: resolver_init failed\n")); 642 free(data); 643 return result; 644 } 645 646 /* We do some initial setup here, all those fields that can't be just 0 */ 647 648 data->state.headerbuff = malloc(HEADERSIZE); 649 if(!data->state.headerbuff) { 650 DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n")); 651 result = CURLE_OUT_OF_MEMORY; 652 } 653 else { 654 result = Curl_init_userdefined(&data->set); 655 656 data->state.headersize=HEADERSIZE; 657 658 Curl_convert_init(data); 659 660 /* most recent connection is not yet defined */ 661 data->state.lastconnect = NULL; 662 663 data->progress.flags |= PGRS_HIDE; 664 data->state.current_speed = -1; /* init to negative == impossible */ 665 666 data->wildcard.state = CURLWC_INIT; 667 data->wildcard.filelist = NULL; 668 data->set.fnmatch = ZERO_NULL; 669 data->set.maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */ 670 671 Curl_http2_init_state(&data->state); 672 } 673 674 if(result) { 675 Curl_resolver_cleanup(data->state.resolver); 676 free(data->state.headerbuff); 677 Curl_freeset(data); 678 free(data); 679 data = NULL; 680 } 681 else 682 *curl = data; 683 684 return result; 685} 686 687CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option, 688 va_list param) 689{ 690 char *argptr; 691 CURLcode result = CURLE_OK; 692 long arg; 693#ifndef CURL_DISABLE_HTTP 694 curl_off_t bigsize; 695#endif 696 697 switch(option) { 698 case CURLOPT_DNS_CACHE_TIMEOUT: 699 data->set.dns_cache_timeout = va_arg(param, long); 700 break; 701 case CURLOPT_DNS_USE_GLOBAL_CACHE: 702 /* remember we want this enabled */ 703 arg = va_arg(param, long); 704 data->set.global_dns_cache = (0 != arg) ? TRUE : FALSE; 705 break; 706 case CURLOPT_SSL_CIPHER_LIST: 707 /* set a list of cipher we want to use in the SSL connection */ 708 result = setstropt(&data->set.str[STRING_SSL_CIPHER_LIST], 709 va_arg(param, char *)); 710 break; 711 712 case CURLOPT_RANDOM_FILE: 713 /* 714 * This is the path name to a file that contains random data to seed 715 * the random SSL stuff with. The file is only used for reading. 716 */ 717 result = setstropt(&data->set.str[STRING_SSL_RANDOM_FILE], 718 va_arg(param, char *)); 719 break; 720 case CURLOPT_EGDSOCKET: 721 /* 722 * The Entropy Gathering Daemon socket pathname 723 */ 724 result = setstropt(&data->set.str[STRING_SSL_EGDSOCKET], 725 va_arg(param, char *)); 726 break; 727 case CURLOPT_MAXCONNECTS: 728 /* 729 * Set the absolute number of maximum simultaneous alive connection that 730 * libcurl is allowed to have. 731 */ 732 data->set.maxconnects = va_arg(param, long); 733 break; 734 case CURLOPT_FORBID_REUSE: 735 /* 736 * When this transfer is done, it must not be left to be reused by a 737 * subsequent transfer but shall be closed immediately. 738 */ 739 data->set.reuse_forbid = (0 != va_arg(param, long)) ? TRUE : FALSE; 740 break; 741 case CURLOPT_FRESH_CONNECT: 742 /* 743 * This transfer shall not use a previously cached connection but 744 * should be made with a fresh new connect! 745 */ 746 data->set.reuse_fresh = (0 != va_arg(param, long)) ? TRUE : FALSE; 747 break; 748 case CURLOPT_VERBOSE: 749 /* 750 * Verbose means infof() calls that give a lot of information about 751 * the connection and transfer procedures as well as internal choices. 752 */ 753 data->set.verbose = (0 != va_arg(param, long)) ? TRUE : FALSE; 754 break; 755 case CURLOPT_HEADER: 756 /* 757 * Set to include the header in the general data output stream. 758 */ 759 data->set.include_header = (0 != va_arg(param, long)) ? TRUE : FALSE; 760 break; 761 case CURLOPT_NOPROGRESS: 762 /* 763 * Shut off the internal supported progress meter 764 */ 765 data->set.hide_progress = (0 != va_arg(param, long)) ? TRUE : FALSE; 766 if(data->set.hide_progress) 767 data->progress.flags |= PGRS_HIDE; 768 else 769 data->progress.flags &= ~PGRS_HIDE; 770 break; 771 case CURLOPT_NOBODY: 772 /* 773 * Do not include the body part in the output data stream. 774 */ 775 data->set.opt_no_body = (0 != va_arg(param, long)) ? TRUE : FALSE; 776 break; 777 case CURLOPT_FAILONERROR: 778 /* 779 * Don't output the >=400 error code HTML-page, but instead only 780 * return error. 781 */ 782 data->set.http_fail_on_error = (0 != va_arg(param, long)) ? TRUE : FALSE; 783 break; 784 case CURLOPT_UPLOAD: 785 case CURLOPT_PUT: 786 /* 787 * We want to sent data to the remote host. If this is HTTP, that equals 788 * using the PUT request. 789 */ 790 data->set.upload = (0 != va_arg(param, long)) ? TRUE : FALSE; 791 if(data->set.upload) { 792 /* If this is HTTP, PUT is what's needed to "upload" */ 793 data->set.httpreq = HTTPREQ_PUT; 794 data->set.opt_no_body = FALSE; /* this is implied */ 795 } 796 else 797 /* In HTTP, the opposite of upload is GET (unless NOBODY is true as 798 then this can be changed to HEAD later on) */ 799 data->set.httpreq = HTTPREQ_GET; 800 break; 801 case CURLOPT_FILETIME: 802 /* 803 * Try to get the file time of the remote document. The time will 804 * later (possibly) become available using curl_easy_getinfo(). 805 */ 806 data->set.get_filetime = (0 != va_arg(param, long)) ? TRUE : FALSE; 807 break; 808 case CURLOPT_FTP_CREATE_MISSING_DIRS: 809 /* 810 * An FTP option that modifies an upload to create missing directories on 811 * the server. 812 */ 813 switch(va_arg(param, long)) { 814 case 0: 815 data->set.ftp_create_missing_dirs = 0; 816 break; 817 case 1: 818 data->set.ftp_create_missing_dirs = 1; 819 break; 820 case 2: 821 data->set.ftp_create_missing_dirs = 2; 822 break; 823 default: 824 /* reserve other values for future use */ 825 result = CURLE_UNKNOWN_OPTION; 826 break; 827 } 828 break; 829 case CURLOPT_SERVER_RESPONSE_TIMEOUT: 830 /* 831 * Option that specifies how quickly an server response must be obtained 832 * before it is considered failure. For pingpong protocols. 833 */ 834 data->set.server_response_timeout = va_arg(param, long) * 1000; 835 break; 836 case CURLOPT_TFTP_NO_OPTIONS: 837 /* 838 * Option that prevents libcurl from sending TFTP option requests to the 839 * server. 840 */ 841 data->set.tftp_no_options = va_arg(param, long) != 0; 842 break; 843 case CURLOPT_TFTP_BLKSIZE: 844 /* 845 * TFTP option that specifies the block size to use for data transmission. 846 */ 847 data->set.tftp_blksize = va_arg(param, long); 848 break; 849 case CURLOPT_DIRLISTONLY: 850 /* 851 * An option that changes the command to one that asks for a list 852 * only, no file info details. 853 */ 854 data->set.ftp_list_only = (0 != va_arg(param, long)) ? TRUE : FALSE; 855 break; 856 case CURLOPT_APPEND: 857 /* 858 * We want to upload and append to an existing file. 859 */ 860 data->set.ftp_append = (0 != va_arg(param, long)) ? TRUE : FALSE; 861 break; 862 case CURLOPT_FTP_FILEMETHOD: 863 /* 864 * How do access files over FTP. 865 */ 866 data->set.ftp_filemethod = (curl_ftpfile)va_arg(param, long); 867 break; 868 case CURLOPT_NETRC: 869 /* 870 * Parse the $HOME/.netrc file 871 */ 872 data->set.use_netrc = (enum CURL_NETRC_OPTION)va_arg(param, long); 873 break; 874 case CURLOPT_NETRC_FILE: 875 /* 876 * Use this file instead of the $HOME/.netrc file 877 */ 878 result = setstropt(&data->set.str[STRING_NETRC_FILE], 879 va_arg(param, char *)); 880 break; 881 case CURLOPT_TRANSFERTEXT: 882 /* 883 * This option was previously named 'FTPASCII'. Renamed to work with 884 * more protocols than merely FTP. 885 * 886 * Transfer using ASCII (instead of BINARY). 887 */ 888 data->set.prefer_ascii = (0 != va_arg(param, long)) ? TRUE : FALSE; 889 break; 890 case CURLOPT_TIMECONDITION: 891 /* 892 * Set HTTP time condition. This must be one of the defines in the 893 * curl/curl.h header file. 894 */ 895 data->set.timecondition = (curl_TimeCond)va_arg(param, long); 896 break; 897 case CURLOPT_TIMEVALUE: 898 /* 899 * This is the value to compare with the remote document with the 900 * method set with CURLOPT_TIMECONDITION 901 */ 902 data->set.timevalue = (time_t)va_arg(param, long); 903 break; 904 case CURLOPT_SSLVERSION: 905 /* 906 * Set explicit SSL version to try to connect with, as some SSL 907 * implementations are lame. 908 */ 909#ifdef USE_SSL 910 data->set.ssl.version = va_arg(param, long); 911#else 912 result = CURLE_UNKNOWN_OPTION; 913#endif 914 break; 915 916#ifndef CURL_DISABLE_HTTP 917 case CURLOPT_AUTOREFERER: 918 /* 919 * Switch on automatic referer that gets set if curl follows locations. 920 */ 921 data->set.http_auto_referer = (0 != va_arg(param, long)) ? TRUE : FALSE; 922 break; 923 924 case CURLOPT_ACCEPT_ENCODING: 925 /* 926 * String to use at the value of Accept-Encoding header. 927 * 928 * If the encoding is set to "" we use an Accept-Encoding header that 929 * encompasses all the encodings we support. 930 * If the encoding is set to NULL we don't send an Accept-Encoding header 931 * and ignore an received Content-Encoding header. 932 * 933 */ 934 argptr = va_arg(param, char *); 935 result = setstropt(&data->set.str[STRING_ENCODING], 936 (argptr && !*argptr)? 937 ALL_CONTENT_ENCODINGS: argptr); 938 break; 939 940 case CURLOPT_TRANSFER_ENCODING: 941 data->set.http_transfer_encoding = (0 != va_arg(param, long)) ? 942 TRUE : FALSE; 943 break; 944 945 case CURLOPT_FOLLOWLOCATION: 946 /* 947 * Follow Location: header hints on a HTTP-server. 948 */ 949 data->set.http_follow_location = (0 != va_arg(param, long)) ? TRUE : FALSE; 950 break; 951 952 case CURLOPT_UNRESTRICTED_AUTH: 953 /* 954 * Send authentication (user+password) when following locations, even when 955 * hostname changed. 956 */ 957 data->set.http_disable_hostname_check_before_authentication = 958 (0 != va_arg(param, long)) ? TRUE : FALSE; 959 break; 960 961 case CURLOPT_MAXREDIRS: 962 /* 963 * The maximum amount of hops you allow curl to follow Location: 964 * headers. This should mostly be used to detect never-ending loops. 965 */ 966 data->set.maxredirs = va_arg(param, long); 967 break; 968 969 case CURLOPT_POSTREDIR: 970 { 971 /* 972 * Set the behaviour of POST when redirecting 973 * CURL_REDIR_GET_ALL - POST is changed to GET after 301 and 302 974 * CURL_REDIR_POST_301 - POST is kept as POST after 301 975 * CURL_REDIR_POST_302 - POST is kept as POST after 302 976 * CURL_REDIR_POST_303 - POST is kept as POST after 303 977 * CURL_REDIR_POST_ALL - POST is kept as POST after 301, 302 and 303 978 * other - POST is kept as POST after 301 and 302 979 */ 980 int postRedir = curlx_sltosi(va_arg(param, long)); 981 data->set.keep_post = postRedir & CURL_REDIR_POST_ALL; 982 } 983 break; 984 985 case CURLOPT_POST: 986 /* Does this option serve a purpose anymore? Yes it does, when 987 CURLOPT_POSTFIELDS isn't used and the POST data is read off the 988 callback! */ 989 if(va_arg(param, long)) { 990 data->set.httpreq = HTTPREQ_POST; 991 data->set.opt_no_body = FALSE; /* this is implied */ 992 } 993 else 994 data->set.httpreq = HTTPREQ_GET; 995 break; 996 997 case CURLOPT_COPYPOSTFIELDS: 998 /* 999 * A string with POST data. Makes curl HTTP POST. Even if it is NULL. 1000 * If needed, CURLOPT_POSTFIELDSIZE must have been set prior to 1001 * CURLOPT_COPYPOSTFIELDS and not altered later. 1002 */ 1003 argptr = va_arg(param, char *); 1004 1005 if(!argptr || data->set.postfieldsize == -1) 1006 result = setstropt(&data->set.str[STRING_COPYPOSTFIELDS], argptr); 1007 else { 1008 /* 1009 * Check that requested length does not overflow the size_t type. 1010 */ 1011 1012 if((data->set.postfieldsize < 0) || 1013 ((sizeof(curl_off_t) != sizeof(size_t)) && 1014 (data->set.postfieldsize > (curl_off_t)((size_t)-1)))) 1015 result = CURLE_OUT_OF_MEMORY; 1016 else { 1017 char * p; 1018 1019 (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL); 1020 1021 /* Allocate even when size == 0. This satisfies the need of possible 1022 later address compare to detect the COPYPOSTFIELDS mode, and 1023 to mark that postfields is used rather than read function or 1024 form data. 1025 */ 1026 p = malloc((size_t)(data->set.postfieldsize? 1027 data->set.postfieldsize:1)); 1028 1029 if(!p) 1030 result = CURLE_OUT_OF_MEMORY; 1031 else { 1032 if(data->set.postfieldsize) 1033 memcpy(p, argptr, (size_t)data->set.postfieldsize); 1034 1035 data->set.str[STRING_COPYPOSTFIELDS] = p; 1036 } 1037 } 1038 } 1039 1040 data->set.postfields = data->set.str[STRING_COPYPOSTFIELDS]; 1041 data->set.httpreq = HTTPREQ_POST; 1042 break; 1043 1044 case CURLOPT_POSTFIELDS: 1045 /* 1046 * Like above, but use static data instead of copying it. 1047 */ 1048 data->set.postfields = va_arg(param, void *); 1049 /* Release old copied data. */ 1050 (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL); 1051 data->set.httpreq = HTTPREQ_POST; 1052 break; 1053 1054 case CURLOPT_POSTFIELDSIZE: 1055 /* 1056 * The size of the POSTFIELD data to prevent libcurl to do strlen() to 1057 * figure it out. Enables binary posts. 1058 */ 1059 bigsize = va_arg(param, long); 1060 1061 if(data->set.postfieldsize < bigsize && 1062 data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) { 1063 /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */ 1064 (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL); 1065 data->set.postfields = NULL; 1066 } 1067 1068 data->set.postfieldsize = bigsize; 1069 break; 1070 1071 case CURLOPT_POSTFIELDSIZE_LARGE: 1072 /* 1073 * The size of the POSTFIELD data to prevent libcurl to do strlen() to 1074 * figure it out. Enables binary posts. 1075 */ 1076 bigsize = va_arg(param, curl_off_t); 1077 1078 if(data->set.postfieldsize < bigsize && 1079 data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) { 1080 /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */ 1081 (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL); 1082 data->set.postfields = NULL; 1083 } 1084 1085 data->set.postfieldsize = bigsize; 1086 break; 1087 1088 case CURLOPT_HTTPPOST: 1089 /* 1090 * Set to make us do HTTP POST 1091 */ 1092 data->set.httppost = va_arg(param, struct curl_httppost *); 1093 data->set.httpreq = HTTPREQ_POST_FORM; 1094 data->set.opt_no_body = FALSE; /* this is implied */ 1095 break; 1096 1097 case CURLOPT_REFERER: 1098 /* 1099 * String to set in the HTTP Referer: field. 1100 */ 1101 if(data->change.referer_alloc) { 1102 Curl_safefree(data->change.referer); 1103 data->change.referer_alloc = FALSE; 1104 } 1105 result = setstropt(&data->set.str[STRING_SET_REFERER], 1106 va_arg(param, char *)); 1107 data->change.referer = data->set.str[STRING_SET_REFERER]; 1108 break; 1109 1110 case CURLOPT_USERAGENT: 1111 /* 1112 * String to use in the HTTP User-Agent field 1113 */ 1114 result = setstropt(&data->set.str[STRING_USERAGENT], 1115 va_arg(param, char *)); 1116 break; 1117 1118 case CURLOPT_HTTPHEADER: 1119 /* 1120 * Set a list with HTTP headers to use (or replace internals with) 1121 */ 1122 data->set.headers = va_arg(param, struct curl_slist *); 1123 break; 1124 1125 case CURLOPT_PROXYHEADER: 1126 /* 1127 * Set a list with proxy headers to use (or replace internals with) 1128 * 1129 * Since CURLOPT_HTTPHEADER was the only way to set HTTP headers for a 1130 * long time we remain doing it this way until CURLOPT_PROXYHEADER is 1131 * used. As soon as this option has been used, if set to anything but 1132 * NULL, custom headers for proxies are only picked from this list. 1133 * 1134 * Set this option to NULL to restore the previous behavior. 1135 */ 1136 data->set.proxyheaders = va_arg(param, struct curl_slist *); 1137 break; 1138 1139 case CURLOPT_HEADEROPT: 1140 /* 1141 * Set header option. 1142 */ 1143 arg = va_arg(param, long); 1144 data->set.sep_headers = (arg & CURLHEADER_SEPARATE)? TRUE: FALSE; 1145 break; 1146 1147 case CURLOPT_HTTP200ALIASES: 1148 /* 1149 * Set a list of aliases for HTTP 200 in response header 1150 */ 1151 data->set.http200aliases = va_arg(param, struct curl_slist *); 1152 break; 1153 1154#if !defined(CURL_DISABLE_COOKIES) 1155 case CURLOPT_COOKIE: 1156 /* 1157 * Cookie string to send to the remote server in the request. 1158 */ 1159 result = setstropt(&data->set.str[STRING_COOKIE], 1160 va_arg(param, char *)); 1161 break; 1162 1163 case CURLOPT_COOKIEFILE: 1164 /* 1165 * Set cookie file to read and parse. Can be used multiple times. 1166 */ 1167 argptr = (char *)va_arg(param, void *); 1168 if(argptr) { 1169 struct curl_slist *cl; 1170 /* append the cookie file name to the list of file names, and deal with 1171 them later */ 1172 cl = curl_slist_append(data->change.cookielist, argptr); 1173 if(!cl) { 1174 curl_slist_free_all(data->change.cookielist); 1175 data->change.cookielist = NULL; 1176 return CURLE_OUT_OF_MEMORY; 1177 } 1178 data->change.cookielist = cl; /* store the list for later use */ 1179 } 1180 break; 1181 1182 case CURLOPT_COOKIEJAR: 1183 /* 1184 * Set cookie file name to dump all cookies to when we're done. 1185 */ 1186 { 1187 struct CookieInfo *newcookies; 1188 result = setstropt(&data->set.str[STRING_COOKIEJAR], 1189 va_arg(param, char *)); 1190 1191 /* 1192 * Activate the cookie parser. This may or may not already 1193 * have been made. 1194 */ 1195 newcookies = Curl_cookie_init(data, NULL, data->cookies, 1196 data->set.cookiesession); 1197 if(!newcookies) 1198 result = CURLE_OUT_OF_MEMORY; 1199 data->cookies = newcookies; 1200 } 1201 break; 1202 1203 case CURLOPT_COOKIESESSION: 1204 /* 1205 * Set this option to TRUE to start a new "cookie session". It will 1206 * prevent the forthcoming read-cookies-from-file actions to accept 1207 * cookies that are marked as being session cookies, as they belong to a 1208 * previous session. 1209 * 1210 * In the original Netscape cookie spec, "session cookies" are cookies 1211 * with no expire date set. RFC2109 describes the same action if no 1212 * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds 1213 * a 'Discard' action that can enforce the discard even for cookies that 1214 * have a Max-Age. 1215 * 1216 * We run mostly with the original cookie spec, as hardly anyone implements 1217 * anything else. 1218 */ 1219 data->set.cookiesession = (0 != va_arg(param, long)) ? TRUE : FALSE; 1220 break; 1221 1222 case CURLOPT_COOKIELIST: 1223 argptr = va_arg(param, char *); 1224 1225 if(argptr == NULL) 1226 break; 1227 1228 if(Curl_raw_equal(argptr, "ALL")) { 1229 /* clear all cookies */ 1230 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); 1231 Curl_cookie_clearall(data->cookies); 1232 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); 1233 } 1234 else if(Curl_raw_equal(argptr, "SESS")) { 1235 /* clear session cookies */ 1236 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); 1237 Curl_cookie_clearsess(data->cookies); 1238 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); 1239 } 1240 else if(Curl_raw_equal(argptr, "FLUSH")) { 1241 /* flush cookies to file, takes care of the locking */ 1242 Curl_flush_cookies(data, 0); 1243 } 1244 else if(Curl_raw_equal(argptr, "RELOAD")) { 1245 /* reload cookies from file */ 1246 Curl_cookie_loadfiles(data); 1247 break; 1248 } 1249 else { 1250 if(!data->cookies) 1251 /* if cookie engine was not running, activate it */ 1252 data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE); 1253 1254 argptr = strdup(argptr); 1255 if(!argptr || !data->cookies) { 1256 result = CURLE_OUT_OF_MEMORY; 1257 free(argptr); 1258 } 1259 else { 1260 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); 1261 1262 if(checkprefix("Set-Cookie:", argptr)) 1263 /* HTTP Header format line */ 1264 Curl_cookie_add(data, data->cookies, TRUE, argptr + 11, NULL, NULL); 1265 1266 else 1267 /* Netscape format line */ 1268 Curl_cookie_add(data, data->cookies, FALSE, argptr, NULL, NULL); 1269 1270 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); 1271 free(argptr); 1272 } 1273 } 1274 1275 break; 1276#endif /* CURL_DISABLE_COOKIES */ 1277 1278 case CURLOPT_HTTPGET: 1279 /* 1280 * Set to force us do HTTP GET 1281 */ 1282 if(va_arg(param, long)) { 1283 data->set.httpreq = HTTPREQ_GET; 1284 data->set.upload = FALSE; /* switch off upload */ 1285 data->set.opt_no_body = FALSE; /* this is implied */ 1286 } 1287 break; 1288 1289 case CURLOPT_HTTP_VERSION: 1290 /* 1291 * This sets a requested HTTP version to be used. The value is one of 1292 * the listed enums in curl/curl.h. 1293 */ 1294 arg = va_arg(param, long); 1295#ifndef USE_NGHTTP2 1296 if(arg >= CURL_HTTP_VERSION_2) 1297 return CURLE_UNSUPPORTED_PROTOCOL; 1298#endif 1299 data->set.httpversion = arg; 1300 break; 1301 1302 case CURLOPT_HTTPAUTH: 1303 /* 1304 * Set HTTP Authentication type BITMASK. 1305 */ 1306 { 1307 int bitcheck; 1308 bool authbits; 1309 unsigned long auth = va_arg(param, unsigned long); 1310 1311 if(auth == CURLAUTH_NONE) { 1312 data->set.httpauth = auth; 1313 break; 1314 } 1315 1316 /* the DIGEST_IE bit is only used to set a special marker, for all the 1317 rest we need to handle it as normal DIGEST */ 1318 data->state.authhost.iestyle = (auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE; 1319 1320 if(auth & CURLAUTH_DIGEST_IE) { 1321 auth |= CURLAUTH_DIGEST; /* set standard digest bit */ 1322 auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */ 1323 } 1324 1325 /* switch off bits we can't support */ 1326#ifndef USE_NTLM 1327 auth &= ~CURLAUTH_NTLM; /* no NTLM support */ 1328 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */ 1329#elif !defined(NTLM_WB_ENABLED) 1330 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */ 1331#endif 1332#ifndef USE_SPNEGO 1333 auth &= ~CURLAUTH_NEGOTIATE; /* no Negotiate (SPNEGO) auth without 1334 GSS-API or SSPI */ 1335#endif 1336 1337 /* check if any auth bit lower than CURLAUTH_ONLY is still set */ 1338 bitcheck = 0; 1339 authbits = FALSE; 1340 while(bitcheck < 31) { 1341 if(auth & (1UL << bitcheck++)) { 1342 authbits = TRUE; 1343 break; 1344 } 1345 } 1346 if(!authbits) 1347 return CURLE_NOT_BUILT_IN; /* no supported types left! */ 1348 1349 data->set.httpauth = auth; 1350 } 1351 break; 1352 1353 case CURLOPT_EXPECT_100_TIMEOUT_MS: 1354 /* 1355 * Time to wait for a response to a HTTP request containing an 1356 * Expect: 100-continue header before sending the data anyway. 1357 */ 1358 data->set.expect_100_timeout = va_arg(param, long); 1359 break; 1360 1361#endif /* CURL_DISABLE_HTTP */ 1362 1363 case CURLOPT_CUSTOMREQUEST: 1364 /* 1365 * Set a custom string to use as request 1366 */ 1367 result = setstropt(&data->set.str[STRING_CUSTOMREQUEST], 1368 va_arg(param, char *)); 1369 1370 /* we don't set 1371 data->set.httpreq = HTTPREQ_CUSTOM; 1372 here, we continue as if we were using the already set type 1373 and this just changes the actual request keyword */ 1374 break; 1375 1376#ifndef CURL_DISABLE_PROXY 1377 case CURLOPT_HTTPPROXYTUNNEL: 1378 /* 1379 * Tunnel operations through the proxy instead of normal proxy use 1380 */ 1381 data->set.tunnel_thru_httpproxy = (0 != va_arg(param, long)) ? 1382 TRUE : FALSE; 1383 break; 1384 1385 case CURLOPT_PROXYPORT: 1386 /* 1387 * Explicitly set HTTP proxy port number. 1388 */ 1389 data->set.proxyport = va_arg(param, long); 1390 break; 1391 1392 case CURLOPT_PROXYAUTH: 1393 /* 1394 * Set HTTP Authentication type BITMASK. 1395 */ 1396 { 1397 int bitcheck; 1398 bool authbits; 1399 unsigned long auth = va_arg(param, unsigned long); 1400 1401 if(auth == CURLAUTH_NONE) { 1402 data->set.proxyauth = auth; 1403 break; 1404 } 1405 1406 /* the DIGEST_IE bit is only used to set a special marker, for all the 1407 rest we need to handle it as normal DIGEST */ 1408 data->state.authproxy.iestyle = (auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE; 1409 1410 if(auth & CURLAUTH_DIGEST_IE) { 1411 auth |= CURLAUTH_DIGEST; /* set standard digest bit */ 1412 auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */ 1413 } 1414 /* switch off bits we can't support */ 1415#ifndef USE_NTLM 1416 auth &= ~CURLAUTH_NTLM; /* no NTLM support */ 1417 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */ 1418#elif !defined(NTLM_WB_ENABLED) 1419 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */ 1420#endif 1421#ifndef USE_SPNEGO 1422 auth &= ~CURLAUTH_NEGOTIATE; /* no Negotiate (SPNEGO) auth without 1423 GSS-API or SSPI */ 1424#endif 1425 1426 /* check if any auth bit lower than CURLAUTH_ONLY is still set */ 1427 bitcheck = 0; 1428 authbits = FALSE; 1429 while(bitcheck < 31) { 1430 if(auth & (1UL << bitcheck++)) { 1431 authbits = TRUE; 1432 break; 1433 } 1434 } 1435 if(!authbits) 1436 return CURLE_NOT_BUILT_IN; /* no supported types left! */ 1437 1438 data->set.proxyauth = auth; 1439 } 1440 break; 1441 1442 case CURLOPT_PROXY: 1443 /* 1444 * Set proxy server:port to use as HTTP proxy. 1445 * 1446 * If the proxy is set to "" we explicitly say that we don't want to use a 1447 * proxy (even though there might be environment variables saying so). 1448 * 1449 * Setting it to NULL, means no proxy but allows the environment variables 1450 * to decide for us. 1451 */ 1452 result = setstropt(&data->set.str[STRING_PROXY], 1453 va_arg(param, char *)); 1454 break; 1455 1456 case CURLOPT_PROXYTYPE: 1457 /* 1458 * Set proxy type. HTTP/HTTP_1_0/SOCKS4/SOCKS4a/SOCKS5/SOCKS5_HOSTNAME 1459 */ 1460 data->set.proxytype = (curl_proxytype)va_arg(param, long); 1461 break; 1462 1463 case CURLOPT_PROXY_TRANSFER_MODE: 1464 /* 1465 * set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy 1466 */ 1467 switch (va_arg(param, long)) { 1468 case 0: 1469 data->set.proxy_transfer_mode = FALSE; 1470 break; 1471 case 1: 1472 data->set.proxy_transfer_mode = TRUE; 1473 break; 1474 default: 1475 /* reserve other values for future use */ 1476 result = CURLE_UNKNOWN_OPTION; 1477 break; 1478 } 1479 break; 1480#endif /* CURL_DISABLE_PROXY */ 1481 1482#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) 1483 case CURLOPT_SOCKS5_GSSAPI_NEC: 1484 /* 1485 * Set flag for NEC SOCK5 support 1486 */ 1487 data->set.socks5_gssapi_nec = (0 != va_arg(param, long)) ? TRUE : FALSE; 1488 break; 1489 1490 case CURLOPT_SOCKS5_GSSAPI_SERVICE: 1491 case CURLOPT_PROXY_SERVICE_NAME: 1492 /* 1493 * Set proxy authentication service name for Kerberos 5 and SPNEGO 1494 */ 1495 result = setstropt(&data->set.str[STRING_PROXY_SERVICE_NAME], 1496 va_arg(param, char *)); 1497 break; 1498#endif 1499 1500#if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) || \ 1501 defined(USE_SPNEGO) 1502 case CURLOPT_SERVICE_NAME: 1503 /* 1504 * Set authentication service name for DIGEST-MD5, Kerberos 5 and SPNEGO 1505 */ 1506 result = setstropt(&data->set.str[STRING_SERVICE_NAME], 1507 va_arg(param, char *)); 1508 break; 1509 1510#endif 1511 1512 case CURLOPT_HEADERDATA: 1513 /* 1514 * Custom pointer to pass the header write callback function 1515 */ 1516 data->set.writeheader = (void *)va_arg(param, void *); 1517 break; 1518 case CURLOPT_ERRORBUFFER: 1519 /* 1520 * Error buffer provided by the caller to get the human readable 1521 * error string in. 1522 */ 1523 data->set.errorbuffer = va_arg(param, char *); 1524 break; 1525 case CURLOPT_WRITEDATA: 1526 /* 1527 * FILE pointer to write to. Or possibly 1528 * used as argument to the write callback. 1529 */ 1530 data->set.out = va_arg(param, void *); 1531 break; 1532 case CURLOPT_FTPPORT: 1533 /* 1534 * Use FTP PORT, this also specifies which IP address to use 1535 */ 1536 result = setstropt(&data->set.str[STRING_FTPPORT], 1537 va_arg(param, char *)); 1538 data->set.ftp_use_port = (data->set.str[STRING_FTPPORT]) ? TRUE : FALSE; 1539 break; 1540 1541 case CURLOPT_FTP_USE_EPRT: 1542 data->set.ftp_use_eprt = (0 != va_arg(param, long)) ? TRUE : FALSE; 1543 break; 1544 1545 case CURLOPT_FTP_USE_EPSV: 1546 data->set.ftp_use_epsv = (0 != va_arg(param, long)) ? TRUE : FALSE; 1547 break; 1548 1549 case CURLOPT_FTP_USE_PRET: 1550 data->set.ftp_use_pret = (0 != va_arg(param, long)) ? TRUE : FALSE; 1551 break; 1552 1553 case CURLOPT_FTP_SSL_CCC: 1554 data->set.ftp_ccc = (curl_ftpccc)va_arg(param, long); 1555 break; 1556 1557 case CURLOPT_FTP_SKIP_PASV_IP: 1558 /* 1559 * Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the 1560 * bypass of the IP address in PASV responses. 1561 */ 1562 data->set.ftp_skip_ip = (0 != va_arg(param, long)) ? TRUE : FALSE; 1563 break; 1564 1565 case CURLOPT_READDATA: 1566 /* 1567 * FILE pointer to read the file to be uploaded from. Or possibly 1568 * used as argument to the read callback. 1569 */ 1570 data->set.in_set = va_arg(param, void *); 1571 break; 1572 case CURLOPT_INFILESIZE: 1573 /* 1574 * If known, this should inform curl about the file size of the 1575 * to-be-uploaded file. 1576 */ 1577 data->set.filesize = va_arg(param, long); 1578 break; 1579 case CURLOPT_INFILESIZE_LARGE: 1580 /* 1581 * If known, this should inform curl about the file size of the 1582 * to-be-uploaded file. 1583 */ 1584 data->set.filesize = va_arg(param, curl_off_t); 1585 break; 1586 case CURLOPT_LOW_SPEED_LIMIT: 1587 /* 1588 * The low speed limit that if transfers are below this for 1589 * CURLOPT_LOW_SPEED_TIME, the transfer is aborted. 1590 */ 1591 data->set.low_speed_limit=va_arg(param, long); 1592 break; 1593 case CURLOPT_MAX_SEND_SPEED_LARGE: 1594 /* 1595 * When transfer uploads are faster then CURLOPT_MAX_SEND_SPEED_LARGE 1596 * bytes per second the transfer is throttled.. 1597 */ 1598 data->set.max_send_speed=va_arg(param, curl_off_t); 1599 break; 1600 case CURLOPT_MAX_RECV_SPEED_LARGE: 1601 /* 1602 * When receiving data faster than CURLOPT_MAX_RECV_SPEED_LARGE bytes per 1603 * second the transfer is throttled.. 1604 */ 1605 data->set.max_recv_speed=va_arg(param, curl_off_t); 1606 break; 1607 case CURLOPT_LOW_SPEED_TIME: 1608 /* 1609 * The low speed time that if transfers are below the set 1610 * CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted. 1611 */ 1612 data->set.low_speed_time=va_arg(param, long); 1613 break; 1614 case CURLOPT_URL: 1615 /* 1616 * The URL to fetch. 1617 */ 1618 if(data->change.url_alloc) { 1619 /* the already set URL is allocated, free it first! */ 1620 Curl_safefree(data->change.url); 1621 data->change.url_alloc = FALSE; 1622 } 1623 result = setstropt(&data->set.str[STRING_SET_URL], 1624 va_arg(param, char *)); 1625 data->change.url = data->set.str[STRING_SET_URL]; 1626 break; 1627 case CURLOPT_PORT: 1628 /* 1629 * The port number to use when getting the URL 1630 */ 1631 data->set.use_port = va_arg(param, long); 1632 break; 1633 case CURLOPT_TIMEOUT: 1634 /* 1635 * The maximum time you allow curl to use for a single transfer 1636 * operation. 1637 */ 1638 data->set.timeout = va_arg(param, long) * 1000L; 1639 break; 1640 1641 case CURLOPT_TIMEOUT_MS: 1642 data->set.timeout = va_arg(param, long); 1643 break; 1644 1645 case CURLOPT_CONNECTTIMEOUT: 1646 /* 1647 * The maximum time you allow curl to use to connect. 1648 */ 1649 data->set.connecttimeout = va_arg(param, long) * 1000L; 1650 break; 1651 1652 case CURLOPT_CONNECTTIMEOUT_MS: 1653 data->set.connecttimeout = va_arg(param, long); 1654 break; 1655 1656 case CURLOPT_ACCEPTTIMEOUT_MS: 1657 /* 1658 * The maximum time you allow curl to wait for server connect 1659 */ 1660 data->set.accepttimeout = va_arg(param, long); 1661 break; 1662 1663 case CURLOPT_USERPWD: 1664 /* 1665 * user:password to use in the operation 1666 */ 1667 result = setstropt_userpwd(va_arg(param, char *), 1668 &data->set.str[STRING_USERNAME], 1669 &data->set.str[STRING_PASSWORD]); 1670 break; 1671 1672 case CURLOPT_USERNAME: 1673 /* 1674 * authentication user name to use in the operation 1675 */ 1676 result = setstropt(&data->set.str[STRING_USERNAME], 1677 va_arg(param, char *)); 1678 break; 1679 1680 case CURLOPT_PASSWORD: 1681 /* 1682 * authentication password to use in the operation 1683 */ 1684 result = setstropt(&data->set.str[STRING_PASSWORD], 1685 va_arg(param, char *)); 1686 break; 1687 1688 case CURLOPT_LOGIN_OPTIONS: 1689 /* 1690 * authentication options to use in the operation 1691 */ 1692 result = setstropt(&data->set.str[STRING_OPTIONS], 1693 va_arg(param, char *)); 1694 break; 1695 1696 case CURLOPT_XOAUTH2_BEARER: 1697 /* 1698 * OAuth 2.0 bearer token to use in the operation 1699 */ 1700 result = setstropt(&data->set.str[STRING_BEARER], 1701 va_arg(param, char *)); 1702 break; 1703 1704 case CURLOPT_POSTQUOTE: 1705 /* 1706 * List of RAW FTP commands to use after a transfer 1707 */ 1708 data->set.postquote = va_arg(param, struct curl_slist *); 1709 break; 1710 case CURLOPT_PREQUOTE: 1711 /* 1712 * List of RAW FTP commands to use prior to RETR (Wesley Laxton) 1713 */ 1714 data->set.prequote = va_arg(param, struct curl_slist *); 1715 break; 1716 case CURLOPT_QUOTE: 1717 /* 1718 * List of RAW FTP commands to use before a transfer 1719 */ 1720 data->set.quote = va_arg(param, struct curl_slist *); 1721 break; 1722 case CURLOPT_RESOLVE: 1723 /* 1724 * List of NAME:[address] names to populate the DNS cache with 1725 * Prefix the NAME with dash (-) to _remove_ the name from the cache. 1726 * 1727 * Names added with this API will remain in the cache until explicitly 1728 * removed or the handle is cleaned up. 1729 * 1730 * This API can remove any name from the DNS cache, but only entries 1731 * that aren't actually in use right now will be pruned immediately. 1732 */ 1733 data->set.resolve = va_arg(param, struct curl_slist *); 1734 data->change.resolve = data->set.resolve; 1735 break; 1736 case CURLOPT_PROGRESSFUNCTION: 1737 /* 1738 * Progress callback function 1739 */ 1740 data->set.fprogress = va_arg(param, curl_progress_callback); 1741 if(data->set.fprogress) 1742 data->progress.callback = TRUE; /* no longer internal */ 1743 else 1744 data->progress.callback = FALSE; /* NULL enforces internal */ 1745 break; 1746 1747 case CURLOPT_XFERINFOFUNCTION: 1748 /* 1749 * Transfer info callback function 1750 */ 1751 data->set.fxferinfo = va_arg(param, curl_xferinfo_callback); 1752 if(data->set.fxferinfo) 1753 data->progress.callback = TRUE; /* no longer internal */ 1754 else 1755 data->progress.callback = FALSE; /* NULL enforces internal */ 1756 1757 break; 1758 1759 case CURLOPT_PROGRESSDATA: 1760 /* 1761 * Custom client data to pass to the progress callback 1762 */ 1763 data->set.progress_client = va_arg(param, void *); 1764 break; 1765 1766#ifndef CURL_DISABLE_PROXY 1767 case CURLOPT_PROXYUSERPWD: 1768 /* 1769 * user:password needed to use the proxy 1770 */ 1771 result = setstropt_userpwd(va_arg(param, char *), 1772 &data->set.str[STRING_PROXYUSERNAME], 1773 &data->set.str[STRING_PROXYPASSWORD]); 1774 break; 1775 case CURLOPT_PROXYUSERNAME: 1776 /* 1777 * authentication user name to use in the operation 1778 */ 1779 result = setstropt(&data->set.str[STRING_PROXYUSERNAME], 1780 va_arg(param, char *)); 1781 break; 1782 case CURLOPT_PROXYPASSWORD: 1783 /* 1784 * authentication password to use in the operation 1785 */ 1786 result = setstropt(&data->set.str[STRING_PROXYPASSWORD], 1787 va_arg(param, char *)); 1788 break; 1789 case CURLOPT_NOPROXY: 1790 /* 1791 * proxy exception list 1792 */ 1793 result = setstropt(&data->set.str[STRING_NOPROXY], 1794 va_arg(param, char *)); 1795 break; 1796#endif 1797 1798 case CURLOPT_RANGE: 1799 /* 1800 * What range of the file you want to transfer 1801 */ 1802 result = setstropt(&data->set.str[STRING_SET_RANGE], 1803 va_arg(param, char *)); 1804 break; 1805 case CURLOPT_RESUME_FROM: 1806 /* 1807 * Resume transfer at the give file position 1808 */ 1809 data->set.set_resume_from = va_arg(param, long); 1810 break; 1811 case CURLOPT_RESUME_FROM_LARGE: 1812 /* 1813 * Resume transfer at the give file position 1814 */ 1815 data->set.set_resume_from = va_arg(param, curl_off_t); 1816 break; 1817 case CURLOPT_DEBUGFUNCTION: 1818 /* 1819 * stderr write callback. 1820 */ 1821 data->set.fdebug = va_arg(param, curl_debug_callback); 1822 /* 1823 * if the callback provided is NULL, it'll use the default callback 1824 */ 1825 break; 1826 case CURLOPT_DEBUGDATA: 1827 /* 1828 * Set to a void * that should receive all error writes. This 1829 * defaults to CURLOPT_STDERR for normal operations. 1830 */ 1831 data->set.debugdata = va_arg(param, void *); 1832 break; 1833 case CURLOPT_STDERR: 1834 /* 1835 * Set to a FILE * that should receive all error writes. This 1836 * defaults to stderr for normal operations. 1837 */ 1838 data->set.err = va_arg(param, FILE *); 1839 if(!data->set.err) 1840 data->set.err = stderr; 1841 break; 1842 case CURLOPT_HEADERFUNCTION: 1843 /* 1844 * Set header write callback 1845 */ 1846 data->set.fwrite_header = va_arg(param, curl_write_callback); 1847 break; 1848 case CURLOPT_WRITEFUNCTION: 1849 /* 1850 * Set data write callback 1851 */ 1852 data->set.fwrite_func = va_arg(param, curl_write_callback); 1853 if(!data->set.fwrite_func) { 1854 data->set.is_fwrite_set = 0; 1855 /* When set to NULL, reset to our internal default function */ 1856 data->set.fwrite_func = (curl_write_callback)fwrite; 1857 } 1858 else 1859 data->set.is_fwrite_set = 1; 1860 break; 1861 case CURLOPT_READFUNCTION: 1862 /* 1863 * Read data callback 1864 */ 1865 data->set.fread_func_set = va_arg(param, curl_read_callback); 1866 if(!data->set.fread_func_set) { 1867 data->set.is_fread_set = 0; 1868 /* When set to NULL, reset to our internal default function */ 1869 data->set.fread_func_set = (curl_read_callback)fread; 1870 } 1871 else 1872 data->set.is_fread_set = 1; 1873 break; 1874 case CURLOPT_SEEKFUNCTION: 1875 /* 1876 * Seek callback. Might be NULL. 1877 */ 1878 data->set.seek_func = va_arg(param, curl_seek_callback); 1879 break; 1880 case CURLOPT_SEEKDATA: 1881 /* 1882 * Seek control callback. Might be NULL. 1883 */ 1884 data->set.seek_client = va_arg(param, void *); 1885 break; 1886 case CURLOPT_CONV_FROM_NETWORK_FUNCTION: 1887 /* 1888 * "Convert from network encoding" callback 1889 */ 1890 data->set.convfromnetwork = va_arg(param, curl_conv_callback); 1891 break; 1892 case CURLOPT_CONV_TO_NETWORK_FUNCTION: 1893 /* 1894 * "Convert to network encoding" callback 1895 */ 1896 data->set.convtonetwork = va_arg(param, curl_conv_callback); 1897 break; 1898 case CURLOPT_CONV_FROM_UTF8_FUNCTION: 1899 /* 1900 * "Convert from UTF-8 encoding" callback 1901 */ 1902 data->set.convfromutf8 = va_arg(param, curl_conv_callback); 1903 break; 1904 case CURLOPT_IOCTLFUNCTION: 1905 /* 1906 * I/O control callback. Might be NULL. 1907 */ 1908 data->set.ioctl_func = va_arg(param, curl_ioctl_callback); 1909 break; 1910 case CURLOPT_IOCTLDATA: 1911 /* 1912 * I/O control data pointer. Might be NULL. 1913 */ 1914 data->set.ioctl_client = va_arg(param, void *); 1915 break; 1916 case CURLOPT_SSLCERT: 1917 /* 1918 * String that holds file name of the SSL certificate to use 1919 */ 1920 result = setstropt(&data->set.str[STRING_CERT], 1921 va_arg(param, char *)); 1922 break; 1923 case CURLOPT_SSLCERTTYPE: 1924 /* 1925 * String that holds file type of the SSL certificate to use 1926 */ 1927 result = setstropt(&data->set.str[STRING_CERT_TYPE], 1928 va_arg(param, char *)); 1929 break; 1930 case CURLOPT_SSLKEY: 1931 /* 1932 * String that holds file name of the SSL key to use 1933 */ 1934 result = setstropt(&data->set.str[STRING_KEY], 1935 va_arg(param, char *)); 1936 break; 1937 case CURLOPT_SSLKEYTYPE: 1938 /* 1939 * String that holds file type of the SSL key to use 1940 */ 1941 result = setstropt(&data->set.str[STRING_KEY_TYPE], 1942 va_arg(param, char *)); 1943 break; 1944 case CURLOPT_KEYPASSWD: 1945 /* 1946 * String that holds the SSL or SSH private key password. 1947 */ 1948 result = setstropt(&data->set.str[STRING_KEY_PASSWD], 1949 va_arg(param, char *)); 1950 break; 1951 case CURLOPT_SSLENGINE: 1952 /* 1953 * String that holds the SSL crypto engine. 1954 */ 1955 argptr = va_arg(param, char *); 1956 if(argptr && argptr[0]) 1957 result = Curl_ssl_set_engine(data, argptr); 1958 break; 1959 1960 case CURLOPT_SSLENGINE_DEFAULT: 1961 /* 1962 * flag to set engine as default. 1963 */ 1964 result = Curl_ssl_set_engine_default(data); 1965 break; 1966 case CURLOPT_CRLF: 1967 /* 1968 * Kludgy option to enable CRLF conversions. Subject for removal. 1969 */ 1970 data->set.crlf = (0 != va_arg(param, long)) ? TRUE : FALSE; 1971 break; 1972 1973 case CURLOPT_INTERFACE: 1974 /* 1975 * Set what interface or address/hostname to bind the socket to when 1976 * performing an operation and thus what from-IP your connection will use. 1977 */ 1978 result = setstropt(&data->set.str[STRING_DEVICE], 1979 va_arg(param, char *)); 1980 break; 1981 case CURLOPT_LOCALPORT: 1982 /* 1983 * Set what local port to bind the socket to when performing an operation. 1984 */ 1985 data->set.localport = curlx_sltous(va_arg(param, long)); 1986 break; 1987 case CURLOPT_LOCALPORTRANGE: 1988 /* 1989 * Set number of local ports to try, starting with CURLOPT_LOCALPORT. 1990 */ 1991 data->set.localportrange = curlx_sltosi(va_arg(param, long)); 1992 break; 1993 case CURLOPT_KRBLEVEL: 1994 /* 1995 * A string that defines the kerberos security level. 1996 */ 1997 result = setstropt(&data->set.str[STRING_KRB_LEVEL], 1998 va_arg(param, char *)); 1999 data->set.krb = (data->set.str[STRING_KRB_LEVEL]) ? TRUE : FALSE; 2000 break; 2001 case CURLOPT_GSSAPI_DELEGATION: 2002 /* 2003 * GSS-API credential delegation 2004 */ 2005 data->set.gssapi_delegation = va_arg(param, long); 2006 break; 2007 case CURLOPT_SSL_VERIFYPEER: 2008 /* 2009 * Enable peer SSL verifying. 2010 */ 2011 data->set.ssl.verifypeer = (0 != va_arg(param, long)) ? TRUE : FALSE; 2012 break; 2013 case CURLOPT_SSL_VERIFYHOST: 2014 /* 2015 * Enable verification of the host name in the peer certificate 2016 */ 2017 arg = va_arg(param, long); 2018 2019 /* Obviously people are not reading documentation and too many thought 2020 this argument took a boolean when it wasn't and misused it. We thus ban 2021 1 as a sensible input and we warn about its use. Then we only have the 2022 2 action internally stored as TRUE. */ 2023 2024 if(1 == arg) { 2025 failf(data, "CURLOPT_SSL_VERIFYHOST no longer supports 1 as value!"); 2026 return CURLE_BAD_FUNCTION_ARGUMENT; 2027 } 2028 2029 data->set.ssl.verifyhost = (0 != arg) ? TRUE : FALSE; 2030 break; 2031 case CURLOPT_SSL_VERIFYSTATUS: 2032 /* 2033 * Enable certificate status verifying. 2034 */ 2035 if(!Curl_ssl_cert_status_request()) { 2036 result = CURLE_NOT_BUILT_IN; 2037 break; 2038 } 2039 2040 data->set.ssl.verifystatus = (0 != va_arg(param, long)) ? TRUE : FALSE; 2041 break; 2042 case CURLOPT_SSL_CTX_FUNCTION: 2043#ifdef have_curlssl_ssl_ctx 2044 /* 2045 * Set a SSL_CTX callback 2046 */ 2047 data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback); 2048#else 2049 result = CURLE_NOT_BUILT_IN; 2050#endif 2051 break; 2052 case CURLOPT_SSL_CTX_DATA: 2053#ifdef have_curlssl_ssl_ctx 2054 /* 2055 * Set a SSL_CTX callback parameter pointer 2056 */ 2057 data->set.ssl.fsslctxp = va_arg(param, void *); 2058#else 2059 result = CURLE_NOT_BUILT_IN; 2060#endif 2061 break; 2062 case CURLOPT_SSL_FALSESTART: 2063 /* 2064 * Enable TLS false start. 2065 */ 2066 if(!Curl_ssl_false_start()) { 2067 result = CURLE_NOT_BUILT_IN; 2068 break; 2069 } 2070 2071 data->set.ssl.falsestart = (0 != va_arg(param, long)) ? TRUE : FALSE; 2072 break; 2073 case CURLOPT_CERTINFO: 2074#ifdef have_curlssl_certinfo 2075 data->set.ssl.certinfo = (0 != va_arg(param, long)) ? TRUE : FALSE; 2076#else 2077 result = CURLE_NOT_BUILT_IN; 2078#endif 2079 break; 2080 case CURLOPT_PINNEDPUBLICKEY: 2081#ifdef have_curlssl_pinnedpubkey /* only by supported backends */ 2082 /* 2083 * Set pinned public key for SSL connection. 2084 * Specify file name of the public key in DER format. 2085 */ 2086 result = setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY], 2087 va_arg(param, char *)); 2088#else 2089 result = CURLE_NOT_BUILT_IN; 2090#endif 2091 break; 2092 case CURLOPT_CAINFO: 2093 /* 2094 * Set CA info for SSL connection. Specify file name of the CA certificate 2095 */ 2096 result = setstropt(&data->set.str[STRING_SSL_CAFILE], 2097 va_arg(param, char *)); 2098 break; 2099 case CURLOPT_CAPATH: 2100#ifdef have_curlssl_ca_path /* not supported by all backends */ 2101 /* 2102 * Set CA path info for SSL connection. Specify directory name of the CA 2103 * certificates which have been prepared using openssl c_rehash utility. 2104 */ 2105 /* This does not work on windows. */ 2106 result = setstropt(&data->set.str[STRING_SSL_CAPATH], 2107 va_arg(param, char *)); 2108#else 2109 result = CURLE_NOT_BUILT_IN; 2110#endif 2111 break; 2112 case CURLOPT_CRLFILE: 2113 /* 2114 * Set CRL file info for SSL connection. Specify file name of the CRL 2115 * to check certificates revocation 2116 */ 2117 result = setstropt(&data->set.str[STRING_SSL_CRLFILE], 2118 va_arg(param, char *)); 2119 break; 2120 case CURLOPT_ISSUERCERT: 2121 /* 2122 * Set Issuer certificate file 2123 * to check certificates issuer 2124 */ 2125 result = setstropt(&data->set.str[STRING_SSL_ISSUERCERT], 2126 va_arg(param, char *)); 2127 break; 2128 case CURLOPT_TELNETOPTIONS: 2129 /* 2130 * Set a linked list of telnet options 2131 */ 2132 data->set.telnet_options = va_arg(param, struct curl_slist *); 2133 break; 2134 2135 case CURLOPT_BUFFERSIZE: 2136 /* 2137 * The application kindly asks for a differently sized receive buffer. 2138 * If it seems reasonable, we'll use it. 2139 */ 2140 data->set.buffer_size = va_arg(param, long); 2141 2142 if((data->set.buffer_size> (BUFSIZE -1)) || 2143 (data->set.buffer_size < 1)) 2144 data->set.buffer_size = 0; /* huge internal default */ 2145 2146 break; 2147 2148 case CURLOPT_NOSIGNAL: 2149 /* 2150 * The application asks not to set any signal() or alarm() handlers, 2151 * even when using a timeout. 2152 */ 2153 data->set.no_signal = (0 != va_arg(param, long)) ? TRUE : FALSE; 2154 break; 2155 2156 case CURLOPT_SHARE: 2157 { 2158 struct Curl_share *set; 2159 set = va_arg(param, struct Curl_share *); 2160 2161 /* disconnect from old share, if any */ 2162 if(data->share) { 2163 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); 2164 2165 if(data->dns.hostcachetype == HCACHE_SHARED) { 2166 data->dns.hostcache = NULL; 2167 data->dns.hostcachetype = HCACHE_NONE; 2168 } 2169 2170#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) 2171 if(data->share->cookies == data->cookies) 2172 data->cookies = NULL; 2173#endif 2174 2175 if(data->share->sslsession == data->state.session) 2176 data->state.session = NULL; 2177 2178 data->share->dirty--; 2179 2180 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); 2181 data->share = NULL; 2182 } 2183 2184 /* use new share if it set */ 2185 data->share = set; 2186 if(data->share) { 2187 2188 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); 2189 2190 data->share->dirty++; 2191 2192 if(data->share->specifier & (1<< CURL_LOCK_DATA_DNS)) { 2193 /* use shared host cache */ 2194 data->dns.hostcache = &data->share->hostcache; 2195 data->dns.hostcachetype = HCACHE_SHARED; 2196 } 2197#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) 2198 if(data->share->cookies) { 2199 /* use shared cookie list, first free own one if any */ 2200 Curl_cookie_cleanup(data->cookies); 2201 /* enable cookies since we now use a share that uses cookies! */ 2202 data->cookies = data->share->cookies; 2203 } 2204#endif /* CURL_DISABLE_HTTP */ 2205 if(data->share->sslsession) { 2206 data->set.ssl.max_ssl_sessions = data->share->max_ssl_sessions; 2207 data->state.session = data->share->sslsession; 2208 } 2209 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); 2210 2211 } 2212 /* check for host cache not needed, 2213 * it will be done by curl_easy_perform */ 2214 } 2215 break; 2216 2217 case CURLOPT_PRIVATE: 2218 /* 2219 * Set private data pointer. 2220 */ 2221 data->set.private_data = va_arg(param, void *); 2222 break; 2223 2224 case CURLOPT_MAXFILESIZE: 2225 /* 2226 * Set the maximum size of a file to download. 2227 */ 2228 data->set.max_filesize = va_arg(param, long); 2229 break; 2230 2231#ifdef USE_SSL 2232 case CURLOPT_USE_SSL: 2233 /* 2234 * Make transfers attempt to use SSL/TLS. 2235 */ 2236 data->set.use_ssl = (curl_usessl)va_arg(param, long); 2237 break; 2238 2239 case CURLOPT_SSL_OPTIONS: 2240 arg = va_arg(param, long); 2241 data->set.ssl_enable_beast = !!(arg & CURLSSLOPT_ALLOW_BEAST); 2242 data->set.ssl_no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE); 2243 break; 2244 2245#endif 2246 case CURLOPT_FTPSSLAUTH: 2247 /* 2248 * Set a specific auth for FTP-SSL transfers. 2249 */ 2250 data->set.ftpsslauth = (curl_ftpauth)va_arg(param, long); 2251 break; 2252 2253 case CURLOPT_IPRESOLVE: 2254 data->set.ipver = va_arg(param, long); 2255 break; 2256 2257 case CURLOPT_MAXFILESIZE_LARGE: 2258 /* 2259 * Set the maximum size of a file to download. 2260 */ 2261 data->set.max_filesize = va_arg(param, curl_off_t); 2262 break; 2263 2264 case CURLOPT_TCP_NODELAY: 2265 /* 2266 * Enable or disable TCP_NODELAY, which will disable/enable the Nagle 2267 * algorithm 2268 */ 2269 data->set.tcp_nodelay = (0 != va_arg(param, long)) ? TRUE : FALSE; 2270 break; 2271 2272 case CURLOPT_FTP_ACCOUNT: 2273 result = setstropt(&data->set.str[STRING_FTP_ACCOUNT], 2274 va_arg(param, char *)); 2275 break; 2276 2277 case CURLOPT_IGNORE_CONTENT_LENGTH: 2278 data->set.ignorecl = (0 != va_arg(param, long)) ? TRUE : FALSE; 2279 break; 2280 2281 case CURLOPT_CONNECT_ONLY: 2282 /* 2283 * No data transfer, set up connection and let application use the socket 2284 */ 2285 data->set.connect_only = (0 != va_arg(param, long)) ? TRUE : FALSE; 2286 break; 2287 2288 case CURLOPT_FTP_ALTERNATIVE_TO_USER: 2289 result = setstropt(&data->set.str[STRING_FTP_ALTERNATIVE_TO_USER], 2290 va_arg(param, char *)); 2291 break; 2292 2293 case CURLOPT_SOCKOPTFUNCTION: 2294 /* 2295 * socket callback function: called after socket() but before connect() 2296 */ 2297 data->set.fsockopt = va_arg(param, curl_sockopt_callback); 2298 break; 2299 2300 case CURLOPT_SOCKOPTDATA: 2301 /* 2302 * socket callback data pointer. Might be NULL. 2303 */ 2304 data->set.sockopt_client = va_arg(param, void *); 2305 break; 2306 2307 case CURLOPT_OPENSOCKETFUNCTION: 2308 /* 2309 * open/create socket callback function: called instead of socket(), 2310 * before connect() 2311 */ 2312 data->set.fopensocket = va_arg(param, curl_opensocket_callback); 2313 break; 2314 2315 case CURLOPT_OPENSOCKETDATA: 2316 /* 2317 * socket callback data pointer. Might be NULL. 2318 */ 2319 data->set.opensocket_client = va_arg(param, void *); 2320 break; 2321 2322 case CURLOPT_CLOSESOCKETFUNCTION: 2323 /* 2324 * close socket callback function: called instead of close() 2325 * when shutting down a connection 2326 */ 2327 data->set.fclosesocket = va_arg(param, curl_closesocket_callback); 2328 break; 2329 2330 case CURLOPT_CLOSESOCKETDATA: 2331 /* 2332 * socket callback data pointer. Might be NULL. 2333 */ 2334 data->set.closesocket_client = va_arg(param, void *); 2335 break; 2336 2337 case CURLOPT_SSL_SESSIONID_CACHE: 2338 data->set.ssl.sessionid = (0 != va_arg(param, long)) ? TRUE : FALSE; 2339 break; 2340 2341#ifdef USE_LIBSSH2 2342 /* we only include SSH options if explicitly built to support SSH */ 2343 case CURLOPT_SSH_AUTH_TYPES: 2344 data->set.ssh_auth_types = va_arg(param, long); 2345 break; 2346 2347 case CURLOPT_SSH_PUBLIC_KEYFILE: 2348 /* 2349 * Use this file instead of the $HOME/.ssh/id_dsa.pub file 2350 */ 2351 result = setstropt(&data->set.str[STRING_SSH_PUBLIC_KEY], 2352 va_arg(param, char *)); 2353 break; 2354 2355 case CURLOPT_SSH_PRIVATE_KEYFILE: 2356 /* 2357 * Use this file instead of the $HOME/.ssh/id_dsa file 2358 */ 2359 result = setstropt(&data->set.str[STRING_SSH_PRIVATE_KEY], 2360 va_arg(param, char *)); 2361 break; 2362 case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5: 2363 /* 2364 * Option to allow for the MD5 of the host public key to be checked 2365 * for validation purposes. 2366 */ 2367 result = setstropt(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5], 2368 va_arg(param, char *)); 2369 break; 2370#ifdef HAVE_LIBSSH2_KNOWNHOST_API 2371 case CURLOPT_SSH_KNOWNHOSTS: 2372 /* 2373 * Store the file name to read known hosts from. 2374 */ 2375 result = setstropt(&data->set.str[STRING_SSH_KNOWNHOSTS], 2376 va_arg(param, char *)); 2377 break; 2378 2379 case CURLOPT_SSH_KEYFUNCTION: 2380 /* setting to NULL is fine since the ssh.c functions themselves will 2381 then rever to use the internal default */ 2382 data->set.ssh_keyfunc = va_arg(param, curl_sshkeycallback); 2383 break; 2384 2385 case CURLOPT_SSH_KEYDATA: 2386 /* 2387 * Custom client data to pass to the SSH keyfunc callback 2388 */ 2389 data->set.ssh_keyfunc_userp = va_arg(param, void *); 2390 break; 2391#endif /* HAVE_LIBSSH2_KNOWNHOST_API */ 2392 2393#endif /* USE_LIBSSH2 */ 2394 2395 case CURLOPT_HTTP_TRANSFER_DECODING: 2396 /* 2397 * disable libcurl transfer encoding is used 2398 */ 2399 data->set.http_te_skip = (0 == va_arg(param, long)) ? TRUE : FALSE; 2400 break; 2401 2402 case CURLOPT_HTTP_CONTENT_DECODING: 2403 /* 2404 * raw data passed to the application when content encoding is used 2405 */ 2406 data->set.http_ce_skip = (0 == va_arg(param, long)) ? TRUE : FALSE; 2407 break; 2408 2409 case CURLOPT_NEW_FILE_PERMS: 2410 /* 2411 * Uses these permissions instead of 0644 2412 */ 2413 data->set.new_file_perms = va_arg(param, long); 2414 break; 2415 2416 case CURLOPT_NEW_DIRECTORY_PERMS: 2417 /* 2418 * Uses these permissions instead of 0755 2419 */ 2420 data->set.new_directory_perms = va_arg(param, long); 2421 break; 2422 2423 case CURLOPT_ADDRESS_SCOPE: 2424 /* 2425 * We always get longs when passed plain numericals, but for this value we 2426 * know that an unsigned int will always hold the value so we blindly 2427 * typecast to this type 2428 */ 2429 data->set.scope_id = curlx_sltoui(va_arg(param, long)); 2430 break; 2431 2432 case CURLOPT_PROTOCOLS: 2433 /* set the bitmask for the protocols that are allowed to be used for the 2434 transfer, which thus helps the app which takes URLs from users or other 2435 external inputs and want to restrict what protocol(s) to deal 2436 with. Defaults to CURLPROTO_ALL. */ 2437 data->set.allowed_protocols = va_arg(param, long); 2438 break; 2439 2440 case CURLOPT_REDIR_PROTOCOLS: 2441 /* set the bitmask for the protocols that libcurl is allowed to follow to, 2442 as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs 2443 to be set in both bitmasks to be allowed to get redirected to. Defaults 2444 to all protocols except FILE and SCP. */ 2445 data->set.redir_protocols = va_arg(param, long); 2446 break; 2447 2448 case CURLOPT_DEFAULT_PROTOCOL: 2449 /* Set the protocol to use when the URL doesn't include any protocol */ 2450 result = setstropt(&data->set.str[STRING_DEFAULT_PROTOCOL], 2451 va_arg(param, char *)); 2452 break; 2453 2454 case CURLOPT_MAIL_FROM: 2455 /* Set the SMTP mail originator */ 2456 result = setstropt(&data->set.str[STRING_MAIL_FROM], 2457 va_arg(param, char *)); 2458 break; 2459 2460 case CURLOPT_MAIL_AUTH: 2461 /* Set the SMTP auth originator */ 2462 result = setstropt(&data->set.str[STRING_MAIL_AUTH], 2463 va_arg(param, char *)); 2464 break; 2465 2466 case CURLOPT_MAIL_RCPT: 2467 /* Set the list of mail recipients */ 2468 data->set.mail_rcpt = va_arg(param, struct curl_slist *); 2469 break; 2470 2471 case CURLOPT_SASL_IR: 2472 /* Enable/disable SASL initial response */ 2473 data->set.sasl_ir = (0 != va_arg(param, long)) ? TRUE : FALSE; 2474 break; 2475 2476 case CURLOPT_RTSP_REQUEST: 2477 { 2478 /* 2479 * Set the RTSP request method (OPTIONS, SETUP, PLAY, etc...) 2480 * Would this be better if the RTSPREQ_* were just moved into here? 2481 */ 2482 long curl_rtspreq = va_arg(param, long); 2483 Curl_RtspReq rtspreq = RTSPREQ_NONE; 2484 switch(curl_rtspreq) { 2485 case CURL_RTSPREQ_OPTIONS: 2486 rtspreq = RTSPREQ_OPTIONS; 2487 break; 2488 2489 case CURL_RTSPREQ_DESCRIBE: 2490 rtspreq = RTSPREQ_DESCRIBE; 2491 break; 2492 2493 case CURL_RTSPREQ_ANNOUNCE: 2494 rtspreq = RTSPREQ_ANNOUNCE; 2495 break; 2496 2497 case CURL_RTSPREQ_SETUP: 2498 rtspreq = RTSPREQ_SETUP; 2499 break; 2500 2501 case CURL_RTSPREQ_PLAY: 2502 rtspreq = RTSPREQ_PLAY; 2503 break; 2504 2505 case CURL_RTSPREQ_PAUSE: 2506 rtspreq = RTSPREQ_PAUSE; 2507 break; 2508 2509 case CURL_RTSPREQ_TEARDOWN: 2510 rtspreq = RTSPREQ_TEARDOWN; 2511 break; 2512 2513 case CURL_RTSPREQ_GET_PARAMETER: 2514 rtspreq = RTSPREQ_GET_PARAMETER; 2515 break; 2516 2517 case CURL_RTSPREQ_SET_PARAMETER: 2518 rtspreq = RTSPREQ_SET_PARAMETER; 2519 break; 2520 2521 case CURL_RTSPREQ_RECORD: 2522 rtspreq = RTSPREQ_RECORD; 2523 break; 2524 2525 case CURL_RTSPREQ_RECEIVE: 2526 rtspreq = RTSPREQ_RECEIVE; 2527 break; 2528 default: 2529 rtspreq = RTSPREQ_NONE; 2530 } 2531 2532 data->set.rtspreq = rtspreq; 2533 break; 2534 } 2535 2536 2537 case CURLOPT_RTSP_SESSION_ID: 2538 /* 2539 * Set the RTSP Session ID manually. Useful if the application is 2540 * resuming a previously established RTSP session 2541 */ 2542 result = setstropt(&data->set.str[STRING_RTSP_SESSION_ID], 2543 va_arg(param, char *)); 2544 break; 2545 2546 case CURLOPT_RTSP_STREAM_URI: 2547 /* 2548 * Set the Stream URI for the RTSP request. Unless the request is 2549 * for generic server options, the application will need to set this. 2550 */ 2551 result = setstropt(&data->set.str[STRING_RTSP_STREAM_URI], 2552 va_arg(param, char *)); 2553 break; 2554 2555 case CURLOPT_RTSP_TRANSPORT: 2556 /* 2557 * The content of the Transport: header for the RTSP request 2558 */ 2559 result = setstropt(&data->set.str[STRING_RTSP_TRANSPORT], 2560 va_arg(param, char *)); 2561 break; 2562 2563 case CURLOPT_RTSP_CLIENT_CSEQ: 2564 /* 2565 * Set the CSEQ number to issue for the next RTSP request. Useful if the 2566 * application is resuming a previously broken connection. The CSEQ 2567 * will increment from this new number henceforth. 2568 */ 2569 data->state.rtsp_next_client_CSeq = va_arg(param, long); 2570 break; 2571 2572 case CURLOPT_RTSP_SERVER_CSEQ: 2573 /* Same as the above, but for server-initiated requests */ 2574 data->state.rtsp_next_client_CSeq = va_arg(param, long); 2575 break; 2576 2577 case CURLOPT_INTERLEAVEDATA: 2578 data->set.rtp_out = va_arg(param, void *); 2579 break; 2580 case CURLOPT_INTERLEAVEFUNCTION: 2581 /* Set the user defined RTP write function */ 2582 data->set.fwrite_rtp = va_arg(param, curl_write_callback); 2583 break; 2584 2585 case CURLOPT_WILDCARDMATCH: 2586 data->set.wildcardmatch = (0 != va_arg(param, long)) ? TRUE : FALSE; 2587 break; 2588 case CURLOPT_CHUNK_BGN_FUNCTION: 2589 data->set.chunk_bgn = va_arg(param, curl_chunk_bgn_callback); 2590 break; 2591 case CURLOPT_CHUNK_END_FUNCTION: 2592 data->set.chunk_end = va_arg(param, curl_chunk_end_callback); 2593 break; 2594 case CURLOPT_FNMATCH_FUNCTION: 2595 data->set.fnmatch = va_arg(param, curl_fnmatch_callback); 2596 break; 2597 case CURLOPT_CHUNK_DATA: 2598 data->wildcard.customptr = va_arg(param, void *); 2599 break; 2600 case CURLOPT_FNMATCH_DATA: 2601 data->set.fnmatch_data = va_arg(param, void *); 2602 break; 2603#ifdef USE_TLS_SRP 2604 case CURLOPT_TLSAUTH_USERNAME: 2605 result = setstropt(&data->set.str[STRING_TLSAUTH_USERNAME], 2606 va_arg(param, char *)); 2607 if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype) 2608 data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */ 2609 break; 2610 case CURLOPT_TLSAUTH_PASSWORD: 2611 result = setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD], 2612 va_arg(param, char *)); 2613 if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype) 2614 data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */ 2615 break; 2616 case CURLOPT_TLSAUTH_TYPE: 2617 if(strnequal((char *)va_arg(param, char *), "SRP", strlen("SRP"))) 2618 data->set.ssl.authtype = CURL_TLSAUTH_SRP; 2619 else 2620 data->set.ssl.authtype = CURL_TLSAUTH_NONE; 2621 break; 2622#endif 2623 case CURLOPT_DNS_SERVERS: 2624 result = Curl_set_dns_servers(data, va_arg(param, char *)); 2625 break; 2626 case CURLOPT_DNS_INTERFACE: 2627 result = Curl_set_dns_interface(data, va_arg(param, char *)); 2628 break; 2629 case CURLOPT_DNS_LOCAL_IP4: 2630 result = Curl_set_dns_local_ip4(data, va_arg(param, char *)); 2631 break; 2632 case CURLOPT_DNS_LOCAL_IP6: 2633 result = Curl_set_dns_local_ip6(data, va_arg(param, char *)); 2634 break; 2635 2636 case CURLOPT_TCP_KEEPALIVE: 2637 data->set.tcp_keepalive = (0 != va_arg(param, long)) ? TRUE : FALSE; 2638 break; 2639 case CURLOPT_TCP_KEEPIDLE: 2640 data->set.tcp_keepidle = va_arg(param, long); 2641 break; 2642 case CURLOPT_TCP_KEEPINTVL: 2643 data->set.tcp_keepintvl = va_arg(param, long); 2644 break; 2645 case CURLOPT_TCP_FASTOPEN: 2646#if defined(CONNECT_DATA_IDEMPOTENT) || defined(MSG_FASTOPEN) 2647 data->set.tcp_fastopen = (0 != va_arg(param, long))?TRUE:FALSE; 2648#else 2649 result = CURLE_NOT_BUILT_IN; 2650#endif 2651 break; 2652 case CURLOPT_SSL_ENABLE_NPN: 2653 data->set.ssl_enable_npn = (0 != va_arg(param, long)) ? TRUE : FALSE; 2654 break; 2655 case CURLOPT_SSL_ENABLE_ALPN: 2656 data->set.ssl_enable_alpn = (0 != va_arg(param, long)) ? TRUE : FALSE; 2657 break; 2658 2659#ifdef USE_UNIX_SOCKETS 2660 case CURLOPT_UNIX_SOCKET_PATH: 2661 result = setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH], 2662 va_arg(param, char *)); 2663 break; 2664#endif 2665 2666 case CURLOPT_PATH_AS_IS: 2667 data->set.path_as_is = (0 != va_arg(param, long)) ? TRUE : FALSE; 2668 break; 2669 case CURLOPT_PIPEWAIT: 2670 data->set.pipewait = (0 != va_arg(param, long)) ? TRUE : FALSE; 2671 break; 2672 case CURLOPT_STREAM_WEIGHT: 2673#ifndef USE_NGHTTP2 2674 return CURLE_NOT_BUILT_IN; 2675#else 2676 arg = va_arg(param, long); 2677 if((arg>=1) && (arg <= 256)) 2678 data->set.stream_weight = (int)arg; 2679 break; 2680#endif 2681 case CURLOPT_STREAM_DEPENDS: 2682 case CURLOPT_STREAM_DEPENDS_E: 2683 { 2684#ifndef USE_NGHTTP2 2685 return CURLE_NOT_BUILT_IN; 2686#else 2687 struct Curl_easy *dep = va_arg(param, struct Curl_easy *); 2688 if(dep && GOOD_EASY_HANDLE(dep)) { 2689 data->set.stream_depends_on = dep; 2690 data->set.stream_depends_e = (option == CURLOPT_STREAM_DEPENDS_E); 2691 } 2692 break; 2693#endif 2694 } 2695 case CURLOPT_CONNECT_TO: 2696 data->set.connect_to = va_arg(param, struct curl_slist *); 2697 break; 2698 default: 2699 /* unknown tag and its companion, just ignore: */ 2700 result = CURLE_UNKNOWN_OPTION; 2701 break; 2702 } 2703 2704 return result; 2705} 2706 2707#ifdef USE_RECV_BEFORE_SEND_WORKAROUND 2708static void conn_reset_postponed_data(struct connectdata *conn, int num) 2709{ 2710 struct postponed_data * const psnd = &(conn->postponed[num]); 2711 if(psnd->buffer) { 2712 DEBUGASSERT(psnd->allocated_size > 0); 2713 DEBUGASSERT(psnd->recv_size <= psnd->allocated_size); 2714 DEBUGASSERT(psnd->recv_size ? 2715 (psnd->recv_processed < psnd->recv_size) : 2716 (psnd->recv_processed == 0)); 2717 DEBUGASSERT(psnd->bindsock != CURL_SOCKET_BAD); 2718 free(psnd->buffer); 2719 psnd->buffer = NULL; 2720 psnd->allocated_size = 0; 2721 psnd->recv_size = 0; 2722 psnd->recv_processed = 0; 2723#ifdef DEBUGBUILD 2724 psnd->bindsock = CURL_SOCKET_BAD; /* used only for DEBUGASSERT */ 2725#endif /* DEBUGBUILD */ 2726 } 2727 else { 2728 DEBUGASSERT (psnd->allocated_size == 0); 2729 DEBUGASSERT (psnd->recv_size == 0); 2730 DEBUGASSERT (psnd->recv_processed == 0); 2731 DEBUGASSERT (psnd->bindsock == CURL_SOCKET_BAD); 2732 } 2733} 2734 2735static void conn_reset_all_postponed_data(struct connectdata *conn) 2736{ 2737 conn_reset_postponed_data(conn, 0); 2738 conn_reset_postponed_data(conn, 1); 2739} 2740#else /* ! USE_RECV_BEFORE_SEND_WORKAROUND */ 2741/* Use "do-nothing" macros instead of functions when workaround not used */ 2742#define conn_reset_postponed_data(c,n) do {} WHILE_FALSE 2743#define conn_reset_all_postponed_data(c) do {} WHILE_FALSE 2744#endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */ 2745 2746static void conn_free(struct connectdata *conn) 2747{ 2748 if(!conn) 2749 return; 2750 2751 /* possible left-overs from the async name resolvers */ 2752 Curl_resolver_cancel(conn); 2753 2754 /* close the SSL stuff before we close any sockets since they will/may 2755 write to the sockets */ 2756 Curl_ssl_close(conn, FIRSTSOCKET); 2757 Curl_ssl_close(conn, SECONDARYSOCKET); 2758 2759 /* close possibly still open sockets */ 2760 if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET]) 2761 Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]); 2762 if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET]) 2763 Curl_closesocket(conn, conn->sock[FIRSTSOCKET]); 2764 if(CURL_SOCKET_BAD != conn->tempsock[0]) 2765 Curl_closesocket(conn, conn->tempsock[0]); 2766 if(CURL_SOCKET_BAD != conn->tempsock[1]) 2767 Curl_closesocket(conn, conn->tempsock[1]); 2768 2769#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \ 2770 defined(NTLM_WB_ENABLED) 2771 Curl_ntlm_wb_cleanup(conn); 2772#endif 2773 2774 Curl_safefree(conn->user); 2775 Curl_safefree(conn->passwd); 2776 Curl_safefree(conn->oauth_bearer); 2777 Curl_safefree(conn->options); 2778 Curl_safefree(conn->proxyuser); 2779 Curl_safefree(conn->proxypasswd); 2780 Curl_safefree(conn->allocptr.proxyuserpwd); 2781 Curl_safefree(conn->allocptr.uagent); 2782 Curl_safefree(conn->allocptr.userpwd); 2783 Curl_safefree(conn->allocptr.accept_encoding); 2784 Curl_safefree(conn->allocptr.te); 2785 Curl_safefree(conn->allocptr.rangeline); 2786 Curl_safefree(conn->allocptr.ref); 2787 Curl_safefree(conn->allocptr.host); 2788 Curl_safefree(conn->allocptr.cookiehost); 2789 Curl_safefree(conn->allocptr.rtsp_transport); 2790 Curl_safefree(conn->trailer); 2791 Curl_safefree(conn->host.rawalloc); /* host name buffer */ 2792 Curl_safefree(conn->conn_to_host.rawalloc); /* host name buffer */ 2793 Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */ 2794 Curl_safefree(conn->master_buffer); 2795 2796 conn_reset_all_postponed_data(conn); 2797 2798 Curl_llist_destroy(conn->send_pipe, NULL); 2799 Curl_llist_destroy(conn->recv_pipe, NULL); 2800 2801 conn->send_pipe = NULL; 2802 conn->recv_pipe = NULL; 2803 2804 Curl_safefree(conn->localdev); 2805 Curl_free_ssl_config(&conn->ssl_config); 2806 2807 free(conn); /* free all the connection oriented data */ 2808} 2809 2810/* 2811 * Disconnects the given connection. Note the connection may not be the 2812 * primary connection, like when freeing room in the connection cache or 2813 * killing of a dead old connection. 2814 * 2815 * This function MUST NOT reset state in the Curl_easy struct if that 2816 * isn't strictly bound to the life-time of *this* particular connection. 2817 * 2818 */ 2819 2820CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection) 2821{ 2822 struct Curl_easy *data; 2823 if(!conn) 2824 return CURLE_OK; /* this is closed and fine already */ 2825 data = conn->data; 2826 2827 if(!data) { 2828 DEBUGF(fprintf(stderr, "DISCONNECT without easy handle, ignoring\n")); 2829 return CURLE_OK; 2830 } 2831 2832 if(conn->dns_entry != NULL) { 2833 Curl_resolv_unlock(data, conn->dns_entry); 2834 conn->dns_entry = NULL; 2835 } 2836 2837 Curl_hostcache_prune(data); /* kill old DNS cache entries */ 2838 2839#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) 2840 /* Cleanup NTLM connection-related data */ 2841 Curl_http_ntlm_cleanup(conn); 2842#endif 2843 2844 if(conn->handler->disconnect) 2845 /* This is set if protocol-specific cleanups should be made */ 2846 conn->handler->disconnect(conn, dead_connection); 2847 2848 /* unlink ourselves! */ 2849 infof(data, "Closing connection %ld\n", conn->connection_id); 2850 Curl_conncache_remove_conn(data->state.conn_cache, conn); 2851 2852 free_fixed_hostname(&conn->host); 2853 free_fixed_hostname(&conn->conn_to_host); 2854 free_fixed_hostname(&conn->proxy); 2855 2856 Curl_ssl_close(conn, FIRSTSOCKET); 2857 2858 /* Indicate to all handles on the pipe that we're dead */ 2859 if(Curl_pipeline_wanted(data->multi, CURLPIPE_ANY)) { 2860 signalPipeClose(conn->send_pipe, TRUE); 2861 signalPipeClose(conn->recv_pipe, TRUE); 2862 } 2863 2864 conn_free(conn); 2865 2866 return CURLE_OK; 2867} 2868 2869/* 2870 * This function should return TRUE if the socket is to be assumed to 2871 * be dead. Most commonly this happens when the server has closed the 2872 * connection due to inactivity. 2873 */ 2874static bool SocketIsDead(curl_socket_t sock) 2875{ 2876 int sval; 2877 bool ret_val = TRUE; 2878 2879 sval = Curl_socket_ready(sock, CURL_SOCKET_BAD, 0); 2880 if(sval == 0) 2881 /* timeout */ 2882 ret_val = FALSE; 2883 2884 return ret_val; 2885} 2886 2887/* 2888 * IsPipeliningPossible() returns TRUE if the options set would allow 2889 * pipelining/multiplexing and the connection is using a HTTP protocol. 2890 */ 2891static bool IsPipeliningPossible(const struct Curl_easy *handle, 2892 const struct connectdata *conn) 2893{ 2894 /* If a HTTP protocol and pipelining is enabled */ 2895 if(conn->handler->protocol & PROTO_FAMILY_HTTP) { 2896 2897 if(Curl_pipeline_wanted(handle->multi, CURLPIPE_HTTP1) && 2898 (handle->set.httpversion != CURL_HTTP_VERSION_1_0) && 2899 (handle->set.httpreq == HTTPREQ_GET || 2900 handle->set.httpreq == HTTPREQ_HEAD)) 2901 /* didn't ask for HTTP/1.0 and a GET or HEAD */ 2902 return TRUE; 2903 2904 if(Curl_pipeline_wanted(handle->multi, CURLPIPE_MULTIPLEX) && 2905 (handle->set.httpversion >= CURL_HTTP_VERSION_2)) 2906 /* allows HTTP/2 */ 2907 return TRUE; 2908 } 2909 return FALSE; 2910} 2911 2912int Curl_removeHandleFromPipeline(struct Curl_easy *handle, 2913 struct curl_llist *pipeline) 2914{ 2915 if(pipeline) { 2916 struct curl_llist_element *curr; 2917 2918 curr = pipeline->head; 2919 while(curr) { 2920 if(curr->ptr == handle) { 2921 Curl_llist_remove(pipeline, curr, NULL); 2922 return 1; /* we removed a handle */ 2923 } 2924 curr = curr->next; 2925 } 2926 } 2927 2928 return 0; 2929} 2930 2931#if 0 /* this code is saved here as it is useful for debugging purposes */ 2932static void Curl_printPipeline(struct curl_llist *pipeline) 2933{ 2934 struct curl_llist_element *curr; 2935 2936 curr = pipeline->head; 2937 while(curr) { 2938 struct Curl_easy *data = (struct Curl_easy *) curr->ptr; 2939 infof(data, "Handle in pipeline: %s\n", data->state.path); 2940 curr = curr->next; 2941 } 2942} 2943#endif 2944 2945static struct Curl_easy* gethandleathead(struct curl_llist *pipeline) 2946{ 2947 struct curl_llist_element *curr = pipeline->head; 2948 if(curr) { 2949 return (struct Curl_easy *) curr->ptr; 2950 } 2951 2952 return NULL; 2953} 2954 2955/* remove the specified connection from all (possible) pipelines and related 2956 queues */ 2957void Curl_getoff_all_pipelines(struct Curl_easy *data, 2958 struct connectdata *conn) 2959{ 2960 bool recv_head = (conn->readchannel_inuse && 2961 Curl_recvpipe_head(data, conn)); 2962 bool send_head = (conn->writechannel_inuse && 2963 Curl_sendpipe_head(data, conn)); 2964 2965 if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) && recv_head) 2966 Curl_pipeline_leave_read(conn); 2967 if(Curl_removeHandleFromPipeline(data, conn->send_pipe) && send_head) 2968 Curl_pipeline_leave_write(conn); 2969} 2970 2971static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke) 2972{ 2973 struct curl_llist_element *curr; 2974 2975 if(!pipeline) 2976 return; 2977 2978 curr = pipeline->head; 2979 while(curr) { 2980 struct curl_llist_element *next = curr->next; 2981 struct Curl_easy *data = (struct Curl_easy *) curr->ptr; 2982 2983#ifdef DEBUGBUILD /* debug-only code */ 2984 if(data->magic != CURLEASY_MAGIC_NUMBER) { 2985 /* MAJOR BADNESS */ 2986 infof(data, "signalPipeClose() found BAAD easy handle\n"); 2987 } 2988#endif 2989 2990 if(pipe_broke) 2991 data->state.pipe_broke = TRUE; 2992 Curl_multi_handlePipeBreak(data); 2993 Curl_llist_remove(pipeline, curr, NULL); 2994 curr = next; 2995 } 2996} 2997 2998/* 2999 * This function finds the connection in the connection 3000 * cache that has been unused for the longest time. 3001 * 3002 * Returns the pointer to the oldest idle connection, or NULL if none was 3003 * found. 3004 */ 3005struct connectdata * 3006Curl_oldest_idle_connection(struct Curl_easy *data) 3007{ 3008 struct conncache *bc = data->state.conn_cache; 3009 struct curl_hash_iterator iter; 3010 struct curl_llist_element *curr; 3011 struct curl_hash_element *he; 3012 long highscore=-1; 3013 long score; 3014 struct timeval now; 3015 struct connectdata *conn_candidate = NULL; 3016 struct connectbundle *bundle; 3017 3018 now = Curl_tvnow(); 3019 3020 Curl_hash_start_iterate(&bc->hash, &iter); 3021 3022 he = Curl_hash_next_element(&iter); 3023 while(he) { 3024 struct connectdata *conn; 3025 3026 bundle = he->ptr; 3027 3028 curr = bundle->conn_list->head; 3029 while(curr) { 3030 conn = curr->ptr; 3031 3032 if(!conn->inuse) { 3033 /* Set higher score for the age passed since the connection was used */ 3034 score = Curl_tvdiff(now, conn->now); 3035 3036 if(score > highscore) { 3037 highscore = score; 3038 conn_candidate = conn; 3039 } 3040 } 3041 curr = curr->next; 3042 } 3043 3044 he = Curl_hash_next_element(&iter); 3045 } 3046 3047 return conn_candidate; 3048} 3049 3050/* 3051 * This function finds the connection in the connection 3052 * bundle that has been unused for the longest time. 3053 * 3054 * Returns the pointer to the oldest idle connection, or NULL if none was 3055 * found. 3056 */ 3057static struct connectdata * 3058find_oldest_idle_connection_in_bundle(struct Curl_easy *data, 3059 struct connectbundle *bundle) 3060{ 3061 struct curl_llist_element *curr; 3062 long highscore=-1; 3063 long score; 3064 struct timeval now; 3065 struct connectdata *conn_candidate = NULL; 3066 struct connectdata *conn; 3067 3068 (void)data; 3069 3070 now = Curl_tvnow(); 3071 3072 curr = bundle->conn_list->head; 3073 while(curr) { 3074 conn = curr->ptr; 3075 3076 if(!conn->inuse) { 3077 /* Set higher score for the age passed since the connection was used */ 3078 score = Curl_tvdiff(now, conn->now); 3079 3080 if(score > highscore) { 3081 highscore = score; 3082 conn_candidate = conn; 3083 } 3084 } 3085 curr = curr->next; 3086 } 3087 3088 return conn_candidate; 3089} 3090 3091/* 3092 * This function checks if given connection is dead and disconnects if so. 3093 * (That also removes it from the connection cache.) 3094 * 3095 * Returns TRUE if the connection actually was dead and disconnected. 3096 */ 3097static bool disconnect_if_dead(struct connectdata *conn, 3098 struct Curl_easy *data) 3099{ 3100 size_t pipeLen = conn->send_pipe->size + conn->recv_pipe->size; 3101 if(!pipeLen && !conn->inuse) { 3102 /* The check for a dead socket makes sense only if there are no 3103 handles in pipeline and the connection isn't already marked in 3104 use */ 3105 bool dead; 3106 if(conn->handler->protocol & CURLPROTO_RTSP) 3107 /* RTSP is a special case due to RTP interleaving */ 3108 dead = Curl_rtsp_connisdead(conn); 3109 else 3110 dead = SocketIsDead(conn->sock[FIRSTSOCKET]); 3111 3112 if(dead) { 3113 conn->data = data; 3114 infof(data, "Connection %ld seems to be dead!\n", conn->connection_id); 3115 3116 /* disconnect resources */ 3117 Curl_disconnect(conn, /* dead_connection */TRUE); 3118 return TRUE; 3119 } 3120 } 3121 return FALSE; 3122} 3123 3124/* 3125 * Wrapper to use disconnect_if_dead() function in Curl_conncache_foreach() 3126 * 3127 * Returns always 0. 3128 */ 3129static int call_disconnect_if_dead(struct connectdata *conn, 3130 void *param) 3131{ 3132 struct Curl_easy* data = (struct Curl_easy*)param; 3133 disconnect_if_dead(conn, data); 3134 return 0; /* continue iteration */ 3135} 3136 3137/* 3138 * This function scans the connection cache for half-open/dead connections, 3139 * closes and removes them. 3140 * The cleanup is done at most once per second. 3141 */ 3142static void prune_dead_connections(struct Curl_easy *data) 3143{ 3144 struct timeval now = Curl_tvnow(); 3145 long elapsed = Curl_tvdiff(now, data->state.conn_cache->last_cleanup); 3146 3147 if(elapsed >= 1000L) { 3148 Curl_conncache_foreach(data->state.conn_cache, data, 3149 call_disconnect_if_dead); 3150 data->state.conn_cache->last_cleanup = now; 3151 } 3152} 3153 3154 3155static size_t max_pipeline_length(struct Curl_multi *multi) 3156{ 3157 return multi ? multi->max_pipeline_length : 0; 3158} 3159 3160 3161/* 3162 * Given one filled in connection struct (named needle), this function should 3163 * detect if there already is one that has all the significant details 3164 * exactly the same and thus should be used instead. 3165 * 3166 * If there is a match, this function returns TRUE - and has marked the 3167 * connection as 'in-use'. It must later be called with ConnectionDone() to 3168 * return back to 'idle' (unused) state. 3169 * 3170 * The force_reuse flag is set if the connection must be used, even if 3171 * the pipelining strategy wants to open a new connection instead of reusing. 3172 */ 3173static bool 3174ConnectionExists(struct Curl_easy *data, 3175 struct connectdata *needle, 3176 struct connectdata **usethis, 3177 bool *force_reuse, 3178 bool *waitpipe) 3179{ 3180 struct connectdata *check; 3181 struct connectdata *chosen = 0; 3182 bool foundPendingCandidate = FALSE; 3183 bool canPipeline = IsPipeliningPossible(data, needle); 3184 struct connectbundle *bundle; 3185 3186#ifdef USE_NTLM 3187 bool wantNTLMhttp = ((data->state.authhost.want & 3188 (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) && 3189 (needle->handler->protocol & PROTO_FAMILY_HTTP)); 3190 bool wantProxyNTLMhttp = (needle->bits.proxy_user_passwd && 3191 ((data->state.authproxy.want & 3192 (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) && 3193 (needle->handler->protocol & PROTO_FAMILY_HTTP))); 3194#endif 3195 3196 *force_reuse = FALSE; 3197 *waitpipe = FALSE; 3198 3199 /* We can't pipe if the site is blacklisted */ 3200 if(canPipeline && Curl_pipeline_site_blacklisted(data, needle)) { 3201 canPipeline = FALSE; 3202 } 3203 3204 /* Look up the bundle with all the connections to this 3205 particular host */ 3206 bundle = Curl_conncache_find_bundle(needle, data->state.conn_cache); 3207 if(bundle) { 3208 /* Max pipe length is zero (unlimited) for multiplexed connections */ 3209 size_t max_pipe_len = (bundle->multiuse != BUNDLE_MULTIPLEX)? 3210 max_pipeline_length(data->multi):0; 3211 size_t best_pipe_len = max_pipe_len; 3212 struct curl_llist_element *curr; 3213 const char *hostname; 3214 3215 if(needle->bits.conn_to_host) 3216 hostname = needle->conn_to_host.name; 3217 else 3218 hostname = needle->host.name; 3219 3220 infof(data, "Found bundle for host %s: %p [%s]\n", 3221 hostname, (void *)bundle, 3222 (bundle->multiuse== BUNDLE_PIPELINING? 3223 "can pipeline": 3224 (bundle->multiuse== BUNDLE_MULTIPLEX? 3225 "can multiplex":"serially"))); 3226 3227 /* We can't pipe if we don't know anything about the server */ 3228 if(canPipeline) { 3229 if(bundle->multiuse <= BUNDLE_UNKNOWN) { 3230 if((bundle->multiuse == BUNDLE_UNKNOWN) && data->set.pipewait) { 3231 infof(data, "Server doesn't support multi-use yet, wait\n"); 3232 *waitpipe = TRUE; 3233 return FALSE; /* no re-use */ 3234 } 3235 3236 infof(data, "Server doesn't support multi-use (yet)\n"); 3237 canPipeline = FALSE; 3238 } 3239 if((bundle->multiuse == BUNDLE_PIPELINING) && 3240 !Curl_pipeline_wanted(data->multi, CURLPIPE_HTTP1)) { 3241 /* not asked for, switch off */ 3242 infof(data, "Could pipeline, but not asked to!\n"); 3243 canPipeline = FALSE; 3244 } 3245 else if((bundle->multiuse == BUNDLE_MULTIPLEX) && 3246 !Curl_pipeline_wanted(data->multi, CURLPIPE_MULTIPLEX)) { 3247 infof(data, "Could multiplex, but not asked to!\n"); 3248 canPipeline = FALSE; 3249 } 3250 } 3251 3252 curr = bundle->conn_list->head; 3253 while(curr) { 3254 bool match = FALSE; 3255 size_t pipeLen; 3256 3257 /* 3258 * Note that if we use a HTTP proxy in normal mode (no tunneling), we 3259 * check connections to that proxy and not to the actual remote server. 3260 */ 3261 check = curr->ptr; 3262 curr = curr->next; 3263 3264 if(disconnect_if_dead(check, data)) 3265 continue; 3266 3267 pipeLen = check->send_pipe->size + check->recv_pipe->size; 3268 3269 if(canPipeline) { 3270 3271 if(!check->bits.multiplex) { 3272 /* If not multiplexing, make sure the pipe has only GET requests */ 3273 struct Curl_easy* sh = gethandleathead(check->send_pipe); 3274 struct Curl_easy* rh = gethandleathead(check->recv_pipe); 3275 if(sh) { 3276 if(!IsPipeliningPossible(sh, check)) 3277 continue; 3278 } 3279 else if(rh) { 3280 if(!IsPipeliningPossible(rh, check)) 3281 continue; 3282 } 3283 } 3284 } 3285 else { 3286 if(pipeLen > 0) { 3287 /* can only happen within multi handles, and means that another easy 3288 handle is using this connection */ 3289 continue; 3290 } 3291 3292 if(Curl_resolver_asynch()) { 3293 /* ip_addr_str[0] is NUL only if the resolving of the name hasn't 3294 completed yet and until then we don't re-use this connection */ 3295 if(!check->ip_addr_str[0]) { 3296 infof(data, 3297 "Connection #%ld is still name resolving, can't reuse\n", 3298 check->connection_id); 3299 continue; 3300 } 3301 } 3302 3303 if((check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) || 3304 check->bits.close) { 3305 if(!check->bits.close) 3306 foundPendingCandidate = TRUE; 3307 /* Don't pick a connection that hasn't connected yet or that is going 3308 to get closed. */ 3309 infof(data, "Connection #%ld isn't open enough, can't reuse\n", 3310 check->connection_id); 3311#ifdef DEBUGBUILD 3312 if(check->recv_pipe->size > 0) { 3313 infof(data, 3314 "BAD! Unconnected #%ld has a non-empty recv pipeline!\n", 3315 check->connection_id); 3316 } 3317#endif 3318 continue; 3319 } 3320 } 3321 3322 if((needle->handler->flags&PROTOPT_SSL) != 3323 (check->handler->flags&PROTOPT_SSL)) 3324 /* don't do mixed SSL and non-SSL connections */ 3325 if(get_protocol_family(check->handler->protocol) != 3326 needle->handler->protocol || !check->tls_upgraded) 3327 /* except protocols that have been upgraded via TLS */ 3328 continue; 3329 3330 if(needle->handler->flags&PROTOPT_SSL) { 3331 if((data->set.ssl.verifypeer != check->verifypeer) || 3332 (data->set.ssl.verifyhost != check->verifyhost)) 3333 continue; 3334 } 3335 3336 if(needle->bits.proxy != check->bits.proxy) 3337 /* don't do mixed proxy and non-proxy connections */ 3338 continue; 3339 3340 if(needle->bits.proxy && 3341 (needle->proxytype != check->proxytype || 3342 needle->bits.httpproxy != check->bits.httpproxy || 3343 needle->bits.tunnel_proxy != check->bits.tunnel_proxy || 3344 !Curl_raw_equal(needle->proxy.name, check->proxy.name) || 3345 needle->port != check->port)) 3346 /* don't mix connections that use different proxies */ 3347 continue; 3348 3349 if(needle->bits.conn_to_host != check->bits.conn_to_host) 3350 /* don't mix connections that use the "connect to host" feature and 3351 * connections that don't use this feature */ 3352 continue; 3353 3354 if(needle->bits.conn_to_port != check->bits.conn_to_port) 3355 /* don't mix connections that use the "connect to port" feature and 3356 * connections that don't use this feature */ 3357 continue; 3358 3359 if(!canPipeline && check->inuse) 3360 /* this request can't be pipelined but the checked connection is 3361 already in use so we skip it */ 3362 continue; 3363 3364 if(needle->localdev || needle->localport) { 3365 /* If we are bound to a specific local end (IP+port), we must not 3366 re-use a random other one, although if we didn't ask for a 3367 particular one we can reuse one that was bound. 3368 3369 This comparison is a bit rough and too strict. Since the input 3370 parameters can be specified in numerous ways and still end up the 3371 same it would take a lot of processing to make it really accurate. 3372 Instead, this matching will assume that re-uses of bound connections 3373 will most likely also re-use the exact same binding parameters and 3374 missing out a few edge cases shouldn't hurt anyone very much. 3375 */ 3376 if((check->localport != needle->localport) || 3377 (check->localportrange != needle->localportrange) || 3378 !check->localdev || 3379 !needle->localdev || 3380 strcmp(check->localdev, needle->localdev)) 3381 continue; 3382 } 3383 3384 if(!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) { 3385 /* This protocol requires credentials per connection, 3386 so verify that we're using the same name and password as well */ 3387 if(!strequal(needle->user, check->user) || 3388 !strequal(needle->passwd, check->passwd)) { 3389 /* one of them was different */ 3390 continue; 3391 } 3392 } 3393 3394 if(!needle->bits.httpproxy || (needle->handler->flags&PROTOPT_SSL) || 3395 (needle->bits.httpproxy && needle->bits.tunnel_proxy)) { 3396 /* The requested connection does not use a HTTP proxy or it uses SSL or 3397 it is a non-SSL protocol tunneled over the same HTTP proxy name and 3398 port number */ 3399 if((Curl_raw_equal(needle->handler->scheme, check->handler->scheme) || 3400 (get_protocol_family(check->handler->protocol) == 3401 needle->handler->protocol && check->tls_upgraded)) && 3402 (!needle->bits.conn_to_host || Curl_raw_equal( 3403 needle->conn_to_host.name, check->conn_to_host.name)) && 3404 (!needle->bits.conn_to_port || 3405 needle->conn_to_port == check->conn_to_port) && 3406 Curl_raw_equal(needle->host.name, check->host.name) && 3407 needle->remote_port == check->remote_port) { 3408 /* The schemes match or the the protocol family is the same and the 3409 previous connection was TLS upgraded, and the hostname and host 3410 port match */ 3411 if(needle->handler->flags & PROTOPT_SSL) { 3412 /* This is a SSL connection so verify that we're using the same 3413 SSL options as well */ 3414 if(!Curl_ssl_config_matches(&needle->ssl_config, 3415 &check->ssl_config)) { 3416 DEBUGF(infof(data, 3417 "Connection #%ld has different SSL parameters, " 3418 "can't reuse\n", 3419 check->connection_id)); 3420 continue; 3421 } 3422 else if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete) { 3423 foundPendingCandidate = TRUE; 3424 DEBUGF(infof(data, 3425 "Connection #%ld has not started SSL connect, " 3426 "can't reuse\n", 3427 check->connection_id)); 3428 continue; 3429 } 3430 } 3431 match = TRUE; 3432 } 3433 } 3434 else { 3435 /* The requested connection is using the same HTTP proxy in normal 3436 mode (no tunneling) */ 3437 match = TRUE; 3438 } 3439 3440 if(match) { 3441#if defined(USE_NTLM) 3442 /* If we are looking for an HTTP+NTLM connection, check if this is 3443 already authenticating with the right credentials. If not, keep 3444 looking so that we can reuse NTLM connections if 3445 possible. (Especially we must not reuse the same connection if 3446 partway through a handshake!) */ 3447 if(wantNTLMhttp) { 3448 if(!strequal(needle->user, check->user) || 3449 !strequal(needle->passwd, check->passwd)) 3450 continue; 3451 } 3452 else if(check->ntlm.state != NTLMSTATE_NONE) { 3453 /* Connection is using NTLM auth but we don't want NTLM */ 3454 continue; 3455 } 3456 3457 /* Same for Proxy NTLM authentication */ 3458 if(wantProxyNTLMhttp) { 3459 /* Both check->proxyuser and check->proxypasswd can be NULL */ 3460 if(!check->proxyuser || !check->proxypasswd) 3461 continue; 3462 3463 if(!strequal(needle->proxyuser, check->proxyuser) || 3464 !strequal(needle->proxypasswd, check->proxypasswd)) 3465 continue; 3466 } 3467 else if(check->proxyntlm.state != NTLMSTATE_NONE) { 3468 /* Proxy connection is using NTLM auth but we don't want NTLM */ 3469 continue; 3470 } 3471 3472 if(wantNTLMhttp || wantProxyNTLMhttp) { 3473 /* Credentials are already checked, we can use this connection */ 3474 chosen = check; 3475 3476 if((wantNTLMhttp && 3477 (check->ntlm.state != NTLMSTATE_NONE)) || 3478 (wantProxyNTLMhttp && 3479 (check->proxyntlm.state != NTLMSTATE_NONE))) { 3480 /* We must use this connection, no other */ 3481 *force_reuse = TRUE; 3482 break; 3483 } 3484 3485 /* Continue look up for a better connection */ 3486 continue; 3487 } 3488#endif 3489 if(canPipeline) { 3490 /* We can pipeline if we want to. Let's continue looking for 3491 the optimal connection to use, i.e the shortest pipe that is not 3492 blacklisted. */ 3493 3494 if(pipeLen == 0) { 3495 /* We have the optimal connection. Let's stop looking. */ 3496 chosen = check; 3497 break; 3498 } 3499 3500 /* We can't use the connection if the pipe is full */ 3501 if(max_pipe_len && (pipeLen >= max_pipe_len)) { 3502 infof(data, "Pipe is full, skip (%zu)\n", pipeLen); 3503 continue; 3504 } 3505#ifdef USE_NGHTTP2 3506 /* If multiplexed, make sure we don't go over concurrency limit */ 3507 if(check->bits.multiplex) { 3508 /* Multiplexed connections can only be HTTP/2 for now */ 3509 struct http_conn *httpc = &check->proto.httpc; 3510 if(pipeLen >= httpc->settings.max_concurrent_streams) { 3511 infof(data, "MAX_CONCURRENT_STREAMS reached, skip (%zu)\n", 3512 pipeLen); 3513 continue; 3514 } 3515 } 3516#endif 3517 /* We can't use the connection if the pipe is penalized */ 3518 if(Curl_pipeline_penalized(data, check)) { 3519 infof(data, "Penalized, skip\n"); 3520 continue; 3521 } 3522 3523 if(max_pipe_len) { 3524 if(pipeLen < best_pipe_len) { 3525 /* This connection has a shorter pipe so far. We'll pick this 3526 and continue searching */ 3527 chosen = check; 3528 best_pipe_len = pipeLen; 3529 continue; 3530 } 3531 } 3532 else { 3533 /* When not pipelining (== multiplexed), we have a match here! */ 3534 chosen = check; 3535 infof(data, "Multiplexed connection found!\n"); 3536 break; 3537 } 3538 } 3539 else { 3540 /* We have found a connection. Let's stop searching. */ 3541 chosen = check; 3542 break; 3543 } 3544 } 3545 } 3546 } 3547 3548 if(chosen) { 3549 *usethis = chosen; 3550 return TRUE; /* yes, we found one to use! */ 3551 } 3552 3553 if(foundPendingCandidate && data->set.pipewait) { 3554 infof(data, 3555 "Found pending candidate for reuse and CURLOPT_PIPEWAIT is set\n"); 3556 *waitpipe = TRUE; 3557 } 3558 3559 return FALSE; /* no matching connecting exists */ 3560} 3561 3562/* after a TCP connection to the proxy has been verified, this function does 3563 the next magic step. 3564 3565 Note: this function's sub-functions call failf() 3566 3567*/ 3568CURLcode Curl_connected_proxy(struct connectdata *conn, 3569 int sockindex) 3570{ 3571 if(!conn->bits.proxy || sockindex) 3572 /* this magic only works for the primary socket as the secondary is used 3573 for FTP only and it has FTP specific magic in ftp.c */ 3574 return CURLE_OK; 3575 3576 switch(conn->proxytype) { 3577#ifndef CURL_DISABLE_PROXY 3578 case CURLPROXY_SOCKS5: 3579 case CURLPROXY_SOCKS5_HOSTNAME: 3580 return Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, 3581 conn->bits.conn_to_host ? conn->conn_to_host.name : 3582 conn->host.name, 3583 conn->bits.conn_to_port ? conn->conn_to_port : 3584 conn->remote_port, 3585 FIRSTSOCKET, conn); 3586 3587 case CURLPROXY_SOCKS4: 3588 return Curl_SOCKS4(conn->proxyuser, 3589 conn->bits.conn_to_host ? conn->conn_to_host.name : 3590 conn->host.name, 3591 conn->bits.conn_to_port ? conn->conn_to_port : 3592 conn->remote_port, 3593 FIRSTSOCKET, conn, FALSE); 3594 3595 case CURLPROXY_SOCKS4A: 3596 return Curl_SOCKS4(conn->proxyuser, 3597 conn->bits.conn_to_host ? conn->conn_to_host.name : 3598 conn->host.name, 3599 conn->bits.conn_to_port ? conn->conn_to_port : 3600 conn->remote_port, 3601 FIRSTSOCKET, conn, TRUE); 3602 3603#endif /* CURL_DISABLE_PROXY */ 3604 case CURLPROXY_HTTP: 3605 case CURLPROXY_HTTP_1_0: 3606 /* do nothing here. handled later. */ 3607 break; 3608 default: 3609 break; 3610 } /* switch proxytype */ 3611 3612 return CURLE_OK; 3613} 3614 3615/* 3616 * verboseconnect() displays verbose information after a connect 3617 */ 3618#ifndef CURL_DISABLE_VERBOSE_STRINGS 3619void Curl_verboseconnect(struct connectdata *conn) 3620{ 3621 if(conn->data->set.verbose) 3622 infof(conn->data, "Connected to %s (%s) port %ld (#%ld)\n", 3623 conn->bits.proxy ? conn->proxy.dispname : conn->host.dispname, 3624 conn->ip_addr_str, conn->port, conn->connection_id); 3625} 3626#endif 3627 3628int Curl_protocol_getsock(struct connectdata *conn, 3629 curl_socket_t *socks, 3630 int numsocks) 3631{ 3632 if(conn->handler->proto_getsock) 3633 return conn->handler->proto_getsock(conn, socks, numsocks); 3634 return GETSOCK_BLANK; 3635} 3636 3637int Curl_doing_getsock(struct connectdata *conn, 3638 curl_socket_t *socks, 3639 int numsocks) 3640{ 3641 if(conn && conn->handler->doing_getsock) 3642 return conn->handler->doing_getsock(conn, socks, numsocks); 3643 return GETSOCK_BLANK; 3644} 3645 3646/* 3647 * We are doing protocol-specific connecting and this is being called over and 3648 * over from the multi interface until the connection phase is done on 3649 * protocol layer. 3650 */ 3651 3652CURLcode Curl_protocol_connecting(struct connectdata *conn, 3653 bool *done) 3654{ 3655 CURLcode result=CURLE_OK; 3656 3657 if(conn && conn->handler->connecting) { 3658 *done = FALSE; 3659 result = conn->handler->connecting(conn, done); 3660 } 3661 else 3662 *done = TRUE; 3663 3664 return result; 3665} 3666 3667/* 3668 * We are DOING this is being called over and over from the multi interface 3669 * until the DOING phase is done on protocol layer. 3670 */ 3671 3672CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done) 3673{ 3674 CURLcode result=CURLE_OK; 3675 3676 if(conn && conn->handler->doing) { 3677 *done = FALSE; 3678 result = conn->handler->doing(conn, done); 3679 } 3680 else 3681 *done = TRUE; 3682 3683 return result; 3684} 3685 3686/* 3687 * We have discovered that the TCP connection has been successful, we can now 3688 * proceed with some action. 3689 * 3690 */ 3691CURLcode Curl_protocol_connect(struct connectdata *conn, 3692 bool *protocol_done) 3693{ 3694 CURLcode result=CURLE_OK; 3695 3696 *protocol_done = FALSE; 3697 3698 if(conn->bits.tcpconnect[FIRSTSOCKET] && conn->bits.protoconnstart) { 3699 /* We already are connected, get back. This may happen when the connect 3700 worked fine in the first call, like when we connect to a local server 3701 or proxy. Note that we don't know if the protocol is actually done. 3702 3703 Unless this protocol doesn't have any protocol-connect callback, as 3704 then we know we're done. */ 3705 if(!conn->handler->connecting) 3706 *protocol_done = TRUE; 3707 3708 return CURLE_OK; 3709 } 3710 3711 if(!conn->bits.protoconnstart) { 3712 3713 result = Curl_proxy_connect(conn); 3714 if(result) 3715 return result; 3716 3717 if(conn->bits.tunnel_proxy && conn->bits.httpproxy && 3718 (conn->tunnel_state[FIRSTSOCKET] != TUNNEL_COMPLETE)) 3719 /* when using an HTTP tunnel proxy, await complete tunnel establishment 3720 before proceeding further. Return CURLE_OK so we'll be called again */ 3721 return CURLE_OK; 3722 3723 if(conn->handler->connect_it) { 3724 /* is there a protocol-specific connect() procedure? */ 3725 3726 /* Call the protocol-specific connect function */ 3727 result = conn->handler->connect_it(conn, protocol_done); 3728 } 3729 else 3730 *protocol_done = TRUE; 3731 3732 /* it has started, possibly even completed but that knowledge isn't stored 3733 in this bit! */ 3734 if(!result) 3735 conn->bits.protoconnstart = TRUE; 3736 } 3737 3738 return result; /* pass back status */ 3739} 3740 3741/* 3742 * Helpers for IDNA convertions. 3743 */ 3744static bool is_ASCII_name(const char *hostname) 3745{ 3746 const unsigned char *ch = (const unsigned char*)hostname; 3747 3748 while(*ch) { 3749 if(*ch++ & 0x80) 3750 return FALSE; 3751 } 3752 return TRUE; 3753} 3754 3755#ifdef USE_LIBIDN 3756/* 3757 * Check if characters in hostname is allowed in Top Level Domain. 3758 */ 3759static bool tld_check_name(struct Curl_easy *data, 3760 const char *ace_hostname) 3761{ 3762 size_t err_pos; 3763 char *uc_name = NULL; 3764 int rc; 3765#ifndef CURL_DISABLE_VERBOSE_STRINGS 3766 const char *tld_errmsg = "<no msg>"; 3767#else 3768 (void)data; 3769#endif 3770 3771 /* Convert (and downcase) ACE-name back into locale's character set */ 3772 rc = idna_to_unicode_lzlz(ace_hostname, &uc_name, 0); 3773 if(rc != IDNA_SUCCESS) 3774 return FALSE; 3775 3776 /* Warning: err_pos receives "the decoded character offset rather than the 3777 byte position in the string." And as of libidn 1.32 that character offset 3778 is for UTF-8, even if the passed in string is another locale. */ 3779 rc = tld_check_lz(uc_name, &err_pos, NULL); 3780#ifndef CURL_DISABLE_VERBOSE_STRINGS 3781#ifdef HAVE_TLD_STRERROR 3782 if(rc != TLD_SUCCESS) 3783 tld_errmsg = tld_strerror((Tld_rc)rc); 3784#endif 3785 if(rc != TLD_SUCCESS) 3786 infof(data, "WARNING: TLD check for %s failed; %s\n", 3787 uc_name, tld_errmsg); 3788#endif /* CURL_DISABLE_VERBOSE_STRINGS */ 3789 if(uc_name) 3790 idn_free(uc_name); 3791 if(rc != TLD_SUCCESS) 3792 return FALSE; 3793 3794 return TRUE; 3795} 3796#endif 3797 3798/* 3799 * Perform any necessary IDN conversion of hostname 3800 */ 3801static void fix_hostname(struct Curl_easy *data, 3802 struct connectdata *conn, struct hostname *host) 3803{ 3804 size_t len; 3805 3806#ifndef USE_LIBIDN 3807 (void)data; 3808 (void)conn; 3809#elif defined(CURL_DISABLE_VERBOSE_STRINGS) 3810 (void)conn; 3811#endif 3812 3813 /* set the name we use to display the host name */ 3814 host->dispname = host->name; 3815 3816 len = strlen(host->name); 3817 if(len && (host->name[len-1] == '.')) 3818 /* strip off a single trailing dot if present, primarily for SNI but 3819 there's no use for it */ 3820 host->name[len-1]=0; 3821 3822 /* Check name for non-ASCII and convert hostname to ACE form if we can */ 3823 if(!is_ASCII_name(host->name)) { 3824#ifdef USE_LIBIDN 3825 if(stringprep_check_version(LIBIDN_REQUIRED_VERSION)) { 3826 char *ace_hostname = NULL; 3827 3828 int rc = idna_to_ascii_lz(host->name, &ace_hostname, 0); 3829 infof(data, "Input domain encoded as `%s'\n", 3830 stringprep_locale_charset()); 3831 if(rc == IDNA_SUCCESS) { 3832 /* tld_check_name() displays a warning if the host name contains 3833 "illegal" characters for this TLD */ 3834 (void)tld_check_name(data, ace_hostname); 3835 3836 host->encalloc = ace_hostname; 3837 /* change the name pointer to point to the encoded hostname */ 3838 host->name = host->encalloc; 3839 } 3840 else 3841 infof(data, "Failed to convert %s to ACE; %s\n", host->name, 3842 Curl_idn_strerror(conn, rc)); 3843 } 3844#elif defined(USE_WIN32_IDN) 3845 char *ace_hostname = NULL; 3846 3847 if(curl_win32_idn_to_ascii(host->name, &ace_hostname)) { 3848 host->encalloc = ace_hostname; 3849 /* change the name pointer to point to the encoded hostname */ 3850 host->name = host->encalloc; 3851 } 3852 else 3853 infof(data, "Failed to convert %s to ACE;\n", host->name); 3854#else 3855 infof(data, "IDN support not present, can't parse Unicode domains\n"); 3856#endif 3857 } 3858} 3859 3860/* 3861 * Frees data allocated by fix_hostname() 3862 */ 3863static void free_fixed_hostname(struct hostname *host) 3864{ 3865#if defined(USE_LIBIDN) 3866 if(host->encalloc) { 3867 idn_free(host->encalloc); /* must be freed with idn_free() since this was 3868 allocated by libidn */ 3869 host->encalloc = NULL; 3870 } 3871#elif defined(USE_WIN32_IDN) 3872 free(host->encalloc); /* must be freed withidn_free() since this was 3873 allocated by curl_win32_idn_to_ascii */ 3874 host->encalloc = NULL; 3875#else 3876 (void)host; 3877#endif 3878} 3879 3880static void llist_dtor(void *user, void *element) 3881{ 3882 (void)user; 3883 (void)element; 3884 /* Do nothing */ 3885} 3886 3887/* 3888 * Allocate and initialize a new connectdata object. 3889 */ 3890static struct connectdata *allocate_conn(struct Curl_easy *data) 3891{ 3892 struct connectdata *conn = calloc(1, sizeof(struct connectdata)); 3893 if(!conn) 3894 return NULL; 3895 3896 conn->handler = &Curl_handler_dummy; /* Be sure we have a handler defined 3897 already from start to avoid NULL 3898 situations and checks */ 3899 3900 /* and we setup a few fields in case we end up actually using this struct */ 3901 3902 conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ 3903 conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ 3904 conn->tempsock[0] = CURL_SOCKET_BAD; /* no file descriptor */ 3905 conn->tempsock[1] = CURL_SOCKET_BAD; /* no file descriptor */ 3906 conn->connection_id = -1; /* no ID */ 3907 conn->port = -1; /* unknown at this point */ 3908 conn->remote_port = -1; /* unknown */ 3909#if defined(USE_RECV_BEFORE_SEND_WORKAROUND) && defined(DEBUGBUILD) 3910 conn->postponed[0].bindsock = CURL_SOCKET_BAD; /* no file descriptor */ 3911 conn->postponed[1].bindsock = CURL_SOCKET_BAD; /* no file descriptor */ 3912#endif /* USE_RECV_BEFORE_SEND_WORKAROUND && DEBUGBUILD */ 3913 3914 /* Default protocol-independent behavior doesn't support persistent 3915 connections, so we set this to force-close. Protocols that support 3916 this need to set this to FALSE in their "curl_do" functions. */ 3917 connclose(conn, "Default to force-close"); 3918 3919 /* Store creation time to help future close decision making */ 3920 conn->created = Curl_tvnow(); 3921 3922 conn->data = data; /* Setup the association between this connection 3923 and the Curl_easy */ 3924 3925 conn->proxytype = data->set.proxytype; /* type */ 3926 3927#ifdef CURL_DISABLE_PROXY 3928 3929 conn->bits.proxy = FALSE; 3930 conn->bits.httpproxy = FALSE; 3931 conn->bits.proxy_user_passwd = FALSE; 3932 conn->bits.tunnel_proxy = FALSE; 3933 3934#else /* CURL_DISABLE_PROXY */ 3935 3936 /* note that these two proxy bits are now just on what looks to be 3937 requested, they may be altered down the road */ 3938 conn->bits.proxy = (data->set.str[STRING_PROXY] && 3939 *data->set.str[STRING_PROXY]) ? TRUE : FALSE; 3940 conn->bits.httpproxy = (conn->bits.proxy && 3941 (conn->proxytype == CURLPROXY_HTTP || 3942 conn->proxytype == CURLPROXY_HTTP_1_0)) ? 3943 TRUE : FALSE; 3944 conn->bits.proxy_user_passwd = (data->set.str[STRING_PROXYUSERNAME]) ? 3945 TRUE : FALSE; 3946 conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy; 3947 3948#endif /* CURL_DISABLE_PROXY */ 3949 3950 conn->bits.user_passwd = (data->set.str[STRING_USERNAME]) ? TRUE : FALSE; 3951 conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; 3952 conn->bits.ftp_use_eprt = data->set.ftp_use_eprt; 3953 3954 conn->verifypeer = data->set.ssl.verifypeer; 3955 conn->verifyhost = data->set.ssl.verifyhost; 3956 3957 conn->ip_version = data->set.ipver; 3958 3959#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \ 3960 defined(NTLM_WB_ENABLED) 3961 conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD; 3962 conn->ntlm_auth_hlpr_pid = 0; 3963 conn->challenge_header = NULL; 3964 conn->response_header = NULL; 3965#endif 3966 3967 if(Curl_pipeline_wanted(data->multi, CURLPIPE_HTTP1) && 3968 !conn->master_buffer) { 3969 /* Allocate master_buffer to be used for HTTP/1 pipelining */ 3970 conn->master_buffer = calloc(BUFSIZE, sizeof (char)); 3971 if(!conn->master_buffer) 3972 goto error; 3973 } 3974 3975 /* Initialize the pipeline lists */ 3976 conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); 3977 conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); 3978 if(!conn->send_pipe || !conn->recv_pipe) 3979 goto error; 3980 3981#ifdef HAVE_GSSAPI 3982 conn->data_prot = PROT_CLEAR; 3983#endif 3984 3985 /* Store the local bind parameters that will be used for this connection */ 3986 if(data->set.str[STRING_DEVICE]) { 3987 conn->localdev = strdup(data->set.str[STRING_DEVICE]); 3988 if(!conn->localdev) 3989 goto error; 3990 } 3991 conn->localportrange = data->set.localportrange; 3992 conn->localport = data->set.localport; 3993 3994 /* the close socket stuff needs to be copied to the connection struct as 3995 it may live on without (this specific) Curl_easy */ 3996 conn->fclosesocket = data->set.fclosesocket; 3997 conn->closesocket_client = data->set.closesocket_client; 3998 3999 return conn; 4000 error: 4001 4002 Curl_llist_destroy(conn->send_pipe, NULL); 4003 Curl_llist_destroy(conn->recv_pipe, NULL); 4004 4005 conn->send_pipe = NULL; 4006 conn->recv_pipe = NULL; 4007 4008 free(conn->master_buffer); 4009 free(conn->localdev); 4010 free(conn); 4011 return NULL; 4012} 4013 4014static CURLcode findprotocol(struct Curl_easy *data, 4015 struct connectdata *conn, 4016 const char *protostr) 4017{ 4018 const struct Curl_handler * const *pp; 4019 const struct Curl_handler *p; 4020 4021 /* Scan protocol handler table and match against 'protostr' to set a few 4022 variables based on the URL. Now that the handler may be changed later 4023 when the protocol specific setup function is called. */ 4024 for(pp = protocols; (p = *pp) != NULL; pp++) { 4025 if(Curl_raw_equal(p->scheme, protostr)) { 4026 /* Protocol found in table. Check if allowed */ 4027 if(!(data->set.allowed_protocols & p->protocol)) 4028 /* nope, get out */ 4029 break; 4030 4031 /* it is allowed for "normal" request, now do an extra check if this is 4032 the result of a redirect */ 4033 if(data->state.this_is_a_follow && 4034 !(data->set.redir_protocols & p->protocol)) 4035 /* nope, get out */ 4036 break; 4037 4038 /* Perform setup complement if some. */ 4039 conn->handler = conn->given = p; 4040 4041 /* 'port' and 'remote_port' are set in setup_connection_internals() */ 4042 return CURLE_OK; 4043 } 4044 } 4045 4046 4047 /* The protocol was not found in the table, but we don't have to assign it 4048 to anything since it is already assigned to a dummy-struct in the 4049 create_conn() function when the connectdata struct is allocated. */ 4050 failf(data, "Protocol \"%s\" not supported or disabled in " LIBCURL_NAME, 4051 protostr); 4052 4053 return CURLE_UNSUPPORTED_PROTOCOL; 4054} 4055 4056/* 4057 * Parse URL and fill in the relevant members of the connection struct. 4058 */ 4059static CURLcode parseurlandfillconn(struct Curl_easy *data, 4060 struct connectdata *conn, 4061 bool *prot_missing, 4062 char **userp, char **passwdp, 4063 char **optionsp) 4064{ 4065 char *at; 4066 char *fragment; 4067 char *path = data->state.path; 4068 char *query; 4069 int rc; 4070 char protobuf[16] = ""; 4071 const char *protop = ""; 4072 CURLcode result; 4073 bool rebuild_url = FALSE; 4074 4075 *prot_missing = FALSE; 4076 4077 /* We might pass the entire URL into the request so we need to make sure 4078 * there are no bad characters in there.*/ 4079 if(strpbrk(data->change.url, "\r\n")) { 4080 failf(data, "Illegal characters found in URL"); 4081 return CURLE_URL_MALFORMAT; 4082 } 4083 4084 /************************************************************* 4085 * Parse the URL. 4086 * 4087 * We need to parse the url even when using the proxy, because we will need 4088 * the hostname and port in case we are trying to SSL connect through the 4089 * proxy -- and we don't know if we will need to use SSL until we parse the 4090 * url ... 4091 ************************************************************/ 4092 if((2 == sscanf(data->change.url, "%15[^:]:%[^\n]", 4093 protobuf, path)) && 4094 Curl_raw_equal(protobuf, "file")) { 4095 if(path[0] == '/' && path[1] == '/') { 4096 /* Allow omitted hostname (e.g. file:/<path>). This is not strictly 4097 * speaking a valid file: URL by RFC 1738, but treating file:/<path> as 4098 * file://localhost/<path> is similar to how other schemes treat missing 4099 * hostnames. See RFC 1808. */ 4100 4101 /* This cannot be done with strcpy() in a portable manner, since the 4102 memory areas overlap! */ 4103 memmove(path, path + 2, strlen(path + 2)+1); 4104 } 4105 /* 4106 * we deal with file://<host>/<path> differently since it supports no 4107 * hostname other than "localhost" and "127.0.0.1", which is unique among 4108 * the URL protocols specified in RFC 1738 4109 */ 4110 if(path[0] != '/') { 4111 /* the URL included a host name, we ignore host names in file:// URLs 4112 as the standards don't define what to do with them */ 4113 char *ptr=strchr(path, '/'); 4114 if(ptr) { 4115 /* there was a slash present 4116 4117 RFC1738 (section 3.1, page 5) says: 4118 4119 The rest of the locator consists of data specific to the scheme, 4120 and is known as the "url-path". It supplies the details of how the 4121 specified resource can be accessed. Note that the "/" between the 4122 host (or port) and the url-path is NOT part of the url-path. 4123 4124 As most agents use file://localhost/foo to get '/foo' although the 4125 slash preceding foo is a separator and not a slash for the path, 4126 a URL as file://localhost//foo must be valid as well, to refer to 4127 the same file with an absolute path. 4128 */ 4129 4130 if(ptr[1] && ('/' == ptr[1])) 4131 /* if there was two slashes, we skip the first one as that is then 4132 used truly as a separator */ 4133 ptr++; 4134 4135 /* This cannot be made with strcpy, as the memory chunks overlap! */ 4136 memmove(path, ptr, strlen(ptr)+1); 4137 } 4138 } 4139 4140 protop = "file"; /* protocol string */ 4141 } 4142 else { 4143 /* clear path */ 4144 char slashbuf[4]; 4145 path[0]=0; 4146 4147 rc = sscanf(data->change.url, 4148 "%15[^\n:]:%3[/]%[^\n/?]%[^\n]", 4149 protobuf, slashbuf, conn->host.name, path); 4150 if(2 == rc) { 4151 failf(data, "Bad URL"); 4152 return CURLE_URL_MALFORMAT; 4153 } 4154 if(3 > rc) { 4155 4156 /* 4157 * The URL was badly formatted, let's try the browser-style _without_ 4158 * protocol specified like 'http://'. 4159 */ 4160 rc = sscanf(data->change.url, "%[^\n/?]%[^\n]", conn->host.name, path); 4161 if(1 > rc) { 4162 /* 4163 * We couldn't even get this format. 4164 * djgpp 2.04 has a sscanf() bug where 'conn->host.name' is 4165 * assigned, but the return value is EOF! 4166 */ 4167#if defined(__DJGPP__) && (DJGPP_MINOR == 4) 4168 if(!(rc == -1 && *conn->host.name)) 4169#endif 4170 { 4171 failf(data, "<url> malformed"); 4172 return CURLE_URL_MALFORMAT; 4173 } 4174 } 4175 4176 /* 4177 * Since there was no protocol part specified in the URL use the 4178 * user-specified default protocol. If we weren't given a default make a 4179 * guess by matching some protocols against the host's outermost 4180 * sub-domain name. Finally if there was no match use HTTP. 4181 */ 4182 4183 protop = data->set.str[STRING_DEFAULT_PROTOCOL]; 4184 if(!protop) { 4185 /* Note: if you add a new protocol, please update the list in 4186 * lib/version.c too! */ 4187 if(checkprefix("FTP.", conn->host.name)) 4188 protop = "ftp"; 4189 else if(checkprefix("DICT.", conn->host.name)) 4190 protop = "DICT"; 4191 else if(checkprefix("LDAP.", conn->host.name)) 4192 protop = "LDAP"; 4193 else if(checkprefix("IMAP.", conn->host.name)) 4194 protop = "IMAP"; 4195 else if(checkprefix("SMTP.", conn->host.name)) 4196 protop = "smtp"; 4197 else if(checkprefix("POP3.", conn->host.name)) 4198 protop = "pop3"; 4199 else 4200 protop = "http"; 4201 } 4202 4203 *prot_missing = TRUE; /* not given in URL */ 4204 } 4205 else { 4206 size_t s = strlen(slashbuf); 4207 protop = protobuf; 4208 if(s != 2) { 4209 infof(data, "Unwillingly accepted illegal URL using %d slash%s!\n", 4210 s, s>1?"es":""); 4211 4212 if(data->change.url_alloc) 4213 free(data->change.url); 4214 /* repair the URL to use two slashes */ 4215 data->change.url = aprintf("%s://%s%s", 4216 protobuf, conn->host.name, path); 4217 if(!data->change.url) 4218 return CURLE_OUT_OF_MEMORY; 4219 data->change.url_alloc = TRUE; 4220 } 4221 } 4222 } 4223 4224 /* We search for '?' in the host name (but only on the right side of a 4225 * @-letter to allow ?-letters in username and password) to handle things 4226 * like http://example.com?param= (notice the missing '/'). 4227 */ 4228 at = strchr(conn->host.name, '@'); 4229 if(at) 4230 query = strchr(at+1, '?'); 4231 else 4232 query = strchr(conn->host.name, '?'); 4233 4234 if(query) { 4235 /* We must insert a slash before the '?'-letter in the URL. If the URL had 4236 a slash after the '?', that is where the path currently begins and the 4237 '?string' is still part of the host name. 4238 4239 We must move the trailing part from the host name and put it first in 4240 the path. And have it all prefixed with a slash. 4241 */ 4242 4243 size_t hostlen = strlen(query); 4244 size_t pathlen = strlen(path); 4245 4246 /* move the existing path plus the zero byte forward, to make room for 4247 the host-name part */ 4248 memmove(path+hostlen+1, path, pathlen+1); 4249 4250 /* now copy the trailing host part in front of the existing path */ 4251 memcpy(path+1, query, hostlen); 4252 4253 path[0]='/'; /* prepend the missing slash */ 4254 rebuild_url = TRUE; 4255 4256 *query=0; /* now cut off the hostname at the ? */ 4257 } 4258 else if(!path[0]) { 4259 /* if there's no path set, use a single slash */ 4260 strcpy(path, "/"); 4261 rebuild_url = TRUE; 4262 } 4263 4264 /* If the URL is malformatted (missing a '/' after hostname before path) we 4265 * insert a slash here. The only letter except '/' we accept to start a path 4266 * is '?'. 4267 */ 4268 if(path[0] == '?') { 4269 /* We need this function to deal with overlapping memory areas. We know 4270 that the memory area 'path' points to is 'urllen' bytes big and that 4271 is bigger than the path. Use +1 to move the zero byte too. */ 4272 memmove(&path[1], path, strlen(path)+1); 4273 path[0] = '/'; 4274 rebuild_url = TRUE; 4275 } 4276 else if(!data->set.path_as_is) { 4277 /* sanitise paths and remove ../ and ./ sequences according to RFC3986 */ 4278 char *newp = Curl_dedotdotify(path); 4279 if(!newp) 4280 return CURLE_OUT_OF_MEMORY; 4281 4282 if(strcmp(newp, path)) { 4283 rebuild_url = TRUE; 4284 free(data->state.pathbuffer); 4285 data->state.pathbuffer = newp; 4286 data->state.path = newp; 4287 path = newp; 4288 } 4289 else 4290 free(newp); 4291 } 4292 4293 /* 4294 * "rebuild_url" means that one or more URL components have been modified so 4295 * we need to generate an updated full version. We need the corrected URL 4296 * when communicating over HTTP proxy and we don't know at this point if 4297 * we're using a proxy or not. 4298 */ 4299 if(rebuild_url) { 4300 char *reurl; 4301 4302 size_t plen = strlen(path); /* new path, should be 1 byte longer than 4303 the original */ 4304 size_t urllen = strlen(data->change.url); /* original URL length */ 4305 4306 size_t prefixlen = strlen(conn->host.name); 4307 4308 if(!*prot_missing) 4309 prefixlen += strlen(protop) + strlen("://"); 4310 4311 reurl = malloc(urllen + 2); /* 2 for zerobyte + slash */ 4312 if(!reurl) 4313 return CURLE_OUT_OF_MEMORY; 4314 4315 /* copy the prefix */ 4316 memcpy(reurl, data->change.url, prefixlen); 4317 4318 /* append the trailing piece + zerobyte */ 4319 memcpy(&reurl[prefixlen], path, plen + 1); 4320 4321 /* possible free the old one */ 4322 if(data->change.url_alloc) { 4323 Curl_safefree(data->change.url); 4324 data->change.url_alloc = FALSE; 4325 } 4326 4327 infof(data, "Rebuilt URL to: %s\n", reurl); 4328 4329 data->change.url = reurl; 4330 data->change.url_alloc = TRUE; /* free this later */ 4331 } 4332 4333 /* 4334 * Parse the login details from the URL and strip them out of 4335 * the host name 4336 */ 4337 result = parse_url_login(data, conn, userp, passwdp, optionsp); 4338 if(result) 4339 return result; 4340 4341 if(conn->host.name[0] == '[') { 4342 /* This looks like an IPv6 address literal. See if there is an address 4343 scope if there is no location header */ 4344 char *percent = strchr(conn->host.name, '%'); 4345 if(percent) { 4346 unsigned int identifier_offset = 3; 4347 char *endp; 4348 unsigned long scope; 4349 if(strncmp("%25", percent, 3) != 0) { 4350 infof(data, 4351 "Please URL encode %% as %%25, see RFC 6874.\n"); 4352 identifier_offset = 1; 4353 } 4354 scope = strtoul(percent + identifier_offset, &endp, 10); 4355 if(*endp == ']') { 4356 /* The address scope was well formed. Knock it out of the 4357 hostname. */ 4358 memmove(percent, endp, strlen(endp)+1); 4359 conn->scope_id = (unsigned int)scope; 4360 } 4361 else { 4362 /* Zone identifier is not numeric */ 4363#if defined(HAVE_NET_IF_H) && defined(IFNAMSIZ) && defined(HAVE_IF_NAMETOINDEX) 4364 char ifname[IFNAMSIZ + 2]; 4365 char *square_bracket; 4366 unsigned int scopeidx = 0; 4367 strncpy(ifname, percent + identifier_offset, IFNAMSIZ + 2); 4368 /* Ensure nullbyte termination */ 4369 ifname[IFNAMSIZ + 1] = '\0'; 4370 square_bracket = strchr(ifname, ']'); 4371 if(square_bracket) { 4372 /* Remove ']' */ 4373 *square_bracket = '\0'; 4374 scopeidx = if_nametoindex(ifname); 4375 if(scopeidx == 0) { 4376 infof(data, "Invalid network interface: %s; %s\n", ifname, 4377 strerror(errno)); 4378 } 4379 } 4380 if(scopeidx > 0) { 4381 char *p = percent + identifier_offset + strlen(ifname); 4382 4383 /* Remove zone identifier from hostname */ 4384 memmove(percent, p, strlen(p) + 1); 4385 conn->scope_id = scopeidx; 4386 } 4387 else 4388#endif /* HAVE_NET_IF_H && IFNAMSIZ */ 4389 infof(data, "Invalid IPv6 address format\n"); 4390 } 4391 } 4392 } 4393 4394 if(data->set.scope_id) 4395 /* Override any scope that was set above. */ 4396 conn->scope_id = data->set.scope_id; 4397 4398 /* Remove the fragment part of the path. Per RFC 2396, this is always the 4399 last part of the URI. We are looking for the first '#' so that we deal 4400 gracefully with non conformant URI such as http://example.com#foo#bar. */ 4401 fragment = strchr(path, '#'); 4402 if(fragment) { 4403 *fragment = 0; 4404 4405 /* we know the path part ended with a fragment, so we know the full URL 4406 string does too and we need to cut it off from there so it isn't used 4407 over proxy */ 4408 fragment = strchr(data->change.url, '#'); 4409 if(fragment) 4410 *fragment = 0; 4411 } 4412 4413 /* 4414 * So if the URL was A://B/C#D, 4415 * protop is A 4416 * conn->host.name is B 4417 * data->state.path is /C 4418 */ 4419 4420 return findprotocol(data, conn, protop); 4421} 4422 4423/* 4424 * If we're doing a resumed transfer, we need to setup our stuff 4425 * properly. 4426 */ 4427static CURLcode setup_range(struct Curl_easy *data) 4428{ 4429 struct UrlState *s = &data->state; 4430 s->resume_from = data->set.set_resume_from; 4431 if(s->resume_from || data->set.str[STRING_SET_RANGE]) { 4432 if(s->rangestringalloc) 4433 free(s->range); 4434 4435 if(s->resume_from) 4436 s->range = aprintf("%" CURL_FORMAT_CURL_OFF_TU "-", s->resume_from); 4437 else 4438 s->range = strdup(data->set.str[STRING_SET_RANGE]); 4439 4440 s->rangestringalloc = (s->range) ? TRUE : FALSE; 4441 4442 if(!s->range) 4443 return CURLE_OUT_OF_MEMORY; 4444 4445 /* tell ourselves to fetch this range */ 4446 s->use_range = TRUE; /* enable range download */ 4447 } 4448 else 4449 s->use_range = FALSE; /* disable range download */ 4450 4451 return CURLE_OK; 4452} 4453 4454 4455/* 4456 * setup_connection_internals() - 4457 * 4458 * Setup connection internals specific to the requested protocol in the 4459 * Curl_easy. This is inited and setup before the connection is made but 4460 * is about the particular protocol that is to be used. 4461 * 4462 * This MUST get called after proxy magic has been figured out. 4463 */ 4464static CURLcode setup_connection_internals(struct connectdata *conn) 4465{ 4466 const struct Curl_handler * p; 4467 CURLcode result; 4468 struct Curl_easy *data = conn->data; 4469 4470 /* in some case in the multi state-machine, we go back to the CONNECT state 4471 and then a second (or third or...) call to this function will be made 4472 without doing a DISCONNECT or DONE in between (since the connection is 4473 yet in place) and therefore this function needs to first make sure 4474 there's no lingering previous data allocated. */ 4475 Curl_free_request_state(data); 4476 4477 memset(&data->req, 0, sizeof(struct SingleRequest)); 4478 data->req.maxdownload = -1; 4479 4480 conn->socktype = SOCK_STREAM; /* most of them are TCP streams */ 4481 4482 /* Perform setup complement if some. */ 4483 p = conn->handler; 4484 4485 if(p->setup_connection) { 4486 result = (*p->setup_connection)(conn); 4487 4488 if(result) 4489 return result; 4490 4491 p = conn->handler; /* May have changed. */ 4492 } 4493 4494 if(conn->port < 0) 4495 /* we check for -1 here since if proxy was detected already, this 4496 was very likely already set to the proxy port */ 4497 conn->port = p->defport; 4498 4499 return CURLE_OK; 4500} 4501 4502/* 4503 * Curl_free_request_state() should free temp data that was allocated in the 4504 * Curl_easy for this single request. 4505 */ 4506 4507void Curl_free_request_state(struct Curl_easy *data) 4508{ 4509 Curl_safefree(data->req.protop); 4510 Curl_safefree(data->req.newurl); 4511} 4512 4513 4514#ifndef CURL_DISABLE_PROXY 4515/**************************************************************** 4516* Checks if the host is in the noproxy list. returns true if it matches 4517* and therefore the proxy should NOT be used. 4518****************************************************************/ 4519static bool check_noproxy(const char* name, const char* no_proxy) 4520{ 4521 /* no_proxy=domain1.dom,host.domain2.dom 4522 * (a comma-separated list of hosts which should 4523 * not be proxied, or an asterisk to override 4524 * all proxy variables) 4525 */ 4526 size_t tok_start; 4527 size_t tok_end; 4528 const char* separator = ", "; 4529 size_t no_proxy_len; 4530 size_t namelen; 4531 char *endptr; 4532 4533 if(no_proxy && no_proxy[0]) { 4534 if(Curl_raw_equal("*", no_proxy)) { 4535 return TRUE; 4536 } 4537 4538 /* NO_PROXY was specified and it wasn't just an asterisk */ 4539 4540 no_proxy_len = strlen(no_proxy); 4541 endptr = strchr(name, ':'); 4542 if(endptr) 4543 namelen = endptr - name; 4544 else 4545 namelen = strlen(name); 4546 4547 for(tok_start = 0; tok_start < no_proxy_len; tok_start = tok_end + 1) { 4548 while(tok_start < no_proxy_len && 4549 strchr(separator, no_proxy[tok_start]) != NULL) { 4550 /* Look for the beginning of the token. */ 4551 ++tok_start; 4552 } 4553 4554 if(tok_start == no_proxy_len) 4555 break; /* It was all trailing separator chars, no more tokens. */ 4556 4557 for(tok_end = tok_start; tok_end < no_proxy_len && 4558 strchr(separator, no_proxy[tok_end]) == NULL; ++tok_end) 4559 /* Look for the end of the token. */ 4560 ; 4561 4562 /* To match previous behaviour, where it was necessary to specify 4563 * ".local.com" to prevent matching "notlocal.com", we will leave 4564 * the '.' off. 4565 */ 4566 if(no_proxy[tok_start] == '.') 4567 ++tok_start; 4568 4569 if((tok_end - tok_start) <= namelen) { 4570 /* Match the last part of the name to the domain we are checking. */ 4571 const char *checkn = name + namelen - (tok_end - tok_start); 4572 if(Curl_raw_nequal(no_proxy + tok_start, checkn, 4573 tok_end - tok_start)) { 4574 if((tok_end - tok_start) == namelen || *(checkn - 1) == '.') { 4575 /* We either have an exact match, or the previous character is a . 4576 * so it is within the same domain, so no proxy for this host. 4577 */ 4578 return TRUE; 4579 } 4580 } 4581 } /* if((tok_end - tok_start) <= namelen) */ 4582 } /* for(tok_start = 0; tok_start < no_proxy_len; 4583 tok_start = tok_end + 1) */ 4584 } /* NO_PROXY was specified and it wasn't just an asterisk */ 4585 4586 return FALSE; 4587} 4588 4589/**************************************************************** 4590* Detect what (if any) proxy to use. Remember that this selects a host 4591* name and is not limited to HTTP proxies only. 4592* The returned pointer must be freed by the caller (unless NULL) 4593****************************************************************/ 4594static char *detect_proxy(struct connectdata *conn) 4595{ 4596 char *proxy = NULL; 4597 4598#ifndef CURL_DISABLE_HTTP 4599 /* If proxy was not specified, we check for default proxy environment 4600 * variables, to enable i.e Lynx compliance: 4601 * 4602 * http_proxy=http://some.server.dom:port/ 4603 * https_proxy=http://some.server.dom:port/ 4604 * ftp_proxy=http://some.server.dom:port/ 4605 * no_proxy=domain1.dom,host.domain2.dom 4606 * (a comma-separated list of hosts which should 4607 * not be proxied, or an asterisk to override 4608 * all proxy variables) 4609 * all_proxy=http://some.server.dom:port/ 4610 * (seems to exist for the CERN www lib. Probably 4611 * the first to check for.) 4612 * 4613 * For compatibility, the all-uppercase versions of these variables are 4614 * checked if the lowercase versions don't exist. 4615 */ 4616 char *no_proxy=NULL; 4617 char proxy_env[128]; 4618 4619 no_proxy=curl_getenv("no_proxy"); 4620 if(!no_proxy) 4621 no_proxy=curl_getenv("NO_PROXY"); 4622 4623 if(!check_noproxy(conn->host.name, no_proxy)) { 4624 /* It was not listed as without proxy */ 4625 const char *protop = conn->handler->scheme; 4626 char *envp = proxy_env; 4627 char *prox; 4628 4629 /* Now, build <protocol>_proxy and check for such a one to use */ 4630 while(*protop) 4631 *envp++ = (char)tolower((int)*protop++); 4632 4633 /* append _proxy */ 4634 strcpy(envp, "_proxy"); 4635 4636 /* read the protocol proxy: */ 4637 prox=curl_getenv(proxy_env); 4638 4639 /* 4640 * We don't try the uppercase version of HTTP_PROXY because of 4641 * security reasons: 4642 * 4643 * When curl is used in a webserver application 4644 * environment (cgi or php), this environment variable can 4645 * be controlled by the web server user by setting the 4646 * http header 'Proxy:' to some value. 4647 * 4648 * This can cause 'internal' http/ftp requests to be 4649 * arbitrarily redirected by any external attacker. 4650 */ 4651 if(!prox && !Curl_raw_equal("http_proxy", proxy_env)) { 4652 /* There was no lowercase variable, try the uppercase version: */ 4653 Curl_strntoupper(proxy_env, proxy_env, sizeof(proxy_env)); 4654 prox=curl_getenv(proxy_env); 4655 } 4656 4657 if(prox) 4658 proxy = prox; /* use this */ 4659 else { 4660 proxy = curl_getenv("all_proxy"); /* default proxy to use */ 4661 if(!proxy) 4662 proxy=curl_getenv("ALL_PROXY"); 4663 } 4664 } /* if(!check_noproxy(conn->host.name, no_proxy)) - it wasn't specified 4665 non-proxy */ 4666 free(no_proxy); 4667 4668#else /* !CURL_DISABLE_HTTP */ 4669 4670 (void)conn; 4671#endif /* CURL_DISABLE_HTTP */ 4672 4673 return proxy; 4674} 4675 4676/* 4677 * If this is supposed to use a proxy, we need to figure out the proxy 4678 * host name, so that we can re-use an existing connection 4679 * that may exist registered to the same proxy host. 4680 */ 4681static CURLcode parse_proxy(struct Curl_easy *data, 4682 struct connectdata *conn, char *proxy) 4683{ 4684 char *prox_portno; 4685 char *endofprot; 4686 4687 /* We use 'proxyptr' to point to the proxy name from now on... */ 4688 char *proxyptr; 4689 char *portptr; 4690 char *atsign; 4691 4692 /* We do the proxy host string parsing here. We want the host name and the 4693 * port name. Accept a protocol:// prefix 4694 */ 4695 4696 /* Parse the protocol part if present */ 4697 endofprot = strstr(proxy, "://"); 4698 if(endofprot) { 4699 proxyptr = endofprot+3; 4700 if(checkprefix("socks5h", proxy)) 4701 conn->proxytype = CURLPROXY_SOCKS5_HOSTNAME; 4702 else if(checkprefix("socks5", proxy)) 4703 conn->proxytype = CURLPROXY_SOCKS5; 4704 else if(checkprefix("socks4a", proxy)) 4705 conn->proxytype = CURLPROXY_SOCKS4A; 4706 else if(checkprefix("socks4", proxy) || checkprefix("socks", proxy)) 4707 conn->proxytype = CURLPROXY_SOCKS4; 4708 /* Any other xxx:// : change to http proxy */ 4709 } 4710 else 4711 proxyptr = proxy; /* No xxx:// head: It's a HTTP proxy */ 4712 4713 /* Is there a username and password given in this proxy url? */ 4714 atsign = strchr(proxyptr, '@'); 4715 if(atsign) { 4716 char *proxyuser = NULL; 4717 char *proxypasswd = NULL; 4718 CURLcode result = 4719 parse_login_details(proxyptr, atsign - proxyptr, 4720 &proxyuser, &proxypasswd, NULL); 4721 if(!result) { 4722 /* found user and password, rip them out. note that we are 4723 unescaping them, as there is otherwise no way to have a 4724 username or password with reserved characters like ':' in 4725 them. */ 4726 Curl_safefree(conn->proxyuser); 4727 if(proxyuser && strlen(proxyuser) < MAX_CURL_USER_LENGTH) 4728 conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL); 4729 else 4730 conn->proxyuser = strdup(""); 4731 4732 if(!conn->proxyuser) 4733 result = CURLE_OUT_OF_MEMORY; 4734 else { 4735 Curl_safefree(conn->proxypasswd); 4736 if(proxypasswd && strlen(proxypasswd) < MAX_CURL_PASSWORD_LENGTH) 4737 conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL); 4738 else 4739 conn->proxypasswd = strdup(""); 4740 4741 if(!conn->proxypasswd) 4742 result = CURLE_OUT_OF_MEMORY; 4743 } 4744 4745 if(!result) { 4746 conn->bits.proxy_user_passwd = TRUE; /* enable it */ 4747 atsign++; /* the right side of the @-letter */ 4748 4749 proxyptr = atsign; /* now use this instead */ 4750 } 4751 } 4752 4753 free(proxyuser); 4754 free(proxypasswd); 4755 4756 if(result) 4757 return result; 4758 } 4759 4760 /* start scanning for port number at this point */ 4761 portptr = proxyptr; 4762 4763 /* detect and extract RFC6874-style IPv6-addresses */ 4764 if(*proxyptr == '[') { 4765 char *ptr = ++proxyptr; /* advance beyond the initial bracket */ 4766 while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '.'))) 4767 ptr++; 4768 if(*ptr == '%') { 4769 /* There might be a zone identifier */ 4770 if(strncmp("%25", ptr, 3)) 4771 infof(data, "Please URL encode %% as %%25, see RFC 6874.\n"); 4772 ptr++; 4773 /* Allow unreserved characters as defined in RFC 3986 */ 4774 while(*ptr && (ISALPHA(*ptr) || ISXDIGIT(*ptr) || (*ptr == '-') || 4775 (*ptr == '.') || (*ptr == '_') || (*ptr == '~'))) 4776 ptr++; 4777 } 4778 if(*ptr == ']') 4779 /* yeps, it ended nicely with a bracket as well */ 4780 *ptr++ = 0; 4781 else 4782 infof(data, "Invalid IPv6 address format\n"); 4783 portptr = ptr; 4784 /* Note that if this didn't end with a bracket, we still advanced the 4785 * proxyptr first, but I can't see anything wrong with that as no host 4786 * name nor a numeric can legally start with a bracket. 4787 */ 4788 } 4789 4790 /* Get port number off proxy.server.com:1080 */ 4791 prox_portno = strchr(portptr, ':'); 4792 if(prox_portno) { 4793 char *endp = NULL; 4794 long port = 0; 4795 *prox_portno = 0x0; /* cut off number from host name */ 4796 prox_portno ++; 4797 /* now set the local port number */ 4798 port = strtol(prox_portno, &endp, 10); 4799 if((endp && *endp && (*endp != '/') && (*endp != ' ')) || 4800 (port < 0) || (port > 65535)) { 4801 /* meant to detect for example invalid IPv6 numerical addresses without 4802 brackets: "2a00:fac0:a000::7:13". Accept a trailing slash only 4803 because we then allow "URL style" with the number followed by a 4804 slash, used in curl test cases already. Space is also an acceptable 4805 terminating symbol. */ 4806 infof(data, "No valid port number in proxy string (%s)\n", 4807 prox_portno); 4808 } 4809 else 4810 conn->port = port; 4811 } 4812 else { 4813 if(proxyptr[0]=='/') 4814 /* If the first character in the proxy string is a slash, fail 4815 immediately. The following code will otherwise clear the string which 4816 will lead to code running as if no proxy was set! */ 4817 return CURLE_COULDNT_RESOLVE_PROXY; 4818 4819 /* without a port number after the host name, some people seem to use 4820 a slash so we strip everything from the first slash */ 4821 atsign = strchr(proxyptr, '/'); 4822 if(atsign) 4823 *atsign = '\0'; /* cut off path part from host name */ 4824 4825 if(data->set.proxyport) 4826 /* None given in the proxy string, then get the default one if it is 4827 given */ 4828 conn->port = data->set.proxyport; 4829 } 4830 4831 /* now, clone the cleaned proxy host name */ 4832 conn->proxy.rawalloc = strdup(proxyptr); 4833 conn->proxy.name = conn->proxy.rawalloc; 4834 4835 if(!conn->proxy.rawalloc) 4836 return CURLE_OUT_OF_MEMORY; 4837 4838 return CURLE_OK; 4839} 4840 4841/* 4842 * Extract the user and password from the authentication string 4843 */ 4844static CURLcode parse_proxy_auth(struct Curl_easy *data, 4845 struct connectdata *conn) 4846{ 4847 char proxyuser[MAX_CURL_USER_LENGTH]=""; 4848 char proxypasswd[MAX_CURL_PASSWORD_LENGTH]=""; 4849 4850 if(data->set.str[STRING_PROXYUSERNAME] != NULL) { 4851 strncpy(proxyuser, data->set.str[STRING_PROXYUSERNAME], 4852 MAX_CURL_USER_LENGTH); 4853 proxyuser[MAX_CURL_USER_LENGTH-1] = '\0'; /*To be on safe side*/ 4854 } 4855 if(data->set.str[STRING_PROXYPASSWORD] != NULL) { 4856 strncpy(proxypasswd, data->set.str[STRING_PROXYPASSWORD], 4857 MAX_CURL_PASSWORD_LENGTH); 4858 proxypasswd[MAX_CURL_PASSWORD_LENGTH-1] = '\0'; /*To be on safe side*/ 4859 } 4860 4861 conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL); 4862 if(!conn->proxyuser) 4863 return CURLE_OUT_OF_MEMORY; 4864 4865 conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL); 4866 if(!conn->proxypasswd) 4867 return CURLE_OUT_OF_MEMORY; 4868 4869 return CURLE_OK; 4870} 4871#endif /* CURL_DISABLE_PROXY */ 4872 4873/* 4874 * parse_url_login() 4875 * 4876 * Parse the login details (user name, password and options) from the URL and 4877 * strip them out of the host name 4878 * 4879 * Inputs: data->set.use_netrc (CURLOPT_NETRC) 4880 * conn->host.name 4881 * 4882 * Outputs: (almost :- all currently undefined) 4883 * conn->bits.user_passwd - non-zero if non-default passwords exist 4884 * user - non-zero length if defined 4885 * passwd - non-zero length if defined 4886 * options - non-zero length if defined 4887 * conn->host.name - remove user name and password 4888 */ 4889static CURLcode parse_url_login(struct Curl_easy *data, 4890 struct connectdata *conn, 4891 char **user, char **passwd, char **options) 4892{ 4893 CURLcode result = CURLE_OK; 4894 char *userp = NULL; 4895 char *passwdp = NULL; 4896 char *optionsp = NULL; 4897 4898 /* At this point, we're hoping all the other special cases have 4899 * been taken care of, so conn->host.name is at most 4900 * [user[:password][;options]]@]hostname 4901 * 4902 * We need somewhere to put the embedded details, so do that first. 4903 */ 4904 4905 char *ptr = strchr(conn->host.name, '@'); 4906 char *login = conn->host.name; 4907 4908 DEBUGASSERT(!**user); 4909 DEBUGASSERT(!**passwd); 4910 DEBUGASSERT(!**options); 4911 4912 if(!ptr) 4913 goto out; 4914 4915 /* We will now try to extract the 4916 * possible login information in a string like: 4917 * ftp://user:password@ftp.my.site:8021/README */ 4918 conn->host.name = ++ptr; 4919 4920 /* So the hostname is sane. Only bother interpreting the 4921 * results if we could care. It could still be wasted 4922 * work because it might be overtaken by the programmatically 4923 * set user/passwd, but doing that first adds more cases here :-( 4924 */ 4925 4926 if(data->set.use_netrc == CURL_NETRC_REQUIRED) 4927 goto out; 4928 4929 /* We could use the login information in the URL so extract it */ 4930 result = parse_login_details(login, ptr - login - 1, 4931 &userp, &passwdp, &optionsp); 4932 if(result) 4933 goto out; 4934 4935 if(userp) { 4936 char *newname; 4937 4938 /* We have a user in the URL */ 4939 conn->bits.userpwd_in_url = TRUE; 4940 conn->bits.user_passwd = TRUE; /* enable user+password */ 4941 4942 /* Decode the user */ 4943 newname = curl_easy_unescape(data, userp, 0, NULL); 4944 if(!newname) { 4945 result = CURLE_OUT_OF_MEMORY; 4946 goto out; 4947 } 4948 4949 free(*user); 4950 *user = newname; 4951 } 4952 4953 if(passwdp) { 4954 /* We have a password in the URL so decode it */ 4955 char *newpasswd = curl_easy_unescape(data, passwdp, 0, NULL); 4956 if(!newpasswd) { 4957 result = CURLE_OUT_OF_MEMORY; 4958 goto out; 4959 } 4960 4961 free(*passwd); 4962 *passwd = newpasswd; 4963 } 4964 4965 if(optionsp) { 4966 /* We have an options list in the URL so decode it */ 4967 char *newoptions = curl_easy_unescape(data, optionsp, 0, NULL); 4968 if(!newoptions) { 4969 result = CURLE_OUT_OF_MEMORY; 4970 goto out; 4971 } 4972 4973 free(*options); 4974 *options = newoptions; 4975 } 4976 4977 4978 out: 4979 4980 free(userp); 4981 free(passwdp); 4982 free(optionsp); 4983 4984 return result; 4985} 4986 4987/* 4988 * parse_login_details() 4989 * 4990 * This is used to parse a login string for user name, password and options in 4991 * the following formats: 4992 * 4993 * user 4994 * user:password 4995 * user:password;options 4996 * user;options 4997 * user;options:password 4998 * :password 4999 * :password;options 5000 * ;options 5001 * ;options:password 5002 * 5003 * Parameters: 5004 * 5005 * login [in] - The login string. 5006 * len [in] - The length of the login string. 5007 * userp [in/out] - The address where a pointer to newly allocated memory 5008 * holding the user will be stored upon completion. 5009 * passdwp [in/out] - The address where a pointer to newly allocated memory 5010 * holding the password will be stored upon completion. 5011 * optionsp [in/out] - The address where a pointer to newly allocated memory 5012 * holding the options will be stored upon completion. 5013 * 5014 * Returns CURLE_OK on success. 5015 */ 5016static CURLcode parse_login_details(const char *login, const size_t len, 5017 char **userp, char **passwdp, 5018 char **optionsp) 5019{ 5020 CURLcode result = CURLE_OK; 5021 char *ubuf = NULL; 5022 char *pbuf = NULL; 5023 char *obuf = NULL; 5024 const char *psep = NULL; 5025 const char *osep = NULL; 5026 size_t ulen; 5027 size_t plen; 5028 size_t olen; 5029 5030 /* Attempt to find the password separator */ 5031 if(passwdp) { 5032 psep = strchr(login, ':'); 5033 5034 /* Within the constraint of the login string */ 5035 if(psep >= login + len) 5036 psep = NULL; 5037 } 5038 5039 /* Attempt to find the options separator */ 5040 if(optionsp) { 5041 osep = strchr(login, ';'); 5042 5043 /* Within the constraint of the login string */ 5044 if(osep >= login + len) 5045 osep = NULL; 5046 } 5047 5048 /* Calculate the portion lengths */ 5049 ulen = (psep ? 5050 (size_t)(osep && psep > osep ? osep - login : psep - login) : 5051 (osep ? (size_t)(osep - login) : len)); 5052 plen = (psep ? 5053 (osep && osep > psep ? (size_t)(osep - psep) : 5054 (size_t)(login + len - psep)) - 1 : 0); 5055 olen = (osep ? 5056 (psep && psep > osep ? (size_t)(psep - osep) : 5057 (size_t)(login + len - osep)) - 1 : 0); 5058 5059 /* Allocate the user portion buffer */ 5060 if(userp && ulen) { 5061 ubuf = malloc(ulen + 1); 5062 if(!ubuf) 5063 result = CURLE_OUT_OF_MEMORY; 5064 } 5065 5066 /* Allocate the password portion buffer */ 5067 if(!result && passwdp && plen) { 5068 pbuf = malloc(plen + 1); 5069 if(!pbuf) { 5070 free(ubuf); 5071 result = CURLE_OUT_OF_MEMORY; 5072 } 5073 } 5074 5075 /* Allocate the options portion buffer */ 5076 if(!result && optionsp && olen) { 5077 obuf = malloc(olen + 1); 5078 if(!obuf) { 5079 free(pbuf); 5080 free(ubuf); 5081 result = CURLE_OUT_OF_MEMORY; 5082 } 5083 } 5084 5085 if(!result) { 5086 /* Store the user portion if necessary */ 5087 if(ubuf) { 5088 memcpy(ubuf, login, ulen); 5089 ubuf[ulen] = '\0'; 5090 Curl_safefree(*userp); 5091 *userp = ubuf; 5092 } 5093 5094 /* Store the password portion if necessary */ 5095 if(pbuf) { 5096 memcpy(pbuf, psep + 1, plen); 5097 pbuf[plen] = '\0'; 5098 Curl_safefree(*passwdp); 5099 *passwdp = pbuf; 5100 } 5101 5102 /* Store the options portion if necessary */ 5103 if(obuf) { 5104 memcpy(obuf, osep + 1, olen); 5105 obuf[olen] = '\0'; 5106 Curl_safefree(*optionsp); 5107 *optionsp = obuf; 5108 } 5109 } 5110 5111 return result; 5112} 5113 5114/************************************************************* 5115 * Figure out the remote port number and fix it in the URL 5116 * 5117 * No matter if we use a proxy or not, we have to figure out the remote 5118 * port number of various reasons. 5119 * 5120 * To be able to detect port number flawlessly, we must not confuse them 5121 * IPv6-specified addresses in the [0::1] style. (RFC2732) 5122 * 5123 * The conn->host.name is currently [user:passwd@]host[:port] where host 5124 * could be a hostname, IPv4 address or IPv6 address. 5125 * 5126 * The port number embedded in the URL is replaced, if necessary. 5127 *************************************************************/ 5128static CURLcode parse_remote_port(struct Curl_easy *data, 5129 struct connectdata *conn) 5130{ 5131 char *portptr; 5132 char endbracket; 5133 5134 /* Note that at this point, the IPv6 address cannot contain any scope 5135 suffix as that has already been removed in the parseurlandfillconn() 5136 function */ 5137 if((1 == sscanf(conn->host.name, "[%*45[0123456789abcdefABCDEF:.]%c", 5138 &endbracket)) && 5139 (']' == endbracket)) { 5140 /* this is a RFC2732-style specified IP-address */ 5141 conn->bits.ipv6_ip = TRUE; 5142 5143 conn->host.name++; /* skip over the starting bracket */ 5144 portptr = strchr(conn->host.name, ']'); 5145 if(portptr) { 5146 *portptr++ = '\0'; /* zero terminate, killing the bracket */ 5147 if(':' != *portptr) 5148 portptr = NULL; /* no port number available */ 5149 } 5150 } 5151 else { 5152#ifdef ENABLE_IPV6 5153 struct in6_addr in6; 5154 if(Curl_inet_pton(AF_INET6, conn->host.name, &in6) > 0) { 5155 /* This is a numerical IPv6 address, meaning this is a wrongly formatted 5156 URL */ 5157 failf(data, "IPv6 numerical address used in URL without brackets"); 5158 return CURLE_URL_MALFORMAT; 5159 } 5160#endif 5161 5162 portptr = strrchr(conn->host.name, ':'); 5163 } 5164 5165 if(data->set.use_port && data->state.allow_port) { 5166 /* if set, we use this and ignore the port possibly given in the URL */ 5167 conn->remote_port = (unsigned short)data->set.use_port; 5168 if(portptr) 5169 *portptr = '\0'; /* cut off the name there anyway - if there was a port 5170 number - since the port number is to be ignored! */ 5171 if(conn->bits.httpproxy) { 5172 /* we need to create new URL with the new port number */ 5173 char *url; 5174 char type[12]=""; 5175 5176 if(conn->bits.type_set) 5177 snprintf(type, sizeof(type), ";type=%c", 5178 data->set.prefer_ascii?'A': 5179 (data->set.ftp_list_only?'D':'I')); 5180 5181 /* 5182 * This synthesized URL isn't always right--suffixes like ;type=A are 5183 * stripped off. It would be better to work directly from the original 5184 * URL and simply replace the port part of it. 5185 */ 5186 url = aprintf("%s://%s%s%s:%hu%s%s%s", conn->given->scheme, 5187 conn->bits.ipv6_ip?"[":"", conn->host.name, 5188 conn->bits.ipv6_ip?"]":"", conn->remote_port, 5189 data->state.slash_removed?"/":"", data->state.path, 5190 type); 5191 if(!url) 5192 return CURLE_OUT_OF_MEMORY; 5193 5194 if(data->change.url_alloc) { 5195 Curl_safefree(data->change.url); 5196 data->change.url_alloc = FALSE; 5197 } 5198 5199 data->change.url = url; 5200 data->change.url_alloc = TRUE; 5201 } 5202 } 5203 else if(portptr) { 5204 /* no CURLOPT_PORT given, extract the one from the URL */ 5205 5206 char *rest; 5207 long port; 5208 5209 port=strtol(portptr+1, &rest, 10); /* Port number must be decimal */ 5210 5211 if((port < 0) || (port > 0xffff)) { 5212 /* Single unix standard says port numbers are 16 bits long */ 5213 failf(data, "Port number out of range"); 5214 return CURLE_URL_MALFORMAT; 5215 } 5216 5217 else if(rest != &portptr[1]) { 5218 *portptr = '\0'; /* cut off the name there */ 5219 conn->remote_port = curlx_ultous(port); 5220 } 5221 else 5222 /* Browser behavior adaptation. If there's a colon with no digits after, 5223 just cut off the name there which makes us ignore the colon and just 5224 use the default port. Firefox and Chrome both do that. */ 5225 *portptr = '\0'; 5226 } 5227 5228 /* only if remote_port was not already parsed off the URL we use the 5229 default port number */ 5230 if(conn->remote_port < 0) 5231 conn->remote_port = (unsigned short)conn->given->defport; 5232 5233 return CURLE_OK; 5234} 5235 5236/* 5237 * Override the login details from the URL with that in the CURLOPT_USERPWD 5238 * option or a .netrc file, if applicable. 5239 */ 5240static CURLcode override_login(struct Curl_easy *data, 5241 struct connectdata *conn, 5242 char **userp, char **passwdp, char **optionsp) 5243{ 5244 if(data->set.str[STRING_USERNAME]) { 5245 free(*userp); 5246 *userp = strdup(data->set.str[STRING_USERNAME]); 5247 if(!*userp) 5248 return CURLE_OUT_OF_MEMORY; 5249 } 5250 5251 if(data->set.str[STRING_PASSWORD]) { 5252 free(*passwdp); 5253 *passwdp = strdup(data->set.str[STRING_PASSWORD]); 5254 if(!*passwdp) 5255 return CURLE_OUT_OF_MEMORY; 5256 } 5257 5258 if(data->set.str[STRING_OPTIONS]) { 5259 free(*optionsp); 5260 *optionsp = strdup(data->set.str[STRING_OPTIONS]); 5261 if(!*optionsp) 5262 return CURLE_OUT_OF_MEMORY; 5263 } 5264 5265 conn->bits.netrc = FALSE; 5266 if(data->set.use_netrc != CURL_NETRC_IGNORED) { 5267 int ret = Curl_parsenetrc(conn->host.name, 5268 userp, passwdp, 5269 data->set.str[STRING_NETRC_FILE]); 5270 if(ret > 0) { 5271 infof(data, "Couldn't find host %s in the " 5272 DOT_CHAR "netrc file; using defaults\n", 5273 conn->host.name); 5274 } 5275 else if(ret < 0) { 5276 return CURLE_OUT_OF_MEMORY; 5277 } 5278 else { 5279 /* set bits.netrc TRUE to remember that we got the name from a .netrc 5280 file, so that it is safe to use even if we followed a Location: to a 5281 different host or similar. */ 5282 conn->bits.netrc = TRUE; 5283 5284 conn->bits.user_passwd = TRUE; /* enable user+password */ 5285 } 5286 } 5287 5288 return CURLE_OK; 5289} 5290 5291/* 5292 * Set the login details so they're available in the connection 5293 */ 5294static CURLcode set_login(struct connectdata *conn, 5295 const char *user, const char *passwd, 5296 const char *options) 5297{ 5298 CURLcode result = CURLE_OK; 5299 5300 /* If our protocol needs a password and we have none, use the defaults */ 5301 if((conn->handler->flags & PROTOPT_NEEDSPWD) && !conn->bits.user_passwd) { 5302 /* Store the default user */ 5303 conn->user = strdup(CURL_DEFAULT_USER); 5304 5305 /* Store the default password */ 5306 if(conn->user) 5307 conn->passwd = strdup(CURL_DEFAULT_PASSWORD); 5308 else 5309 conn->passwd = NULL; 5310 5311 /* This is the default password, so DON'T set conn->bits.user_passwd */ 5312 } 5313 else { 5314 /* Store the user, zero-length if not set */ 5315 conn->user = strdup(user); 5316 5317 /* Store the password (only if user is present), zero-length if not set */ 5318 if(conn->user) 5319 conn->passwd = strdup(passwd); 5320 else 5321 conn->passwd = NULL; 5322 } 5323 5324 if(!conn->user || !conn->passwd) 5325 result = CURLE_OUT_OF_MEMORY; 5326 5327 /* Store the options, null if not set */ 5328 if(!result && options[0]) { 5329 conn->options = strdup(options); 5330 5331 if(!conn->options) 5332 result = CURLE_OUT_OF_MEMORY; 5333 } 5334 5335 return result; 5336} 5337 5338/* 5339 * Parses a "host:port" string to connect to. 5340 * The hostname and the port may be empty; in this case, NULL is returned for 5341 * the hostname and -1 for the port. 5342 */ 5343static CURLcode parse_connect_to_host_port(struct Curl_easy *data, 5344 const char *host, 5345 char **hostname_result, 5346 int *port_result) 5347{ 5348 char *host_dup; 5349 char *hostptr; 5350 char *host_portno; 5351 char *portptr; 5352 int port = -1; 5353 5354 *hostname_result = NULL; 5355 *port_result = -1; 5356 5357 if(!host || !*host) 5358 return CURLE_OK; 5359 5360 host_dup = strdup(host); 5361 if(!host_dup) 5362 return CURLE_OUT_OF_MEMORY; 5363 5364 hostptr = host_dup; 5365 5366 /* start scanning for port number at this point */ 5367 portptr = hostptr; 5368 5369 /* detect and extract RFC6874-style IPv6-addresses */ 5370 if(*hostptr == '[') { 5371 char *ptr = ++hostptr; /* advance beyond the initial bracket */ 5372 while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '.'))) 5373 ptr++; 5374 if(*ptr == '%') { 5375 /* There might be a zone identifier */ 5376 if(strncmp("%25", ptr, 3)) 5377 infof(data, "Please URL encode %% as %%25, see RFC 6874.\n"); 5378 ptr++; 5379 /* Allow unreserved characters as defined in RFC 3986 */ 5380 while(*ptr && (ISALPHA(*ptr) || ISXDIGIT(*ptr) || (*ptr == '-') || 5381 (*ptr == '.') || (*ptr == '_') || (*ptr == '~'))) 5382 ptr++; 5383 } 5384 if(*ptr == ']') 5385 /* yeps, it ended nicely with a bracket as well */ 5386 *ptr++ = '\0'; 5387 else 5388 infof(data, "Invalid IPv6 address format\n"); 5389 portptr = ptr; 5390 /* Note that if this didn't end with a bracket, we still advanced the 5391 * hostptr first, but I can't see anything wrong with that as no host 5392 * name nor a numeric can legally start with a bracket. 5393 */ 5394 } 5395 5396 /* Get port number off server.com:1080 */ 5397 host_portno = strchr(portptr, ':'); 5398 if(host_portno) { 5399 char *endp = NULL; 5400 *host_portno = '\0'; /* cut off number from host name */ 5401 host_portno++; 5402 if(*host_portno) { 5403 long portparse = strtol(host_portno, &endp, 10); 5404 if((endp && *endp) || (portparse < 0) || (portparse > 65535)) { 5405 infof(data, "No valid port number in connect to host string (%s)\n", 5406 host_portno); 5407 hostptr = NULL; 5408 port = -1; 5409 } 5410 else 5411 port = (int)portparse; /* we know it will fit */ 5412 } 5413 } 5414 5415 /* now, clone the cleaned host name */ 5416 if(hostptr) { 5417 *hostname_result = strdup(hostptr); 5418 if(!*hostname_result) { 5419 free(host_dup); 5420 return CURLE_OUT_OF_MEMORY; 5421 } 5422 } 5423 5424 *port_result = port; 5425 5426 free(host_dup); 5427 return CURLE_OK; 5428} 5429 5430/* 5431 * Parses one "connect to" string in the form: 5432 * "HOST:PORT:CONNECT-TO-HOST:CONNECT-TO-PORT". 5433 */ 5434static CURLcode parse_connect_to_string(struct Curl_easy *data, 5435 struct connectdata *conn, 5436 const char *conn_to_host, 5437 char **host_result, 5438 int *port_result) 5439{ 5440 CURLcode result = CURLE_OK; 5441 const char *ptr = conn_to_host; 5442 int host_match = FALSE; 5443 int port_match = FALSE; 5444 5445 if(*ptr == ':') { 5446 /* an empty hostname always matches */ 5447 host_match = TRUE; 5448 ptr++; 5449 } 5450 else { 5451 /* check whether the URL's hostname matches */ 5452 size_t hostname_to_match_len; 5453 char *hostname_to_match = aprintf("%s%s%s", 5454 conn->bits.ipv6_ip ? "[" : "", 5455 conn->host.name, 5456 conn->bits.ipv6_ip ? "]" : ""); 5457 if(!hostname_to_match) 5458 return CURLE_OUT_OF_MEMORY; 5459 hostname_to_match_len = strlen(hostname_to_match); 5460 host_match = curl_strnequal(ptr, hostname_to_match, hostname_to_match_len); 5461 free(hostname_to_match); 5462 ptr += hostname_to_match_len; 5463 5464 host_match = host_match && *ptr == ':'; 5465 ptr++; 5466 } 5467 5468 if(host_match) { 5469 if(*ptr == ':') { 5470 /* an empty port always matches */ 5471 port_match = TRUE; 5472 ptr++; 5473 } 5474 else { 5475 /* check whether the URL's port matches */ 5476 char *ptr_next = strchr(ptr, ':'); 5477 if(ptr_next) { 5478 char *endp = NULL; 5479 long port_to_match = strtol(ptr, &endp, 10); 5480 if((endp == ptr_next) && (port_to_match == conn->remote_port)) { 5481 port_match = TRUE; 5482 ptr = ptr_next + 1; 5483 } 5484 } 5485 } 5486 } 5487 5488 if(host_match && port_match) { 5489 /* parse the hostname and port to connect to */ 5490 result = parse_connect_to_host_port(data, ptr, host_result, port_result); 5491 } 5492 5493 return result; 5494} 5495 5496/* 5497 * Processes all strings in the "connect to" slist, and uses the "connect 5498 * to host" and "connect to port" of the first string that matches. 5499 */ 5500static CURLcode parse_connect_to_slist(struct Curl_easy *data, 5501 struct connectdata *conn, 5502 struct curl_slist *conn_to_host) 5503{ 5504 CURLcode result = CURLE_OK; 5505 char *host = NULL; 5506 int port = 0; 5507 5508 while(conn_to_host && !host) { 5509 result = parse_connect_to_string(data, conn, conn_to_host->data, 5510 &host, &port); 5511 if(result) 5512 return result; 5513 5514 if(host && *host) { 5515 bool ipv6host; 5516 conn->conn_to_host.rawalloc = host; 5517 conn->conn_to_host.name = host; 5518 conn->bits.conn_to_host = TRUE; 5519 5520 ipv6host = strchr(host, ':') != NULL; 5521 infof(data, "Connecting to hostname: %s%s%s\n", 5522 ipv6host ? "[" : "", host, ipv6host ? "]" : ""); 5523 } 5524 else { 5525 /* no "connect to host" */ 5526 conn->bits.conn_to_host = FALSE; 5527 free(host); 5528 } 5529 5530 if(port >= 0) { 5531 conn->conn_to_port = port; 5532 conn->bits.conn_to_port = TRUE; 5533 infof(data, "Connecting to port: %d\n", port); 5534 } 5535 else { 5536 /* no "connect to port" */ 5537 conn->bits.conn_to_port = FALSE; 5538 } 5539 5540 conn_to_host = conn_to_host->next; 5541 } 5542 5543 return result; 5544} 5545 5546/************************************************************* 5547 * Resolve the address of the server or proxy 5548 *************************************************************/ 5549static CURLcode resolve_server(struct Curl_easy *data, 5550 struct connectdata *conn, 5551 bool *async) 5552{ 5553 CURLcode result=CURLE_OK; 5554 long timeout_ms = Curl_timeleft(data, NULL, TRUE); 5555 5556 /************************************************************* 5557 * Resolve the name of the server or proxy 5558 *************************************************************/ 5559 if(conn->bits.reuse) 5560 /* We're reusing the connection - no need to resolve anything, and 5561 fix_hostname() was called already in create_conn() for the re-use 5562 case. */ 5563 *async = FALSE; 5564 5565 else { 5566 /* this is a fresh connect */ 5567 int rc; 5568 struct Curl_dns_entry *hostaddr; 5569 5570#ifdef USE_UNIX_SOCKETS 5571 if(data->set.str[STRING_UNIX_SOCKET_PATH]) { 5572 /* Unix domain sockets are local. The host gets ignored, just use the 5573 * specified domain socket address. Do not cache "DNS entries". There is 5574 * no DNS involved and we already have the filesystem path available */ 5575 const char *path = data->set.str[STRING_UNIX_SOCKET_PATH]; 5576 5577 hostaddr = calloc(1, sizeof(struct Curl_dns_entry)); 5578 if(!hostaddr) 5579 result = CURLE_OUT_OF_MEMORY; 5580 else if((hostaddr->addr = Curl_unix2addr(path)) != NULL) 5581 hostaddr->inuse++; 5582 else { 5583 /* Long paths are not supported for now */ 5584 if(strlen(path) >= sizeof(((struct sockaddr_un *)0)->sun_path)) { 5585 failf(data, "Unix socket path too long: '%s'", path); 5586 result = CURLE_COULDNT_RESOLVE_HOST; 5587 } 5588 else 5589 result = CURLE_OUT_OF_MEMORY; 5590 free(hostaddr); 5591 hostaddr = NULL; 5592 } 5593 } 5594 else 5595#endif 5596 if(!conn->proxy.name || !*conn->proxy.name) { 5597 struct hostname *connhost; 5598 if(conn->bits.conn_to_host) 5599 connhost = &conn->conn_to_host; 5600 else 5601 connhost = &conn->host; 5602 5603 /* If not connecting via a proxy, extract the port from the URL, if it is 5604 * there, thus overriding any defaults that might have been set above. */ 5605 if(conn->bits.conn_to_port) 5606 conn->port = conn->conn_to_port; 5607 else 5608 conn->port = conn->remote_port; /* it is the same port */ 5609 5610 /* Resolve target host right on */ 5611 rc = Curl_resolv_timeout(conn, connhost->name, (int)conn->port, 5612 &hostaddr, timeout_ms); 5613 if(rc == CURLRESOLV_PENDING) 5614 *async = TRUE; 5615 5616 else if(rc == CURLRESOLV_TIMEDOUT) 5617 result = CURLE_OPERATION_TIMEDOUT; 5618 5619 else if(!hostaddr) { 5620 failf(data, "Couldn't resolve host '%s'", connhost->dispname); 5621 result = CURLE_COULDNT_RESOLVE_HOST; 5622 /* don't return yet, we need to clean up the timeout first */ 5623 } 5624 } 5625 else { 5626 /* This is a proxy that hasn't been resolved yet. */ 5627 5628 /* resolve proxy */ 5629 rc = Curl_resolv_timeout(conn, conn->proxy.name, (int)conn->port, 5630 &hostaddr, timeout_ms); 5631 5632 if(rc == CURLRESOLV_PENDING) 5633 *async = TRUE; 5634 5635 else if(rc == CURLRESOLV_TIMEDOUT) 5636 result = CURLE_OPERATION_TIMEDOUT; 5637 5638 else if(!hostaddr) { 5639 failf(data, "Couldn't resolve proxy '%s'", conn->proxy.dispname); 5640 result = CURLE_COULDNT_RESOLVE_PROXY; 5641 /* don't return yet, we need to clean up the timeout first */ 5642 } 5643 } 5644 DEBUGASSERT(conn->dns_entry == NULL); 5645 conn->dns_entry = hostaddr; 5646 } 5647 5648 return result; 5649} 5650 5651/* 5652 * Cleanup the connection just allocated before we can move along and use the 5653 * previously existing one. All relevant data is copied over and old_conn is 5654 * ready for freeing once this function returns. 5655 */ 5656static void reuse_conn(struct connectdata *old_conn, 5657 struct connectdata *conn) 5658{ 5659 free_fixed_hostname(&old_conn->proxy); 5660 free(old_conn->proxy.rawalloc); 5661 5662 /* free the SSL config struct from this connection struct as this was 5663 allocated in vain and is targeted for destruction */ 5664 Curl_free_ssl_config(&old_conn->ssl_config); 5665 5666 conn->data = old_conn->data; 5667 5668 /* get the user+password information from the old_conn struct since it may 5669 * be new for this request even when we re-use an existing connection */ 5670 conn->bits.user_passwd = old_conn->bits.user_passwd; 5671 if(conn->bits.user_passwd) { 5672 /* use the new user name and password though */ 5673 Curl_safefree(conn->user); 5674 Curl_safefree(conn->passwd); 5675 conn->user = old_conn->user; 5676 conn->passwd = old_conn->passwd; 5677 old_conn->user = NULL; 5678 old_conn->passwd = NULL; 5679 } 5680 5681 conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd; 5682 if(conn->bits.proxy_user_passwd) { 5683 /* use the new proxy user name and proxy password though */ 5684 Curl_safefree(conn->proxyuser); 5685 Curl_safefree(conn->proxypasswd); 5686 conn->proxyuser = old_conn->proxyuser; 5687 conn->proxypasswd = old_conn->proxypasswd; 5688 old_conn->proxyuser = NULL; 5689 old_conn->proxypasswd = NULL; 5690 } 5691 5692 /* host can change, when doing keepalive with a proxy or if the case is 5693 different this time etc */ 5694 free_fixed_hostname(&conn->host); 5695 free_fixed_hostname(&conn->conn_to_host); 5696 Curl_safefree(conn->host.rawalloc); 5697 Curl_safefree(conn->conn_to_host.rawalloc); 5698 conn->host=old_conn->host; 5699 conn->bits.conn_to_host = old_conn->bits.conn_to_host; 5700 conn->conn_to_host = old_conn->conn_to_host; 5701 conn->bits.conn_to_port = old_conn->bits.conn_to_port; 5702 conn->conn_to_port = old_conn->conn_to_port; 5703 5704 /* persist connection info in session handle */ 5705 Curl_persistconninfo(conn); 5706 5707 conn_reset_all_postponed_data(old_conn); /* free buffers */ 5708 conn_reset_all_postponed_data(conn); /* reset unprocessed data */ 5709 5710 /* re-use init */ 5711 conn->bits.reuse = TRUE; /* yes, we're re-using here */ 5712 5713 Curl_safefree(old_conn->user); 5714 Curl_safefree(old_conn->passwd); 5715 Curl_safefree(old_conn->proxyuser); 5716 Curl_safefree(old_conn->proxypasswd); 5717 Curl_safefree(old_conn->localdev); 5718 5719 Curl_llist_destroy(old_conn->send_pipe, NULL); 5720 Curl_llist_destroy(old_conn->recv_pipe, NULL); 5721 5722 old_conn->send_pipe = NULL; 5723 old_conn->recv_pipe = NULL; 5724 5725 Curl_safefree(old_conn->master_buffer); 5726} 5727 5728/** 5729 * create_conn() sets up a new connectdata struct, or re-uses an already 5730 * existing one, and resolves host name. 5731 * 5732 * if this function returns CURLE_OK and *async is set to TRUE, the resolve 5733 * response will be coming asynchronously. If *async is FALSE, the name is 5734 * already resolved. 5735 * 5736 * @param data The sessionhandle pointer 5737 * @param in_connect is set to the next connection data pointer 5738 * @param async is set TRUE when an async DNS resolution is pending 5739 * @see Curl_setup_conn() 5740 * 5741 * *NOTE* this function assigns the conn->data pointer! 5742 */ 5743 5744static CURLcode create_conn(struct Curl_easy *data, 5745 struct connectdata **in_connect, 5746 bool *async) 5747{ 5748 CURLcode result = CURLE_OK; 5749 struct connectdata *conn; 5750 struct connectdata *conn_temp = NULL; 5751 size_t urllen; 5752 char *user = NULL; 5753 char *passwd = NULL; 5754 char *options = NULL; 5755 bool reuse; 5756 char *proxy = NULL; 5757 bool prot_missing = FALSE; 5758 bool connections_available = TRUE; 5759 bool force_reuse = FALSE; 5760 bool waitpipe = FALSE; 5761 size_t max_host_connections = Curl_multi_max_host_connections(data->multi); 5762 size_t max_total_connections = Curl_multi_max_total_connections(data->multi); 5763 5764 *async = FALSE; 5765 5766 /************************************************************* 5767 * Check input data 5768 *************************************************************/ 5769 5770 if(!data->change.url) { 5771 result = CURLE_URL_MALFORMAT; 5772 goto out; 5773 } 5774 5775 /* First, split up the current URL in parts so that we can use the 5776 parts for checking against the already present connections. In order 5777 to not have to modify everything at once, we allocate a temporary 5778 connection data struct and fill in for comparison purposes. */ 5779 conn = allocate_conn(data); 5780 5781 if(!conn) { 5782 result = CURLE_OUT_OF_MEMORY; 5783 goto out; 5784 } 5785 5786 /* We must set the return variable as soon as possible, so that our 5787 parent can cleanup any possible allocs we may have done before 5788 any failure */ 5789 *in_connect = conn; 5790 5791 /* This initing continues below, see the comment "Continue connectdata 5792 * initialization here" */ 5793 5794 /*********************************************************** 5795 * We need to allocate memory to store the path in. We get the size of the 5796 * full URL to be sure, and we need to make it at least 256 bytes since 5797 * other parts of the code will rely on this fact 5798 ***********************************************************/ 5799#define LEAST_PATH_ALLOC 256 5800 urllen=strlen(data->change.url); 5801 if(urllen < LEAST_PATH_ALLOC) 5802 urllen=LEAST_PATH_ALLOC; 5803 5804 /* 5805 * We malloc() the buffers below urllen+2 to make room for 2 possibilities: 5806 * 1 - an extra terminating zero 5807 * 2 - an extra slash (in case a syntax like "www.host.com?moo" is used) 5808 */ 5809 5810 Curl_safefree(data->state.pathbuffer); 5811 data->state.path = NULL; 5812 5813 data->state.pathbuffer = malloc(urllen+2); 5814 if(NULL == data->state.pathbuffer) { 5815 result = CURLE_OUT_OF_MEMORY; /* really bad error */ 5816 goto out; 5817 } 5818 data->state.path = data->state.pathbuffer; 5819 5820 conn->host.rawalloc = malloc(urllen+2); 5821 if(NULL == conn->host.rawalloc) { 5822 Curl_safefree(data->state.pathbuffer); 5823 data->state.path = NULL; 5824 result = CURLE_OUT_OF_MEMORY; 5825 goto out; 5826 } 5827 5828 conn->host.name = conn->host.rawalloc; 5829 conn->host.name[0] = 0; 5830 5831 user = strdup(""); 5832 passwd = strdup(""); 5833 options = strdup(""); 5834 if(!user || !passwd || !options) { 5835 result = CURLE_OUT_OF_MEMORY; 5836 goto out; 5837 } 5838 5839 result = parseurlandfillconn(data, conn, &prot_missing, &user, &passwd, 5840 &options); 5841 if(result) 5842 goto out; 5843 5844 /************************************************************* 5845 * No protocol part in URL was used, add it! 5846 *************************************************************/ 5847 if(prot_missing) { 5848 /* We're guessing prefixes here and if we're told to use a proxy or if 5849 we're gonna follow a Location: later or... then we need the protocol 5850 part added so that we have a valid URL. */ 5851 char *reurl; 5852 char *ch_lower; 5853 5854 reurl = aprintf("%s://%s", conn->handler->scheme, data->change.url); 5855 5856 if(!reurl) { 5857 result = CURLE_OUT_OF_MEMORY; 5858 goto out; 5859 } 5860 5861 /* Change protocol prefix to lower-case */ 5862 for(ch_lower = reurl; *ch_lower != ':'; ch_lower++) 5863 *ch_lower = (char)TOLOWER(*ch_lower); 5864 5865 if(data->change.url_alloc) { 5866 Curl_safefree(data->change.url); 5867 data->change.url_alloc = FALSE; 5868 } 5869 5870 data->change.url = reurl; 5871 data->change.url_alloc = TRUE; /* free this later */ 5872 } 5873 5874 /************************************************************* 5875 * If the protocol can't handle url query strings, then cut 5876 * off the unhandable part 5877 *************************************************************/ 5878 if((conn->given->flags&PROTOPT_NOURLQUERY)) { 5879 char *path_q_sep = strchr(conn->data->state.path, '?'); 5880 if(path_q_sep) { 5881 /* according to rfc3986, allow the query (?foo=bar) 5882 also on protocols that can't handle it. 5883 5884 cut the string-part after '?' 5885 */ 5886 5887 /* terminate the string */ 5888 path_q_sep[0] = 0; 5889 } 5890 } 5891 5892 if(data->set.str[STRING_BEARER]) { 5893 conn->oauth_bearer = strdup(data->set.str[STRING_BEARER]); 5894 if(!conn->oauth_bearer) { 5895 result = CURLE_OUT_OF_MEMORY; 5896 goto out; 5897 } 5898 } 5899 5900#ifndef CURL_DISABLE_PROXY 5901 /************************************************************* 5902 * Extract the user and password from the authentication string 5903 *************************************************************/ 5904 if(conn->bits.proxy_user_passwd) { 5905 result = parse_proxy_auth(data, conn); 5906 if(result) 5907 goto out; 5908 } 5909 5910 /************************************************************* 5911 * Detect what (if any) proxy to use 5912 *************************************************************/ 5913 if(data->set.str[STRING_PROXY]) { 5914 proxy = strdup(data->set.str[STRING_PROXY]); 5915 /* if global proxy is set, this is it */ 5916 if(NULL == proxy) { 5917 failf(data, "memory shortage"); 5918 result = CURLE_OUT_OF_MEMORY; 5919 goto out; 5920 } 5921 } 5922 5923 if(data->set.str[STRING_NOPROXY] && 5924 check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY])) { 5925 free(proxy); /* proxy is in exception list */ 5926 proxy = NULL; 5927 } 5928 else if(!proxy) 5929 proxy = detect_proxy(conn); 5930 5931#ifdef USE_UNIX_SOCKETS 5932 if(proxy && data->set.str[STRING_UNIX_SOCKET_PATH]) { 5933 free(proxy); /* Unix domain sockets cannot be proxied, so disable it */ 5934 proxy = NULL; 5935 } 5936#endif 5937 5938 if(proxy && (!*proxy || (conn->handler->flags & PROTOPT_NONETWORK))) { 5939 free(proxy); /* Don't bother with an empty proxy string or if the 5940 protocol doesn't work with network */ 5941 proxy = NULL; 5942 } 5943 5944 /*********************************************************************** 5945 * If this is supposed to use a proxy, we need to figure out the proxy host 5946 * name, proxy type and port number, so that we can re-use an existing 5947 * connection that may exist registered to the same proxy host. 5948 ***********************************************************************/ 5949 if(proxy) { 5950 result = parse_proxy(data, conn, proxy); 5951 5952 free(proxy); /* parse_proxy copies the proxy string */ 5953 proxy = NULL; 5954 5955 if(result) 5956 goto out; 5957 5958 if((conn->proxytype == CURLPROXY_HTTP) || 5959 (conn->proxytype == CURLPROXY_HTTP_1_0)) { 5960#ifdef CURL_DISABLE_HTTP 5961 /* asking for a HTTP proxy is a bit funny when HTTP is disabled... */ 5962 result = CURLE_UNSUPPORTED_PROTOCOL; 5963 goto out; 5964#else 5965 /* force this connection's protocol to become HTTP if not already 5966 compatible - if it isn't tunneling through */ 5967 if(!(conn->handler->protocol & PROTO_FAMILY_HTTP) && 5968 !conn->bits.tunnel_proxy) 5969 conn->handler = &Curl_handler_http; 5970 5971 conn->bits.httpproxy = TRUE; 5972#endif 5973 } 5974 else { 5975 conn->bits.httpproxy = FALSE; /* not a HTTP proxy */ 5976 conn->bits.tunnel_proxy = FALSE; /* no tunneling if not HTTP */ 5977 } 5978 conn->bits.proxy = TRUE; 5979 } 5980 else { 5981 /* we aren't using the proxy after all... */ 5982 conn->bits.proxy = FALSE; 5983 conn->bits.httpproxy = FALSE; 5984 conn->bits.proxy_user_passwd = FALSE; 5985 conn->bits.tunnel_proxy = FALSE; 5986 } 5987 5988#endif /* CURL_DISABLE_PROXY */ 5989 5990 /************************************************************* 5991 * If the protocol is using SSL and HTTP proxy is used, we set 5992 * the tunnel_proxy bit. 5993 *************************************************************/ 5994 if((conn->given->flags&PROTOPT_SSL) && conn->bits.httpproxy) 5995 conn->bits.tunnel_proxy = TRUE; 5996 5997 /************************************************************* 5998 * Figure out the remote port number and fix it in the URL 5999 *************************************************************/ 6000 result = parse_remote_port(data, conn); 6001 if(result) 6002 goto out; 6003 6004 /* Check for overridden login details and set them accordingly so they 6005 they are known when protocol->setup_connection is called! */ 6006 result = override_login(data, conn, &user, &passwd, &options); 6007 if(result) 6008 goto out; 6009 result = set_login(conn, user, passwd, options); 6010 if(result) 6011 goto out; 6012 6013 /************************************************************* 6014 * Process the "connect to" linked list of hostname/port mappings. 6015 * Do this after the remote port number has been fixed in the URL. 6016 *************************************************************/ 6017 result = parse_connect_to_slist(data, conn, data->set.connect_to); 6018 if(result) 6019 goto out; 6020 6021 /************************************************************* 6022 * IDN-fix the hostnames 6023 *************************************************************/ 6024 fix_hostname(data, conn, &conn->host); 6025 if(conn->bits.conn_to_host) 6026 fix_hostname(data, conn, &conn->conn_to_host); 6027 if(conn->proxy.name && *conn->proxy.name) 6028 fix_hostname(data, conn, &conn->proxy); 6029 6030 /************************************************************* 6031 * Check whether the host and the "connect to host" are equal. 6032 * Do this after the hostnames have been IDN-fixed . 6033 *************************************************************/ 6034 if(conn->bits.conn_to_host && 6035 Curl_raw_equal(conn->conn_to_host.name, conn->host.name)) { 6036 conn->bits.conn_to_host = FALSE; 6037 } 6038 6039 /************************************************************* 6040 * Check whether the port and the "connect to port" are equal. 6041 * Do this after the remote port number has been fixed in the URL. 6042 *************************************************************/ 6043 if(conn->bits.conn_to_port && conn->conn_to_port == conn->remote_port) { 6044 conn->bits.conn_to_port = FALSE; 6045 } 6046 6047 /************************************************************* 6048 * If the "connect to" feature is used with an HTTP proxy, 6049 * we set the tunnel_proxy bit. 6050 *************************************************************/ 6051 if((conn->bits.conn_to_host || conn->bits.conn_to_port) && 6052 conn->bits.httpproxy) 6053 conn->bits.tunnel_proxy = TRUE; 6054 6055 /************************************************************* 6056 * Setup internals depending on protocol. Needs to be done after 6057 * we figured out what/if proxy to use. 6058 *************************************************************/ 6059 result = setup_connection_internals(conn); 6060 if(result) 6061 goto out; 6062 6063 conn->recv[FIRSTSOCKET] = Curl_recv_plain; 6064 conn->send[FIRSTSOCKET] = Curl_send_plain; 6065 conn->recv[SECONDARYSOCKET] = Curl_recv_plain; 6066 conn->send[SECONDARYSOCKET] = Curl_send_plain; 6067 6068 conn->bits.tcp_fastopen = data->set.tcp_fastopen; 6069 6070 /*********************************************************************** 6071 * file: is a special case in that it doesn't need a network connection 6072 ***********************************************************************/ 6073#ifndef CURL_DISABLE_FILE 6074 if(conn->handler->flags & PROTOPT_NONETWORK) { 6075 bool done; 6076 /* this is supposed to be the connect function so we better at least check 6077 that the file is present here! */ 6078 DEBUGASSERT(conn->handler->connect_it); 6079 result = conn->handler->connect_it(conn, &done); 6080 6081 /* Setup a "faked" transfer that'll do nothing */ 6082 if(!result) { 6083 conn->data = data; 6084 conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; /* we are "connected */ 6085 6086 Curl_conncache_add_conn(data->state.conn_cache, conn); 6087 6088 /* 6089 * Setup whatever necessary for a resumed transfer 6090 */ 6091 result = setup_range(data); 6092 if(result) { 6093 DEBUGASSERT(conn->handler->done); 6094 /* we ignore the return code for the protocol-specific DONE */ 6095 (void)conn->handler->done(conn, result, FALSE); 6096 goto out; 6097 } 6098 6099 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */ 6100 -1, NULL); /* no upload */ 6101 } 6102 6103 /* since we skip do_init() */ 6104 Curl_init_do(data, conn); 6105 6106 goto out; 6107 } 6108#endif 6109 6110 /* Get a cloned copy of the SSL config situation stored in the 6111 connection struct. But to get this going nicely, we must first make 6112 sure that the strings in the master copy are pointing to the correct 6113 strings in the session handle strings array! 6114 6115 Keep in mind that the pointers in the master copy are pointing to strings 6116 that will be freed as part of the Curl_easy struct, but all cloned 6117 copies will be separately allocated. 6118 */ 6119 data->set.ssl.CApath = data->set.str[STRING_SSL_CAPATH]; 6120 data->set.ssl.CAfile = data->set.str[STRING_SSL_CAFILE]; 6121 data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE]; 6122 data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT]; 6123 data->set.ssl.random_file = data->set.str[STRING_SSL_RANDOM_FILE]; 6124 data->set.ssl.egdsocket = data->set.str[STRING_SSL_EGDSOCKET]; 6125 data->set.ssl.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST]; 6126 data->set.ssl.clientcert = data->set.str[STRING_CERT]; 6127#ifdef USE_TLS_SRP 6128 data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME]; 6129 data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD]; 6130#endif 6131 6132 if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config)) { 6133 result = CURLE_OUT_OF_MEMORY; 6134 goto out; 6135 } 6136 6137 prune_dead_connections(data); 6138 6139 /************************************************************* 6140 * Check the current list of connections to see if we can 6141 * re-use an already existing one or if we have to create a 6142 * new one. 6143 *************************************************************/ 6144 6145 /* reuse_fresh is TRUE if we are told to use a new connection by force, but 6146 we only acknowledge this option if this is not a re-used connection 6147 already (which happens due to follow-location or during a HTTP 6148 authentication phase). */ 6149 if(data->set.reuse_fresh && !data->state.this_is_a_follow) 6150 reuse = FALSE; 6151 else 6152 reuse = ConnectionExists(data, conn, &conn_temp, &force_reuse, &waitpipe); 6153 6154 /* If we found a reusable connection, we may still want to 6155 open a new connection if we are pipelining. */ 6156 if(reuse && !force_reuse && IsPipeliningPossible(data, conn_temp)) { 6157 size_t pipelen = conn_temp->send_pipe->size + conn_temp->recv_pipe->size; 6158 if(pipelen > 0) { 6159 infof(data, "Found connection %ld, with requests in the pipe (%zu)\n", 6160 conn_temp->connection_id, pipelen); 6161 6162 if(conn_temp->bundle->num_connections < max_host_connections && 6163 data->state.conn_cache->num_connections < max_total_connections) { 6164 /* We want a new connection anyway */ 6165 reuse = FALSE; 6166 6167 infof(data, "We can reuse, but we want a new connection anyway\n"); 6168 } 6169 } 6170 } 6171 6172 if(reuse) { 6173 /* 6174 * We already have a connection for this, we got the former connection 6175 * in the conn_temp variable and thus we need to cleanup the one we 6176 * just allocated before we can move along and use the previously 6177 * existing one. 6178 */ 6179 conn_temp->inuse = TRUE; /* mark this as being in use so that no other 6180 handle in a multi stack may nick it */ 6181 reuse_conn(conn, conn_temp); 6182 free(conn); /* we don't need this anymore */ 6183 conn = conn_temp; 6184 *in_connect = conn; 6185 6186 infof(data, "Re-using existing connection! (#%ld) with %s %s\n", 6187 conn->connection_id, 6188 conn->bits.proxy?"proxy":"host", 6189 conn->proxy.name?conn->proxy.dispname:conn->host.dispname); 6190 } 6191 else { 6192 /* We have decided that we want a new connection. However, we may not 6193 be able to do that if we have reached the limit of how many 6194 connections we are allowed to open. */ 6195 struct connectbundle *bundle = NULL; 6196 6197 if(conn->handler->flags & PROTOPT_ALPN_NPN) { 6198 /* The protocol wants it, so set the bits if enabled in the easy handle 6199 (default) */ 6200 if(data->set.ssl_enable_alpn) 6201 conn->bits.tls_enable_alpn = TRUE; 6202 if(data->set.ssl_enable_npn) 6203 conn->bits.tls_enable_npn = TRUE; 6204 } 6205 6206 if(waitpipe) 6207 /* There is a connection that *might* become usable for pipelining 6208 "soon", and we wait for that */ 6209 connections_available = FALSE; 6210 else 6211 bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache); 6212 6213 if(max_host_connections > 0 && bundle && 6214 (bundle->num_connections >= max_host_connections)) { 6215 struct connectdata *conn_candidate; 6216 6217 /* The bundle is full. Let's see if we can kill a connection. */ 6218 conn_candidate = find_oldest_idle_connection_in_bundle(data, bundle); 6219 6220 if(conn_candidate) { 6221 /* Set the connection's owner correctly, then kill it */ 6222 conn_candidate->data = data; 6223 (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE); 6224 } 6225 else { 6226 infof(data, "No more connections allowed to host: %d\n", 6227 max_host_connections); 6228 connections_available = FALSE; 6229 } 6230 } 6231 6232 if(connections_available && 6233 (max_total_connections > 0) && 6234 (data->state.conn_cache->num_connections >= max_total_connections)) { 6235 struct connectdata *conn_candidate; 6236 6237 /* The cache is full. Let's see if we can kill a connection. */ 6238 conn_candidate = Curl_oldest_idle_connection(data); 6239 6240 if(conn_candidate) { 6241 /* Set the connection's owner correctly, then kill it */ 6242 conn_candidate->data = data; 6243 (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE); 6244 } 6245 else { 6246 infof(data, "No connections available in cache\n"); 6247 connections_available = FALSE; 6248 } 6249 } 6250 6251 if(!connections_available) { 6252 infof(data, "No connections available.\n"); 6253 6254 conn_free(conn); 6255 *in_connect = NULL; 6256 6257 result = CURLE_NO_CONNECTION_AVAILABLE; 6258 goto out; 6259 } 6260 else { 6261 /* 6262 * This is a brand new connection, so let's store it in the connection 6263 * cache of ours! 6264 */ 6265 Curl_conncache_add_conn(data->state.conn_cache, conn); 6266 } 6267 6268#if defined(USE_NTLM) 6269 /* If NTLM is requested in a part of this connection, make sure we don't 6270 assume the state is fine as this is a fresh connection and NTLM is 6271 connection based. */ 6272 if((data->state.authhost.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) && 6273 data->state.authhost.done) { 6274 infof(data, "NTLM picked AND auth done set, clear picked!\n"); 6275 data->state.authhost.picked = CURLAUTH_NONE; 6276 data->state.authhost.done = FALSE; 6277 } 6278 6279 if((data->state.authproxy.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) && 6280 data->state.authproxy.done) { 6281 infof(data, "NTLM-proxy picked AND auth done set, clear picked!\n"); 6282 data->state.authproxy.picked = CURLAUTH_NONE; 6283 data->state.authproxy.done = FALSE; 6284 } 6285#endif 6286 } 6287 6288 /* Mark the connection as used */ 6289 conn->inuse = TRUE; 6290 6291 /* Setup and init stuff before DO starts, in preparing for the transfer. */ 6292 Curl_init_do(data, conn); 6293 6294 /* 6295 * Setup whatever necessary for a resumed transfer 6296 */ 6297 result = setup_range(data); 6298 if(result) 6299 goto out; 6300 6301 /* Continue connectdata initialization here. */ 6302 6303 /* 6304 * Inherit the proper values from the urldata struct AFTER we have arranged 6305 * the persistent connection stuff 6306 */ 6307 conn->seek_func = data->set.seek_func; 6308 conn->seek_client = data->set.seek_client; 6309 6310 /************************************************************* 6311 * Resolve the address of the server or proxy 6312 *************************************************************/ 6313 result = resolve_server(data, conn, async); 6314 6315 out: 6316 6317 free(options); 6318 free(passwd); 6319 free(user); 6320 free(proxy); 6321 return result; 6322} 6323 6324/* Curl_setup_conn() is called after the name resolve initiated in 6325 * create_conn() is all done. 6326 * 6327 * Curl_setup_conn() also handles reused connections 6328 * 6329 * conn->data MUST already have been setup fine (in create_conn) 6330 */ 6331 6332CURLcode Curl_setup_conn(struct connectdata *conn, 6333 bool *protocol_done) 6334{ 6335 CURLcode result = CURLE_OK; 6336 struct Curl_easy *data = conn->data; 6337 6338 Curl_pgrsTime(data, TIMER_NAMELOOKUP); 6339 6340 if(conn->handler->flags & PROTOPT_NONETWORK) { 6341 /* nothing to setup when not using a network */ 6342 *protocol_done = TRUE; 6343 return result; 6344 } 6345 *protocol_done = FALSE; /* default to not done */ 6346 6347 /* set proxy_connect_closed to false unconditionally already here since it 6348 is used strictly to provide extra information to a parent function in the 6349 case of proxy CONNECT failures and we must make sure we don't have it 6350 lingering set from a previous invoke */ 6351 conn->bits.proxy_connect_closed = FALSE; 6352 6353 /* 6354 * Set user-agent. Used for HTTP, but since we can attempt to tunnel 6355 * basically anything through a http proxy we can't limit this based on 6356 * protocol. 6357 */ 6358 if(data->set.str[STRING_USERAGENT]) { 6359 Curl_safefree(conn->allocptr.uagent); 6360 conn->allocptr.uagent = 6361 aprintf("User-Agent: %s\r\n", data->set.str[STRING_USERAGENT]); 6362 if(!conn->allocptr.uagent) 6363 return CURLE_OUT_OF_MEMORY; 6364 } 6365 6366 data->req.headerbytecount = 0; 6367 6368#ifdef CURL_DO_LINEEND_CONV 6369 data->state.crlf_conversions = 0; /* reset CRLF conversion counter */ 6370#endif /* CURL_DO_LINEEND_CONV */ 6371 6372 /* set start time here for timeout purposes in the connect procedure, it 6373 is later set again for the progress meter purpose */ 6374 conn->now = Curl_tvnow(); 6375 6376 if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) { 6377 conn->bits.tcpconnect[FIRSTSOCKET] = FALSE; 6378 result = Curl_connecthost(conn, conn->dns_entry); 6379 if(result) 6380 return result; 6381 } 6382 else { 6383 Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */ 6384 Curl_pgrsTime(data, TIMER_APPCONNECT); /* we're connected already */ 6385 conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; 6386 *protocol_done = TRUE; 6387 Curl_updateconninfo(conn, conn->sock[FIRSTSOCKET]); 6388 Curl_verboseconnect(conn); 6389 } 6390 6391 conn->now = Curl_tvnow(); /* time this *after* the connect is done, we 6392 set this here perhaps a second time */ 6393 6394#ifdef __EMX__ 6395 /* 6396 * This check is quite a hack. We're calling _fsetmode to fix the problem 6397 * with fwrite converting newline characters (you get mangled text files, 6398 * and corrupted binary files when you download to stdout and redirect it to 6399 * a file). 6400 */ 6401 6402 if((data->set.out)->_handle == NULL) { 6403 _fsetmode(stdout, "b"); 6404 } 6405#endif 6406 6407 return result; 6408} 6409 6410CURLcode Curl_connect(struct Curl_easy *data, 6411 struct connectdata **in_connect, 6412 bool *asyncp, 6413 bool *protocol_done) 6414{ 6415 CURLcode result; 6416 6417 *asyncp = FALSE; /* assume synchronous resolves by default */ 6418 6419 /* call the stuff that needs to be called */ 6420 result = create_conn(data, in_connect, asyncp); 6421 6422 if(!result) { 6423 /* no error */ 6424 if((*in_connect)->send_pipe->size || (*in_connect)->recv_pipe->size) 6425 /* pipelining */ 6426 *protocol_done = TRUE; 6427 else if(!*asyncp) { 6428 /* DNS resolution is done: that's either because this is a reused 6429 connection, in which case DNS was unnecessary, or because DNS 6430 really did finish already (synch resolver/fast async resolve) */ 6431 result = Curl_setup_conn(*in_connect, protocol_done); 6432 } 6433 } 6434 6435 if(result == CURLE_NO_CONNECTION_AVAILABLE) { 6436 *in_connect = NULL; 6437 return result; 6438 } 6439 6440 if(result && *in_connect) { 6441 /* We're not allowed to return failure with memory left allocated 6442 in the connectdata struct, free those here */ 6443 Curl_disconnect(*in_connect, FALSE); /* close the connection */ 6444 *in_connect = NULL; /* return a NULL */ 6445 } 6446 6447 return result; 6448} 6449 6450/* 6451 * Curl_init_do() inits the readwrite session. This is inited each time (in 6452 * the DO function before the protocol-specific DO functions are invoked) for 6453 * a transfer, sometimes multiple times on the same Curl_easy. Make sure 6454 * nothing in here depends on stuff that are setup dynamically for the 6455 * transfer. 6456 * 6457 * Allow this function to get called with 'conn' set to NULL. 6458 */ 6459 6460CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn) 6461{ 6462 struct SingleRequest *k = &data->req; 6463 6464 if(conn) 6465 conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to 6466 * use */ 6467 6468 data->state.done = FALSE; /* *_done() is not called yet */ 6469 data->state.expect100header = FALSE; 6470 6471 if(data->set.opt_no_body) 6472 /* in HTTP lingo, no body means using the HEAD request... */ 6473 data->set.httpreq = HTTPREQ_HEAD; 6474 else if(HTTPREQ_HEAD == data->set.httpreq) 6475 /* ... but if unset there really is no perfect method that is the 6476 "opposite" of HEAD but in reality most people probably think GET 6477 then. The important thing is that we can't let it remain HEAD if the 6478 opt_no_body is set FALSE since then we'll behave wrong when getting 6479 HTTP. */ 6480 data->set.httpreq = HTTPREQ_GET; 6481 6482 k->start = Curl_tvnow(); /* start time */ 6483 k->now = k->start; /* current time is now */ 6484 k->header = TRUE; /* assume header */ 6485 6486 k->bytecount = 0; 6487 6488 k->buf = data->state.buffer; 6489 k->uploadbuf = data->state.uploadbuffer; 6490 k->hbufp = data->state.headerbuff; 6491 k->ignorebody=FALSE; 6492 6493 Curl_speedinit(data); 6494 6495 Curl_pgrsSetUploadCounter(data, 0); 6496 Curl_pgrsSetDownloadCounter(data, 0); 6497 6498 return CURLE_OK; 6499} 6500 6501/* 6502* get_protocol_family() 6503* 6504* This is used to return the protocol family for a given protocol. 6505* 6506* Parameters: 6507* 6508* protocol [in] - A single bit protocol identifier such as HTTP or HTTPS. 6509* 6510* Returns the family as a single bit protocol identifier. 6511*/ 6512 6513unsigned int get_protocol_family(unsigned int protocol) 6514{ 6515 unsigned int family; 6516 6517 switch(protocol) { 6518 case CURLPROTO_HTTP: 6519 case CURLPROTO_HTTPS: 6520 family = CURLPROTO_HTTP; 6521 break; 6522 6523 case CURLPROTO_FTP: 6524 case CURLPROTO_FTPS: 6525 family = CURLPROTO_FTP; 6526 break; 6527 6528 case CURLPROTO_SCP: 6529 family = CURLPROTO_SCP; 6530 break; 6531 6532 case CURLPROTO_SFTP: 6533 family = CURLPROTO_SFTP; 6534 break; 6535 6536 case CURLPROTO_TELNET: 6537 family = CURLPROTO_TELNET; 6538 break; 6539 6540 case CURLPROTO_LDAP: 6541 case CURLPROTO_LDAPS: 6542 family = CURLPROTO_LDAP; 6543 break; 6544 6545 case CURLPROTO_DICT: 6546 family = CURLPROTO_DICT; 6547 break; 6548 6549 case CURLPROTO_FILE: 6550 family = CURLPROTO_FILE; 6551 break; 6552 6553 case CURLPROTO_TFTP: 6554 family = CURLPROTO_TFTP; 6555 break; 6556 6557 case CURLPROTO_IMAP: 6558 case CURLPROTO_IMAPS: 6559 family = CURLPROTO_IMAP; 6560 break; 6561 6562 case CURLPROTO_POP3: 6563 case CURLPROTO_POP3S: 6564 family = CURLPROTO_POP3; 6565 break; 6566 6567 case CURLPROTO_SMTP: 6568 case CURLPROTO_SMTPS: 6569 family = CURLPROTO_SMTP; 6570 break; 6571 6572 case CURLPROTO_RTSP: 6573 family = CURLPROTO_RTSP; 6574 break; 6575 6576 case CURLPROTO_RTMP: 6577 case CURLPROTO_RTMPS: 6578 family = CURLPROTO_RTMP; 6579 break; 6580 6581 case CURLPROTO_RTMPT: 6582 case CURLPROTO_RTMPTS: 6583 family = CURLPROTO_RTMPT; 6584 break; 6585 6586 case CURLPROTO_RTMPE: 6587 family = CURLPROTO_RTMPE; 6588 break; 6589 6590 case CURLPROTO_RTMPTE: 6591 family = CURLPROTO_RTMPTE; 6592 break; 6593 6594 case CURLPROTO_GOPHER: 6595 family = CURLPROTO_GOPHER; 6596 break; 6597 6598 case CURLPROTO_SMB: 6599 case CURLPROTO_SMBS: 6600 family = CURLPROTO_SMB; 6601 break; 6602 6603 default: 6604 family = 0; 6605 break; 6606 } 6607 6608 return family; 6609} 6610