Coverage Report

Created: 2025-12-04 06:52

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