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