VirtualBox

source: vbox/trunk/src/libs/curl-8.7.1/lib/setopt.c@ 106542

最後變更 在這個檔案從106542是 104083,由 vboxsync 提交於 11 月 前

curl-8.7.1: Applied and adjusted our curl changes to 8.4.0. bugref:10639

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette