Coverage Report

Created: 2026-01-09 07:25

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