setopt.c (89634B)
1 /*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 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.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 * SPDX-License-Identifier: curl 22 * 23 ***************************************************************************/ 24 25 #include "curl_setup.h" 26 27 #include <limits.h> 28 29 #ifdef HAVE_NETINET_IN_H 30 #include <netinet/in.h> 31 #endif 32 33 #ifdef HAVE_LINUX_TCP_H 34 #include <linux/tcp.h> 35 #elif defined(HAVE_NETINET_TCP_H) 36 #include <netinet/tcp.h> 37 #endif 38 39 #include "urldata.h" 40 #include "url.h" 41 #include "progress.h" 42 #include "content_encoding.h" 43 #include "strcase.h" 44 #include "share.h" 45 #include "vtls/vtls.h" 46 #include "curlx/warnless.h" 47 #include "sendf.h" 48 #include "hostip.h" 49 #include "http2.h" 50 #include "setopt.h" 51 #include "multiif.h" 52 #include "altsvc.h" 53 #include "hsts.h" 54 #include "tftp.h" 55 #include "strdup.h" 56 #include "escape.h" 57 58 /* The last 3 #include files should be in this order */ 59 #include "curl_printf.h" 60 #include "curl_memory.h" 61 #include "memdebug.h" 62 63 64 static CURLcode setopt_set_timeout_sec(timediff_t *ptimeout_ms, long secs) 65 { 66 if(secs < 0) 67 return CURLE_BAD_FUNCTION_ARGUMENT; 68 #if LONG_MAX > (TIMEDIFF_T_MAX/1000) 69 if(secs > (TIMEDIFF_T_MAX/1000)) { 70 *ptimeout_ms = TIMEDIFF_T_MAX; 71 return CURLE_OK; 72 } 73 #endif 74 *ptimeout_ms = (timediff_t)secs * 1000; 75 return CURLE_OK; 76 } 77 78 static CURLcode setopt_set_timeout_ms(timediff_t *ptimeout_ms, long ms) 79 { 80 if(ms < 0) 81 return CURLE_BAD_FUNCTION_ARGUMENT; 82 #if LONG_MAX > TIMEDIFF_T_MAX 83 if(ms > TIMEDIFF_T_MAX) { 84 *ptimeout_ms = TIMEDIFF_T_MAX; 85 return CURLE_OK; 86 } 87 #endif 88 *ptimeout_ms = (timediff_t)ms; 89 return CURLE_OK; 90 } 91 92 CURLcode Curl_setstropt(char **charp, const char *s) 93 { 94 /* Release the previous storage at `charp' and replace by a dynamic storage 95 copy of `s'. Return CURLE_OK or CURLE_OUT_OF_MEMORY. */ 96 97 Curl_safefree(*charp); 98 99 if(s) { 100 if(strlen(s) > CURL_MAX_INPUT_LENGTH) 101 return CURLE_BAD_FUNCTION_ARGUMENT; 102 103 *charp = strdup(s); 104 if(!*charp) 105 return CURLE_OUT_OF_MEMORY; 106 } 107 108 return CURLE_OK; 109 } 110 111 CURLcode Curl_setblobopt(struct curl_blob **blobp, 112 const struct curl_blob *blob) 113 { 114 /* free the previous storage at `blobp' and replace by a dynamic storage 115 copy of blob. If CURL_BLOB_COPY is set, the data is copied. */ 116 117 Curl_safefree(*blobp); 118 119 if(blob) { 120 struct curl_blob *nblob; 121 if(blob->len > CURL_MAX_INPUT_LENGTH) 122 return CURLE_BAD_FUNCTION_ARGUMENT; 123 nblob = (struct curl_blob *) 124 malloc(sizeof(struct curl_blob) + 125 ((blob->flags & CURL_BLOB_COPY) ? blob->len : 0)); 126 if(!nblob) 127 return CURLE_OUT_OF_MEMORY; 128 *nblob = *blob; 129 if(blob->flags & CURL_BLOB_COPY) { 130 /* put the data after the blob struct in memory */ 131 nblob->data = (char *)nblob + sizeof(struct curl_blob); 132 memcpy(nblob->data, blob->data, blob->len); 133 } 134 135 *blobp = nblob; 136 return CURLE_OK; 137 } 138 139 return CURLE_OK; 140 } 141 142 static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp) 143 { 144 char *user = NULL; 145 char *passwd = NULL; 146 147 DEBUGASSERT(userp); 148 DEBUGASSERT(passwdp); 149 150 /* Parse the login details if specified. It not then we treat NULL as a hint 151 to clear the existing data */ 152 if(option) { 153 size_t len = strlen(option); 154 CURLcode result; 155 if(len > CURL_MAX_INPUT_LENGTH) 156 return CURLE_BAD_FUNCTION_ARGUMENT; 157 158 result = Curl_parse_login_details(option, len, &user, &passwd, NULL); 159 if(result) 160 return result; 161 } 162 163 free(*userp); 164 *userp = user; 165 166 free(*passwdp); 167 *passwdp = passwd; 168 169 return CURLE_OK; 170 } 171 172 static CURLcode setstropt_interface(char *option, char **devp, 173 char **ifacep, char **hostp) 174 { 175 char *dev = NULL; 176 char *iface = NULL; 177 char *host = NULL; 178 CURLcode result; 179 180 DEBUGASSERT(devp); 181 DEBUGASSERT(ifacep); 182 DEBUGASSERT(hostp); 183 184 if(option) { 185 /* Parse the interface details if set, otherwise clear them all */ 186 result = Curl_parse_interface(option, &dev, &iface, &host); 187 if(result) 188 return result; 189 } 190 free(*devp); 191 *devp = dev; 192 193 free(*ifacep); 194 *ifacep = iface; 195 196 free(*hostp); 197 *hostp = host; 198 199 return CURLE_OK; 200 } 201 202 #define C_SSLVERSION_VALUE(x) (x & 0xffff) 203 #define C_SSLVERSION_MAX_VALUE(x) ((unsigned long)x & 0xffff0000) 204 205 static CURLcode protocol2num(const char *str, curl_prot_t *val) 206 { 207 /* 208 * We are asked to cherry-pick protocols, so play it safe and disallow all 209 * protocols to start with, and re-add the wanted ones back in. 210 */ 211 *val = 0; 212 213 if(!str) 214 return CURLE_BAD_FUNCTION_ARGUMENT; 215 216 if(curl_strequal(str, "all")) { 217 *val = ~(curl_prot_t) 0; 218 return CURLE_OK; 219 } 220 221 do { 222 const char *token = str; 223 size_t tlen; 224 225 str = strchr(str, ','); 226 tlen = str ? (size_t) (str - token) : strlen(token); 227 if(tlen) { 228 const struct Curl_handler *h = Curl_getn_scheme_handler(token, tlen); 229 230 if(!h) 231 return CURLE_UNSUPPORTED_PROTOCOL; 232 233 *val |= h->protocol; 234 } 235 } while(str && str++); 236 237 if(!*val) 238 /* no protocol listed */ 239 return CURLE_BAD_FUNCTION_ARGUMENT; 240 return CURLE_OK; 241 } 242 243 #if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_PROXY) 244 static CURLcode httpauth(struct Curl_easy *data, bool proxy, 245 unsigned long auth) 246 { 247 if(auth != CURLAUTH_NONE) { 248 int bitcheck = 0; 249 bool authbits = FALSE; 250 /* the DIGEST_IE bit is only used to set a special marker, for all the 251 rest we need to handle it as normal DIGEST */ 252 bool iestyle = !!(auth & CURLAUTH_DIGEST_IE); 253 if(proxy) 254 data->state.authproxy.iestyle = iestyle; 255 else 256 data->state.authhost.iestyle = iestyle; 257 258 if(auth & CURLAUTH_DIGEST_IE) { 259 auth |= CURLAUTH_DIGEST; /* set standard digest bit */ 260 auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */ 261 } 262 263 /* switch off bits we cannot support */ 264 #ifndef USE_NTLM 265 auth &= ~CURLAUTH_NTLM; /* no NTLM support */ 266 #endif 267 #ifndef USE_SPNEGO 268 auth &= ~CURLAUTH_NEGOTIATE; /* no Negotiate (SPNEGO) auth without GSS-API 269 or SSPI */ 270 #endif 271 272 /* check if any auth bit lower than CURLAUTH_ONLY is still set */ 273 while(bitcheck < 31) { 274 if(auth & (1UL << bitcheck++)) { 275 authbits = TRUE; 276 break; 277 } 278 } 279 if(!authbits) 280 return CURLE_NOT_BUILT_IN; /* no supported types left! */ 281 } 282 if(proxy) 283 data->set.proxyauth = auth; 284 else 285 data->set.httpauth = auth; 286 return CURLE_OK; 287 } 288 #endif /* !CURL_DISABLE_HTTP || !CURL_DISABLE_PROXY */ 289 290 #ifndef CURL_DISABLE_HTTP 291 static CURLcode setopt_HTTP_VERSION(struct Curl_easy *data, long arg) 292 { 293 /* 294 * This sets a requested HTTP version to be used. The value is one of 295 * the listed enums in curl/curl.h. 296 */ 297 switch(arg) { 298 case CURL_HTTP_VERSION_NONE: 299 /* accepted */ 300 break; 301 case CURL_HTTP_VERSION_1_0: 302 case CURL_HTTP_VERSION_1_1: 303 /* accepted */ 304 break; 305 #ifdef USE_HTTP2 306 case CURL_HTTP_VERSION_2_0: 307 case CURL_HTTP_VERSION_2TLS: 308 case CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE: 309 /* accepted */ 310 break; 311 #endif 312 #ifdef USE_HTTP3 313 case CURL_HTTP_VERSION_3: 314 case CURL_HTTP_VERSION_3ONLY: 315 /* accepted */ 316 break; 317 #endif 318 default: 319 /* not accepted */ 320 if(arg < CURL_HTTP_VERSION_NONE) 321 return CURLE_BAD_FUNCTION_ARGUMENT; 322 return CURLE_UNSUPPORTED_PROTOCOL; 323 } 324 data->set.httpwant = (unsigned char)arg; 325 return CURLE_OK; 326 } 327 #endif /* ! CURL_DISABLE_HTTP */ 328 329 #ifdef USE_SSL 330 static CURLcode setopt_SSLVERSION(struct Curl_easy *data, CURLoption option, 331 long arg) 332 { 333 /* 334 * Set explicit SSL version to try to connect with, as some SSL 335 * implementations are lame. 336 */ 337 { 338 long version, version_max; 339 struct ssl_primary_config *primary = &data->set.ssl.primary; 340 #ifndef CURL_DISABLE_PROXY 341 if(option != CURLOPT_SSLVERSION) 342 primary = &data->set.proxy_ssl.primary; 343 #else 344 if(option) {} 345 #endif 346 version = C_SSLVERSION_VALUE(arg); 347 version_max = (long)C_SSLVERSION_MAX_VALUE(arg); 348 349 if(version < CURL_SSLVERSION_DEFAULT || 350 version == CURL_SSLVERSION_SSLv2 || 351 version == CURL_SSLVERSION_SSLv3 || 352 version >= CURL_SSLVERSION_LAST || 353 version_max < CURL_SSLVERSION_MAX_NONE || 354 version_max >= CURL_SSLVERSION_MAX_LAST) 355 return CURLE_BAD_FUNCTION_ARGUMENT; 356 357 primary->version = (unsigned char)version; 358 primary->version_max = (unsigned int)version_max; 359 } 360 return CURLE_OK; 361 } 362 #endif /* ! USE_SSL */ 363 364 #ifndef CURL_DISABLE_RTSP 365 static CURLcode setopt_RTSP_REQUEST(struct Curl_easy *data, long arg) 366 { 367 /* 368 * Set the RTSP request method (OPTIONS, SETUP, PLAY, etc...) 369 * Would this be better if the RTSPREQ_* were just moved into here? 370 */ 371 Curl_RtspReq rtspreq = RTSPREQ_NONE; 372 switch(arg) { 373 case CURL_RTSPREQ_OPTIONS: 374 rtspreq = RTSPREQ_OPTIONS; 375 break; 376 377 case CURL_RTSPREQ_DESCRIBE: 378 rtspreq = RTSPREQ_DESCRIBE; 379 break; 380 381 case CURL_RTSPREQ_ANNOUNCE: 382 rtspreq = RTSPREQ_ANNOUNCE; 383 break; 384 385 case CURL_RTSPREQ_SETUP: 386 rtspreq = RTSPREQ_SETUP; 387 break; 388 389 case CURL_RTSPREQ_PLAY: 390 rtspreq = RTSPREQ_PLAY; 391 break; 392 393 case CURL_RTSPREQ_PAUSE: 394 rtspreq = RTSPREQ_PAUSE; 395 break; 396 397 case CURL_RTSPREQ_TEARDOWN: 398 rtspreq = RTSPREQ_TEARDOWN; 399 break; 400 401 case CURL_RTSPREQ_GET_PARAMETER: 402 rtspreq = RTSPREQ_GET_PARAMETER; 403 break; 404 405 case CURL_RTSPREQ_SET_PARAMETER: 406 rtspreq = RTSPREQ_SET_PARAMETER; 407 break; 408 409 case CURL_RTSPREQ_RECORD: 410 rtspreq = RTSPREQ_RECORD; 411 break; 412 413 case CURL_RTSPREQ_RECEIVE: 414 rtspreq = RTSPREQ_RECEIVE; 415 break; 416 default: 417 return CURLE_BAD_FUNCTION_ARGUMENT; 418 } 419 420 data->set.rtspreq = rtspreq; 421 return CURLE_OK; 422 } 423 #endif /* ! CURL_DISABLE_RTSP */ 424 425 #ifdef USE_SSL 426 static void set_ssl_options(struct ssl_config_data *ssl, 427 struct ssl_primary_config *config, 428 long arg) 429 { 430 config->ssl_options = (unsigned char)(arg & 0xff); 431 ssl->enable_beast = !!(arg & CURLSSLOPT_ALLOW_BEAST); 432 ssl->no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE); 433 ssl->no_partialchain = !!(arg & CURLSSLOPT_NO_PARTIALCHAIN); 434 ssl->revoke_best_effort = !!(arg & CURLSSLOPT_REVOKE_BEST_EFFORT); 435 ssl->native_ca_store = !!(arg & CURLSSLOPT_NATIVE_CA); 436 ssl->auto_client_cert = !!(arg & CURLSSLOPT_AUTO_CLIENT_CERT); 437 ssl->earlydata = !!(arg & CURLSSLOPT_EARLYDATA); 438 } 439 #endif 440 441 static CURLcode setopt_long(struct Curl_easy *data, CURLoption option, 442 long arg) 443 { 444 bool enabled = (0 != arg); 445 unsigned long uarg = (unsigned long)arg; 446 switch(option) { 447 case CURLOPT_DNS_CACHE_TIMEOUT: 448 if(arg < -1) 449 return CURLE_BAD_FUNCTION_ARGUMENT; 450 else if(arg > INT_MAX) 451 arg = INT_MAX; 452 453 data->set.dns_cache_timeout = (int)arg; 454 break; 455 case CURLOPT_CA_CACHE_TIMEOUT: 456 if(Curl_ssl_supports(data, SSLSUPP_CA_CACHE)) { 457 if(arg < -1) 458 return CURLE_BAD_FUNCTION_ARGUMENT; 459 else if(arg > INT_MAX) 460 arg = INT_MAX; 461 462 data->set.general_ssl.ca_cache_timeout = (int)arg; 463 } 464 else 465 return CURLE_NOT_BUILT_IN; 466 break; 467 case CURLOPT_MAXCONNECTS: 468 /* 469 * Set the absolute number of maximum simultaneous alive connection that 470 * libcurl is allowed to have. 471 */ 472 if(uarg > UINT_MAX) 473 return CURLE_BAD_FUNCTION_ARGUMENT; 474 data->set.maxconnects = (unsigned int)uarg; 475 break; 476 case CURLOPT_FORBID_REUSE: 477 /* 478 * When this transfer is done, it must not be left to be reused by a 479 * subsequent transfer but shall be closed immediately. 480 */ 481 data->set.reuse_forbid = enabled; 482 break; 483 case CURLOPT_FRESH_CONNECT: 484 /* 485 * This transfer shall not use a previously cached connection but 486 * should be made with a fresh new connect! 487 */ 488 data->set.reuse_fresh = enabled; 489 break; 490 case CURLOPT_VERBOSE: 491 /* 492 * Verbose means infof() calls that give a lot of information about 493 * the connection and transfer procedures as well as internal choices. 494 */ 495 data->set.verbose = enabled; 496 break; 497 case CURLOPT_HEADER: 498 /* 499 * Set to include the header in the general data output stream. 500 */ 501 data->set.include_header = enabled; 502 break; 503 case CURLOPT_NOPROGRESS: 504 /* 505 * Shut off the internal supported progress meter 506 */ 507 data->progress.hide = enabled; 508 break; 509 case CURLOPT_NOBODY: 510 /* 511 * Do not include the body part in the output data stream. 512 */ 513 data->set.opt_no_body = enabled; 514 #ifndef CURL_DISABLE_HTTP 515 if(data->set.opt_no_body) 516 /* in HTTP lingo, no body means using the HEAD request... */ 517 data->set.method = HTTPREQ_HEAD; 518 else if(data->set.method == HTTPREQ_HEAD) 519 data->set.method = HTTPREQ_GET; 520 #endif 521 break; 522 case CURLOPT_FAILONERROR: 523 /* 524 * Do not output the >=400 error code HTML-page, but instead only 525 * return error. 526 */ 527 data->set.http_fail_on_error = enabled; 528 break; 529 case CURLOPT_KEEP_SENDING_ON_ERROR: 530 data->set.http_keep_sending_on_error = enabled; 531 break; 532 case CURLOPT_UPLOAD: 533 case CURLOPT_PUT: 534 /* 535 * We want to sent data to the remote host. If this is HTTP, that equals 536 * using the PUT request. 537 */ 538 if(arg) { 539 /* If this is HTTP, PUT is what's needed to "upload" */ 540 data->set.method = HTTPREQ_PUT; 541 data->set.opt_no_body = FALSE; /* this is implied */ 542 } 543 else 544 /* In HTTP, the opposite of upload is GET (unless NOBODY is true as 545 then this can be changed to HEAD later on) */ 546 data->set.method = HTTPREQ_GET; 547 break; 548 case CURLOPT_FILETIME: 549 /* 550 * Try to get the file time of the remote document. The time will 551 * later (possibly) become available using curl_easy_getinfo(). 552 */ 553 data->set.get_filetime = enabled; 554 break; 555 case CURLOPT_SERVER_RESPONSE_TIMEOUT: 556 /* 557 * Option that specifies how quickly a server response must be obtained 558 * before it is considered failure. For pingpong protocols. 559 */ 560 return setopt_set_timeout_sec(&data->set.server_response_timeout, arg); 561 562 case CURLOPT_SERVER_RESPONSE_TIMEOUT_MS: 563 /* 564 * Option that specifies how quickly a server response must be obtained 565 * before it is considered failure. For pingpong protocols. 566 */ 567 return setopt_set_timeout_ms(&data->set.server_response_timeout, arg); 568 569 #ifndef CURL_DISABLE_TFTP 570 case CURLOPT_TFTP_NO_OPTIONS: 571 /* 572 * Option that prevents libcurl from sending TFTP option requests to the 573 * server. 574 */ 575 data->set.tftp_no_options = enabled; 576 break; 577 case CURLOPT_TFTP_BLKSIZE: 578 /* 579 * TFTP option that specifies the block size to use for data transmission. 580 */ 581 if(arg < TFTP_BLKSIZE_MIN) 582 arg = 512; 583 else if(arg > TFTP_BLKSIZE_MAX) 584 arg = TFTP_BLKSIZE_MAX; 585 data->set.tftp_blksize = arg; 586 break; 587 #endif 588 #ifndef CURL_DISABLE_NETRC 589 case CURLOPT_NETRC: 590 /* 591 * Parse the $HOME/.netrc file 592 */ 593 if((arg < CURL_NETRC_IGNORED) || (arg >= CURL_NETRC_LAST)) 594 return CURLE_BAD_FUNCTION_ARGUMENT; 595 data->set.use_netrc = (unsigned char)arg; 596 break; 597 #endif 598 case CURLOPT_TRANSFERTEXT: 599 /* 600 * This option was previously named 'FTPASCII'. Renamed to work with 601 * more protocols than merely FTP. 602 * 603 * Transfer using ASCII (instead of BINARY). 604 */ 605 data->set.prefer_ascii = enabled; 606 break; 607 case CURLOPT_TIMECONDITION: 608 /* 609 * Set HTTP time condition. This must be one of the defines in the 610 * curl/curl.h header file. 611 */ 612 if((arg < CURL_TIMECOND_NONE) || (arg >= CURL_TIMECOND_LAST)) 613 return CURLE_BAD_FUNCTION_ARGUMENT; 614 data->set.timecondition = (unsigned char)arg; 615 break; 616 case CURLOPT_TIMEVALUE: 617 /* 618 * This is the value to compare with the remote document with the 619 * method set with CURLOPT_TIMECONDITION 620 */ 621 data->set.timevalue = (time_t)arg; 622 break; 623 case CURLOPT_SSLVERSION: 624 #ifndef CURL_DISABLE_PROXY 625 case CURLOPT_PROXY_SSLVERSION: 626 #endif 627 #ifdef USE_SSL 628 return setopt_SSLVERSION(data, option, arg); 629 #else 630 return CURLE_NOT_BUILT_IN; 631 #endif 632 633 case CURLOPT_POSTFIELDSIZE: 634 /* 635 * The size of the POSTFIELD data to prevent libcurl to do strlen() to 636 * figure it out. Enables binary posts. 637 */ 638 if(arg < -1) 639 return CURLE_BAD_FUNCTION_ARGUMENT; 640 641 if(data->set.postfieldsize < arg && 642 data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) { 643 /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */ 644 Curl_safefree(data->set.str[STRING_COPYPOSTFIELDS]); 645 data->set.postfields = NULL; 646 } 647 648 data->set.postfieldsize = arg; 649 break; 650 #ifndef CURL_DISABLE_HTTP 651 #if !defined(CURL_DISABLE_COOKIES) 652 case CURLOPT_COOKIESESSION: 653 /* 654 * Set this option to TRUE to start a new "cookie session". It will 655 * prevent the forthcoming read-cookies-from-file actions to accept 656 * cookies that are marked as being session cookies, as they belong to a 657 * previous session. 658 */ 659 data->set.cookiesession = enabled; 660 break; 661 #endif 662 case CURLOPT_AUTOREFERER: 663 /* 664 * Switch on automatic referer that gets set if curl follows locations. 665 */ 666 data->set.http_auto_referer = enabled; 667 break; 668 669 case CURLOPT_TRANSFER_ENCODING: 670 data->set.http_transfer_encoding = enabled; 671 break; 672 673 case CURLOPT_FOLLOWLOCATION: 674 /* 675 * Follow Location: header hints on an HTTP-server. 676 */ 677 if(uarg > 3) 678 return CURLE_BAD_FUNCTION_ARGUMENT; 679 data->set.http_follow_mode = (unsigned char)uarg; 680 break; 681 682 case CURLOPT_UNRESTRICTED_AUTH: 683 /* 684 * Send authentication (user+password) when following locations, even when 685 * hostname changed. 686 */ 687 data->set.allow_auth_to_other_hosts = enabled; 688 break; 689 690 case CURLOPT_MAXREDIRS: 691 /* 692 * The maximum amount of hops you allow curl to follow Location: 693 * headers. This should mostly be used to detect never-ending loops. 694 */ 695 if(arg < -1) 696 return CURLE_BAD_FUNCTION_ARGUMENT; 697 data->set.maxredirs = arg; 698 break; 699 700 case CURLOPT_POSTREDIR: 701 /* 702 * Set the behavior of POST when redirecting 703 * CURL_REDIR_GET_ALL - POST is changed to GET after 301 and 302 704 * CURL_REDIR_POST_301 - POST is kept as POST after 301 705 * CURL_REDIR_POST_302 - POST is kept as POST after 302 706 * CURL_REDIR_POST_303 - POST is kept as POST after 303 707 * CURL_REDIR_POST_ALL - POST is kept as POST after 301, 302 and 303 708 * other - POST is kept as POST after 301 and 302 709 */ 710 if(arg < CURL_REDIR_GET_ALL) 711 /* no return error on too high numbers since the bitmask could be 712 extended in a future */ 713 return CURLE_BAD_FUNCTION_ARGUMENT; 714 data->set.keep_post = arg & CURL_REDIR_POST_ALL; 715 break; 716 717 case CURLOPT_POST: 718 /* Does this option serve a purpose anymore? Yes it does, when 719 CURLOPT_POSTFIELDS is not used and the POST data is read off the 720 callback! */ 721 if(arg) { 722 data->set.method = HTTPREQ_POST; 723 data->set.opt_no_body = FALSE; /* this is implied */ 724 } 725 else 726 data->set.method = HTTPREQ_GET; 727 break; 728 case CURLOPT_HEADEROPT: 729 /* 730 * Set header option. 731 */ 732 data->set.sep_headers = !!(arg & CURLHEADER_SEPARATE); 733 break; 734 case CURLOPT_HTTPAUTH: 735 return httpauth(data, FALSE, uarg); 736 737 case CURLOPT_HTTPGET: 738 /* 739 * Set to force us do HTTP GET 740 */ 741 if(enabled) { 742 data->set.method = HTTPREQ_GET; 743 data->set.opt_no_body = FALSE; /* this is implied */ 744 } 745 break; 746 747 case CURLOPT_HTTP_VERSION: 748 return setopt_HTTP_VERSION(data, arg); 749 750 case CURLOPT_EXPECT_100_TIMEOUT_MS: 751 /* 752 * Time to wait for a response to an HTTP request containing an 753 * Expect: 100-continue header before sending the data anyway. 754 */ 755 if(arg < 0) 756 return CURLE_BAD_FUNCTION_ARGUMENT; 757 data->set.expect_100_timeout = arg; 758 break; 759 760 case CURLOPT_HTTP09_ALLOWED: 761 data->set.http09_allowed = enabled; 762 break; 763 #endif /* ! CURL_DISABLE_HTTP */ 764 765 #ifndef CURL_DISABLE_MIME 766 case CURLOPT_MIME_OPTIONS: 767 data->set.mime_formescape = !!(arg & CURLMIMEOPT_FORMESCAPE); 768 break; 769 #endif 770 #ifndef CURL_DISABLE_PROXY 771 case CURLOPT_HTTPPROXYTUNNEL: 772 /* 773 * Tunnel operations through the proxy instead of normal proxy use 774 */ 775 data->set.tunnel_thru_httpproxy = enabled; 776 break; 777 778 case CURLOPT_PROXYPORT: 779 /* 780 * Explicitly set HTTP proxy port number. 781 */ 782 if((arg < 0) || (arg > 65535)) 783 return CURLE_BAD_FUNCTION_ARGUMENT; 784 data->set.proxyport = (unsigned short)arg; 785 break; 786 787 case CURLOPT_PROXYAUTH: 788 return httpauth(data, TRUE, uarg); 789 790 case CURLOPT_PROXYTYPE: 791 /* 792 * Set proxy type. 793 */ 794 if((arg < CURLPROXY_HTTP) || (arg > CURLPROXY_SOCKS5_HOSTNAME)) 795 return CURLE_BAD_FUNCTION_ARGUMENT; 796 data->set.proxytype = (unsigned char)(curl_proxytype)arg; 797 break; 798 799 case CURLOPT_PROXY_TRANSFER_MODE: 800 /* 801 * set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy 802 */ 803 if(uarg > 1) 804 /* reserve other values for future use */ 805 return CURLE_BAD_FUNCTION_ARGUMENT; 806 data->set.proxy_transfer_mode = (bool)uarg; 807 break; 808 case CURLOPT_SOCKS5_AUTH: 809 if(uarg & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI)) 810 return CURLE_NOT_BUILT_IN; 811 data->set.socks5auth = (unsigned char)uarg; 812 break; 813 case CURLOPT_HAPROXYPROTOCOL: 814 /* 815 * Set to send the HAProxy Proxy Protocol header 816 */ 817 data->set.haproxyprotocol = enabled; 818 break; 819 case CURLOPT_PROXY_SSL_VERIFYPEER: 820 /* 821 * Enable peer SSL verifying for proxy. 822 */ 823 data->set.proxy_ssl.primary.verifypeer = enabled; 824 825 /* Update the current connection proxy_ssl_config. */ 826 Curl_ssl_conn_config_update(data, TRUE); 827 break; 828 case CURLOPT_PROXY_SSL_VERIFYHOST: 829 /* 830 * Enable verification of the hostname in the peer certificate for proxy 831 */ 832 data->set.proxy_ssl.primary.verifyhost = enabled; 833 834 /* Update the current connection proxy_ssl_config. */ 835 Curl_ssl_conn_config_update(data, TRUE); 836 break; 837 #endif /* ! CURL_DISABLE_PROXY */ 838 839 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) 840 case CURLOPT_SOCKS5_GSSAPI_NEC: 841 /* 842 * Set flag for NEC SOCK5 support 843 */ 844 data->set.socks5_gssapi_nec = enabled; 845 break; 846 #endif 847 #ifdef CURL_LIST_ONLY_PROTOCOL 848 case CURLOPT_DIRLISTONLY: 849 /* 850 * An option that changes the command to one that asks for a list only, no 851 * file info details. Used for FTP, POP3 and SFTP. 852 */ 853 data->set.list_only = enabled; 854 break; 855 #endif 856 case CURLOPT_APPEND: 857 /* 858 * We want to upload and append to an existing file. Used for FTP and 859 * SFTP. 860 */ 861 data->set.remote_append = enabled; 862 break; 863 864 #ifndef CURL_DISABLE_FTP 865 case CURLOPT_FTP_FILEMETHOD: 866 /* 867 * How do access files over FTP. 868 */ 869 if((arg < CURLFTPMETHOD_DEFAULT) || (arg >= CURLFTPMETHOD_LAST)) 870 return CURLE_BAD_FUNCTION_ARGUMENT; 871 data->set.ftp_filemethod = (unsigned char)arg; 872 break; 873 case CURLOPT_FTP_USE_EPRT: 874 data->set.ftp_use_eprt = enabled; 875 break; 876 877 case CURLOPT_FTP_USE_EPSV: 878 data->set.ftp_use_epsv = enabled; 879 break; 880 881 case CURLOPT_FTP_USE_PRET: 882 data->set.ftp_use_pret = enabled; 883 break; 884 885 case CURLOPT_FTP_SSL_CCC: 886 if((arg < CURLFTPSSL_CCC_NONE) || (arg >= CURLFTPSSL_CCC_LAST)) 887 return CURLE_BAD_FUNCTION_ARGUMENT; 888 data->set.ftp_ccc = (unsigned char)arg; 889 break; 890 891 case CURLOPT_FTP_SKIP_PASV_IP: 892 /* 893 * Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the 894 * bypass of the IP address in PASV responses. 895 */ 896 data->set.ftp_skip_ip = enabled; 897 break; 898 899 case CURLOPT_FTPSSLAUTH: 900 /* 901 * Set a specific auth for FTP-SSL transfers. 902 */ 903 if((arg < CURLFTPAUTH_DEFAULT) || (arg >= CURLFTPAUTH_LAST)) 904 return CURLE_BAD_FUNCTION_ARGUMENT; 905 data->set.ftpsslauth = (unsigned char)(curl_ftpauth)arg; 906 break; 907 case CURLOPT_ACCEPTTIMEOUT_MS: 908 /* 909 * The maximum time for curl to wait for FTP server connect 910 */ 911 return setopt_set_timeout_ms(&data->set.accepttimeout, arg); 912 913 case CURLOPT_WILDCARDMATCH: 914 data->set.wildcard_enabled = enabled; 915 break; 916 #endif /* ! CURL_DISABLE_FTP */ 917 #if !defined(CURL_DISABLE_FTP) || defined(USE_SSH) 918 case CURLOPT_FTP_CREATE_MISSING_DIRS: 919 /* 920 * An FTP/SFTP option that modifies an upload to create missing 921 * directories on the server. 922 */ 923 /* reserve other values for future use */ 924 if((arg < CURLFTP_CREATE_DIR_NONE) || (arg > CURLFTP_CREATE_DIR_RETRY)) 925 return CURLE_BAD_FUNCTION_ARGUMENT; 926 data->set.ftp_create_missing_dirs = (unsigned char)arg; 927 break; 928 #endif /* ! CURL_DISABLE_FTP || USE_SSH */ 929 case CURLOPT_INFILESIZE: 930 /* 931 * If known, this should inform curl about the file size of the 932 * to-be-uploaded file. 933 */ 934 if(arg < -1) 935 return CURLE_BAD_FUNCTION_ARGUMENT; 936 data->set.filesize = arg; 937 break; 938 case CURLOPT_LOW_SPEED_LIMIT: 939 /* 940 * The low speed limit that if transfers are below this for 941 * CURLOPT_LOW_SPEED_TIME, the transfer is aborted. 942 */ 943 if(arg < 0) 944 return CURLE_BAD_FUNCTION_ARGUMENT; 945 data->set.low_speed_limit = arg; 946 break; 947 case CURLOPT_LOW_SPEED_TIME: 948 /* 949 * The low speed time that if transfers are below the set 950 * CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted. 951 */ 952 if(arg < 0) 953 return CURLE_BAD_FUNCTION_ARGUMENT; 954 data->set.low_speed_time = arg; 955 break; 956 case CURLOPT_PORT: 957 /* 958 * The port number to use when getting the URL. 0 disables it. 959 */ 960 if((arg < 0) || (arg > 65535)) 961 return CURLE_BAD_FUNCTION_ARGUMENT; 962 data->set.use_port = (unsigned short)arg; 963 break; 964 case CURLOPT_TIMEOUT: 965 /* 966 * The maximum time you allow curl to use for a single transfer 967 * operation. 968 */ 969 return setopt_set_timeout_sec(&data->set.timeout, arg); 970 971 case CURLOPT_TIMEOUT_MS: 972 return setopt_set_timeout_ms(&data->set.timeout, arg); 973 974 case CURLOPT_CONNECTTIMEOUT: 975 /* 976 * The maximum time you allow curl to use to connect. 977 */ 978 return setopt_set_timeout_sec(&data->set.connecttimeout, arg); 979 980 case CURLOPT_CONNECTTIMEOUT_MS: 981 return setopt_set_timeout_ms(&data->set.connecttimeout, arg); 982 983 case CURLOPT_RESUME_FROM: 984 /* 985 * Resume transfer at the given file position 986 */ 987 if(arg < -1) 988 return CURLE_BAD_FUNCTION_ARGUMENT; 989 data->set.set_resume_from = arg; 990 break; 991 992 case CURLOPT_CRLF: 993 /* 994 * Kludgy option to enable CRLF conversions. Subject for removal. 995 */ 996 data->set.crlf = enabled; 997 break; 998 999 #ifndef CURL_DISABLE_BINDLOCAL 1000 case CURLOPT_LOCALPORT: 1001 /* 1002 * Set what local port to bind the socket to when performing an operation. 1003 */ 1004 if((arg < 0) || (arg > 65535)) 1005 return CURLE_BAD_FUNCTION_ARGUMENT; 1006 data->set.localport = curlx_sltous(arg); 1007 break; 1008 case CURLOPT_LOCALPORTRANGE: 1009 /* 1010 * Set number of local ports to try, starting with CURLOPT_LOCALPORT. 1011 */ 1012 if((arg < 0) || (arg > 65535)) 1013 return CURLE_BAD_FUNCTION_ARGUMENT; 1014 data->set.localportrange = curlx_sltous(arg); 1015 break; 1016 #endif 1017 1018 #ifdef HAVE_GSSAPI 1019 case CURLOPT_GSSAPI_DELEGATION: 1020 /* 1021 * GSS-API credential delegation bitmask 1022 */ 1023 data->set.gssapi_delegation = (unsigned char)uarg& 1024 (CURLGSSAPI_DELEGATION_POLICY_FLAG|CURLGSSAPI_DELEGATION_FLAG); 1025 break; 1026 #endif 1027 case CURLOPT_SSL_VERIFYPEER: 1028 /* 1029 * Enable peer SSL verifying. 1030 */ 1031 data->set.ssl.primary.verifypeer = enabled; 1032 1033 /* Update the current connection ssl_config. */ 1034 Curl_ssl_conn_config_update(data, FALSE); 1035 break; 1036 #ifndef CURL_DISABLE_DOH 1037 case CURLOPT_DOH_SSL_VERIFYPEER: 1038 /* 1039 * Enable peer SSL verifying for DoH. 1040 */ 1041 data->set.doh_verifypeer = enabled; 1042 break; 1043 case CURLOPT_DOH_SSL_VERIFYHOST: 1044 /* 1045 * Enable verification of the hostname in the peer certificate for DoH 1046 */ 1047 data->set.doh_verifyhost = enabled; 1048 break; 1049 case CURLOPT_DOH_SSL_VERIFYSTATUS: 1050 /* 1051 * Enable certificate status verifying for DoH. 1052 */ 1053 if(!Curl_ssl_cert_status_request()) 1054 return CURLE_NOT_BUILT_IN; 1055 1056 data->set.doh_verifystatus = enabled; 1057 break; 1058 #endif /* ! CURL_DISABLE_DOH */ 1059 case CURLOPT_SSL_VERIFYHOST: 1060 /* 1061 * Enable verification of the hostname in the peer certificate 1062 */ 1063 1064 /* Obviously people are not reading documentation and too many thought 1065 this argument took a boolean when it was not and misused it. 1066 Treat 1 and 2 the same */ 1067 data->set.ssl.primary.verifyhost = enabled; 1068 1069 /* Update the current connection ssl_config. */ 1070 Curl_ssl_conn_config_update(data, FALSE); 1071 break; 1072 case CURLOPT_SSL_VERIFYSTATUS: 1073 /* 1074 * Enable certificate status verifying. 1075 */ 1076 if(!Curl_ssl_cert_status_request()) 1077 return CURLE_NOT_BUILT_IN; 1078 1079 data->set.ssl.primary.verifystatus = enabled; 1080 1081 /* Update the current connection ssl_config. */ 1082 Curl_ssl_conn_config_update(data, FALSE); 1083 break; 1084 case CURLOPT_SSL_FALSESTART: 1085 /* 1086 * No TLS backends support false start anymore. 1087 */ 1088 return CURLE_NOT_BUILT_IN; 1089 case CURLOPT_CERTINFO: 1090 #ifdef USE_SSL 1091 if(Curl_ssl_supports(data, SSLSUPP_CERTINFO)) 1092 data->set.ssl.certinfo = enabled; 1093 else 1094 #endif 1095 return CURLE_NOT_BUILT_IN; 1096 break; 1097 case CURLOPT_BUFFERSIZE: 1098 /* 1099 * The application kindly asks for a differently sized receive buffer. 1100 * If it seems reasonable, we will use it. 1101 */ 1102 if(arg > READBUFFER_MAX) 1103 arg = READBUFFER_MAX; 1104 else if(arg < 1) 1105 arg = READBUFFER_SIZE; 1106 else if(arg < READBUFFER_MIN) 1107 arg = READBUFFER_MIN; 1108 1109 data->set.buffer_size = (unsigned int)arg; 1110 break; 1111 1112 case CURLOPT_UPLOAD_BUFFERSIZE: 1113 /* 1114 * The application kindly asks for a differently sized upload buffer. 1115 * Cap it to sensible. 1116 */ 1117 if(arg > UPLOADBUFFER_MAX) 1118 arg = UPLOADBUFFER_MAX; 1119 else if(arg < UPLOADBUFFER_MIN) 1120 arg = UPLOADBUFFER_MIN; 1121 1122 data->set.upload_buffer_size = (unsigned int)arg; 1123 break; 1124 1125 case CURLOPT_NOSIGNAL: 1126 /* 1127 * The application asks not to set any signal() or alarm() handlers, 1128 * even when using a timeout. 1129 */ 1130 data->set.no_signal = enabled; 1131 break; 1132 case CURLOPT_MAXFILESIZE: 1133 /* 1134 * Set the maximum size of a file to download. 1135 */ 1136 if(arg < 0) 1137 return CURLE_BAD_FUNCTION_ARGUMENT; 1138 data->set.max_filesize = arg; 1139 break; 1140 1141 #ifdef USE_SSL 1142 case CURLOPT_USE_SSL: 1143 /* 1144 * Make transfers attempt to use SSL/TLS. 1145 */ 1146 if((arg < CURLUSESSL_NONE) || (arg >= CURLUSESSL_LAST)) 1147 return CURLE_BAD_FUNCTION_ARGUMENT; 1148 data->set.use_ssl = (unsigned char)arg; 1149 break; 1150 case CURLOPT_SSL_OPTIONS: 1151 set_ssl_options(&data->set.ssl, &data->set.ssl.primary, arg); 1152 break; 1153 1154 #ifndef CURL_DISABLE_PROXY 1155 case CURLOPT_PROXY_SSL_OPTIONS: 1156 set_ssl_options(&data->set.proxy_ssl, &data->set.proxy_ssl.primary, arg); 1157 break; 1158 #endif 1159 1160 #endif /* USE_SSL */ 1161 case CURLOPT_IPRESOLVE: 1162 if((arg < CURL_IPRESOLVE_WHATEVER) || (arg > CURL_IPRESOLVE_V6)) 1163 return CURLE_BAD_FUNCTION_ARGUMENT; 1164 data->set.ipver = (unsigned char) arg; 1165 break; 1166 case CURLOPT_TCP_NODELAY: 1167 /* 1168 * Enable or disable TCP_NODELAY, which will disable/enable the Nagle 1169 * algorithm 1170 */ 1171 data->set.tcp_nodelay = enabled; 1172 break; 1173 1174 case CURLOPT_IGNORE_CONTENT_LENGTH: 1175 data->set.ignorecl = enabled; 1176 break; 1177 1178 case CURLOPT_CONNECT_ONLY: 1179 /* 1180 * No data transfer. 1181 * (1) - only do connection 1182 * (2) - do first get request but get no content 1183 */ 1184 if(arg > 2) 1185 return CURLE_BAD_FUNCTION_ARGUMENT; 1186 data->set.connect_only = !!arg; 1187 data->set.connect_only_ws = (arg == 2); 1188 break; 1189 1190 case CURLOPT_SSL_SESSIONID_CACHE: 1191 data->set.ssl.primary.cache_session = enabled; 1192 #ifndef CURL_DISABLE_PROXY 1193 data->set.proxy_ssl.primary.cache_session = 1194 data->set.ssl.primary.cache_session; 1195 #endif 1196 break; 1197 1198 #ifdef USE_SSH 1199 /* we only include SSH options if explicitly built to support SSH */ 1200 case CURLOPT_SSH_AUTH_TYPES: 1201 data->set.ssh_auth_types = (int)arg; 1202 break; 1203 case CURLOPT_SSH_COMPRESSION: 1204 data->set.ssh_compression = enabled; 1205 break; 1206 #endif 1207 1208 case CURLOPT_HTTP_TRANSFER_DECODING: 1209 /* 1210 * disable libcurl transfer encoding is used 1211 */ 1212 data->set.http_te_skip = !enabled; /* reversed */ 1213 break; 1214 1215 case CURLOPT_HTTP_CONTENT_DECODING: 1216 /* 1217 * raw data passed to the application when content encoding is used 1218 */ 1219 data->set.http_ce_skip = !enabled; /* reversed */ 1220 break; 1221 1222 #if !defined(CURL_DISABLE_FTP) || defined(USE_SSH) 1223 case CURLOPT_NEW_FILE_PERMS: 1224 /* 1225 * Uses these permissions instead of 0644 1226 */ 1227 if((arg < 0) || (arg > 0777)) 1228 return CURLE_BAD_FUNCTION_ARGUMENT; 1229 data->set.new_file_perms = (unsigned int)arg; 1230 break; 1231 #endif 1232 #ifdef USE_SSH 1233 case CURLOPT_NEW_DIRECTORY_PERMS: 1234 /* 1235 * Uses these permissions instead of 0755 1236 */ 1237 if((arg < 0) || (arg > 0777)) 1238 return CURLE_BAD_FUNCTION_ARGUMENT; 1239 data->set.new_directory_perms = (unsigned int)arg; 1240 break; 1241 #endif 1242 #ifdef USE_IPV6 1243 case CURLOPT_ADDRESS_SCOPE: 1244 /* 1245 * Use this scope id when using IPv6 1246 * We always get longs when passed plain numericals so we should check 1247 * that the value fits into an unsigned 32-bit integer. 1248 */ 1249 #if SIZEOF_LONG > 4 1250 if(uarg > UINT_MAX) 1251 return CURLE_BAD_FUNCTION_ARGUMENT; 1252 #endif 1253 data->set.scope_id = (unsigned int)uarg; 1254 break; 1255 #endif 1256 case CURLOPT_PROTOCOLS: 1257 /* set the bitmask for the protocols that are allowed to be used for the 1258 transfer, which thus helps the app which takes URLs from users or other 1259 external inputs and want to restrict what protocol(s) to deal with. 1260 Defaults to CURLPROTO_ALL. */ 1261 data->set.allowed_protocols = (curl_prot_t)arg; 1262 break; 1263 1264 case CURLOPT_REDIR_PROTOCOLS: 1265 /* set the bitmask for the protocols that libcurl is allowed to follow to, 1266 as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol 1267 needs to be set in both bitmasks to be allowed to get redirected to. */ 1268 data->set.redir_protocols = (curl_prot_t)arg; 1269 break; 1270 1271 #ifndef CURL_DISABLE_SMTP 1272 case CURLOPT_MAIL_RCPT_ALLOWFAILS: 1273 /* allow RCPT TO command to fail for some recipients */ 1274 data->set.mail_rcpt_allowfails = enabled; 1275 break; 1276 #endif /* !CURL_DISABLE_SMTP */ 1277 case CURLOPT_SASL_IR: 1278 /* Enable/disable SASL initial response */ 1279 data->set.sasl_ir = enabled; 1280 break; 1281 #ifndef CURL_DISABLE_RTSP 1282 case CURLOPT_RTSP_REQUEST: 1283 return setopt_RTSP_REQUEST(data, arg); 1284 case CURLOPT_RTSP_CLIENT_CSEQ: 1285 /* 1286 * Set the CSEQ number to issue for the next RTSP request. Useful if the 1287 * application is resuming a previously broken connection. The CSEQ 1288 * will increment from this new number henceforth. 1289 */ 1290 data->state.rtsp_next_client_CSeq = arg; 1291 break; 1292 1293 case CURLOPT_RTSP_SERVER_CSEQ: 1294 /* Same as the above, but for server-initiated requests */ 1295 data->state.rtsp_next_server_CSeq = arg; 1296 break; 1297 1298 #endif /* ! CURL_DISABLE_RTSP */ 1299 1300 case CURLOPT_TCP_KEEPALIVE: 1301 data->set.tcp_keepalive = enabled; 1302 break; 1303 case CURLOPT_TCP_KEEPIDLE: 1304 if(arg < 0) 1305 return CURLE_BAD_FUNCTION_ARGUMENT; 1306 else if(arg > INT_MAX) 1307 arg = INT_MAX; 1308 data->set.tcp_keepidle = (int)arg; 1309 break; 1310 case CURLOPT_TCP_KEEPINTVL: 1311 if(arg < 0) 1312 return CURLE_BAD_FUNCTION_ARGUMENT; 1313 else if(arg > INT_MAX) 1314 arg = INT_MAX; 1315 data->set.tcp_keepintvl = (int)arg; 1316 break; 1317 case CURLOPT_TCP_KEEPCNT: 1318 if(arg < 0) 1319 return CURLE_BAD_FUNCTION_ARGUMENT; 1320 else if(arg > INT_MAX) 1321 arg = INT_MAX; 1322 data->set.tcp_keepcnt = (int)arg; 1323 break; 1324 case CURLOPT_TCP_FASTOPEN: 1325 #if defined(CONNECT_DATA_IDEMPOTENT) || defined(MSG_FASTOPEN) || \ 1326 defined(TCP_FASTOPEN_CONNECT) 1327 data->set.tcp_fastopen = enabled; 1328 #else 1329 return CURLE_NOT_BUILT_IN; 1330 #endif 1331 break; 1332 case CURLOPT_SSL_ENABLE_NPN: 1333 break; 1334 case CURLOPT_SSL_ENABLE_ALPN: 1335 data->set.ssl_enable_alpn = enabled; 1336 break; 1337 case CURLOPT_PATH_AS_IS: 1338 data->set.path_as_is = enabled; 1339 break; 1340 case CURLOPT_PIPEWAIT: 1341 data->set.pipewait = enabled; 1342 break; 1343 case CURLOPT_STREAM_WEIGHT: 1344 #if defined(USE_HTTP2) || defined(USE_HTTP3) 1345 if((arg >= 1) && (arg <= 256)) 1346 data->set.priority.weight = (int)arg; 1347 break; 1348 #else 1349 return CURLE_NOT_BUILT_IN; 1350 #endif 1351 case CURLOPT_SUPPRESS_CONNECT_HEADERS: 1352 data->set.suppress_connect_headers = enabled; 1353 break; 1354 case CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS: 1355 return setopt_set_timeout_ms(&data->set.happy_eyeballs_timeout, arg); 1356 1357 #ifndef CURL_DISABLE_SHUFFLE_DNS 1358 case CURLOPT_DNS_SHUFFLE_ADDRESSES: 1359 data->set.dns_shuffle_addresses = enabled; 1360 break; 1361 #endif 1362 case CURLOPT_DISALLOW_USERNAME_IN_URL: 1363 data->set.disallow_username_in_url = enabled; 1364 break; 1365 1366 case CURLOPT_UPKEEP_INTERVAL_MS: 1367 if(arg < 0) 1368 return CURLE_BAD_FUNCTION_ARGUMENT; 1369 data->set.upkeep_interval_ms = arg; 1370 break; 1371 case CURLOPT_MAXAGE_CONN: 1372 return setopt_set_timeout_sec(&data->set.conn_max_idle_ms, arg); 1373 1374 case CURLOPT_MAXLIFETIME_CONN: 1375 return setopt_set_timeout_sec(&data->set.conn_max_age_ms, arg); 1376 1377 #ifndef CURL_DISABLE_HSTS 1378 case CURLOPT_HSTS_CTRL: 1379 if(arg & CURLHSTS_ENABLE) { 1380 if(!data->hsts) { 1381 data->hsts = Curl_hsts_init(); 1382 if(!data->hsts) 1383 return CURLE_OUT_OF_MEMORY; 1384 } 1385 } 1386 else 1387 Curl_hsts_cleanup(&data->hsts); 1388 break; 1389 #endif /* ! CURL_DISABLE_HSTS */ 1390 #ifndef CURL_DISABLE_ALTSVC 1391 case CURLOPT_ALTSVC_CTRL: 1392 if(!arg) { 1393 DEBUGF(infof(data, "bad CURLOPT_ALTSVC_CTRL input")); 1394 return CURLE_BAD_FUNCTION_ARGUMENT; 1395 } 1396 if(!data->asi) { 1397 data->asi = Curl_altsvc_init(); 1398 if(!data->asi) 1399 return CURLE_OUT_OF_MEMORY; 1400 } 1401 return Curl_altsvc_ctrl(data->asi, arg); 1402 #endif /* ! CURL_DISABLE_ALTSVC */ 1403 #ifndef CURL_DISABLE_WEBSOCKETS 1404 case CURLOPT_WS_OPTIONS: 1405 data->set.ws_raw_mode = (bool)(arg & CURLWS_RAW_MODE); 1406 data->set.ws_no_auto_pong = (bool)(arg & CURLWS_NOAUTOPONG); 1407 break; 1408 #endif 1409 case CURLOPT_QUICK_EXIT: 1410 data->set.quick_exit = enabled; 1411 break; 1412 case CURLOPT_DNS_USE_GLOBAL_CACHE: 1413 /* deprecated */ 1414 break; 1415 case CURLOPT_SSLENGINE_DEFAULT: 1416 /* 1417 * flag to set engine as default. 1418 */ 1419 Curl_safefree(data->set.str[STRING_SSL_ENGINE]); 1420 return Curl_ssl_set_engine_default(data); 1421 case CURLOPT_UPLOAD_FLAGS: 1422 data->set.upload_flags = (unsigned char)arg; 1423 break; 1424 default: 1425 /* unknown option */ 1426 return CURLE_UNKNOWN_OPTION; 1427 } 1428 return CURLE_OK; 1429 } 1430 1431 static CURLcode setopt_slist(struct Curl_easy *data, CURLoption option, 1432 struct curl_slist *slist) 1433 { 1434 CURLcode result = CURLE_OK; 1435 switch(option) { 1436 #ifndef CURL_DISABLE_PROXY 1437 case CURLOPT_PROXYHEADER: 1438 /* 1439 * Set a list with proxy headers to use (or replace internals with) 1440 * 1441 * Since CURLOPT_HTTPHEADER was the only way to set HTTP headers for a 1442 * long time we remain doing it this way until CURLOPT_PROXYHEADER is 1443 * used. As soon as this option has been used, if set to anything but 1444 * NULL, custom headers for proxies are only picked from this list. 1445 * 1446 * Set this option to NULL to restore the previous behavior. 1447 */ 1448 data->set.proxyheaders = slist; 1449 break; 1450 #endif 1451 #ifndef CURL_DISABLE_HTTP 1452 case CURLOPT_HTTP200ALIASES: 1453 /* 1454 * Set a list of aliases for HTTP 200 in response header 1455 */ 1456 data->set.http200aliases = slist; 1457 break; 1458 #endif 1459 #if !defined(CURL_DISABLE_FTP) || defined(USE_SSH) 1460 case CURLOPT_POSTQUOTE: 1461 /* 1462 * List of RAW FTP commands to use after a transfer 1463 */ 1464 data->set.postquote = slist; 1465 break; 1466 case CURLOPT_PREQUOTE: 1467 /* 1468 * List of RAW FTP commands to use prior to RETR (Wesley Laxton) 1469 */ 1470 data->set.prequote = slist; 1471 break; 1472 case CURLOPT_QUOTE: 1473 /* 1474 * List of RAW FTP commands to use before a transfer 1475 */ 1476 data->set.quote = slist; 1477 break; 1478 #endif 1479 case CURLOPT_RESOLVE: 1480 /* 1481 * List of HOST:PORT:[addresses] strings to populate the DNS cache with 1482 * Entries added this way will remain in the cache until explicitly 1483 * removed or the handle is cleaned up. 1484 * 1485 * Prefix the HOST with plus sign (+) to have the entry expire just like 1486 * automatically added entries. 1487 * 1488 * Prefix the HOST with dash (-) to _remove_ the entry from the cache. 1489 * 1490 * This API can remove any entry from the DNS cache, but only entries 1491 * that are not actually in use right now will be pruned immediately. 1492 */ 1493 data->set.resolve = slist; 1494 data->state.resolve = data->set.resolve; 1495 break; 1496 #if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_MIME) 1497 case CURLOPT_HTTPHEADER: 1498 /* 1499 * Set a list with HTTP headers to use (or replace internals with) 1500 */ 1501 data->set.headers = slist; 1502 break; 1503 #endif 1504 #ifndef CURL_DISABLE_TELNET 1505 case CURLOPT_TELNETOPTIONS: 1506 /* 1507 * Set a linked list of telnet options 1508 */ 1509 data->set.telnet_options = slist; 1510 break; 1511 #endif 1512 #ifndef CURL_DISABLE_SMTP 1513 case CURLOPT_MAIL_RCPT: 1514 /* Set the list of mail recipients */ 1515 data->set.mail_rcpt = slist; 1516 break; 1517 #endif 1518 case CURLOPT_CONNECT_TO: 1519 data->set.connect_to = slist; 1520 break; 1521 default: 1522 return CURLE_UNKNOWN_OPTION; 1523 } 1524 return result; 1525 } 1526 1527 /* assorted pointer type arguments */ 1528 static CURLcode setopt_pointers(struct Curl_easy *data, CURLoption option, 1529 va_list param) 1530 { 1531 CURLcode result = CURLE_OK; 1532 switch(option) { 1533 #ifndef CURL_DISABLE_HTTP 1534 #ifndef CURL_DISABLE_FORM_API 1535 case CURLOPT_HTTPPOST: 1536 /* 1537 * Set to make us do HTTP POST. Legacy API-style. 1538 */ 1539 data->set.httppost = va_arg(param, struct curl_httppost *); 1540 data->set.method = HTTPREQ_POST_FORM; 1541 data->set.opt_no_body = FALSE; /* this is implied */ 1542 Curl_mime_cleanpart(data->state.formp); 1543 Curl_safefree(data->state.formp); 1544 data->state.mimepost = NULL; 1545 break; 1546 #endif /* ! CURL_DISABLE_FORM_API */ 1547 #endif /* ! CURL_DISABLE_HTTP */ 1548 #if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_SMTP) || \ 1549 !defined(CURL_DISABLE_IMAP) 1550 # ifndef CURL_DISABLE_MIME 1551 case CURLOPT_MIMEPOST: 1552 /* 1553 * Set to make us do MIME POST 1554 */ 1555 result = Curl_mime_set_subparts(&data->set.mimepost, 1556 va_arg(param, curl_mime *), 1557 FALSE); 1558 if(!result) { 1559 data->set.method = HTTPREQ_POST_MIME; 1560 data->set.opt_no_body = FALSE; /* this is implied */ 1561 #ifndef CURL_DISABLE_FORM_API 1562 Curl_mime_cleanpart(data->state.formp); 1563 Curl_safefree(data->state.formp); 1564 data->state.mimepost = NULL; 1565 #endif 1566 } 1567 break; 1568 #endif /* ! CURL_DISABLE_MIME */ 1569 #endif /* ! disabled HTTP, SMTP or IMAP */ 1570 case CURLOPT_STDERR: 1571 /* 1572 * Set to a FILE * that should receive all error writes. This 1573 * defaults to stderr for normal operations. 1574 */ 1575 data->set.err = va_arg(param, FILE *); 1576 if(!data->set.err) 1577 data->set.err = stderr; 1578 break; 1579 case CURLOPT_SHARE: 1580 { 1581 struct Curl_share *set = va_arg(param, struct Curl_share *); 1582 1583 /* disconnect from old share, if any */ 1584 if(data->share) { 1585 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); 1586 1587 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) 1588 if(data->share->cookies == data->cookies) 1589 data->cookies = NULL; 1590 #endif 1591 1592 #ifndef CURL_DISABLE_HSTS 1593 if(data->share->hsts == data->hsts) 1594 data->hsts = NULL; 1595 #endif 1596 #ifdef USE_LIBPSL 1597 if(data->psl == &data->share->psl) 1598 data->psl = data->multi ? &data->multi->psl : NULL; 1599 #endif 1600 if(data->share->specifier & (1 << CURL_LOCK_DATA_DNS)) { 1601 Curl_resolv_unlink(data, &data->state.dns[0]); 1602 Curl_resolv_unlink(data, &data->state.dns[1]); 1603 } 1604 1605 data->share->dirty--; 1606 1607 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); 1608 data->share = NULL; 1609 } 1610 1611 if(GOOD_SHARE_HANDLE(set)) 1612 /* use new share if it set */ 1613 data->share = set; 1614 if(data->share) { 1615 1616 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); 1617 1618 data->share->dirty++; 1619 1620 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) 1621 if(data->share->cookies) { 1622 /* use shared cookie list, first free own one if any */ 1623 Curl_cookie_cleanup(data->cookies); 1624 /* enable cookies since we now use a share that uses cookies! */ 1625 data->cookies = data->share->cookies; 1626 } 1627 #endif /* CURL_DISABLE_HTTP */ 1628 #ifndef CURL_DISABLE_HSTS 1629 if(data->share->hsts) { 1630 /* first free the private one if any */ 1631 Curl_hsts_cleanup(&data->hsts); 1632 data->hsts = data->share->hsts; 1633 } 1634 #endif 1635 #ifdef USE_LIBPSL 1636 if(data->share->specifier & (1 << CURL_LOCK_DATA_PSL)) 1637 data->psl = &data->share->psl; 1638 #endif 1639 1640 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); 1641 } 1642 /* check for host cache not needed, 1643 * it will be done by curl_easy_perform */ 1644 } 1645 break; 1646 1647 #ifdef USE_HTTP2 1648 case CURLOPT_STREAM_DEPENDS: 1649 case CURLOPT_STREAM_DEPENDS_E: { 1650 struct Curl_easy *dep = va_arg(param, struct Curl_easy *); 1651 if(!dep || GOOD_EASY_HANDLE(dep)) 1652 return Curl_data_priority_add_child(dep, data, 1653 option == CURLOPT_STREAM_DEPENDS_E); 1654 break; 1655 } 1656 #endif 1657 1658 default: 1659 return CURLE_UNKNOWN_OPTION; 1660 } 1661 return result; 1662 } 1663 1664 static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, 1665 char *ptr) 1666 { 1667 CURLcode result = CURLE_OK; 1668 switch(option) { 1669 case CURLOPT_SSL_CIPHER_LIST: 1670 if(Curl_ssl_supports(data, SSLSUPP_CIPHER_LIST)) 1671 /* set a list of cipher we want to use in the SSL connection */ 1672 return Curl_setstropt(&data->set.str[STRING_SSL_CIPHER_LIST], ptr); 1673 else 1674 return CURLE_NOT_BUILT_IN; 1675 #ifndef CURL_DISABLE_PROXY 1676 case CURLOPT_PROXY_SSL_CIPHER_LIST: 1677 if(Curl_ssl_supports(data, SSLSUPP_CIPHER_LIST)) { 1678 /* set a list of cipher we want to use in the SSL connection for proxy */ 1679 return Curl_setstropt(&data->set.str[STRING_SSL_CIPHER_LIST_PROXY], 1680 ptr); 1681 } 1682 else 1683 return CURLE_NOT_BUILT_IN; 1684 #endif 1685 case CURLOPT_TLS13_CIPHERS: 1686 if(Curl_ssl_supports(data, SSLSUPP_TLS13_CIPHERSUITES)) { 1687 /* set preferred list of TLS 1.3 cipher suites */ 1688 return Curl_setstropt(&data->set.str[STRING_SSL_CIPHER13_LIST], ptr); 1689 } 1690 else 1691 return CURLE_NOT_BUILT_IN; 1692 #ifndef CURL_DISABLE_PROXY 1693 case CURLOPT_PROXY_TLS13_CIPHERS: 1694 if(Curl_ssl_supports(data, SSLSUPP_TLS13_CIPHERSUITES)) 1695 /* set preferred list of TLS 1.3 cipher suites for proxy */ 1696 return Curl_setstropt(&data->set.str[STRING_SSL_CIPHER13_LIST_PROXY], 1697 ptr); 1698 else 1699 return CURLE_NOT_BUILT_IN; 1700 #endif 1701 case CURLOPT_RANDOM_FILE: 1702 break; 1703 case CURLOPT_EGDSOCKET: 1704 break; 1705 case CURLOPT_REQUEST_TARGET: 1706 return Curl_setstropt(&data->set.str[STRING_TARGET], ptr); 1707 #ifndef CURL_DISABLE_NETRC 1708 case CURLOPT_NETRC_FILE: 1709 /* 1710 * Use this file instead of the $HOME/.netrc file 1711 */ 1712 return Curl_setstropt(&data->set.str[STRING_NETRC_FILE], ptr); 1713 #endif 1714 1715 #if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_MQTT) 1716 case CURLOPT_COPYPOSTFIELDS: 1717 /* 1718 * A string with POST data. Makes curl HTTP POST. Even if it is NULL. 1719 * If needed, CURLOPT_POSTFIELDSIZE must have been set prior to 1720 * CURLOPT_COPYPOSTFIELDS and not altered later. 1721 */ 1722 if(!ptr || data->set.postfieldsize == -1) 1723 result = Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], ptr); 1724 else { 1725 if(data->set.postfieldsize < 0) 1726 return CURLE_BAD_FUNCTION_ARGUMENT; 1727 #if SIZEOF_CURL_OFF_T > SIZEOF_SIZE_T 1728 /* 1729 * Check that requested length does not overflow the size_t type. 1730 */ 1731 else if(data->set.postfieldsize > SIZE_T_MAX) 1732 return CURLE_OUT_OF_MEMORY; 1733 #endif 1734 else { 1735 /* Allocate even when size == 0. This satisfies the need of possible 1736 later address compare to detect the COPYPOSTFIELDS mode, and to 1737 mark that postfields is used rather than read function or form 1738 data. 1739 */ 1740 char *p = Curl_memdup0(ptr, (size_t)data->set.postfieldsize); 1741 if(!p) 1742 return CURLE_OUT_OF_MEMORY; 1743 else { 1744 free(data->set.str[STRING_COPYPOSTFIELDS]); 1745 data->set.str[STRING_COPYPOSTFIELDS] = p; 1746 } 1747 } 1748 } 1749 1750 data->set.postfields = data->set.str[STRING_COPYPOSTFIELDS]; 1751 data->set.method = HTTPREQ_POST; 1752 break; 1753 1754 case CURLOPT_POSTFIELDS: 1755 /* 1756 * Like above, but use static data instead of copying it. 1757 */ 1758 data->set.postfields = ptr; 1759 /* Release old copied data. */ 1760 Curl_safefree(data->set.str[STRING_COPYPOSTFIELDS]); 1761 data->set.method = HTTPREQ_POST; 1762 break; 1763 #endif /* ! CURL_DISABLE_HTTP || ! CURL_DISABLE_MQTT */ 1764 1765 #ifndef CURL_DISABLE_HTTP 1766 case CURLOPT_ACCEPT_ENCODING: 1767 /* 1768 * String to use at the value of Accept-Encoding header. 1769 * 1770 * If the encoding is set to "" we use an Accept-Encoding header that 1771 * encompasses all the encodings we support. 1772 * If the encoding is set to NULL we do not send an Accept-Encoding header 1773 * and ignore an received Content-Encoding header. 1774 * 1775 */ 1776 if(ptr && !*ptr) { 1777 char all[256]; 1778 Curl_all_content_encodings(all, sizeof(all)); 1779 return Curl_setstropt(&data->set.str[STRING_ENCODING], all); 1780 } 1781 return Curl_setstropt(&data->set.str[STRING_ENCODING], ptr); 1782 1783 #if !defined(CURL_DISABLE_AWS) 1784 case CURLOPT_AWS_SIGV4: 1785 /* 1786 * String that is merged to some authentication 1787 * parameters are used by the algorithm. 1788 */ 1789 result = Curl_setstropt(&data->set.str[STRING_AWS_SIGV4], ptr); 1790 /* 1791 * Basic been set by default it need to be unset here 1792 */ 1793 if(data->set.str[STRING_AWS_SIGV4]) 1794 data->set.httpauth = CURLAUTH_AWS_SIGV4; 1795 break; 1796 #endif 1797 case CURLOPT_REFERER: 1798 /* 1799 * String to set in the HTTP Referer: field. 1800 */ 1801 if(data->state.referer_alloc) { 1802 Curl_safefree(data->state.referer); 1803 data->state.referer_alloc = FALSE; 1804 } 1805 result = Curl_setstropt(&data->set.str[STRING_SET_REFERER], ptr); 1806 data->state.referer = data->set.str[STRING_SET_REFERER]; 1807 break; 1808 1809 case CURLOPT_USERAGENT: 1810 /* 1811 * String to use in the HTTP User-Agent field 1812 */ 1813 return Curl_setstropt(&data->set.str[STRING_USERAGENT], ptr); 1814 1815 #if !defined(CURL_DISABLE_COOKIES) 1816 case CURLOPT_COOKIE: 1817 /* 1818 * Cookie string to send to the remote server in the request. 1819 */ 1820 return Curl_setstropt(&data->set.str[STRING_COOKIE], ptr); 1821 1822 case CURLOPT_COOKIEFILE: 1823 /* 1824 * Set cookie file to read and parse. Can be used multiple times. 1825 */ 1826 if(ptr) { 1827 struct curl_slist *cl; 1828 /* general protection against mistakes and abuse */ 1829 if(strlen(ptr) > CURL_MAX_INPUT_LENGTH) 1830 return CURLE_BAD_FUNCTION_ARGUMENT; 1831 /* append the cookie filename to the list of filenames, and deal with 1832 them later */ 1833 cl = curl_slist_append(data->state.cookielist, ptr); 1834 if(!cl) { 1835 curl_slist_free_all(data->state.cookielist); 1836 data->state.cookielist = NULL; 1837 return CURLE_OUT_OF_MEMORY; 1838 } 1839 data->state.cookielist = cl; /* store the list for later use */ 1840 } 1841 else { 1842 /* clear the list of cookie files */ 1843 curl_slist_free_all(data->state.cookielist); 1844 data->state.cookielist = NULL; 1845 1846 if(!data->share || !data->share->cookies) { 1847 /* throw away all existing cookies if this is not a shared cookie 1848 container */ 1849 Curl_cookie_clearall(data->cookies); 1850 Curl_cookie_cleanup(data->cookies); 1851 } 1852 /* disable the cookie engine */ 1853 data->cookies = NULL; 1854 } 1855 break; 1856 1857 case CURLOPT_COOKIEJAR: 1858 /* 1859 * Set cookie filename to dump all cookies to when we are done. 1860 */ 1861 result = Curl_setstropt(&data->set.str[STRING_COOKIEJAR], ptr); 1862 if(!result) { 1863 /* 1864 * Activate the cookie parser. This may or may not already 1865 * have been made. 1866 */ 1867 struct CookieInfo *newcookies = 1868 Curl_cookie_init(data, NULL, data->cookies, data->set.cookiesession); 1869 if(!newcookies) 1870 result = CURLE_OUT_OF_MEMORY; 1871 data->cookies = newcookies; 1872 } 1873 break; 1874 1875 case CURLOPT_COOKIELIST: 1876 if(!ptr) 1877 break; 1878 1879 if(curl_strequal(ptr, "ALL")) { 1880 /* clear all cookies */ 1881 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); 1882 Curl_cookie_clearall(data->cookies); 1883 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); 1884 } 1885 else if(curl_strequal(ptr, "SESS")) { 1886 /* clear session cookies */ 1887 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); 1888 Curl_cookie_clearsess(data->cookies); 1889 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); 1890 } 1891 else if(curl_strequal(ptr, "FLUSH")) { 1892 /* flush cookies to file, takes care of the locking */ 1893 Curl_flush_cookies(data, FALSE); 1894 } 1895 else if(curl_strequal(ptr, "RELOAD")) { 1896 /* reload cookies from file */ 1897 Curl_cookie_loadfiles(data); 1898 break; 1899 } 1900 else { 1901 if(!data->cookies) { 1902 /* if cookie engine was not running, activate it */ 1903 data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE); 1904 if(!data->cookies) 1905 return CURLE_OUT_OF_MEMORY; 1906 } 1907 1908 /* general protection against mistakes and abuse */ 1909 if(strlen(ptr) > CURL_MAX_INPUT_LENGTH) 1910 return CURLE_BAD_FUNCTION_ARGUMENT; 1911 1912 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); 1913 if(checkprefix("Set-Cookie:", ptr)) 1914 /* HTTP Header format line */ 1915 Curl_cookie_add(data, data->cookies, TRUE, FALSE, ptr + 11, NULL, 1916 NULL, TRUE); 1917 else 1918 /* Netscape format line */ 1919 Curl_cookie_add(data, data->cookies, FALSE, FALSE, ptr, NULL, 1920 NULL, TRUE); 1921 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); 1922 } 1923 break; 1924 #endif /* !CURL_DISABLE_COOKIES */ 1925 1926 #endif /* ! CURL_DISABLE_HTTP */ 1927 1928 case CURLOPT_CUSTOMREQUEST: 1929 /* 1930 * Set a custom string to use as request 1931 */ 1932 return Curl_setstropt(&data->set.str[STRING_CUSTOMREQUEST], ptr); 1933 1934 /* we do not set 1935 data->set.method = HTTPREQ_CUSTOM; 1936 here, we continue as if we were using the already set type 1937 and this just changes the actual request keyword */ 1938 1939 #ifndef CURL_DISABLE_PROXY 1940 case CURLOPT_PROXY: 1941 /* 1942 * Set proxy server:port to use as proxy. 1943 * 1944 * If the proxy is set to "" (and CURLOPT_SOCKS_PROXY is set to "" or NULL) 1945 * we explicitly say that we do not want to use a proxy 1946 * (even though there might be environment variables saying so). 1947 * 1948 * Setting it to NULL, means no proxy but allows the environment variables 1949 * to decide for us (if CURLOPT_SOCKS_PROXY setting it to NULL). 1950 */ 1951 return Curl_setstropt(&data->set.str[STRING_PROXY], ptr); 1952 1953 case CURLOPT_PRE_PROXY: 1954 /* 1955 * Set proxy server:port to use as SOCKS proxy. 1956 * 1957 * If the proxy is set to "" or NULL we explicitly say that we do not want 1958 * to use the socks proxy. 1959 */ 1960 return Curl_setstropt(&data->set.str[STRING_PRE_PROXY], ptr); 1961 #endif /* CURL_DISABLE_PROXY */ 1962 1963 #ifndef CURL_DISABLE_PROXY 1964 case CURLOPT_SOCKS5_GSSAPI_SERVICE: 1965 case CURLOPT_PROXY_SERVICE_NAME: 1966 /* 1967 * Set proxy authentication service name for Kerberos 5 and SPNEGO 1968 */ 1969 return Curl_setstropt(&data->set.str[STRING_PROXY_SERVICE_NAME], ptr); 1970 #endif 1971 case CURLOPT_SERVICE_NAME: 1972 /* 1973 * Set authentication service name for DIGEST-MD5, Kerberos 5 and SPNEGO 1974 */ 1975 return Curl_setstropt(&data->set.str[STRING_SERVICE_NAME], ptr); 1976 1977 case CURLOPT_HEADERDATA: 1978 /* 1979 * Custom pointer to pass the header write callback function 1980 */ 1981 data->set.writeheader = ptr; 1982 break; 1983 case CURLOPT_READDATA: 1984 /* 1985 * FILE pointer to read the file to be uploaded from. Or possibly used as 1986 * argument to the read callback. 1987 */ 1988 data->set.in_set = ptr; 1989 break; 1990 case CURLOPT_WRITEDATA: 1991 /* 1992 * FILE pointer to write to. Or possibly used as argument to the write 1993 * callback. 1994 */ 1995 data->set.out = ptr; 1996 break; 1997 case CURLOPT_DEBUGDATA: 1998 /* 1999 * Set to a void * that should receive all error writes. This 2000 * defaults to CURLOPT_STDERR for normal operations. 2001 */ 2002 data->set.debugdata = ptr; 2003 break; 2004 case CURLOPT_PROGRESSDATA: 2005 /* 2006 * Custom client data to pass to the progress callback 2007 */ 2008 data->set.progress_client = ptr; 2009 break; 2010 case CURLOPT_SEEKDATA: 2011 /* 2012 * Seek control callback. Might be NULL. 2013 */ 2014 data->set.seek_client = ptr; 2015 break; 2016 case CURLOPT_IOCTLDATA: 2017 /* 2018 * I/O control data pointer. Might be NULL. 2019 */ 2020 data->set.ioctl_client = ptr; 2021 break; 2022 case CURLOPT_SSL_CTX_DATA: 2023 /* 2024 * Set an SSL_CTX callback parameter pointer 2025 */ 2026 #ifdef USE_SSL 2027 if(Curl_ssl_supports(data, SSLSUPP_SSL_CTX)) { 2028 data->set.ssl.fsslctxp = ptr; 2029 break; 2030 } 2031 else 2032 #endif 2033 return CURLE_NOT_BUILT_IN; 2034 case CURLOPT_SOCKOPTDATA: 2035 /* 2036 * socket callback data pointer. Might be NULL. 2037 */ 2038 data->set.sockopt_client = ptr; 2039 break; 2040 case CURLOPT_OPENSOCKETDATA: 2041 /* 2042 * socket callback data pointer. Might be NULL. 2043 */ 2044 data->set.opensocket_client = ptr; 2045 break; 2046 case CURLOPT_RESOLVER_START_DATA: 2047 /* 2048 * resolver start callback data pointer. Might be NULL. 2049 */ 2050 data->set.resolver_start_client = ptr; 2051 break; 2052 case CURLOPT_CLOSESOCKETDATA: 2053 /* 2054 * socket callback data pointer. Might be NULL. 2055 */ 2056 data->set.closesocket_client = ptr; 2057 break; 2058 case CURLOPT_TRAILERDATA: 2059 #ifndef CURL_DISABLE_HTTP 2060 data->set.trailer_data = ptr; 2061 #endif 2062 break; 2063 case CURLOPT_PREREQDATA: 2064 data->set.prereq_userp = ptr; 2065 break; 2066 2067 case CURLOPT_ERRORBUFFER: 2068 /* 2069 * Error buffer provided by the caller to get the human readable error 2070 * string in. 2071 */ 2072 data->set.errorbuffer = ptr; 2073 break; 2074 2075 #ifndef CURL_DISABLE_FTP 2076 case CURLOPT_FTPPORT: 2077 /* 2078 * Use FTP PORT, this also specifies which IP address to use 2079 */ 2080 result = Curl_setstropt(&data->set.str[STRING_FTPPORT], ptr); 2081 data->set.ftp_use_port = !!(data->set.str[STRING_FTPPORT]); 2082 break; 2083 2084 case CURLOPT_FTP_ACCOUNT: 2085 return Curl_setstropt(&data->set.str[STRING_FTP_ACCOUNT], ptr); 2086 2087 case CURLOPT_FTP_ALTERNATIVE_TO_USER: 2088 return Curl_setstropt(&data->set.str[STRING_FTP_ALTERNATIVE_TO_USER], ptr); 2089 2090 #ifdef HAVE_GSSAPI 2091 case CURLOPT_KRBLEVEL: 2092 /* 2093 * A string that defines the kerberos security level. 2094 */ 2095 result = Curl_setstropt(&data->set.str[STRING_KRB_LEVEL], ptr); 2096 data->set.krb = !!(data->set.str[STRING_KRB_LEVEL]); 2097 break; 2098 #endif 2099 #endif 2100 case CURLOPT_URL: 2101 /* 2102 * The URL to fetch. 2103 */ 2104 if(data->state.url_alloc) { 2105 Curl_safefree(data->state.url); 2106 data->state.url_alloc = FALSE; 2107 } 2108 result = Curl_setstropt(&data->set.str[STRING_SET_URL], ptr); 2109 data->state.url = data->set.str[STRING_SET_URL]; 2110 break; 2111 2112 case CURLOPT_USERPWD: 2113 /* 2114 * user:password to use in the operation 2115 */ 2116 return setstropt_userpwd(ptr, &data->set.str[STRING_USERNAME], 2117 &data->set.str[STRING_PASSWORD]); 2118 2119 case CURLOPT_USERNAME: 2120 /* 2121 * authentication username to use in the operation 2122 */ 2123 return Curl_setstropt(&data->set.str[STRING_USERNAME], ptr); 2124 2125 case CURLOPT_PASSWORD: 2126 /* 2127 * authentication password to use in the operation 2128 */ 2129 return Curl_setstropt(&data->set.str[STRING_PASSWORD], ptr); 2130 2131 case CURLOPT_LOGIN_OPTIONS: 2132 /* 2133 * authentication options to use in the operation 2134 */ 2135 return Curl_setstropt(&data->set.str[STRING_OPTIONS], ptr); 2136 2137 case CURLOPT_XOAUTH2_BEARER: 2138 /* 2139 * OAuth 2.0 bearer token to use in the operation 2140 */ 2141 return Curl_setstropt(&data->set.str[STRING_BEARER], ptr); 2142 2143 #ifndef CURL_DISABLE_PROXY 2144 case CURLOPT_PROXYUSERPWD: { 2145 /* 2146 * user:password needed to use the proxy 2147 */ 2148 char *u = NULL; 2149 char *p = NULL; 2150 result = setstropt_userpwd(ptr, &u, &p); 2151 2152 /* URL decode the components */ 2153 if(!result && u) { 2154 Curl_safefree(data->set.str[STRING_PROXYUSERNAME]); 2155 result = Curl_urldecode(u, 0, &data->set.str[STRING_PROXYUSERNAME], NULL, 2156 REJECT_ZERO); 2157 } 2158 if(!result && p) { 2159 Curl_safefree(data->set.str[STRING_PROXYPASSWORD]); 2160 result = Curl_urldecode(p, 0, &data->set.str[STRING_PROXYPASSWORD], NULL, 2161 REJECT_ZERO); 2162 } 2163 free(u); 2164 free(p); 2165 } 2166 break; 2167 case CURLOPT_PROXYUSERNAME: 2168 /* 2169 * authentication username to use in the operation 2170 */ 2171 return Curl_setstropt(&data->set.str[STRING_PROXYUSERNAME], ptr); 2172 2173 case CURLOPT_PROXYPASSWORD: 2174 /* 2175 * authentication password to use in the operation 2176 */ 2177 return Curl_setstropt(&data->set.str[STRING_PROXYPASSWORD], ptr); 2178 2179 case CURLOPT_NOPROXY: 2180 /* 2181 * proxy exception list 2182 */ 2183 return Curl_setstropt(&data->set.str[STRING_NOPROXY], ptr); 2184 #endif /* ! CURL_DISABLE_PROXY */ 2185 2186 case CURLOPT_RANGE: 2187 /* 2188 * What range of the file you want to transfer 2189 */ 2190 return Curl_setstropt(&data->set.str[STRING_SET_RANGE], ptr); 2191 2192 case CURLOPT_CURLU: 2193 /* 2194 * pass CURLU to set URL 2195 */ 2196 if(data->state.url_alloc) { 2197 Curl_safefree(data->state.url); 2198 data->state.url_alloc = FALSE; 2199 } 2200 else 2201 data->state.url = NULL; 2202 Curl_safefree(data->set.str[STRING_SET_URL]); 2203 data->set.uh = (CURLU *)ptr; 2204 break; 2205 case CURLOPT_SSLCERT: 2206 /* 2207 * String that holds filename of the SSL certificate to use 2208 */ 2209 return Curl_setstropt(&data->set.str[STRING_CERT], ptr); 2210 2211 #ifndef CURL_DISABLE_PROXY 2212 case CURLOPT_PROXY_SSLCERT: 2213 /* 2214 * String that holds filename of the SSL certificate to use for proxy 2215 */ 2216 return Curl_setstropt(&data->set.str[STRING_CERT_PROXY], ptr); 2217 2218 #endif 2219 case CURLOPT_SSLCERTTYPE: 2220 /* 2221 * String that holds file type of the SSL certificate to use 2222 */ 2223 return Curl_setstropt(&data->set.str[STRING_CERT_TYPE], ptr); 2224 2225 #ifndef CURL_DISABLE_PROXY 2226 case CURLOPT_PROXY_SSLCERTTYPE: 2227 /* 2228 * String that holds file type of the SSL certificate to use for proxy 2229 */ 2230 return Curl_setstropt(&data->set.str[STRING_CERT_TYPE_PROXY], ptr); 2231 2232 #endif 2233 case CURLOPT_SSLKEY: 2234 /* 2235 * String that holds filename of the SSL key to use 2236 */ 2237 return Curl_setstropt(&data->set.str[STRING_KEY], ptr); 2238 2239 #ifndef CURL_DISABLE_PROXY 2240 case CURLOPT_PROXY_SSLKEY: 2241 /* 2242 * String that holds filename of the SSL key to use for proxy 2243 */ 2244 return Curl_setstropt(&data->set.str[STRING_KEY_PROXY], ptr); 2245 2246 #endif 2247 case CURLOPT_SSLKEYTYPE: 2248 /* 2249 * String that holds file type of the SSL key to use 2250 */ 2251 return Curl_setstropt(&data->set.str[STRING_KEY_TYPE], ptr); 2252 2253 #ifndef CURL_DISABLE_PROXY 2254 case CURLOPT_PROXY_SSLKEYTYPE: 2255 /* 2256 * String that holds file type of the SSL key to use for proxy 2257 */ 2258 return Curl_setstropt(&data->set.str[STRING_KEY_TYPE_PROXY], ptr); 2259 2260 #endif 2261 case CURLOPT_KEYPASSWD: 2262 /* 2263 * String that holds the SSL or SSH private key password. 2264 */ 2265 return Curl_setstropt(&data->set.str[STRING_KEY_PASSWD], ptr); 2266 2267 #ifndef CURL_DISABLE_PROXY 2268 case CURLOPT_PROXY_KEYPASSWD: 2269 /* 2270 * String that holds the SSL private key password for proxy. 2271 */ 2272 return Curl_setstropt(&data->set.str[STRING_KEY_PASSWD_PROXY], ptr); 2273 2274 #endif 2275 case CURLOPT_SSLENGINE: 2276 /* 2277 * String that holds the SSL crypto engine. 2278 */ 2279 if(ptr && ptr[0]) { 2280 result = Curl_setstropt(&data->set.str[STRING_SSL_ENGINE], ptr); 2281 if(!result) { 2282 result = Curl_ssl_set_engine(data, ptr); 2283 } 2284 } 2285 break; 2286 2287 #ifndef CURL_DISABLE_PROXY 2288 case CURLOPT_HAPROXY_CLIENT_IP: 2289 /* 2290 * Set the client IP to send through HAProxy PROXY protocol 2291 */ 2292 result = Curl_setstropt(&data->set.str[STRING_HAPROXY_CLIENT_IP], ptr); 2293 /* enable the HAProxy protocol */ 2294 data->set.haproxyprotocol = TRUE; 2295 break; 2296 2297 #endif 2298 case CURLOPT_INTERFACE: 2299 /* 2300 * Set what interface or address/hostname to bind the socket to when 2301 * performing an operation and thus what from-IP your connection will use. 2302 */ 2303 return setstropt_interface(ptr, 2304 &data->set.str[STRING_DEVICE], 2305 &data->set.str[STRING_INTERFACE], 2306 &data->set.str[STRING_BINDHOST]); 2307 2308 case CURLOPT_PINNEDPUBLICKEY: 2309 /* 2310 * Set pinned public key for SSL connection. 2311 * Specify filename of the public key in DER format. 2312 */ 2313 #ifdef USE_SSL 2314 if(Curl_ssl_supports(data, SSLSUPP_PINNEDPUBKEY)) 2315 return Curl_setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY], ptr); 2316 #endif 2317 return CURLE_NOT_BUILT_IN; 2318 2319 #ifndef CURL_DISABLE_PROXY 2320 case CURLOPT_PROXY_PINNEDPUBLICKEY: 2321 /* 2322 * Set pinned public key for SSL connection. 2323 * Specify filename of the public key in DER format. 2324 */ 2325 #ifdef USE_SSL 2326 if(Curl_ssl_supports(data, SSLSUPP_PINNEDPUBKEY)) 2327 return Curl_setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY], 2328 ptr); 2329 #endif 2330 return CURLE_NOT_BUILT_IN; 2331 #endif 2332 case CURLOPT_CAINFO: 2333 /* 2334 * Set CA info for SSL connection. Specify filename of the CA certificate 2335 */ 2336 return Curl_setstropt(&data->set.str[STRING_SSL_CAFILE], ptr); 2337 2338 #ifndef CURL_DISABLE_PROXY 2339 case CURLOPT_PROXY_CAINFO: 2340 /* 2341 * Set CA info SSL connection for proxy. Specify filename of the 2342 * CA certificate 2343 */ 2344 return Curl_setstropt(&data->set.str[STRING_SSL_CAFILE_PROXY], ptr); 2345 2346 #endif 2347 case CURLOPT_CAPATH: 2348 /* 2349 * Set CA path info for SSL connection. Specify directory name of the CA 2350 * certificates which have been prepared using openssl c_rehash utility. 2351 */ 2352 #ifdef USE_SSL 2353 if(Curl_ssl_supports(data, SSLSUPP_CA_PATH)) 2354 /* This does not work on Windows. */ 2355 return Curl_setstropt(&data->set.str[STRING_SSL_CAPATH], ptr); 2356 #endif 2357 return CURLE_NOT_BUILT_IN; 2358 #ifndef CURL_DISABLE_PROXY 2359 case CURLOPT_PROXY_CAPATH: 2360 /* 2361 * Set CA path info for SSL connection proxy. Specify directory name of the 2362 * CA certificates which have been prepared using openssl c_rehash utility. 2363 */ 2364 #ifdef USE_SSL 2365 if(Curl_ssl_supports(data, SSLSUPP_CA_PATH)) 2366 /* This does not work on Windows. */ 2367 return Curl_setstropt(&data->set.str[STRING_SSL_CAPATH_PROXY], ptr); 2368 #endif 2369 return CURLE_NOT_BUILT_IN; 2370 #endif 2371 case CURLOPT_CRLFILE: 2372 /* 2373 * Set CRL file info for SSL connection. Specify filename of the CRL 2374 * to check certificates revocation 2375 */ 2376 return Curl_setstropt(&data->set.str[STRING_SSL_CRLFILE], ptr); 2377 2378 #ifndef CURL_DISABLE_PROXY 2379 case CURLOPT_PROXY_CRLFILE: 2380 /* 2381 * Set CRL file info for SSL connection for proxy. Specify filename of the 2382 * CRL to check certificates revocation 2383 */ 2384 return Curl_setstropt(&data->set.str[STRING_SSL_CRLFILE_PROXY], ptr); 2385 2386 #endif 2387 case CURLOPT_ISSUERCERT: 2388 /* 2389 * Set Issuer certificate file 2390 * to check certificates issuer 2391 */ 2392 return Curl_setstropt(&data->set.str[STRING_SSL_ISSUERCERT], ptr); 2393 2394 #ifndef CURL_DISABLE_PROXY 2395 case CURLOPT_PROXY_ISSUERCERT: 2396 /* 2397 * Set Issuer certificate file 2398 * to check certificates issuer 2399 */ 2400 return Curl_setstropt(&data->set.str[STRING_SSL_ISSUERCERT_PROXY], ptr); 2401 2402 #endif 2403 case CURLOPT_PRIVATE: 2404 /* 2405 * Set private data pointer. 2406 */ 2407 data->set.private_data = ptr; 2408 break; 2409 2410 #ifdef USE_SSL 2411 case CURLOPT_SSL_EC_CURVES: 2412 /* 2413 * Set accepted curves in SSL connection setup. 2414 * Specify colon-delimited list of curve algorithm names. 2415 */ 2416 return Curl_setstropt(&data->set.str[STRING_SSL_EC_CURVES], ptr); 2417 2418 case CURLOPT_SSL_SIGNATURE_ALGORITHMS: 2419 /* 2420 * Set accepted signature algorithms. 2421 * Specify colon-delimited list of signature scheme names. 2422 */ 2423 if(Curl_ssl_supports(data, SSLSUPP_SIGNATURE_ALGORITHMS)) 2424 return Curl_setstropt(&data->set.str[STRING_SSL_SIGNATURE_ALGORITHMS], 2425 ptr); 2426 return CURLE_NOT_BUILT_IN; 2427 #endif 2428 #ifdef USE_SSH 2429 case CURLOPT_SSH_PUBLIC_KEYFILE: 2430 /* 2431 * Use this file instead of the $HOME/.ssh/id_dsa.pub file 2432 */ 2433 return Curl_setstropt(&data->set.str[STRING_SSH_PUBLIC_KEY], ptr); 2434 2435 case CURLOPT_SSH_PRIVATE_KEYFILE: 2436 /* 2437 * Use this file instead of the $HOME/.ssh/id_dsa file 2438 */ 2439 return Curl_setstropt(&data->set.str[STRING_SSH_PRIVATE_KEY], ptr); 2440 2441 #if defined(USE_LIBSSH2) || defined(USE_LIBSSH) 2442 case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5: 2443 /* 2444 * Option to allow for the MD5 of the host public key to be checked 2445 * for validation purposes. 2446 */ 2447 return Curl_setstropt(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5], ptr); 2448 2449 case CURLOPT_SSH_KNOWNHOSTS: 2450 /* 2451 * Store the filename to read known hosts from. 2452 */ 2453 return Curl_setstropt(&data->set.str[STRING_SSH_KNOWNHOSTS], ptr); 2454 #endif 2455 case CURLOPT_SSH_KEYDATA: 2456 /* 2457 * Custom client data to pass to the SSH keyfunc callback 2458 */ 2459 data->set.ssh_keyfunc_userp = ptr; 2460 break; 2461 #ifdef USE_LIBSSH2 2462 case CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256: 2463 /* 2464 * Option to allow for the SHA256 of the host public key to be checked 2465 * for validation purposes. 2466 */ 2467 return Curl_setstropt(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_SHA256], 2468 ptr); 2469 2470 case CURLOPT_SSH_HOSTKEYDATA: 2471 /* 2472 * Custom client data to pass to the SSH keyfunc callback 2473 */ 2474 data->set.ssh_hostkeyfunc_userp = ptr; 2475 break; 2476 #endif /* USE_LIBSSH2 */ 2477 #endif /* USE_SSH */ 2478 case CURLOPT_PROTOCOLS_STR: 2479 if(ptr) 2480 return protocol2num(ptr, &data->set.allowed_protocols); 2481 /* make a NULL argument reset to default */ 2482 data->set.allowed_protocols = (curl_prot_t) CURLPROTO_ALL; 2483 break; 2484 2485 case CURLOPT_REDIR_PROTOCOLS_STR: 2486 if(ptr) 2487 return protocol2num(ptr, &data->set.redir_protocols); 2488 /* make a NULL argument reset to default */ 2489 data->set.redir_protocols = (curl_prot_t) CURLPROTO_REDIR; 2490 break; 2491 2492 case CURLOPT_DEFAULT_PROTOCOL: 2493 /* Set the protocol to use when the URL does not include any protocol */ 2494 return Curl_setstropt(&data->set.str[STRING_DEFAULT_PROTOCOL], ptr); 2495 2496 #ifndef CURL_DISABLE_SMTP 2497 case CURLOPT_MAIL_FROM: 2498 /* Set the SMTP mail originator */ 2499 return Curl_setstropt(&data->set.str[STRING_MAIL_FROM], ptr); 2500 2501 case CURLOPT_MAIL_AUTH: 2502 /* Set the SMTP auth originator */ 2503 return Curl_setstropt(&data->set.str[STRING_MAIL_AUTH], ptr); 2504 #endif 2505 case CURLOPT_SASL_AUTHZID: 2506 /* Authorization identity (identity to act as) */ 2507 return Curl_setstropt(&data->set.str[STRING_SASL_AUTHZID], ptr); 2508 2509 #ifndef CURL_DISABLE_RTSP 2510 case CURLOPT_RTSP_SESSION_ID: 2511 /* 2512 * Set the RTSP Session ID manually. Useful if the application is 2513 * resuming a previously established RTSP session 2514 */ 2515 return Curl_setstropt(&data->set.str[STRING_RTSP_SESSION_ID], ptr); 2516 2517 case CURLOPT_RTSP_STREAM_URI: 2518 /* 2519 * Set the Stream URI for the RTSP request. Unless the request is 2520 * for generic server options, the application will need to set this. 2521 */ 2522 return Curl_setstropt(&data->set.str[STRING_RTSP_STREAM_URI], ptr); 2523 2524 case CURLOPT_RTSP_TRANSPORT: 2525 /* 2526 * The content of the Transport: header for the RTSP request 2527 */ 2528 return Curl_setstropt(&data->set.str[STRING_RTSP_TRANSPORT], ptr); 2529 2530 case CURLOPT_INTERLEAVEDATA: 2531 data->set.rtp_out = ptr; 2532 break; 2533 #endif /* ! CURL_DISABLE_RTSP */ 2534 #ifndef CURL_DISABLE_FTP 2535 case CURLOPT_CHUNK_DATA: 2536 data->set.wildcardptr = ptr; 2537 break; 2538 case CURLOPT_FNMATCH_DATA: 2539 data->set.fnmatch_data = ptr; 2540 break; 2541 #endif 2542 #ifdef USE_TLS_SRP 2543 case CURLOPT_TLSAUTH_USERNAME: 2544 return Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME], ptr); 2545 2546 #ifndef CURL_DISABLE_PROXY 2547 case CURLOPT_PROXY_TLSAUTH_USERNAME: 2548 return Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME_PROXY], ptr); 2549 2550 #endif 2551 case CURLOPT_TLSAUTH_PASSWORD: 2552 return Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD], ptr); 2553 2554 #ifndef CURL_DISABLE_PROXY 2555 case CURLOPT_PROXY_TLSAUTH_PASSWORD: 2556 return Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_PROXY], ptr); 2557 #endif 2558 case CURLOPT_TLSAUTH_TYPE: 2559 if(ptr && !curl_strequal(ptr, "SRP")) 2560 return CURLE_BAD_FUNCTION_ARGUMENT; 2561 break; 2562 #ifndef CURL_DISABLE_PROXY 2563 case CURLOPT_PROXY_TLSAUTH_TYPE: 2564 if(ptr && !curl_strequal(ptr, "SRP")) 2565 return CURLE_BAD_FUNCTION_ARGUMENT; 2566 break; 2567 #endif 2568 #endif 2569 #ifdef CURLRES_ARES 2570 case CURLOPT_DNS_SERVERS: 2571 result = Curl_setstropt(&data->set.str[STRING_DNS_SERVERS], ptr); 2572 if(result) 2573 return result; 2574 return Curl_async_ares_set_dns_servers(data); 2575 2576 case CURLOPT_DNS_INTERFACE: 2577 result = Curl_setstropt(&data->set.str[STRING_DNS_INTERFACE], ptr); 2578 if(result) 2579 return result; 2580 return Curl_async_ares_set_dns_interface(data); 2581 2582 case CURLOPT_DNS_LOCAL_IP4: 2583 result = Curl_setstropt(&data->set.str[STRING_DNS_LOCAL_IP4], ptr); 2584 if(result) 2585 return result; 2586 return Curl_async_ares_set_dns_local_ip4(data); 2587 2588 case CURLOPT_DNS_LOCAL_IP6: 2589 result = Curl_setstropt(&data->set.str[STRING_DNS_LOCAL_IP6], ptr); 2590 if(result) 2591 return result; 2592 return Curl_async_ares_set_dns_local_ip6(data); 2593 2594 #endif 2595 #ifdef USE_UNIX_SOCKETS 2596 case CURLOPT_UNIX_SOCKET_PATH: 2597 data->set.abstract_unix_socket = FALSE; 2598 return Curl_setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH], ptr); 2599 2600 case CURLOPT_ABSTRACT_UNIX_SOCKET: 2601 data->set.abstract_unix_socket = TRUE; 2602 return Curl_setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH], ptr); 2603 2604 #endif 2605 2606 #ifndef CURL_DISABLE_DOH 2607 case CURLOPT_DOH_URL: 2608 result = Curl_setstropt(&data->set.str[STRING_DOH], ptr); 2609 data->set.doh = !!(data->set.str[STRING_DOH]); 2610 break; 2611 #endif 2612 #ifndef CURL_DISABLE_HSTS 2613 case CURLOPT_HSTSREADDATA: 2614 data->set.hsts_read_userp = ptr; 2615 break; 2616 case CURLOPT_HSTSWRITEDATA: 2617 data->set.hsts_write_userp = ptr; 2618 break; 2619 case CURLOPT_HSTS: { 2620 struct curl_slist *h; 2621 if(!data->hsts) { 2622 data->hsts = Curl_hsts_init(); 2623 if(!data->hsts) 2624 return CURLE_OUT_OF_MEMORY; 2625 } 2626 if(ptr) { 2627 result = Curl_setstropt(&data->set.str[STRING_HSTS], ptr); 2628 if(result) 2629 return result; 2630 /* this needs to build a list of filenames to read from, so that it can 2631 read them later, as we might get a shared HSTS handle to load them 2632 into */ 2633 h = curl_slist_append(data->state.hstslist, ptr); 2634 if(!h) { 2635 curl_slist_free_all(data->state.hstslist); 2636 data->state.hstslist = NULL; 2637 return CURLE_OUT_OF_MEMORY; 2638 } 2639 data->state.hstslist = h; /* store the list for later use */ 2640 } 2641 else { 2642 /* clear the list of HSTS files */ 2643 curl_slist_free_all(data->state.hstslist); 2644 data->state.hstslist = NULL; 2645 if(!data->share || !data->share->hsts) 2646 /* throw away the HSTS cache unless shared */ 2647 Curl_hsts_cleanup(&data->hsts); 2648 } 2649 break; 2650 } 2651 #endif /* ! CURL_DISABLE_HSTS */ 2652 #ifndef CURL_DISABLE_ALTSVC 2653 case CURLOPT_ALTSVC: 2654 if(!data->asi) { 2655 data->asi = Curl_altsvc_init(); 2656 if(!data->asi) 2657 return CURLE_OUT_OF_MEMORY; 2658 } 2659 result = Curl_setstropt(&data->set.str[STRING_ALTSVC], ptr); 2660 if(result) 2661 return result; 2662 if(ptr) 2663 (void)Curl_altsvc_load(data->asi, ptr); 2664 break; 2665 #endif /* ! CURL_DISABLE_ALTSVC */ 2666 #ifdef USE_ECH 2667 case CURLOPT_ECH: { 2668 size_t plen = 0; 2669 2670 if(!ptr) { 2671 data->set.tls_ech = CURLECH_DISABLE; 2672 return CURLE_OK; 2673 } 2674 plen = strlen(ptr); 2675 if(plen > CURL_MAX_INPUT_LENGTH) { 2676 data->set.tls_ech = CURLECH_DISABLE; 2677 return CURLE_BAD_FUNCTION_ARGUMENT; 2678 } 2679 /* set tls_ech flag value, preserving CLA_CFG bit */ 2680 if(!strcmp(ptr, "false")) 2681 data->set.tls_ech = CURLECH_DISABLE | 2682 (data->set.tls_ech & CURLECH_CLA_CFG); 2683 else if(!strcmp(ptr, "grease")) 2684 data->set.tls_ech = CURLECH_GREASE | 2685 (data->set.tls_ech & CURLECH_CLA_CFG); 2686 else if(!strcmp(ptr, "true")) 2687 data->set.tls_ech = CURLECH_ENABLE | 2688 (data->set.tls_ech & CURLECH_CLA_CFG); 2689 else if(!strcmp(ptr, "hard")) 2690 data->set.tls_ech = CURLECH_HARD | 2691 (data->set.tls_ech & CURLECH_CLA_CFG); 2692 else if(plen > 5 && !strncmp(ptr, "ecl:", 4)) { 2693 result = Curl_setstropt(&data->set.str[STRING_ECH_CONFIG], ptr + 4); 2694 if(result) 2695 return result; 2696 data->set.tls_ech |= CURLECH_CLA_CFG; 2697 } 2698 else if(plen > 4 && !strncmp(ptr, "pn:", 3)) { 2699 result = Curl_setstropt(&data->set.str[STRING_ECH_PUBLIC], ptr + 3); 2700 if(result) 2701 return result; 2702 } 2703 break; 2704 } 2705 #endif 2706 default: 2707 return CURLE_UNKNOWN_OPTION; 2708 } 2709 return result; 2710 } 2711 2712 static CURLcode setopt_func(struct Curl_easy *data, CURLoption option, 2713 va_list param) 2714 { 2715 switch(option) { 2716 case CURLOPT_PROGRESSFUNCTION: 2717 /* 2718 * Progress callback function 2719 */ 2720 data->set.fprogress = va_arg(param, curl_progress_callback); 2721 if(data->set.fprogress) 2722 data->progress.callback = TRUE; /* no longer internal */ 2723 else 2724 data->progress.callback = FALSE; /* NULL enforces internal */ 2725 break; 2726 2727 case CURLOPT_XFERINFOFUNCTION: 2728 /* 2729 * Transfer info callback function 2730 */ 2731 data->set.fxferinfo = va_arg(param, curl_xferinfo_callback); 2732 if(data->set.fxferinfo) 2733 data->progress.callback = TRUE; /* no longer internal */ 2734 else 2735 data->progress.callback = FALSE; /* NULL enforces internal */ 2736 2737 break; 2738 case CURLOPT_DEBUGFUNCTION: 2739 /* 2740 * stderr write callback. 2741 */ 2742 data->set.fdebug = va_arg(param, curl_debug_callback); 2743 /* 2744 * if the callback provided is NULL, it will use the default callback 2745 */ 2746 break; 2747 case CURLOPT_HEADERFUNCTION: 2748 /* 2749 * Set header write callback 2750 */ 2751 data->set.fwrite_header = va_arg(param, curl_write_callback); 2752 break; 2753 case CURLOPT_WRITEFUNCTION: 2754 /* 2755 * Set data write callback 2756 */ 2757 data->set.fwrite_func = va_arg(param, curl_write_callback); 2758 if(!data->set.fwrite_func) 2759 /* When set to NULL, reset to our internal default function */ 2760 data->set.fwrite_func = (curl_write_callback)fwrite; 2761 break; 2762 case CURLOPT_READFUNCTION: 2763 /* 2764 * Read data callback 2765 */ 2766 data->set.fread_func_set = va_arg(param, curl_read_callback); 2767 if(!data->set.fread_func_set) { 2768 data->set.is_fread_set = 0; 2769 /* When set to NULL, reset to our internal default function */ 2770 data->set.fread_func_set = (curl_read_callback)fread; 2771 } 2772 else 2773 data->set.is_fread_set = 1; 2774 break; 2775 case CURLOPT_SEEKFUNCTION: 2776 /* 2777 * Seek callback. Might be NULL. 2778 */ 2779 data->set.seek_func = va_arg(param, curl_seek_callback); 2780 break; 2781 case CURLOPT_IOCTLFUNCTION: 2782 /* 2783 * I/O control callback. Might be NULL. 2784 */ 2785 data->set.ioctl_func = va_arg(param, curl_ioctl_callback); 2786 break; 2787 case CURLOPT_SSL_CTX_FUNCTION: 2788 /* 2789 * Set an SSL_CTX callback 2790 */ 2791 #ifdef USE_SSL 2792 if(Curl_ssl_supports(data, SSLSUPP_SSL_CTX)) { 2793 data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback); 2794 break; 2795 } 2796 else 2797 #endif 2798 return CURLE_NOT_BUILT_IN; 2799 2800 case CURLOPT_SOCKOPTFUNCTION: 2801 /* 2802 * socket callback function: called after socket() but before connect() 2803 */ 2804 data->set.fsockopt = va_arg(param, curl_sockopt_callback); 2805 break; 2806 2807 case CURLOPT_OPENSOCKETFUNCTION: 2808 /* 2809 * open/create socket callback function: called instead of socket(), 2810 * before connect() 2811 */ 2812 data->set.fopensocket = va_arg(param, curl_opensocket_callback); 2813 break; 2814 2815 case CURLOPT_CLOSESOCKETFUNCTION: 2816 /* 2817 * close socket callback function: called instead of close() 2818 * when shutting down a connection 2819 */ 2820 data->set.fclosesocket = va_arg(param, curl_closesocket_callback); 2821 break; 2822 2823 case CURLOPT_RESOLVER_START_FUNCTION: 2824 /* 2825 * resolver start callback function: called before a new resolver request 2826 * is started 2827 */ 2828 data->set.resolver_start = va_arg(param, curl_resolver_start_callback); 2829 break; 2830 2831 #ifdef USE_SSH 2832 #ifdef USE_LIBSSH2 2833 case CURLOPT_SSH_HOSTKEYFUNCTION: 2834 /* the callback to check the hostkey without the knownhost file */ 2835 data->set.ssh_hostkeyfunc = va_arg(param, curl_sshhostkeycallback); 2836 break; 2837 #endif 2838 2839 case CURLOPT_SSH_KEYFUNCTION: 2840 /* setting to NULL is fine since the ssh.c functions themselves will 2841 then revert to use the internal default */ 2842 data->set.ssh_keyfunc = va_arg(param, curl_sshkeycallback); 2843 break; 2844 2845 #endif /* USE_SSH */ 2846 2847 #ifndef CURL_DISABLE_RTSP 2848 case CURLOPT_INTERLEAVEFUNCTION: 2849 /* Set the user defined RTP write function */ 2850 data->set.fwrite_rtp = va_arg(param, curl_write_callback); 2851 break; 2852 #endif 2853 #ifndef CURL_DISABLE_FTP 2854 case CURLOPT_CHUNK_BGN_FUNCTION: 2855 data->set.chunk_bgn = va_arg(param, curl_chunk_bgn_callback); 2856 break; 2857 case CURLOPT_CHUNK_END_FUNCTION: 2858 data->set.chunk_end = va_arg(param, curl_chunk_end_callback); 2859 break; 2860 case CURLOPT_FNMATCH_FUNCTION: 2861 data->set.fnmatch = va_arg(param, curl_fnmatch_callback); 2862 break; 2863 #endif 2864 #ifndef CURL_DISABLE_HTTP 2865 case CURLOPT_TRAILERFUNCTION: 2866 data->set.trailer_callback = va_arg(param, curl_trailer_callback); 2867 break; 2868 #endif 2869 #ifndef CURL_DISABLE_HSTS 2870 case CURLOPT_HSTSREADFUNCTION: 2871 data->set.hsts_read = va_arg(param, curl_hstsread_callback); 2872 break; 2873 case CURLOPT_HSTSWRITEFUNCTION: 2874 data->set.hsts_write = va_arg(param, curl_hstswrite_callback); 2875 break; 2876 #endif 2877 case CURLOPT_PREREQFUNCTION: 2878 data->set.fprereq = va_arg(param, curl_prereq_callback); 2879 break; 2880 default: 2881 return CURLE_UNKNOWN_OPTION; 2882 } 2883 return CURLE_OK; 2884 } 2885 2886 static CURLcode setopt_offt(struct Curl_easy *data, CURLoption option, 2887 curl_off_t offt) 2888 { 2889 switch(option) { 2890 case CURLOPT_TIMEVALUE_LARGE: 2891 /* 2892 * This is the value to compare with the remote document with the 2893 * method set with CURLOPT_TIMECONDITION 2894 */ 2895 data->set.timevalue = (time_t)offt; 2896 break; 2897 2898 /* MQTT "borrows" some of the HTTP options */ 2899 case CURLOPT_POSTFIELDSIZE_LARGE: 2900 /* 2901 * The size of the POSTFIELD data to prevent libcurl to do strlen() to 2902 * figure it out. Enables binary posts. 2903 */ 2904 if(offt < -1) 2905 return CURLE_BAD_FUNCTION_ARGUMENT; 2906 2907 if(data->set.postfieldsize < offt && 2908 data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) { 2909 /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */ 2910 Curl_safefree(data->set.str[STRING_COPYPOSTFIELDS]); 2911 data->set.postfields = NULL; 2912 } 2913 data->set.postfieldsize = offt; 2914 break; 2915 case CURLOPT_INFILESIZE_LARGE: 2916 /* 2917 * If known, this should inform curl about the file size of the 2918 * to-be-uploaded file. 2919 */ 2920 if(offt < -1) 2921 return CURLE_BAD_FUNCTION_ARGUMENT; 2922 data->set.filesize = offt; 2923 break; 2924 case CURLOPT_MAX_SEND_SPEED_LARGE: 2925 /* 2926 * When transfer uploads are faster then CURLOPT_MAX_SEND_SPEED_LARGE 2927 * bytes per second the transfer is throttled.. 2928 */ 2929 if(offt < 0) 2930 return CURLE_BAD_FUNCTION_ARGUMENT; 2931 data->set.max_send_speed = offt; 2932 break; 2933 case CURLOPT_MAX_RECV_SPEED_LARGE: 2934 /* 2935 * When receiving data faster than CURLOPT_MAX_RECV_SPEED_LARGE bytes per 2936 * second the transfer is throttled.. 2937 */ 2938 if(offt < 0) 2939 return CURLE_BAD_FUNCTION_ARGUMENT; 2940 data->set.max_recv_speed = offt; 2941 break; 2942 case CURLOPT_RESUME_FROM_LARGE: 2943 /* 2944 * Resume transfer at the given file position 2945 */ 2946 if(offt < -1) 2947 return CURLE_BAD_FUNCTION_ARGUMENT; 2948 data->set.set_resume_from = offt; 2949 break; 2950 case CURLOPT_MAXFILESIZE_LARGE: 2951 /* 2952 * Set the maximum size of a file to download. 2953 */ 2954 if(offt < 0) 2955 return CURLE_BAD_FUNCTION_ARGUMENT; 2956 data->set.max_filesize = offt; 2957 break; 2958 2959 default: 2960 return CURLE_UNKNOWN_OPTION; 2961 } 2962 return CURLE_OK; 2963 } 2964 2965 static CURLcode setopt_blob(struct Curl_easy *data, CURLoption option, 2966 struct curl_blob *blob) 2967 { 2968 switch(option) { 2969 case CURLOPT_SSLCERT_BLOB: 2970 /* 2971 * Blob that holds file content of the SSL certificate to use 2972 */ 2973 return Curl_setblobopt(&data->set.blobs[BLOB_CERT], blob); 2974 #ifndef CURL_DISABLE_PROXY 2975 case CURLOPT_PROXY_SSLCERT_BLOB: 2976 /* 2977 * Blob that holds file content of the SSL certificate to use for proxy 2978 */ 2979 return Curl_setblobopt(&data->set.blobs[BLOB_CERT_PROXY], blob); 2980 case CURLOPT_PROXY_SSLKEY_BLOB: 2981 /* 2982 * Blob that holds file content of the SSL key to use for proxy 2983 */ 2984 return Curl_setblobopt(&data->set.blobs[BLOB_KEY_PROXY], blob); 2985 case CURLOPT_PROXY_CAINFO_BLOB: 2986 /* 2987 * Blob that holds CA info for SSL connection proxy. 2988 * Specify entire PEM of the CA certificate 2989 */ 2990 #ifdef USE_SSL 2991 if(Curl_ssl_supports(data, SSLSUPP_CAINFO_BLOB)) 2992 return Curl_setblobopt(&data->set.blobs[BLOB_CAINFO_PROXY], blob); 2993 #endif 2994 return CURLE_NOT_BUILT_IN; 2995 case CURLOPT_PROXY_ISSUERCERT_BLOB: 2996 /* 2997 * Blob that holds Issuer certificate to check certificates issuer 2998 */ 2999 return Curl_setblobopt(&data->set.blobs[BLOB_SSL_ISSUERCERT_PROXY], 3000 blob); 3001 #endif 3002 case CURLOPT_SSLKEY_BLOB: 3003 /* 3004 * Blob that holds file content of the SSL key to use 3005 */ 3006 return Curl_setblobopt(&data->set.blobs[BLOB_KEY], blob); 3007 case CURLOPT_CAINFO_BLOB: 3008 /* 3009 * Blob that holds CA info for SSL connection. 3010 * Specify entire PEM of the CA certificate 3011 */ 3012 #ifdef USE_SSL 3013 if(Curl_ssl_supports(data, SSLSUPP_CAINFO_BLOB)) 3014 return Curl_setblobopt(&data->set.blobs[BLOB_CAINFO], blob); 3015 #endif 3016 return CURLE_NOT_BUILT_IN; 3017 case CURLOPT_ISSUERCERT_BLOB: 3018 /* 3019 * Blob that holds Issuer certificate to check certificates issuer 3020 */ 3021 return Curl_setblobopt(&data->set.blobs[BLOB_SSL_ISSUERCERT], blob); 3022 3023 default: 3024 return CURLE_UNKNOWN_OPTION; 3025 } 3026 /* unreachable */ 3027 } 3028 3029 /* 3030 * Do not make Curl_vsetopt() static: it is called from 3031 * packages/OS400/ccsidcurl.c. 3032 */ 3033 CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) 3034 { 3035 if(option < CURLOPTTYPE_OBJECTPOINT) 3036 return setopt_long(data, option, va_arg(param, long)); 3037 else if(option < CURLOPTTYPE_FUNCTIONPOINT) { 3038 /* unfortunately, different pointer types cannot be identified any other 3039 way than being listed explicitly */ 3040 switch(option) { 3041 case CURLOPT_HTTPHEADER: 3042 case CURLOPT_QUOTE: 3043 case CURLOPT_POSTQUOTE: 3044 case CURLOPT_TELNETOPTIONS: 3045 case CURLOPT_PREQUOTE: 3046 case CURLOPT_HTTP200ALIASES: 3047 case CURLOPT_MAIL_RCPT: 3048 case CURLOPT_RESOLVE: 3049 case CURLOPT_PROXYHEADER: 3050 case CURLOPT_CONNECT_TO: 3051 return setopt_slist(data, option, va_arg(param, struct curl_slist *)); 3052 case CURLOPT_HTTPPOST: /* curl_httppost * */ 3053 case CURLOPT_MIMEPOST: /* curl_mime * */ 3054 case CURLOPT_STDERR: /* FILE * */ 3055 case CURLOPT_SHARE: /* CURLSH * */ 3056 case CURLOPT_STREAM_DEPENDS: /* CURL * */ 3057 case CURLOPT_STREAM_DEPENDS_E: /* CURL * */ 3058 return setopt_pointers(data, option, param); 3059 default: 3060 break; 3061 } 3062 /* the char pointer options */ 3063 return setopt_cptr(data, option, va_arg(param, char *)); 3064 } 3065 else if(option < CURLOPTTYPE_OFF_T) 3066 return setopt_func(data, option, param); 3067 else if(option < CURLOPTTYPE_BLOB) 3068 return setopt_offt(data, option, va_arg(param, curl_off_t)); 3069 return setopt_blob(data, option, va_arg(param, struct curl_blob *)); 3070 } 3071 3072 /* 3073 * curl_easy_setopt() is the external interface for setting options on an 3074 * easy handle. 3075 * 3076 * NOTE: This is one of few API functions that are allowed to be called from 3077 * within a callback. 3078 */ 3079 3080 #undef curl_easy_setopt 3081 CURLcode curl_easy_setopt(CURL *d, CURLoption tag, ...) 3082 { 3083 va_list arg; 3084 CURLcode result; 3085 struct Curl_easy *data = d; 3086 3087 if(!data) 3088 return CURLE_BAD_FUNCTION_ARGUMENT; 3089 3090 va_start(arg, tag); 3091 3092 result = Curl_vsetopt(data, tag, arg); 3093 3094 va_end(arg); 3095 if(result == CURLE_BAD_FUNCTION_ARGUMENT) 3096 failf(data, "setopt 0x%x got bad argument", tag); 3097 return result; 3098 }