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