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