1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
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.
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.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ***************************************************************************/
23 #include "curl_setup.h"
27 #ifdef HAVE_NETINET_IN_H
28 #include <netinet/in.h>
31 #ifdef HAVE_LINUX_TCP_H
32 #include <linux/tcp.h>
38 #include "content_encoding.h"
41 #include "vtls/vtls.h"
48 /* The last 3 #include files should be in this order */
49 #include "curl_printf.h"
50 #include "curl_memory.h"
53 CURLcode Curl_setstropt(char **charp, const char *s)
55 /* Release the previous storage at `charp' and replace by a dynamic storage
56 copy of `s'. Return CURLE_OK or CURLE_OUT_OF_MEMORY. */
58 Curl_safefree(*charp);
61 char *str = strdup(s);
64 return CURLE_OUT_OF_MEMORY;
72 static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp)
74 CURLcode result = CURLE_OK;
78 /* Parse the login details if specified. It not then we treat NULL as a hint
79 to clear the existing data */
81 result = Curl_parse_login_details(option, strlen(option),
82 (userp ? &user : NULL),
83 (passwdp ? &passwd : NULL),
88 /* Store the username part of option if required */
90 if(!user && option && option[0] == ':') {
91 /* Allocate an empty string instead of returning NULL as user name */
94 result = CURLE_OUT_OF_MEMORY;
97 Curl_safefree(*userp);
101 /* Store the password part of option if required */
103 Curl_safefree(*passwdp);
111 #define C_SSLVERSION_VALUE(x) (x & 0xffff)
112 #define C_SSLVERSION_MAX_VALUE(x) (x & 0xffff0000)
114 CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
118 CURLcode result = CURLE_OK;
123 case CURLOPT_DNS_CACHE_TIMEOUT:
124 arg = va_arg(param, long);
126 return CURLE_BAD_FUNCTION_ARGUMENT;
127 data->set.dns_cache_timeout = arg;
129 case CURLOPT_DNS_USE_GLOBAL_CACHE:
130 /* remember we want this enabled */
131 arg = va_arg(param, long);
132 data->set.global_dns_cache = (0 != arg) ? TRUE : FALSE;
134 case CURLOPT_SSL_CIPHER_LIST:
135 /* set a list of cipher we want to use in the SSL connection */
136 result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER_LIST_ORIG],
137 va_arg(param, char *));
139 case CURLOPT_PROXY_SSL_CIPHER_LIST:
140 /* set a list of cipher we want to use in the SSL connection for proxy */
141 result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER_LIST_PROXY],
142 va_arg(param, char *));
145 case CURLOPT_RANDOM_FILE:
147 * This is the path name to a file that contains random data to seed
148 * the random SSL stuff with. The file is only used for reading.
150 result = Curl_setstropt(&data->set.str[STRING_SSL_RANDOM_FILE],
151 va_arg(param, char *));
153 case CURLOPT_EGDSOCKET:
155 * The Entropy Gathering Daemon socket pathname
157 result = Curl_setstropt(&data->set.str[STRING_SSL_EGDSOCKET],
158 va_arg(param, char *));
160 case CURLOPT_MAXCONNECTS:
162 * Set the absolute number of maximum simultaneous alive connection that
163 * libcurl is allowed to have.
165 arg = va_arg(param, long);
167 return CURLE_BAD_FUNCTION_ARGUMENT;
168 data->set.maxconnects = arg;
170 case CURLOPT_FORBID_REUSE:
172 * When this transfer is done, it must not be left to be reused by a
173 * subsequent transfer but shall be closed immediately.
175 data->set.reuse_forbid = (0 != va_arg(param, long)) ? TRUE : FALSE;
177 case CURLOPT_FRESH_CONNECT:
179 * This transfer shall not use a previously cached connection but
180 * should be made with a fresh new connect!
182 data->set.reuse_fresh = (0 != va_arg(param, long)) ? TRUE : FALSE;
184 case CURLOPT_VERBOSE:
186 * Verbose means infof() calls that give a lot of information about
187 * the connection and transfer procedures as well as internal choices.
189 data->set.verbose = (0 != va_arg(param, long)) ? TRUE : FALSE;
193 * Set to include the header in the general data output stream.
195 data->set.include_header = (0 != va_arg(param, long)) ? TRUE : FALSE;
197 case CURLOPT_NOPROGRESS:
199 * Shut off the internal supported progress meter
201 data->set.hide_progress = (0 != va_arg(param, long)) ? TRUE : FALSE;
202 if(data->set.hide_progress)
203 data->progress.flags |= PGRS_HIDE;
205 data->progress.flags &= ~PGRS_HIDE;
209 * Do not include the body part in the output data stream.
211 data->set.opt_no_body = (0 != va_arg(param, long)) ? TRUE : FALSE;
213 case CURLOPT_FAILONERROR:
215 * Don't output the >=400 error code HTML-page, but instead only
218 data->set.http_fail_on_error = (0 != va_arg(param, long)) ? TRUE : FALSE;
220 case CURLOPT_KEEP_SENDING_ON_ERROR:
221 data->set.http_keep_sending_on_error = (0 != va_arg(param, long)) ?
227 * We want to sent data to the remote host. If this is HTTP, that equals
228 * using the PUT request.
230 data->set.upload = (0 != va_arg(param, long)) ? TRUE : FALSE;
231 if(data->set.upload) {
232 /* If this is HTTP, PUT is what's needed to "upload" */
233 data->set.httpreq = HTTPREQ_PUT;
234 data->set.opt_no_body = FALSE; /* this is implied */
237 /* In HTTP, the opposite of upload is GET (unless NOBODY is true as
238 then this can be changed to HEAD later on) */
239 data->set.httpreq = HTTPREQ_GET;
241 case CURLOPT_REQUEST_TARGET:
242 result = Curl_setstropt(&data->set.str[STRING_TARGET],
243 va_arg(param, char *));
245 case CURLOPT_FILETIME:
247 * Try to get the file time of the remote document. The time will
248 * later (possibly) become available using curl_easy_getinfo().
250 data->set.get_filetime = (0 != va_arg(param, long)) ? TRUE : FALSE;
252 case CURLOPT_FTP_CREATE_MISSING_DIRS:
254 * An FTP option that modifies an upload to create missing directories on
257 switch(va_arg(param, long)) {
259 data->set.ftp_create_missing_dirs = 0;
262 data->set.ftp_create_missing_dirs = 1;
265 data->set.ftp_create_missing_dirs = 2;
268 /* reserve other values for future use */
269 result = CURLE_UNKNOWN_OPTION;
273 case CURLOPT_SERVER_RESPONSE_TIMEOUT:
275 * Option that specifies how quickly an server response must be obtained
276 * before it is considered failure. For pingpong protocols.
278 arg = va_arg(param, long);
279 if((arg >= 0) && (arg <= (INT_MAX/1000)))
280 data->set.server_response_timeout = arg * 1000;
282 return CURLE_BAD_FUNCTION_ARGUMENT;
284 case CURLOPT_TFTP_NO_OPTIONS:
286 * Option that prevents libcurl from sending TFTP option requests to the
289 data->set.tftp_no_options = va_arg(param, long) != 0;
291 case CURLOPT_TFTP_BLKSIZE:
293 * TFTP option that specifies the block size to use for data transmission.
295 arg = va_arg(param, long);
297 return CURLE_BAD_FUNCTION_ARGUMENT;
298 data->set.tftp_blksize = arg;
300 case CURLOPT_DIRLISTONLY:
302 * An option that changes the command to one that asks for a list
303 * only, no file info details.
305 data->set.ftp_list_only = (0 != va_arg(param, long)) ? TRUE : FALSE;
309 * We want to upload and append to an existing file.
311 data->set.ftp_append = (0 != va_arg(param, long)) ? TRUE : FALSE;
313 case CURLOPT_FTP_FILEMETHOD:
315 * How do access files over FTP.
317 arg = va_arg(param, long);
318 if((arg < CURLFTPMETHOD_DEFAULT) || (arg > CURLFTPMETHOD_SINGLECWD))
319 return CURLE_BAD_FUNCTION_ARGUMENT;
320 data->set.ftp_filemethod = (curl_ftpfile)arg;
324 * Parse the $HOME/.netrc file
326 arg = va_arg(param, long);
327 if((arg < CURL_NETRC_IGNORED) || (arg > CURL_NETRC_REQUIRED))
328 return CURLE_BAD_FUNCTION_ARGUMENT;
329 data->set.use_netrc = (enum CURL_NETRC_OPTION)arg;
331 case CURLOPT_NETRC_FILE:
333 * Use this file instead of the $HOME/.netrc file
335 result = Curl_setstropt(&data->set.str[STRING_NETRC_FILE],
336 va_arg(param, char *));
338 case CURLOPT_TRANSFERTEXT:
340 * This option was previously named 'FTPASCII'. Renamed to work with
341 * more protocols than merely FTP.
343 * Transfer using ASCII (instead of BINARY).
345 data->set.prefer_ascii = (0 != va_arg(param, long)) ? TRUE : FALSE;
347 case CURLOPT_TIMECONDITION:
349 * Set HTTP time condition. This must be one of the defines in the
350 * curl/curl.h header file.
352 arg = va_arg(param, long);
353 if((arg < CURL_TIMECOND_NONE) || (arg > CURL_TIMECOND_LASTMOD))
354 return CURLE_BAD_FUNCTION_ARGUMENT;
355 data->set.timecondition = (curl_TimeCond)arg;
357 case CURLOPT_TIMEVALUE:
359 * This is the value to compare with the remote document with the
360 * method set with CURLOPT_TIMECONDITION
362 data->set.timevalue = (time_t)va_arg(param, long);
365 case CURLOPT_TIMEVALUE_LARGE:
367 * This is the value to compare with the remote document with the
368 * method set with CURLOPT_TIMECONDITION
370 data->set.timevalue = (time_t)va_arg(param, curl_off_t);
373 case CURLOPT_SSLVERSION:
374 case CURLOPT_PROXY_SSLVERSION:
376 * Set explicit SSL version to try to connect with, as some SSL
377 * implementations are lame.
381 long version, version_max;
382 struct ssl_primary_config *primary = (option == CURLOPT_SSLVERSION ?
383 &data->set.ssl.primary :
384 &data->set.proxy_ssl.primary);
386 arg = va_arg(param, long);
388 version = C_SSLVERSION_VALUE(arg);
389 version_max = C_SSLVERSION_MAX_VALUE(arg);
391 if(version < CURL_SSLVERSION_DEFAULT ||
392 version >= CURL_SSLVERSION_LAST ||
393 version_max < CURL_SSLVERSION_MAX_NONE ||
394 version_max >= CURL_SSLVERSION_MAX_LAST)
395 return CURLE_BAD_FUNCTION_ARGUMENT;
397 primary->version = version;
398 primary->version_max = version_max;
401 result = CURLE_UNKNOWN_OPTION;
405 #ifndef CURL_DISABLE_HTTP
406 case CURLOPT_AUTOREFERER:
408 * Switch on automatic referer that gets set if curl follows locations.
410 data->set.http_auto_referer = (0 != va_arg(param, long)) ? TRUE : FALSE;
413 case CURLOPT_ACCEPT_ENCODING:
415 * String to use at the value of Accept-Encoding header.
417 * If the encoding is set to "" we use an Accept-Encoding header that
418 * encompasses all the encodings we support.
419 * If the encoding is set to NULL we don't send an Accept-Encoding header
420 * and ignore an received Content-Encoding header.
423 argptr = va_arg(param, char *);
424 if(argptr && !*argptr) {
425 argptr = Curl_all_content_encodings();
427 result = CURLE_OUT_OF_MEMORY;
429 result = Curl_setstropt(&data->set.str[STRING_ENCODING], argptr);
434 result = Curl_setstropt(&data->set.str[STRING_ENCODING], argptr);
437 case CURLOPT_TRANSFER_ENCODING:
438 data->set.http_transfer_encoding = (0 != va_arg(param, long)) ?
442 case CURLOPT_FOLLOWLOCATION:
444 * Follow Location: header hints on a HTTP-server.
446 data->set.http_follow_location = (0 != va_arg(param, long)) ? TRUE : FALSE;
449 case CURLOPT_UNRESTRICTED_AUTH:
451 * Send authentication (user+password) when following locations, even when
454 data->set.allow_auth_to_other_hosts =
455 (0 != va_arg(param, long)) ? TRUE : FALSE;
458 case CURLOPT_MAXREDIRS:
460 * The maximum amount of hops you allow curl to follow Location:
461 * headers. This should mostly be used to detect never-ending loops.
463 arg = va_arg(param, long);
465 return CURLE_BAD_FUNCTION_ARGUMENT;
466 data->set.maxredirs = arg;
469 case CURLOPT_POSTREDIR:
471 * Set the behaviour of POST when redirecting
472 * CURL_REDIR_GET_ALL - POST is changed to GET after 301 and 302
473 * CURL_REDIR_POST_301 - POST is kept as POST after 301
474 * CURL_REDIR_POST_302 - POST is kept as POST after 302
475 * CURL_REDIR_POST_303 - POST is kept as POST after 303
476 * CURL_REDIR_POST_ALL - POST is kept as POST after 301, 302 and 303
477 * other - POST is kept as POST after 301 and 302
479 arg = va_arg(param, long);
480 if(arg < CURL_REDIR_GET_ALL)
481 /* no return error on too high numbers since the bitmask could be
482 extended in a future */
483 return CURLE_BAD_FUNCTION_ARGUMENT;
484 data->set.keep_post = arg & CURL_REDIR_POST_ALL;
488 /* Does this option serve a purpose anymore? Yes it does, when
489 CURLOPT_POSTFIELDS isn't used and the POST data is read off the
491 if(va_arg(param, long)) {
492 data->set.httpreq = HTTPREQ_POST;
493 data->set.opt_no_body = FALSE; /* this is implied */
496 data->set.httpreq = HTTPREQ_GET;
499 case CURLOPT_COPYPOSTFIELDS:
501 * A string with POST data. Makes curl HTTP POST. Even if it is NULL.
502 * If needed, CURLOPT_POSTFIELDSIZE must have been set prior to
503 * CURLOPT_COPYPOSTFIELDS and not altered later.
505 argptr = va_arg(param, char *);
507 if(!argptr || data->set.postfieldsize == -1)
508 result = Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], argptr);
511 * Check that requested length does not overflow the size_t type.
514 if((data->set.postfieldsize < 0) ||
515 ((sizeof(curl_off_t) != sizeof(size_t)) &&
516 (data->set.postfieldsize > (curl_off_t)((size_t)-1))))
517 result = CURLE_OUT_OF_MEMORY;
521 (void) Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
523 /* Allocate even when size == 0. This satisfies the need of possible
524 later address compare to detect the COPYPOSTFIELDS mode, and
525 to mark that postfields is used rather than read function or
528 p = malloc((size_t)(data->set.postfieldsize?
529 data->set.postfieldsize:1));
532 result = CURLE_OUT_OF_MEMORY;
534 if(data->set.postfieldsize)
535 memcpy(p, argptr, (size_t)data->set.postfieldsize);
537 data->set.str[STRING_COPYPOSTFIELDS] = p;
542 data->set.postfields = data->set.str[STRING_COPYPOSTFIELDS];
543 data->set.httpreq = HTTPREQ_POST;
546 case CURLOPT_POSTFIELDS:
548 * Like above, but use static data instead of copying it.
550 data->set.postfields = va_arg(param, void *);
551 /* Release old copied data. */
552 (void) Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
553 data->set.httpreq = HTTPREQ_POST;
556 case CURLOPT_POSTFIELDSIZE:
558 * The size of the POSTFIELD data to prevent libcurl to do strlen() to
559 * figure it out. Enables binary posts.
561 bigsize = va_arg(param, long);
563 return CURLE_BAD_FUNCTION_ARGUMENT;
565 if(data->set.postfieldsize < bigsize &&
566 data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
567 /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */
568 (void) Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
569 data->set.postfields = NULL;
572 data->set.postfieldsize = bigsize;
575 case CURLOPT_POSTFIELDSIZE_LARGE:
577 * The size of the POSTFIELD data to prevent libcurl to do strlen() to
578 * figure it out. Enables binary posts.
580 bigsize = va_arg(param, curl_off_t);
582 return CURLE_BAD_FUNCTION_ARGUMENT;
584 if(data->set.postfieldsize < bigsize &&
585 data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
586 /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */
587 (void) Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
588 data->set.postfields = NULL;
591 data->set.postfieldsize = bigsize;
594 case CURLOPT_HTTPPOST:
596 * Set to make us do HTTP POST
598 data->set.httppost = va_arg(param, struct curl_httppost *);
599 data->set.httpreq = HTTPREQ_POST_FORM;
600 data->set.opt_no_body = FALSE; /* this is implied */
602 #endif /* CURL_DISABLE_HTTP */
604 case CURLOPT_MIMEPOST:
606 * Set to make us do MIME/form POST
608 result = Curl_mime_set_subparts(&data->set.mimepost,
609 va_arg(param, curl_mime *), FALSE);
611 data->set.httpreq = HTTPREQ_POST_MIME;
612 data->set.opt_no_body = FALSE; /* this is implied */
616 case CURLOPT_REFERER:
618 * String to set in the HTTP Referer: field.
620 if(data->change.referer_alloc) {
621 Curl_safefree(data->change.referer);
622 data->change.referer_alloc = FALSE;
624 result = Curl_setstropt(&data->set.str[STRING_SET_REFERER],
625 va_arg(param, char *));
626 data->change.referer = data->set.str[STRING_SET_REFERER];
629 case CURLOPT_USERAGENT:
631 * String to use in the HTTP User-Agent field
633 result = Curl_setstropt(&data->set.str[STRING_USERAGENT],
634 va_arg(param, char *));
637 case CURLOPT_HTTPHEADER:
639 * Set a list with HTTP headers to use (or replace internals with)
641 data->set.headers = va_arg(param, struct curl_slist *);
644 #ifndef CURL_DISABLE_HTTP
645 case CURLOPT_PROXYHEADER:
647 * Set a list with proxy headers to use (or replace internals with)
649 * Since CURLOPT_HTTPHEADER was the only way to set HTTP headers for a
650 * long time we remain doing it this way until CURLOPT_PROXYHEADER is
651 * used. As soon as this option has been used, if set to anything but
652 * NULL, custom headers for proxies are only picked from this list.
654 * Set this option to NULL to restore the previous behavior.
656 data->set.proxyheaders = va_arg(param, struct curl_slist *);
659 case CURLOPT_HEADEROPT:
663 arg = va_arg(param, long);
664 data->set.sep_headers = (arg & CURLHEADER_SEPARATE)? TRUE: FALSE;
667 case CURLOPT_HTTP200ALIASES:
669 * Set a list of aliases for HTTP 200 in response header
671 data->set.http200aliases = va_arg(param, struct curl_slist *);
674 #if !defined(CURL_DISABLE_COOKIES)
677 * Cookie string to send to the remote server in the request.
679 result = Curl_setstropt(&data->set.str[STRING_COOKIE],
680 va_arg(param, char *));
683 case CURLOPT_COOKIEFILE:
685 * Set cookie file to read and parse. Can be used multiple times.
687 argptr = (char *)va_arg(param, void *);
689 struct curl_slist *cl;
690 /* append the cookie file name to the list of file names, and deal with
692 cl = curl_slist_append(data->change.cookielist, argptr);
694 curl_slist_free_all(data->change.cookielist);
695 data->change.cookielist = NULL;
696 return CURLE_OUT_OF_MEMORY;
698 data->change.cookielist = cl; /* store the list for later use */
702 case CURLOPT_COOKIEJAR:
704 * Set cookie file name to dump all cookies to when we're done.
707 struct CookieInfo *newcookies;
708 result = Curl_setstropt(&data->set.str[STRING_COOKIEJAR],
709 va_arg(param, char *));
712 * Activate the cookie parser. This may or may not already
715 newcookies = Curl_cookie_init(data, NULL, data->cookies,
716 data->set.cookiesession);
718 result = CURLE_OUT_OF_MEMORY;
719 data->cookies = newcookies;
723 case CURLOPT_COOKIESESSION:
725 * Set this option to TRUE to start a new "cookie session". It will
726 * prevent the forthcoming read-cookies-from-file actions to accept
727 * cookies that are marked as being session cookies, as they belong to a
730 * In the original Netscape cookie spec, "session cookies" are cookies
731 * with no expire date set. RFC2109 describes the same action if no
732 * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds
733 * a 'Discard' action that can enforce the discard even for cookies that
736 * We run mostly with the original cookie spec, as hardly anyone implements
739 data->set.cookiesession = (0 != va_arg(param, long)) ? TRUE : FALSE;
742 case CURLOPT_COOKIELIST:
743 argptr = va_arg(param, char *);
748 if(strcasecompare(argptr, "ALL")) {
749 /* clear all cookies */
750 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
751 Curl_cookie_clearall(data->cookies);
752 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
754 else if(strcasecompare(argptr, "SESS")) {
755 /* clear session cookies */
756 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
757 Curl_cookie_clearsess(data->cookies);
758 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
760 else if(strcasecompare(argptr, "FLUSH")) {
761 /* flush cookies to file, takes care of the locking */
762 Curl_flush_cookies(data, 0);
764 else if(strcasecompare(argptr, "RELOAD")) {
765 /* reload cookies from file */
766 Curl_cookie_loadfiles(data);
771 /* if cookie engine was not running, activate it */
772 data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE);
774 argptr = strdup(argptr);
775 if(!argptr || !data->cookies) {
776 result = CURLE_OUT_OF_MEMORY;
780 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
782 if(checkprefix("Set-Cookie:", argptr))
783 /* HTTP Header format line */
784 Curl_cookie_add(data, data->cookies, TRUE, argptr + 11, NULL, NULL);
787 /* Netscape format line */
788 Curl_cookie_add(data, data->cookies, FALSE, argptr, NULL, NULL);
790 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
796 #endif /* !CURL_DISABLE_COOKIES */
798 case CURLOPT_HTTPGET:
800 * Set to force us do HTTP GET
802 if(va_arg(param, long)) {
803 data->set.httpreq = HTTPREQ_GET;
804 data->set.upload = FALSE; /* switch off upload */
805 data->set.opt_no_body = FALSE; /* this is implied */
809 case CURLOPT_HTTP_VERSION:
811 * This sets a requested HTTP version to be used. The value is one of
812 * the listed enums in curl/curl.h.
814 arg = va_arg(param, long);
815 if(arg < CURL_HTTP_VERSION_NONE)
816 return CURLE_BAD_FUNCTION_ARGUMENT;
818 if(arg >= CURL_HTTP_VERSION_2)
819 return CURLE_UNSUPPORTED_PROTOCOL;
821 if(arg > CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE)
822 return CURLE_UNSUPPORTED_PROTOCOL;
824 data->set.httpversion = arg;
827 case CURLOPT_EXPECT_100_TIMEOUT_MS:
829 * Time to wait for a response to a HTTP request containing an
830 * Expect: 100-continue header before sending the data anyway.
832 arg = va_arg(param, long);
834 return CURLE_BAD_FUNCTION_ARGUMENT;
835 data->set.expect_100_timeout = arg;
838 #endif /* CURL_DISABLE_HTTP */
840 case CURLOPT_HTTPAUTH:
842 * Set HTTP Authentication type BITMASK.
847 unsigned long auth = va_arg(param, unsigned long);
849 if(auth == CURLAUTH_NONE) {
850 data->set.httpauth = auth;
854 /* the DIGEST_IE bit is only used to set a special marker, for all the
855 rest we need to handle it as normal DIGEST */
856 data->state.authhost.iestyle = (auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE;
858 if(auth & CURLAUTH_DIGEST_IE) {
859 auth |= CURLAUTH_DIGEST; /* set standard digest bit */
860 auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */
863 /* switch off bits we can't support */
865 auth &= ~CURLAUTH_NTLM; /* no NTLM support */
866 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
867 #elif !defined(NTLM_WB_ENABLED)
868 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
871 auth &= ~CURLAUTH_NEGOTIATE; /* no Negotiate (SPNEGO) auth without
875 /* check if any auth bit lower than CURLAUTH_ONLY is still set */
878 while(bitcheck < 31) {
879 if(auth & (1UL << bitcheck++)) {
885 return CURLE_NOT_BUILT_IN; /* no supported types left! */
887 data->set.httpauth = auth;
891 case CURLOPT_CUSTOMREQUEST:
893 * Set a custom string to use as request
895 result = Curl_setstropt(&data->set.str[STRING_CUSTOMREQUEST],
896 va_arg(param, char *));
899 data->set.httpreq = HTTPREQ_CUSTOM;
900 here, we continue as if we were using the already set type
901 and this just changes the actual request keyword */
904 #ifndef CURL_DISABLE_PROXY
905 case CURLOPT_HTTPPROXYTUNNEL:
907 * Tunnel operations through the proxy instead of normal proxy use
909 data->set.tunnel_thru_httpproxy = (0 != va_arg(param, long)) ?
913 case CURLOPT_PROXYPORT:
915 * Explicitly set HTTP proxy port number.
917 arg = va_arg(param, long);
918 if((arg < 0) || (arg > 65535))
919 return CURLE_BAD_FUNCTION_ARGUMENT;
920 data->set.proxyport = arg;
923 case CURLOPT_PROXYAUTH:
925 * Set HTTP Authentication type BITMASK.
930 unsigned long auth = va_arg(param, unsigned long);
932 if(auth == CURLAUTH_NONE) {
933 data->set.proxyauth = auth;
937 /* the DIGEST_IE bit is only used to set a special marker, for all the
938 rest we need to handle it as normal DIGEST */
939 data->state.authproxy.iestyle = (auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE;
941 if(auth & CURLAUTH_DIGEST_IE) {
942 auth |= CURLAUTH_DIGEST; /* set standard digest bit */
943 auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */
945 /* switch off bits we can't support */
947 auth &= ~CURLAUTH_NTLM; /* no NTLM support */
948 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
949 #elif !defined(NTLM_WB_ENABLED)
950 auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
953 auth &= ~CURLAUTH_NEGOTIATE; /* no Negotiate (SPNEGO) auth without
957 /* check if any auth bit lower than CURLAUTH_ONLY is still set */
960 while(bitcheck < 31) {
961 if(auth & (1UL << bitcheck++)) {
967 return CURLE_NOT_BUILT_IN; /* no supported types left! */
969 data->set.proxyauth = auth;
975 * Set proxy server:port to use as proxy.
977 * If the proxy is set to "" (and CURLOPT_SOCKS_PROXY is set to "" or NULL)
978 * we explicitly say that we don't want to use a proxy
979 * (even though there might be environment variables saying so).
981 * Setting it to NULL, means no proxy but allows the environment variables
982 * to decide for us (if CURLOPT_SOCKS_PROXY setting it to NULL).
984 result = Curl_setstropt(&data->set.str[STRING_PROXY],
985 va_arg(param, char *));
988 case CURLOPT_PRE_PROXY:
990 * Set proxy server:port to use as SOCKS proxy.
992 * If the proxy is set to "" or NULL we explicitly say that we don't want
993 * to use the socks proxy.
995 result = Curl_setstropt(&data->set.str[STRING_PRE_PROXY],
996 va_arg(param, char *));
999 case CURLOPT_PROXYTYPE:
1001 * Set proxy type. HTTP/HTTP_1_0/SOCKS4/SOCKS4a/SOCKS5/SOCKS5_HOSTNAME
1003 arg = va_arg(param, long);
1004 if((arg < CURLPROXY_HTTP) || (arg > CURLPROXY_SOCKS5_HOSTNAME))
1005 return CURLE_BAD_FUNCTION_ARGUMENT;
1006 data->set.proxytype = (curl_proxytype)arg;
1009 case CURLOPT_PROXY_TRANSFER_MODE:
1011 * set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy
1013 switch(va_arg(param, long)) {
1015 data->set.proxy_transfer_mode = FALSE;
1018 data->set.proxy_transfer_mode = TRUE;
1021 /* reserve other values for future use */
1022 result = CURLE_UNKNOWN_OPTION;
1026 #endif /* CURL_DISABLE_PROXY */
1028 case CURLOPT_SOCKS5_AUTH:
1029 data->set.socks5auth = va_arg(param, unsigned long);
1030 if(data->set.socks5auth & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI))
1031 result = CURLE_NOT_BUILT_IN;
1033 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
1034 case CURLOPT_SOCKS5_GSSAPI_NEC:
1036 * Set flag for NEC SOCK5 support
1038 data->set.socks5_gssapi_nec = (0 != va_arg(param, long)) ? TRUE : FALSE;
1041 case CURLOPT_SOCKS5_GSSAPI_SERVICE:
1042 case CURLOPT_PROXY_SERVICE_NAME:
1044 * Set proxy authentication service name for Kerberos 5 and SPNEGO
1046 result = Curl_setstropt(&data->set.str[STRING_PROXY_SERVICE_NAME],
1047 va_arg(param, char *));
1051 #if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) || \
1053 case CURLOPT_SERVICE_NAME:
1055 * Set authentication service name for DIGEST-MD5, Kerberos 5 and SPNEGO
1057 result = Curl_setstropt(&data->set.str[STRING_SERVICE_NAME],
1058 va_arg(param, char *));
1063 case CURLOPT_HEADERDATA:
1065 * Custom pointer to pass the header write callback function
1067 data->set.writeheader = (void *)va_arg(param, void *);
1069 case CURLOPT_ERRORBUFFER:
1071 * Error buffer provided by the caller to get the human readable
1074 data->set.errorbuffer = va_arg(param, char *);
1076 case CURLOPT_WRITEDATA:
1078 * FILE pointer to write to. Or possibly
1079 * used as argument to the write callback.
1081 data->set.out = va_arg(param, void *);
1083 case CURLOPT_FTPPORT:
1085 * Use FTP PORT, this also specifies which IP address to use
1087 result = Curl_setstropt(&data->set.str[STRING_FTPPORT],
1088 va_arg(param, char *));
1089 data->set.ftp_use_port = (data->set.str[STRING_FTPPORT]) ? TRUE : FALSE;
1092 case CURLOPT_FTP_USE_EPRT:
1093 data->set.ftp_use_eprt = (0 != va_arg(param, long)) ? TRUE : FALSE;
1096 case CURLOPT_FTP_USE_EPSV:
1097 data->set.ftp_use_epsv = (0 != va_arg(param, long)) ? TRUE : FALSE;
1100 case CURLOPT_FTP_USE_PRET:
1101 data->set.ftp_use_pret = (0 != va_arg(param, long)) ? TRUE : FALSE;
1104 case CURLOPT_FTP_SSL_CCC:
1105 arg = va_arg(param, long);
1106 if((arg < CURLFTPSSL_CCC_NONE) || (arg > CURLFTPSSL_CCC_ACTIVE))
1107 return CURLE_BAD_FUNCTION_ARGUMENT;
1108 data->set.ftp_ccc = (curl_ftpccc)arg;
1111 case CURLOPT_FTP_SKIP_PASV_IP:
1113 * Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the
1114 * bypass of the IP address in PASV responses.
1116 data->set.ftp_skip_ip = (0 != va_arg(param, long)) ? TRUE : FALSE;
1119 case CURLOPT_READDATA:
1121 * FILE pointer to read the file to be uploaded from. Or possibly
1122 * used as argument to the read callback.
1124 data->set.in_set = va_arg(param, void *);
1126 case CURLOPT_INFILESIZE:
1128 * If known, this should inform curl about the file size of the
1129 * to-be-uploaded file.
1131 arg = va_arg(param, long);
1133 return CURLE_BAD_FUNCTION_ARGUMENT;
1134 data->set.filesize = arg;
1136 case CURLOPT_INFILESIZE_LARGE:
1138 * If known, this should inform curl about the file size of the
1139 * to-be-uploaded file.
1141 bigsize = va_arg(param, curl_off_t);
1143 return CURLE_BAD_FUNCTION_ARGUMENT;
1144 data->set.filesize = bigsize;
1146 case CURLOPT_LOW_SPEED_LIMIT:
1148 * The low speed limit that if transfers are below this for
1149 * CURLOPT_LOW_SPEED_TIME, the transfer is aborted.
1151 arg = va_arg(param, long);
1153 return CURLE_BAD_FUNCTION_ARGUMENT;
1154 data->set.low_speed_limit = arg;
1156 case CURLOPT_MAX_SEND_SPEED_LARGE:
1158 * When transfer uploads are faster then CURLOPT_MAX_SEND_SPEED_LARGE
1159 * bytes per second the transfer is throttled..
1161 bigsize = va_arg(param, curl_off_t);
1163 return CURLE_BAD_FUNCTION_ARGUMENT;
1164 data->set.max_send_speed = bigsize;
1166 case CURLOPT_MAX_RECV_SPEED_LARGE:
1168 * When receiving data faster than CURLOPT_MAX_RECV_SPEED_LARGE bytes per
1169 * second the transfer is throttled..
1171 bigsize = va_arg(param, curl_off_t);
1173 return CURLE_BAD_FUNCTION_ARGUMENT;
1174 data->set.max_recv_speed = bigsize;
1176 case CURLOPT_LOW_SPEED_TIME:
1178 * The low speed time that if transfers are below the set
1179 * CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted.
1181 arg = va_arg(param, long);
1183 return CURLE_BAD_FUNCTION_ARGUMENT;
1184 data->set.low_speed_time = arg;
1190 if(data->change.url_alloc) {
1191 /* the already set URL is allocated, free it first! */
1192 Curl_safefree(data->change.url);
1193 data->change.url_alloc = FALSE;
1195 result = Curl_setstropt(&data->set.str[STRING_SET_URL],
1196 va_arg(param, char *));
1197 data->change.url = data->set.str[STRING_SET_URL];
1201 * The port number to use when getting the URL
1203 arg = va_arg(param, long);
1204 if((arg < 0) || (arg > 65535))
1205 return CURLE_BAD_FUNCTION_ARGUMENT;
1206 data->set.use_port = arg;
1208 case CURLOPT_TIMEOUT:
1210 * The maximum time you allow curl to use for a single transfer
1213 arg = va_arg(param, long);
1214 if((arg >= 0) && (arg <= (INT_MAX/1000)))
1215 data->set.timeout = arg * 1000;
1217 return CURLE_BAD_FUNCTION_ARGUMENT;
1220 case CURLOPT_TIMEOUT_MS:
1221 arg = va_arg(param, long);
1223 return CURLE_BAD_FUNCTION_ARGUMENT;
1224 data->set.timeout = arg;
1227 case CURLOPT_CONNECTTIMEOUT:
1229 * The maximum time you allow curl to use to connect.
1231 arg = va_arg(param, long);
1232 if((arg >= 0) && (arg <= (INT_MAX/1000)))
1233 data->set.connecttimeout = arg * 1000;
1235 return CURLE_BAD_FUNCTION_ARGUMENT;
1238 case CURLOPT_CONNECTTIMEOUT_MS:
1239 arg = va_arg(param, long);
1241 return CURLE_BAD_FUNCTION_ARGUMENT;
1242 data->set.connecttimeout = arg;
1245 case CURLOPT_ACCEPTTIMEOUT_MS:
1247 * The maximum time you allow curl to wait for server connect
1249 arg = va_arg(param, long);
1251 return CURLE_BAD_FUNCTION_ARGUMENT;
1252 data->set.accepttimeout = arg;
1255 case CURLOPT_USERPWD:
1257 * user:password to use in the operation
1259 result = setstropt_userpwd(va_arg(param, char *),
1260 &data->set.str[STRING_USERNAME],
1261 &data->set.str[STRING_PASSWORD]);
1264 case CURLOPT_USERNAME:
1266 * authentication user name to use in the operation
1268 result = Curl_setstropt(&data->set.str[STRING_USERNAME],
1269 va_arg(param, char *));
1272 case CURLOPT_PASSWORD:
1274 * authentication password to use in the operation
1276 result = Curl_setstropt(&data->set.str[STRING_PASSWORD],
1277 va_arg(param, char *));
1280 case CURLOPT_LOGIN_OPTIONS:
1282 * authentication options to use in the operation
1284 result = Curl_setstropt(&data->set.str[STRING_OPTIONS],
1285 va_arg(param, char *));
1288 case CURLOPT_XOAUTH2_BEARER:
1290 * OAuth 2.0 bearer token to use in the operation
1292 result = Curl_setstropt(&data->set.str[STRING_BEARER],
1293 va_arg(param, char *));
1296 case CURLOPT_POSTQUOTE:
1298 * List of RAW FTP commands to use after a transfer
1300 data->set.postquote = va_arg(param, struct curl_slist *);
1302 case CURLOPT_PREQUOTE:
1304 * List of RAW FTP commands to use prior to RETR (Wesley Laxton)
1306 data->set.prequote = va_arg(param, struct curl_slist *);
1310 * List of RAW FTP commands to use before a transfer
1312 data->set.quote = va_arg(param, struct curl_slist *);
1314 case CURLOPT_RESOLVE:
1316 * List of NAME:[address] names to populate the DNS cache with
1317 * Prefix the NAME with dash (-) to _remove_ the name from the cache.
1319 * Names added with this API will remain in the cache until explicitly
1320 * removed or the handle is cleaned up.
1322 * This API can remove any name from the DNS cache, but only entries
1323 * that aren't actually in use right now will be pruned immediately.
1325 data->set.resolve = va_arg(param, struct curl_slist *);
1326 data->change.resolve = data->set.resolve;
1328 case CURLOPT_PROGRESSFUNCTION:
1330 * Progress callback function
1332 data->set.fprogress = va_arg(param, curl_progress_callback);
1333 if(data->set.fprogress)
1334 data->progress.callback = TRUE; /* no longer internal */
1336 data->progress.callback = FALSE; /* NULL enforces internal */
1339 case CURLOPT_XFERINFOFUNCTION:
1341 * Transfer info callback function
1343 data->set.fxferinfo = va_arg(param, curl_xferinfo_callback);
1344 if(data->set.fxferinfo)
1345 data->progress.callback = TRUE; /* no longer internal */
1347 data->progress.callback = FALSE; /* NULL enforces internal */
1351 case CURLOPT_PROGRESSDATA:
1353 * Custom client data to pass to the progress callback
1355 data->set.progress_client = va_arg(param, void *);
1358 #ifndef CURL_DISABLE_PROXY
1359 case CURLOPT_PROXYUSERPWD:
1361 * user:password needed to use the proxy
1363 result = setstropt_userpwd(va_arg(param, char *),
1364 &data->set.str[STRING_PROXYUSERNAME],
1365 &data->set.str[STRING_PROXYPASSWORD]);
1367 case CURLOPT_PROXYUSERNAME:
1369 * authentication user name to use in the operation
1371 result = Curl_setstropt(&data->set.str[STRING_PROXYUSERNAME],
1372 va_arg(param, char *));
1374 case CURLOPT_PROXYPASSWORD:
1376 * authentication password to use in the operation
1378 result = Curl_setstropt(&data->set.str[STRING_PROXYPASSWORD],
1379 va_arg(param, char *));
1381 case CURLOPT_NOPROXY:
1383 * proxy exception list
1385 result = Curl_setstropt(&data->set.str[STRING_NOPROXY],
1386 va_arg(param, char *));
1392 * What range of the file you want to transfer
1394 result = Curl_setstropt(&data->set.str[STRING_SET_RANGE],
1395 va_arg(param, char *));
1397 case CURLOPT_RESUME_FROM:
1399 * Resume transfer at the given file position
1401 arg = va_arg(param, long);
1403 return CURLE_BAD_FUNCTION_ARGUMENT;
1404 data->set.set_resume_from = arg;
1406 case CURLOPT_RESUME_FROM_LARGE:
1408 * Resume transfer at the given file position
1410 bigsize = va_arg(param, curl_off_t);
1412 return CURLE_BAD_FUNCTION_ARGUMENT;
1413 data->set.set_resume_from = bigsize;
1415 case CURLOPT_DEBUGFUNCTION:
1417 * stderr write callback.
1419 data->set.fdebug = va_arg(param, curl_debug_callback);
1421 * if the callback provided is NULL, it'll use the default callback
1424 case CURLOPT_DEBUGDATA:
1426 * Set to a void * that should receive all error writes. This
1427 * defaults to CURLOPT_STDERR for normal operations.
1429 data->set.debugdata = va_arg(param, void *);
1431 case CURLOPT_STDERR:
1433 * Set to a FILE * that should receive all error writes. This
1434 * defaults to stderr for normal operations.
1436 data->set.err = va_arg(param, FILE *);
1438 data->set.err = stderr;
1440 case CURLOPT_HEADERFUNCTION:
1442 * Set header write callback
1444 data->set.fwrite_header = va_arg(param, curl_write_callback);
1446 case CURLOPT_WRITEFUNCTION:
1448 * Set data write callback
1450 data->set.fwrite_func = va_arg(param, curl_write_callback);
1451 if(!data->set.fwrite_func) {
1452 data->set.is_fwrite_set = 0;
1453 /* When set to NULL, reset to our internal default function */
1454 data->set.fwrite_func = (curl_write_callback)fwrite;
1457 data->set.is_fwrite_set = 1;
1459 case CURLOPT_READFUNCTION:
1461 * Read data callback
1463 data->set.fread_func_set = va_arg(param, curl_read_callback);
1464 if(!data->set.fread_func_set) {
1465 data->set.is_fread_set = 0;
1466 /* When set to NULL, reset to our internal default function */
1467 data->set.fread_func_set = (curl_read_callback)fread;
1470 data->set.is_fread_set = 1;
1472 case CURLOPT_SEEKFUNCTION:
1474 * Seek callback. Might be NULL.
1476 data->set.seek_func = va_arg(param, curl_seek_callback);
1478 case CURLOPT_SEEKDATA:
1480 * Seek control callback. Might be NULL.
1482 data->set.seek_client = va_arg(param, void *);
1484 case CURLOPT_CONV_FROM_NETWORK_FUNCTION:
1486 * "Convert from network encoding" callback
1488 data->set.convfromnetwork = va_arg(param, curl_conv_callback);
1490 case CURLOPT_CONV_TO_NETWORK_FUNCTION:
1492 * "Convert to network encoding" callback
1494 data->set.convtonetwork = va_arg(param, curl_conv_callback);
1496 case CURLOPT_CONV_FROM_UTF8_FUNCTION:
1498 * "Convert from UTF-8 encoding" callback
1500 data->set.convfromutf8 = va_arg(param, curl_conv_callback);
1502 case CURLOPT_IOCTLFUNCTION:
1504 * I/O control callback. Might be NULL.
1506 data->set.ioctl_func = va_arg(param, curl_ioctl_callback);
1508 case CURLOPT_IOCTLDATA:
1510 * I/O control data pointer. Might be NULL.
1512 data->set.ioctl_client = va_arg(param, void *);
1514 case CURLOPT_SSLCERT:
1516 * String that holds file name of the SSL certificate to use
1518 result = Curl_setstropt(&data->set.str[STRING_CERT_ORIG],
1519 va_arg(param, char *));
1521 case CURLOPT_PROXY_SSLCERT:
1523 * String that holds file name of the SSL certificate to use for proxy
1525 result = Curl_setstropt(&data->set.str[STRING_CERT_PROXY],
1526 va_arg(param, char *));
1528 case CURLOPT_SSLCERTTYPE:
1530 * String that holds file type of the SSL certificate to use
1532 result = Curl_setstropt(&data->set.str[STRING_CERT_TYPE_ORIG],
1533 va_arg(param, char *));
1535 case CURLOPT_PROXY_SSLCERTTYPE:
1537 * String that holds file type of the SSL certificate to use for proxy
1539 result = Curl_setstropt(&data->set.str[STRING_CERT_TYPE_PROXY],
1540 va_arg(param, char *));
1542 case CURLOPT_SSLKEY:
1544 * String that holds file name of the SSL key to use
1546 result = Curl_setstropt(&data->set.str[STRING_KEY_ORIG],
1547 va_arg(param, char *));
1549 case CURLOPT_PROXY_SSLKEY:
1551 * String that holds file name of the SSL key to use for proxy
1553 result = Curl_setstropt(&data->set.str[STRING_KEY_PROXY],
1554 va_arg(param, char *));
1556 case CURLOPT_SSLKEYTYPE:
1558 * String that holds file type of the SSL key to use
1560 result = Curl_setstropt(&data->set.str[STRING_KEY_TYPE_ORIG],
1561 va_arg(param, char *));
1563 case CURLOPT_PROXY_SSLKEYTYPE:
1565 * String that holds file type of the SSL key to use for proxy
1567 result = Curl_setstropt(&data->set.str[STRING_KEY_TYPE_PROXY],
1568 va_arg(param, char *));
1570 case CURLOPT_KEYPASSWD:
1572 * String that holds the SSL or SSH private key password.
1574 result = Curl_setstropt(&data->set.str[STRING_KEY_PASSWD_ORIG],
1575 va_arg(param, char *));
1577 case CURLOPT_PROXY_KEYPASSWD:
1579 * String that holds the SSL private key password for proxy.
1581 result = Curl_setstropt(&data->set.str[STRING_KEY_PASSWD_PROXY],
1582 va_arg(param, char *));
1584 case CURLOPT_SSLENGINE:
1586 * String that holds the SSL crypto engine.
1588 argptr = va_arg(param, char *);
1589 if(argptr && argptr[0])
1590 result = Curl_ssl_set_engine(data, argptr);
1593 case CURLOPT_SSLENGINE_DEFAULT:
1595 * flag to set engine as default.
1597 result = Curl_ssl_set_engine_default(data);
1601 * Kludgy option to enable CRLF conversions. Subject for removal.
1603 data->set.crlf = (0 != va_arg(param, long)) ? TRUE : FALSE;
1606 case CURLOPT_INTERFACE:
1608 * Set what interface or address/hostname to bind the socket to when
1609 * performing an operation and thus what from-IP your connection will use.
1611 result = Curl_setstropt(&data->set.str[STRING_DEVICE],
1612 va_arg(param, char *));
1614 case CURLOPT_LOCALPORT:
1616 * Set what local port to bind the socket to when performing an operation.
1618 arg = va_arg(param, long);
1619 if((arg < 0) || (arg > 65535))
1620 return CURLE_BAD_FUNCTION_ARGUMENT;
1621 data->set.localport = curlx_sltous(arg);
1623 case CURLOPT_LOCALPORTRANGE:
1625 * Set number of local ports to try, starting with CURLOPT_LOCALPORT.
1627 arg = va_arg(param, long);
1628 if((arg < 0) || (arg > 65535))
1629 return CURLE_BAD_FUNCTION_ARGUMENT;
1630 data->set.localportrange = curlx_sltosi(arg);
1632 case CURLOPT_KRBLEVEL:
1634 * A string that defines the kerberos security level.
1636 result = Curl_setstropt(&data->set.str[STRING_KRB_LEVEL],
1637 va_arg(param, char *));
1638 data->set.krb = (data->set.str[STRING_KRB_LEVEL]) ? TRUE : FALSE;
1640 case CURLOPT_GSSAPI_DELEGATION:
1642 * GSS-API credential delegation bitmask
1644 arg = va_arg(param, long);
1645 if(arg < CURLGSSAPI_DELEGATION_NONE)
1646 return CURLE_BAD_FUNCTION_ARGUMENT;
1647 data->set.gssapi_delegation = arg;
1649 case CURLOPT_SSL_VERIFYPEER:
1651 * Enable peer SSL verifying.
1653 data->set.ssl.primary.verifypeer = (0 != va_arg(param, long)) ?
1656 /* Update the current connection ssl_config. */
1657 if(data->easy_conn) {
1658 data->easy_conn->ssl_config.verifypeer =
1659 data->set.ssl.primary.verifypeer;
1662 case CURLOPT_PROXY_SSL_VERIFYPEER:
1664 * Enable peer SSL verifying for proxy.
1666 data->set.proxy_ssl.primary.verifypeer =
1667 (0 != va_arg(param, long))?TRUE:FALSE;
1669 /* Update the current connection proxy_ssl_config. */
1670 if(data->easy_conn) {
1671 data->easy_conn->proxy_ssl_config.verifypeer =
1672 data->set.proxy_ssl.primary.verifypeer;
1675 case CURLOPT_SSL_VERIFYHOST:
1677 * Enable verification of the host name in the peer certificate
1679 arg = va_arg(param, long);
1681 /* Obviously people are not reading documentation and too many thought
1682 this argument took a boolean when it wasn't and misused it. We thus ban
1683 1 as a sensible input and we warn about its use. Then we only have the
1684 2 action internally stored as TRUE. */
1687 failf(data, "CURLOPT_SSL_VERIFYHOST no longer supports 1 as value!");
1688 return CURLE_BAD_FUNCTION_ARGUMENT;
1691 data->set.ssl.primary.verifyhost = (0 != arg) ? TRUE : FALSE;
1693 /* Update the current connection ssl_config. */
1694 if(data->easy_conn) {
1695 data->easy_conn->ssl_config.verifyhost =
1696 data->set.ssl.primary.verifyhost;
1699 case CURLOPT_PROXY_SSL_VERIFYHOST:
1701 * Enable verification of the host name in the peer certificate for proxy
1703 arg = va_arg(param, long);
1705 /* Obviously people are not reading documentation and too many thought
1706 this argument took a boolean when it wasn't and misused it. We thus ban
1707 1 as a sensible input and we warn about its use. Then we only have the
1708 2 action internally stored as TRUE. */
1711 failf(data, "CURLOPT_SSL_VERIFYHOST no longer supports 1 as value!");
1712 return CURLE_BAD_FUNCTION_ARGUMENT;
1715 data->set.proxy_ssl.primary.verifyhost = (0 != arg)?TRUE:FALSE;
1717 /* Update the current connection proxy_ssl_config. */
1718 if(data->easy_conn) {
1719 data->easy_conn->proxy_ssl_config.verifyhost =
1720 data->set.proxy_ssl.primary.verifyhost;
1723 case CURLOPT_SSL_VERIFYSTATUS:
1725 * Enable certificate status verifying.
1727 if(!Curl_ssl_cert_status_request()) {
1728 result = CURLE_NOT_BUILT_IN;
1732 data->set.ssl.primary.verifystatus = (0 != va_arg(param, long)) ?
1735 /* Update the current connection ssl_config. */
1736 if(data->easy_conn) {
1737 data->easy_conn->ssl_config.verifystatus =
1738 data->set.ssl.primary.verifystatus;
1741 case CURLOPT_SSL_CTX_FUNCTION:
1743 * Set a SSL_CTX callback
1746 if(Curl_ssl->have_ssl_ctx)
1747 data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback);
1750 result = CURLE_NOT_BUILT_IN;
1752 case CURLOPT_SSL_CTX_DATA:
1754 * Set a SSL_CTX callback parameter pointer
1757 if(Curl_ssl->have_ssl_ctx)
1758 data->set.ssl.fsslctxp = va_arg(param, void *);
1761 result = CURLE_NOT_BUILT_IN;
1763 case CURLOPT_SSL_FALSESTART:
1765 * Enable TLS false start.
1767 if(!Curl_ssl_false_start()) {
1768 result = CURLE_NOT_BUILT_IN;
1772 data->set.ssl.falsestart = (0 != va_arg(param, long)) ? TRUE : FALSE;
1774 case CURLOPT_CERTINFO:
1776 if(Curl_ssl->have_certinfo)
1777 data->set.ssl.certinfo = (0 != va_arg(param, long)) ? TRUE : FALSE;
1780 result = CURLE_NOT_BUILT_IN;
1782 case CURLOPT_PINNEDPUBLICKEY:
1784 * Set pinned public key for SSL connection.
1785 * Specify file name of the public key in DER format.
1788 if(Curl_ssl->have_pinnedpubkey)
1789 result = Curl_setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG],
1790 va_arg(param, char *));
1793 result = CURLE_NOT_BUILT_IN;
1795 case CURLOPT_PROXY_PINNEDPUBLICKEY:
1797 * Set pinned public key for SSL connection.
1798 * Specify file name of the public key in DER format.
1801 if(Curl_ssl->have_pinnedpubkey)
1802 result = Curl_setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY],
1803 va_arg(param, char *));
1806 result = CURLE_NOT_BUILT_IN;
1808 case CURLOPT_CAINFO:
1810 * Set CA info for SSL connection. Specify file name of the CA certificate
1812 result = Curl_setstropt(&data->set.str[STRING_SSL_CAFILE_ORIG],
1813 va_arg(param, char *));
1815 case CURLOPT_PROXY_CAINFO:
1817 * Set CA info SSL connection for proxy. Specify file name of the
1820 result = Curl_setstropt(&data->set.str[STRING_SSL_CAFILE_PROXY],
1821 va_arg(param, char *));
1823 case CURLOPT_CAPATH:
1825 * Set CA path info for SSL connection. Specify directory name of the CA
1826 * certificates which have been prepared using openssl c_rehash utility.
1829 if(Curl_ssl->have_ca_path)
1830 /* This does not work on windows. */
1831 result = Curl_setstropt(&data->set.str[STRING_SSL_CAPATH_ORIG],
1832 va_arg(param, char *));
1835 result = CURLE_NOT_BUILT_IN;
1837 case CURLOPT_PROXY_CAPATH:
1839 * Set CA path info for SSL connection proxy. Specify directory name of the
1840 * CA certificates which have been prepared using openssl c_rehash utility.
1843 if(Curl_ssl->have_ca_path)
1844 /* This does not work on windows. */
1845 result = Curl_setstropt(&data->set.str[STRING_SSL_CAPATH_PROXY],
1846 va_arg(param, char *));
1849 result = CURLE_NOT_BUILT_IN;
1851 case CURLOPT_CRLFILE:
1853 * Set CRL file info for SSL connection. Specify file name of the CRL
1854 * to check certificates revocation
1856 result = Curl_setstropt(&data->set.str[STRING_SSL_CRLFILE_ORIG],
1857 va_arg(param, char *));
1859 case CURLOPT_PROXY_CRLFILE:
1861 * Set CRL file info for SSL connection for proxy. Specify file name of the
1862 * CRL to check certificates revocation
1864 result = Curl_setstropt(&data->set.str[STRING_SSL_CRLFILE_PROXY],
1865 va_arg(param, char *));
1867 case CURLOPT_ISSUERCERT:
1869 * Set Issuer certificate file
1870 * to check certificates issuer
1872 result = Curl_setstropt(&data->set.str[STRING_SSL_ISSUERCERT_ORIG],
1873 va_arg(param, char *));
1875 case CURLOPT_TELNETOPTIONS:
1877 * Set a linked list of telnet options
1879 data->set.telnet_options = va_arg(param, struct curl_slist *);
1882 case CURLOPT_BUFFERSIZE:
1884 * The application kindly asks for a differently sized receive buffer.
1885 * If it seems reasonable, we'll use it.
1887 arg = va_arg(param, long);
1889 if(arg > READBUFFER_MAX)
1890 arg = READBUFFER_MAX;
1892 arg = READBUFFER_SIZE;
1893 else if(arg < READBUFFER_MIN)
1894 arg = READBUFFER_MIN;
1896 /* Resize if new size */
1897 if(arg != data->set.buffer_size) {
1898 char *newbuff = realloc(data->state.buffer, arg + 1);
1900 DEBUGF(fprintf(stderr, "Error: realloc of buffer failed\n"));
1901 result = CURLE_OUT_OF_MEMORY;
1904 data->state.buffer = newbuff;
1906 data->set.buffer_size = arg;
1910 case CURLOPT_NOSIGNAL:
1912 * The application asks not to set any signal() or alarm() handlers,
1913 * even when using a timeout.
1915 data->set.no_signal = (0 != va_arg(param, long)) ? TRUE : FALSE;
1920 struct Curl_share *set;
1921 set = va_arg(param, struct Curl_share *);
1923 /* disconnect from old share, if any */
1925 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
1927 if(data->dns.hostcachetype == HCACHE_SHARED) {
1928 data->dns.hostcache = NULL;
1929 data->dns.hostcachetype = HCACHE_NONE;
1932 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
1933 if(data->share->cookies == data->cookies)
1934 data->cookies = NULL;
1937 if(data->share->sslsession == data->state.session)
1938 data->state.session = NULL;
1940 data->share->dirty--;
1942 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
1946 /* use new share if it set */
1950 Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
1952 data->share->dirty++;
1954 if(data->share->specifier & (1<< CURL_LOCK_DATA_DNS)) {
1955 /* use shared host cache */
1956 data->dns.hostcache = &data->share->hostcache;
1957 data->dns.hostcachetype = HCACHE_SHARED;
1959 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
1960 if(data->share->cookies) {
1961 /* use shared cookie list, first free own one if any */
1962 Curl_cookie_cleanup(data->cookies);
1963 /* enable cookies since we now use a share that uses cookies! */
1964 data->cookies = data->share->cookies;
1966 #endif /* CURL_DISABLE_HTTP */
1967 if(data->share->sslsession) {
1968 data->set.general_ssl.max_ssl_sessions = data->share->max_ssl_sessions;
1969 data->state.session = data->share->sslsession;
1971 Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
1974 /* check for host cache not needed,
1975 * it will be done by curl_easy_perform */
1979 case CURLOPT_PRIVATE:
1981 * Set private data pointer.
1983 data->set.private_data = va_arg(param, void *);
1986 case CURLOPT_MAXFILESIZE:
1988 * Set the maximum size of a file to download.
1990 arg = va_arg(param, long);
1992 return CURLE_BAD_FUNCTION_ARGUMENT;
1993 data->set.max_filesize = arg;
1997 case CURLOPT_USE_SSL:
1999 * Make transfers attempt to use SSL/TLS.
2001 arg = va_arg(param, long);
2002 if((arg < CURLUSESSL_NONE) || (arg > CURLUSESSL_ALL))
2003 return CURLE_BAD_FUNCTION_ARGUMENT;
2004 data->set.use_ssl = (curl_usessl)arg;
2007 case CURLOPT_SSL_OPTIONS:
2008 arg = va_arg(param, long);
2009 data->set.ssl.enable_beast = arg&CURLSSLOPT_ALLOW_BEAST?TRUE:FALSE;
2010 data->set.ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
2013 case CURLOPT_PROXY_SSL_OPTIONS:
2014 arg = va_arg(param, long);
2015 data->set.proxy_ssl.enable_beast = arg&CURLSSLOPT_ALLOW_BEAST?TRUE:FALSE;
2016 data->set.proxy_ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
2020 case CURLOPT_FTPSSLAUTH:
2022 * Set a specific auth for FTP-SSL transfers.
2024 arg = va_arg(param, long);
2025 if((arg < CURLFTPAUTH_DEFAULT) || (arg > CURLFTPAUTH_TLS))
2026 return CURLE_BAD_FUNCTION_ARGUMENT;
2027 data->set.ftpsslauth = (curl_ftpauth)arg;
2030 case CURLOPT_IPRESOLVE:
2031 arg = va_arg(param, long);
2032 if((arg < CURL_IPRESOLVE_WHATEVER) || (arg > CURL_IPRESOLVE_V6))
2033 return CURLE_BAD_FUNCTION_ARGUMENT;
2034 data->set.ipver = arg;
2037 case CURLOPT_MAXFILESIZE_LARGE:
2039 * Set the maximum size of a file to download.
2041 bigsize = va_arg(param, curl_off_t);
2043 return CURLE_BAD_FUNCTION_ARGUMENT;
2044 data->set.max_filesize = bigsize;
2047 case CURLOPT_TCP_NODELAY:
2049 * Enable or disable TCP_NODELAY, which will disable/enable the Nagle
2052 data->set.tcp_nodelay = (0 != va_arg(param, long)) ? TRUE : FALSE;
2055 case CURLOPT_FTP_ACCOUNT:
2056 result = Curl_setstropt(&data->set.str[STRING_FTP_ACCOUNT],
2057 va_arg(param, char *));
2060 case CURLOPT_IGNORE_CONTENT_LENGTH:
2061 data->set.ignorecl = (0 != va_arg(param, long)) ? TRUE : FALSE;
2064 case CURLOPT_CONNECT_ONLY:
2066 * No data transfer, set up connection and let application use the socket
2068 data->set.connect_only = (0 != va_arg(param, long)) ? TRUE : FALSE;
2071 case CURLOPT_FTP_ALTERNATIVE_TO_USER:
2072 result = Curl_setstropt(&data->set.str[STRING_FTP_ALTERNATIVE_TO_USER],
2073 va_arg(param, char *));
2076 case CURLOPT_SOCKOPTFUNCTION:
2078 * socket callback function: called after socket() but before connect()
2080 data->set.fsockopt = va_arg(param, curl_sockopt_callback);
2083 case CURLOPT_SOCKOPTDATA:
2085 * socket callback data pointer. Might be NULL.
2087 data->set.sockopt_client = va_arg(param, void *);
2090 case CURLOPT_OPENSOCKETFUNCTION:
2092 * open/create socket callback function: called instead of socket(),
2095 data->set.fopensocket = va_arg(param, curl_opensocket_callback);
2098 case CURLOPT_OPENSOCKETDATA:
2100 * socket callback data pointer. Might be NULL.
2102 data->set.opensocket_client = va_arg(param, void *);
2105 case CURLOPT_CLOSESOCKETFUNCTION:
2107 * close socket callback function: called instead of close()
2108 * when shutting down a connection
2110 data->set.fclosesocket = va_arg(param, curl_closesocket_callback);
2113 case CURLOPT_RESOLVER_START_FUNCTION:
2115 * resolver start callback function: called before a new resolver request
2118 data->set.resolver_start = va_arg(param, curl_resolver_start_callback);
2121 case CURLOPT_RESOLVER_START_DATA:
2123 * resolver start callback data pointer. Might be NULL.
2125 data->set.resolver_start_client = va_arg(param, void *);
2128 case CURLOPT_CLOSESOCKETDATA:
2130 * socket callback data pointer. Might be NULL.
2132 data->set.closesocket_client = va_arg(param, void *);
2135 case CURLOPT_SSL_SESSIONID_CACHE:
2136 data->set.ssl.primary.sessionid = (0 != va_arg(param, long)) ?
2138 data->set.proxy_ssl.primary.sessionid = data->set.ssl.primary.sessionid;
2141 #if defined(USE_LIBSSH2) || defined(USE_LIBSSH)
2142 /* we only include SSH options if explicitly built to support SSH */
2143 case CURLOPT_SSH_AUTH_TYPES:
2144 data->set.ssh_auth_types = va_arg(param, long);
2147 case CURLOPT_SSH_PUBLIC_KEYFILE:
2149 * Use this file instead of the $HOME/.ssh/id_dsa.pub file
2151 result = Curl_setstropt(&data->set.str[STRING_SSH_PUBLIC_KEY],
2152 va_arg(param, char *));
2155 case CURLOPT_SSH_PRIVATE_KEYFILE:
2157 * Use this file instead of the $HOME/.ssh/id_dsa file
2159 result = Curl_setstropt(&data->set.str[STRING_SSH_PRIVATE_KEY],
2160 va_arg(param, char *));
2162 case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5:
2164 * Option to allow for the MD5 of the host public key to be checked
2165 * for validation purposes.
2167 result = Curl_setstropt(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5],
2168 va_arg(param, char *));
2170 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2171 case CURLOPT_SSH_KNOWNHOSTS:
2173 * Store the file name to read known hosts from.
2175 result = Curl_setstropt(&data->set.str[STRING_SSH_KNOWNHOSTS],
2176 va_arg(param, char *));
2179 case CURLOPT_SSH_KEYFUNCTION:
2180 /* setting to NULL is fine since the ssh.c functions themselves will
2181 then rever to use the internal default */
2182 data->set.ssh_keyfunc = va_arg(param, curl_sshkeycallback);
2185 case CURLOPT_SSH_KEYDATA:
2187 * Custom client data to pass to the SSH keyfunc callback
2189 data->set.ssh_keyfunc_userp = va_arg(param, void *);
2191 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2192 #endif /* USE_LIBSSH2 */
2194 case CURLOPT_HTTP_TRANSFER_DECODING:
2196 * disable libcurl transfer encoding is used
2198 data->set.http_te_skip = (0 == va_arg(param, long)) ? TRUE : FALSE;
2201 case CURLOPT_HTTP_CONTENT_DECODING:
2203 * raw data passed to the application when content encoding is used
2205 data->set.http_ce_skip = (0 == va_arg(param, long)) ? TRUE : FALSE;
2208 case CURLOPT_NEW_FILE_PERMS:
2210 * Uses these permissions instead of 0644
2212 arg = va_arg(param, long);
2213 if((arg < 0) || (arg > 0777))
2214 return CURLE_BAD_FUNCTION_ARGUMENT;
2215 data->set.new_file_perms = arg;
2218 case CURLOPT_NEW_DIRECTORY_PERMS:
2220 * Uses these permissions instead of 0755
2222 arg = va_arg(param, long);
2223 if((arg < 0) || (arg > 0777))
2224 return CURLE_BAD_FUNCTION_ARGUMENT;
2225 data->set.new_directory_perms = arg;
2228 case CURLOPT_ADDRESS_SCOPE:
2230 * We always get longs when passed plain numericals, but for this value we
2231 * know that an unsigned int will always hold the value so we blindly
2232 * typecast to this type
2234 arg = va_arg(param, long);
2235 if((arg < 0) || (arg > 0xf))
2236 return CURLE_BAD_FUNCTION_ARGUMENT;
2237 data->set.scope_id = curlx_sltoui(arg);
2240 case CURLOPT_PROTOCOLS:
2241 /* set the bitmask for the protocols that are allowed to be used for the
2242 transfer, which thus helps the app which takes URLs from users or other
2243 external inputs and want to restrict what protocol(s) to deal
2244 with. Defaults to CURLPROTO_ALL. */
2245 data->set.allowed_protocols = va_arg(param, long);
2248 case CURLOPT_REDIR_PROTOCOLS:
2249 /* set the bitmask for the protocols that libcurl is allowed to follow to,
2250 as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
2251 to be set in both bitmasks to be allowed to get redirected to. Defaults
2252 to all protocols except FILE and SCP. */
2253 data->set.redir_protocols = va_arg(param, long);
2256 case CURLOPT_DEFAULT_PROTOCOL:
2257 /* Set the protocol to use when the URL doesn't include any protocol */
2258 result = Curl_setstropt(&data->set.str[STRING_DEFAULT_PROTOCOL],
2259 va_arg(param, char *));
2262 case CURLOPT_MAIL_FROM:
2263 /* Set the SMTP mail originator */
2264 result = Curl_setstropt(&data->set.str[STRING_MAIL_FROM],
2265 va_arg(param, char *));
2268 case CURLOPT_MAIL_AUTH:
2269 /* Set the SMTP auth originator */
2270 result = Curl_setstropt(&data->set.str[STRING_MAIL_AUTH],
2271 va_arg(param, char *));
2274 case CURLOPT_MAIL_RCPT:
2275 /* Set the list of mail recipients */
2276 data->set.mail_rcpt = va_arg(param, struct curl_slist *);
2279 case CURLOPT_SASL_IR:
2280 /* Enable/disable SASL initial response */
2281 data->set.sasl_ir = (0 != va_arg(param, long)) ? TRUE : FALSE;
2284 case CURLOPT_RTSP_REQUEST:
2287 * Set the RTSP request method (OPTIONS, SETUP, PLAY, etc...)
2288 * Would this be better if the RTSPREQ_* were just moved into here?
2290 long curl_rtspreq = va_arg(param, long);
2291 Curl_RtspReq rtspreq = RTSPREQ_NONE;
2292 switch(curl_rtspreq) {
2293 case CURL_RTSPREQ_OPTIONS:
2294 rtspreq = RTSPREQ_OPTIONS;
2297 case CURL_RTSPREQ_DESCRIBE:
2298 rtspreq = RTSPREQ_DESCRIBE;
2301 case CURL_RTSPREQ_ANNOUNCE:
2302 rtspreq = RTSPREQ_ANNOUNCE;
2305 case CURL_RTSPREQ_SETUP:
2306 rtspreq = RTSPREQ_SETUP;
2309 case CURL_RTSPREQ_PLAY:
2310 rtspreq = RTSPREQ_PLAY;
2313 case CURL_RTSPREQ_PAUSE:
2314 rtspreq = RTSPREQ_PAUSE;
2317 case CURL_RTSPREQ_TEARDOWN:
2318 rtspreq = RTSPREQ_TEARDOWN;
2321 case CURL_RTSPREQ_GET_PARAMETER:
2322 rtspreq = RTSPREQ_GET_PARAMETER;
2325 case CURL_RTSPREQ_SET_PARAMETER:
2326 rtspreq = RTSPREQ_SET_PARAMETER;
2329 case CURL_RTSPREQ_RECORD:
2330 rtspreq = RTSPREQ_RECORD;
2333 case CURL_RTSPREQ_RECEIVE:
2334 rtspreq = RTSPREQ_RECEIVE;
2337 rtspreq = RTSPREQ_NONE;
2340 data->set.rtspreq = rtspreq;
2345 case CURLOPT_RTSP_SESSION_ID:
2347 * Set the RTSP Session ID manually. Useful if the application is
2348 * resuming a previously established RTSP session
2350 result = Curl_setstropt(&data->set.str[STRING_RTSP_SESSION_ID],
2351 va_arg(param, char *));
2354 case CURLOPT_RTSP_STREAM_URI:
2356 * Set the Stream URI for the RTSP request. Unless the request is
2357 * for generic server options, the application will need to set this.
2359 result = Curl_setstropt(&data->set.str[STRING_RTSP_STREAM_URI],
2360 va_arg(param, char *));
2363 case CURLOPT_RTSP_TRANSPORT:
2365 * The content of the Transport: header for the RTSP request
2367 result = Curl_setstropt(&data->set.str[STRING_RTSP_TRANSPORT],
2368 va_arg(param, char *));
2371 case CURLOPT_RTSP_CLIENT_CSEQ:
2373 * Set the CSEQ number to issue for the next RTSP request. Useful if the
2374 * application is resuming a previously broken connection. The CSEQ
2375 * will increment from this new number henceforth.
2377 data->state.rtsp_next_client_CSeq = va_arg(param, long);
2380 case CURLOPT_RTSP_SERVER_CSEQ:
2381 /* Same as the above, but for server-initiated requests */
2382 data->state.rtsp_next_client_CSeq = va_arg(param, long);
2385 case CURLOPT_INTERLEAVEDATA:
2386 data->set.rtp_out = va_arg(param, void *);
2388 case CURLOPT_INTERLEAVEFUNCTION:
2389 /* Set the user defined RTP write function */
2390 data->set.fwrite_rtp = va_arg(param, curl_write_callback);
2393 case CURLOPT_WILDCARDMATCH:
2394 data->set.wildcard_enabled = (0 != va_arg(param, long)) ? TRUE : FALSE;
2396 case CURLOPT_CHUNK_BGN_FUNCTION:
2397 data->set.chunk_bgn = va_arg(param, curl_chunk_bgn_callback);
2399 case CURLOPT_CHUNK_END_FUNCTION:
2400 data->set.chunk_end = va_arg(param, curl_chunk_end_callback);
2402 case CURLOPT_FNMATCH_FUNCTION:
2403 data->set.fnmatch = va_arg(param, curl_fnmatch_callback);
2405 case CURLOPT_CHUNK_DATA:
2406 data->wildcard.customptr = va_arg(param, void *);
2408 case CURLOPT_FNMATCH_DATA:
2409 data->set.fnmatch_data = va_arg(param, void *);
2412 case CURLOPT_TLSAUTH_USERNAME:
2413 result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME_ORIG],
2414 va_arg(param, char *));
2415 if(data->set.str[STRING_TLSAUTH_USERNAME_ORIG] && !data->set.ssl.authtype)
2416 data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
2418 case CURLOPT_PROXY_TLSAUTH_USERNAME:
2419 result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME_PROXY],
2420 va_arg(param, char *));
2421 if(data->set.str[STRING_TLSAUTH_USERNAME_PROXY] &&
2422 !data->set.proxy_ssl.authtype)
2423 data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
2425 case CURLOPT_TLSAUTH_PASSWORD:
2426 result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_ORIG],
2427 va_arg(param, char *));
2428 if(data->set.str[STRING_TLSAUTH_USERNAME_ORIG] && !data->set.ssl.authtype)
2429 data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
2431 case CURLOPT_PROXY_TLSAUTH_PASSWORD:
2432 result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_PROXY],
2433 va_arg(param, char *));
2434 if(data->set.str[STRING_TLSAUTH_USERNAME_PROXY] &&
2435 !data->set.proxy_ssl.authtype)
2436 data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
2438 case CURLOPT_TLSAUTH_TYPE:
2439 argptr = va_arg(param, char *);
2441 strncasecompare(argptr, "SRP", strlen("SRP")))
2442 data->set.ssl.authtype = CURL_TLSAUTH_SRP;
2444 data->set.ssl.authtype = CURL_TLSAUTH_NONE;
2446 case CURLOPT_PROXY_TLSAUTH_TYPE:
2447 argptr = va_arg(param, char *);
2449 strncasecompare(argptr, "SRP", strlen("SRP")))
2450 data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP;
2452 data->set.proxy_ssl.authtype = CURL_TLSAUTH_NONE;
2455 case CURLOPT_DNS_SERVERS:
2456 result = Curl_set_dns_servers(data, va_arg(param, char *));
2458 case CURLOPT_DNS_INTERFACE:
2459 result = Curl_set_dns_interface(data, va_arg(param, char *));
2461 case CURLOPT_DNS_LOCAL_IP4:
2462 result = Curl_set_dns_local_ip4(data, va_arg(param, char *));
2464 case CURLOPT_DNS_LOCAL_IP6:
2465 result = Curl_set_dns_local_ip6(data, va_arg(param, char *));
2468 case CURLOPT_TCP_KEEPALIVE:
2469 data->set.tcp_keepalive = (0 != va_arg(param, long)) ? TRUE : FALSE;
2471 case CURLOPT_TCP_KEEPIDLE:
2472 arg = va_arg(param, long);
2474 return CURLE_BAD_FUNCTION_ARGUMENT;
2475 data->set.tcp_keepidle = arg;
2477 case CURLOPT_TCP_KEEPINTVL:
2478 arg = va_arg(param, long);
2480 return CURLE_BAD_FUNCTION_ARGUMENT;
2481 data->set.tcp_keepintvl = arg;
2483 case CURLOPT_TCP_FASTOPEN:
2484 #if defined(CONNECT_DATA_IDEMPOTENT) || defined(MSG_FASTOPEN) || \
2485 defined(TCP_FASTOPEN_CONNECT)
2486 data->set.tcp_fastopen = (0 != va_arg(param, long))?TRUE:FALSE;
2488 result = CURLE_NOT_BUILT_IN;
2491 case CURLOPT_SSL_ENABLE_NPN:
2492 data->set.ssl_enable_npn = (0 != va_arg(param, long)) ? TRUE : FALSE;
2494 case CURLOPT_SSL_ENABLE_ALPN:
2495 data->set.ssl_enable_alpn = (0 != va_arg(param, long)) ? TRUE : FALSE;
2498 #ifdef USE_UNIX_SOCKETS
2499 case CURLOPT_UNIX_SOCKET_PATH:
2500 data->set.abstract_unix_socket = FALSE;
2501 result = Curl_setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH],
2502 va_arg(param, char *));
2504 case CURLOPT_ABSTRACT_UNIX_SOCKET:
2505 data->set.abstract_unix_socket = TRUE;
2506 result = Curl_setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH],
2507 va_arg(param, char *));
2511 case CURLOPT_PATH_AS_IS:
2512 data->set.path_as_is = (0 != va_arg(param, long)) ? TRUE : FALSE;
2514 case CURLOPT_PIPEWAIT:
2515 data->set.pipewait = (0 != va_arg(param, long)) ? TRUE : FALSE;
2517 case CURLOPT_STREAM_WEIGHT:
2519 return CURLE_NOT_BUILT_IN;
2521 arg = va_arg(param, long);
2522 if((arg >= 1) && (arg <= 256))
2523 data->set.stream_weight = (int)arg;
2526 case CURLOPT_STREAM_DEPENDS:
2527 case CURLOPT_STREAM_DEPENDS_E:
2530 return CURLE_NOT_BUILT_IN;
2532 struct Curl_easy *dep = va_arg(param, struct Curl_easy *);
2533 if(!dep || GOOD_EASY_HANDLE(dep)) {
2534 if(data->set.stream_depends_on) {
2535 Curl_http2_remove_child(data->set.stream_depends_on, data);
2537 Curl_http2_add_child(dep, data, (option == CURLOPT_STREAM_DEPENDS_E));
2542 case CURLOPT_CONNECT_TO:
2543 data->set.connect_to = va_arg(param, struct curl_slist *);
2545 case CURLOPT_SUPPRESS_CONNECT_HEADERS:
2546 data->set.suppress_connect_headers = (0 != va_arg(param, long))?TRUE:FALSE;
2548 case CURLOPT_SSH_COMPRESSION:
2549 data->set.ssh_compression = (0 != va_arg(param, long))?TRUE:FALSE;
2551 case CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS:
2552 arg = va_arg(param, long);
2554 return CURLE_BAD_FUNCTION_ARGUMENT;
2555 data->set.happy_eyeballs_timeout = arg;
2558 /* unknown tag and its companion, just ignore: */
2559 result = CURLE_UNKNOWN_OPTION;
2567 * curl_easy_setopt() is the external interface for setting options on an
2570 * NOTE: This is one of few API functions that are allowed to be called from
2571 * within a callback.
2574 #undef curl_easy_setopt
2575 CURLcode curl_easy_setopt(struct Curl_easy *data, CURLoption tag, ...)
2581 return CURLE_BAD_FUNCTION_ARGUMENT;
2585 result = Curl_vsetopt(data, tag, arg);