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