Coverage Report

Created: 2026-01-10 06:51

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