source: azure_iot_hub/trunk/curl-7.57.0/lib/setopt.c@ 389

Last change on this file since 389 was 389, checked in by coas-nagasima, 5 years ago

ビルドが通るよう更新

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