VirtualBox

source: vbox/trunk/src/libs/curl-7.83.1/lib/setopt.c@ 97138

最後變更 在這個檔案從97138是 95312,由 vboxsync 提交於 3 年 前

libs/{curl,libxml2}: OSE export fixes, bugref:8515

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

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