Coverage Report

Created: 2026-06-15 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Utilities/cmcurl/lib/protocol.c
Line
Count
Source
1
/***************************************************************************
2
 *                                  _   _ ____  _
3
 *  Project                     ___| | | |  _ \| |
4
 *                             / __| | | | |_) | |
5
 *                            | (__| |_| |  _ <| |___
6
 *                             \___|\___/|_| \_\_____|
7
 *
8
 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
9
 *
10
 * This software is licensed as described in the file COPYING, which
11
 * you should have received as part of this distribution. The terms
12
 * are also available at https://curl.se/docs/copyright.html.
13
 *
14
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15
 * copies of the Software, and permit persons to whom the Software is
16
 * furnished to do so, under the terms of the COPYING file.
17
 *
18
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19
 * KIND, either express or implied.
20
 *
21
 * SPDX-License-Identifier: curl
22
 *
23
 ***************************************************************************/
24
#include "curl_setup.h"
25
26
#include "protocol.h"
27
#include "strcase.h"
28
29
#include "dict.h"
30
#include "file.h"
31
#include "ftp.h"
32
#include "gopher.h"
33
#include "http.h"
34
#include "imap.h"
35
#include "curl_ldap.h"
36
#include "mqtt.h"
37
#include "pop3.h"
38
#include "rtsp.h"
39
#include "smb.h"
40
#include "smtp.h"
41
#include "telnet.h"
42
#include "tftp.h"
43
#include "ws.h"
44
#include "vssh/ssh.h"
45
46
47
/* All URI schemes known to libcurl, but not necessarily implemented
48
 * by protocol handlers. */
49
const struct Curl_scheme Curl_scheme_dict = {
50
  "dict",                               /* scheme */
51
#ifdef CURL_DISABLE_DICT
52
  ZERO_NULL,
53
#else
54
  &Curl_protocol_dict,
55
#endif
56
  CURLPROTO_DICT,                       /* protocol */
57
  CURLPROTO_DICT,                       /* family */
58
  PROTOPT_NONE | PROTOPT_NOURLQUERY,    /* flags */
59
  PORT_DICT,                            /* defport */
60
};
61
62
const struct Curl_scheme Curl_scheme_file = {
63
  "file",                               /* scheme */
64
#ifdef CURL_DISABLE_FILE
65
  ZERO_NULL,
66
#else
67
  &Curl_protocol_file,
68
#endif
69
  CURLPROTO_FILE,                       /* protocol */
70
  CURLPROTO_FILE,                       /* family */
71
  PROTOPT_NONETWORK | PROTOPT_NOURLQUERY, /* flags */
72
  0                                     /* defport */
73
};
74
75
const struct Curl_scheme Curl_scheme_ftp = {
76
  "ftp",                           /* scheme */
77
#ifdef CURL_DISABLE_FTP
78
  ZERO_NULL,
79
#else
80
  &Curl_protocol_ftp,
81
#endif
82
  CURLPROTO_FTP,                   /* protocol */
83
  CURLPROTO_FTP,                   /* family */
84
  PROTOPT_DUAL | PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD |
85
  PROTOPT_NOURLQUERY | PROTOPT_PROXY_AS_HTTP |
86
  PROTOPT_WILDCARD | PROTOPT_SSL_REUSE |
87
  PROTOPT_CONN_REUSE, /* flags */
88
  PORT_FTP,                        /* defport */
89
};
90
91
const struct Curl_scheme Curl_scheme_ftps = {
92
  "ftps",                          /* scheme */
93
#if defined(CURL_DISABLE_FTP) || !defined(USE_SSL)
94
  ZERO_NULL,
95
#else
96
  &Curl_protocol_ftp,
97
#endif
98
  CURLPROTO_FTPS,                  /* protocol */
99
  CURLPROTO_FTP,                   /* family */
100
  PROTOPT_SSL | PROTOPT_DUAL | PROTOPT_CLOSEACTION |
101
  PROTOPT_NEEDSPWD | PROTOPT_NOURLQUERY | PROTOPT_WILDCARD |
102
  PROTOPT_CONN_REUSE, /* flags */
103
  PORT_FTPS,                       /* defport */
104
};
105
106
const struct Curl_scheme Curl_scheme_gopher = {
107
  "gopher",                             /* scheme */
108
#ifdef CURL_DISABLE_GOPHER
109
  ZERO_NULL,
110
#else
111
  &Curl_protocol_gopher,
112
#endif
113
  CURLPROTO_GOPHER,                     /* protocol */
114
  CURLPROTO_GOPHER,                     /* family */
115
  PROTOPT_NONE,                         /* flags */
116
  PORT_GOPHER,                          /* defport */
117
};
118
119
const struct Curl_scheme Curl_scheme_gophers = {
120
  "gophers",                            /* scheme */
121
#if defined(CURL_DISABLE_GOPHER) || !defined(USE_SSL)
122
  ZERO_NULL,
123
#else
124
  &Curl_protocol_gophers,
125
#endif
126
  CURLPROTO_GOPHERS,                    /* protocol */
127
  CURLPROTO_GOPHER,                     /* family */
128
  PROTOPT_SSL,                          /* flags */
129
  PORT_GOPHER,                          /* defport */
130
};
131
132
const struct Curl_scheme Curl_scheme_http = {
133
  "http",                               /* scheme */
134
#ifdef CURL_DISABLE_HTTP
135
  ZERO_NULL,
136
#else
137
  &Curl_protocol_http,
138
#endif
139
  CURLPROTO_HTTP,                       /* protocol */
140
  CURLPROTO_HTTP,                       /* family */
141
  PROTOPT_CREDSPERREQUEST |             /* flags */
142
  PROTOPT_USERPWDCTRL | PROTOPT_CONN_REUSE,
143
  PORT_HTTP,                            /* defport */
144
};
145
146
const struct Curl_scheme Curl_scheme_https = {
147
  "https",                              /* scheme */
148
#if defined(CURL_DISABLE_HTTP) || !defined(USE_SSL)
149
  ZERO_NULL,
150
#else
151
  &Curl_protocol_http,
152
#endif
153
  CURLPROTO_HTTPS,                      /* protocol */
154
  CURLPROTO_HTTP,                       /* family */
155
  PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN | /* flags */
156
  PROTOPT_USERPWDCTRL | PROTOPT_CONN_REUSE,
157
  PORT_HTTPS,                           /* defport */
158
};
159
160
const struct Curl_scheme Curl_scheme_imap = {
161
  "imap",                           /* scheme */
162
#ifdef CURL_DISABLE_IMAP
163
  ZERO_NULL,
164
#else
165
  &Curl_protocol_imap,
166
#endif
167
  CURLPROTO_IMAP,                   /* protocol */
168
  CURLPROTO_IMAP,                   /* family */
169
  PROTOPT_CLOSEACTION |             /* flags */
170
  PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE |
171
  PROTOPT_CONN_REUSE,
172
  PORT_IMAP,                        /* defport */
173
};
174
175
const struct Curl_scheme Curl_scheme_imaps = {
176
  "imaps",                          /* scheme */
177
#if defined(CURL_DISABLE_IMAP) || !defined(USE_SSL)
178
  ZERO_NULL,
179
#else
180
  &Curl_protocol_imap,
181
#endif
182
  CURLPROTO_IMAPS,                  /* protocol */
183
  CURLPROTO_IMAP,                   /* family */
184
  PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */
185
  PROTOPT_URLOPTIONS | PROTOPT_CONN_REUSE,
186
  PORT_IMAPS,                       /* defport */
187
};
188
189
const struct Curl_scheme Curl_scheme_ldap = {
190
  "ldap",                               /* scheme */
191
#ifdef CURL_DISABLE_LDAP
192
  ZERO_NULL,
193
#else
194
  &Curl_protocol_ldap,
195
#endif
196
  CURLPROTO_LDAP,                       /* protocol */
197
  CURLPROTO_LDAP,                       /* family */
198
  PROTOPT_SSL_REUSE,                    /* flags */
199
  PORT_LDAP,                            /* defport */
200
};
201
202
const struct Curl_scheme Curl_scheme_ldaps = {
203
  "ldaps",                              /* scheme */
204
#if defined(CURL_DISABLE_LDAP) || !defined(HAVE_LDAP_SSL)
205
  ZERO_NULL,
206
#else
207
  &Curl_protocol_ldap,
208
#endif
209
  CURLPROTO_LDAPS,                      /* protocol */
210
  CURLPROTO_LDAP,                       /* family */
211
  PROTOPT_SSL,                          /* flags */
212
  PORT_LDAPS,                           /* defport */
213
};
214
215
const struct Curl_scheme Curl_scheme_mqtt = {
216
  "mqtt",                             /* scheme */
217
#ifdef CURL_DISABLE_MQTT
218
  ZERO_NULL,
219
#else
220
  &Curl_protocol_mqtt,
221
#endif
222
  CURLPROTO_MQTT,                     /* protocol */
223
  CURLPROTO_MQTT,                     /* family */
224
  PROTOPT_NONE,                       /* flags */
225
  PORT_MQTT,                          /* defport */
226
};
227
228
const struct Curl_scheme Curl_scheme_mqtts = {
229
  "mqtts",                            /* scheme */
230
#if defined(CURL_DISABLE_MQTT) || !defined(USE_SSL)
231
  ZERO_NULL,
232
#else
233
  &Curl_protocol_mqtts,
234
#endif
235
  CURLPROTO_MQTTS,                    /* protocol */
236
  CURLPROTO_MQTT,                     /* family */
237
  PROTOPT_SSL,                        /* flags */
238
  PORT_MQTTS,                         /* defport */
239
};
240
241
const struct Curl_scheme Curl_scheme_pop3 = {
242
  "pop3",                           /* scheme */
243
#ifdef CURL_DISABLE_POP3
244
  ZERO_NULL,
245
#else
246
  &Curl_protocol_pop3,
247
#endif
248
  CURLPROTO_POP3,                   /* protocol */
249
  CURLPROTO_POP3,                   /* family */
250
  PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */
251
  PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE | PROTOPT_CONN_REUSE,
252
  PORT_POP3,                        /* defport */
253
};
254
255
const struct Curl_scheme Curl_scheme_pop3s = {
256
  "pop3s",                          /* scheme */
257
#if defined(CURL_DISABLE_POP3) || !defined(USE_SSL)
258
  ZERO_NULL,
259
#else
260
  &Curl_protocol_pop3,
261
#endif
262
  CURLPROTO_POP3S,                  /* protocol */
263
  CURLPROTO_POP3,                   /* family */
264
  PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */
265
  PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS | PROTOPT_CONN_REUSE,
266
  PORT_POP3S,                       /* defport */
267
};
268
269
const struct Curl_scheme Curl_scheme_rtsp = {
270
  "rtsp",                               /* scheme */
271
#ifdef CURL_DISABLE_RTSP
272
  ZERO_NULL,
273
#else
274
  &Curl_protocol_rtsp,
275
#endif
276
  CURLPROTO_RTSP,                       /* protocol */
277
  CURLPROTO_RTSP,                       /* family */
278
  PROTOPT_CONN_REUSE,                   /* flags */
279
  PORT_RTSP,                            /* defport */
280
};
281
282
const struct Curl_scheme Curl_scheme_sftp = {
283
  "sftp",                               /* scheme */
284
#ifndef USE_SSH
285
  NULL,
286
#else
287
  &Curl_protocol_sftp,
288
#endif
289
  CURLPROTO_SFTP,                       /* protocol */
290
  CURLPROTO_SFTP,                       /* family */
291
  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | /* flags */
292
  PROTOPT_NOURLQUERY | PROTOPT_CONN_REUSE,
293
  PORT_SSH                              /* defport */
294
};
295
296
const struct Curl_scheme Curl_scheme_scp = {
297
  "scp",                                /* scheme */
298
#ifndef USE_SSH
299
  NULL,
300
#else
301
  &Curl_protocol_scp,
302
#endif
303
  CURLPROTO_SCP,                        /* protocol */
304
  CURLPROTO_SCP,                        /* family */
305
  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | /* flags */
306
  PROTOPT_NOURLQUERY | PROTOPT_CONN_REUSE,
307
  PORT_SSH,                             /* defport */
308
};
309
310
const struct Curl_scheme Curl_scheme_smb = {
311
  "smb",                                /* scheme */
312
#if defined(CURL_ENABLE_SMB) && defined(USE_CURL_NTLM_CORE)
313
  &Curl_protocol_smb,
314
#else
315
  ZERO_NULL,
316
#endif
317
  CURLPROTO_SMB,                        /* protocol */
318
  CURLPROTO_SMB,                        /* family */
319
  PROTOPT_NONE,                         /* flags */
320
  PORT_SMB,                             /* defport */
321
};
322
323
const struct Curl_scheme Curl_scheme_smbs = {
324
  "smbs",                               /* scheme */
325
#if defined(CURL_ENABLE_SMB) && defined(USE_CURL_NTLM_CORE) && defined(USE_SSL)
326
  &Curl_protocol_smb,
327
#else
328
  ZERO_NULL,
329
#endif
330
  CURLPROTO_SMBS,                       /* protocol */
331
  CURLPROTO_SMB,                        /* family */
332
  PROTOPT_SSL,                          /* flags */
333
  PORT_SMBS,                            /* defport */
334
};
335
336
const struct Curl_scheme Curl_scheme_smtp = {
337
  "smtp",                           /* scheme */
338
#ifdef CURL_DISABLE_SMTP
339
  ZERO_NULL,
340
#else
341
  &Curl_protocol_smtp,
342
#endif
343
  CURLPROTO_SMTP,                   /* protocol */
344
  CURLPROTO_SMTP,                   /* family */
345
  PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */
346
  PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE | PROTOPT_CONN_REUSE,
347
  PORT_SMTP,                        /* defport */
348
};
349
350
const struct Curl_scheme Curl_scheme_smtps = {
351
  "smtps",                          /* scheme */
352
#if defined(CURL_DISABLE_SMTP) || !defined(USE_SSL)
353
  ZERO_NULL,
354
#else
355
  &Curl_protocol_smtp,
356
#endif
357
  CURLPROTO_SMTPS,                  /* protocol */
358
  CURLPROTO_SMTP,                   /* family */
359
  PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */
360
  PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS | PROTOPT_CONN_REUSE,
361
  PORT_SMTPS,                       /* defport */
362
};
363
364
const struct Curl_scheme Curl_scheme_telnet = {
365
  "telnet",                             /* scheme */
366
#ifdef CURL_DISABLE_TELNET
367
  ZERO_NULL,
368
#else
369
  &Curl_protocol_telnet,
370
#endif
371
  CURLPROTO_TELNET,                     /* protocol */
372
  CURLPROTO_TELNET,                     /* family */
373
  PROTOPT_NONE | PROTOPT_NOURLQUERY,    /* flags */
374
  PORT_TELNET,                          /* defport */
375
};
376
377
const struct Curl_scheme Curl_scheme_tftp = {
378
  "tftp",                               /* scheme */
379
#ifdef CURL_DISABLE_TFTP
380
  ZERO_NULL,
381
#else
382
  &Curl_protocol_tftp,
383
#endif
384
  CURLPROTO_TFTP,                       /* protocol */
385
  CURLPROTO_TFTP,                       /* family */
386
  PROTOPT_NOTCPPROXY | PROTOPT_NOURLQUERY, /* flags */
387
  PORT_TFTP,                            /* defport */
388
};
389
390
const struct Curl_scheme Curl_scheme_ws = {
391
  "ws",                                 /* scheme */
392
#if defined(CURL_DISABLE_WEBSOCKETS) || defined(CURL_DISABLE_HTTP)
393
  ZERO_NULL,
394
#else
395
  &Curl_protocol_ws,
396
#endif
397
  CURLPROTO_WS,                         /* protocol */
398
  CURLPROTO_HTTP,                       /* family */
399
  PROTOPT_CREDSPERREQUEST |             /* flags */
400
  PROTOPT_USERPWDCTRL,
401
  PORT_HTTP                             /* defport */
402
};
403
404
const struct Curl_scheme Curl_scheme_wss = {
405
  "wss",                                /* scheme */
406
#if defined(CURL_DISABLE_WEBSOCKETS) || defined(CURL_DISABLE_HTTP) || \
407
  !defined(USE_SSL)
408
  ZERO_NULL,
409
#else
410
  &Curl_protocol_ws,
411
#endif
412
  CURLPROTO_WSS,                        /* protocol */
413
  CURLPROTO_HTTP,                       /* family */
414
  PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | /* flags */
415
  PROTOPT_USERPWDCTRL,
416
  PORT_HTTPS                            /* defport */
417
};
418
419
/* Returns a struct scheme pointer if the name is a known scheme. Check the
420
   ->run struct field for non-NULL to figure out if an implementation is
421
   present. */
422
const struct Curl_scheme *Curl_getn_scheme(const char *scheme, size_t len)
423
0
{
424
  /* table generated by schemetable.c:
425
     1. gcc schemetable.c && ./a.out
426
     2. check how small the table gets
427
     3. tweak the hash algorithm, then rerun from 1
428
     4. when the table is good enough
429
     5. copy the table into this source code
430
     6. make sure this function uses the same hash function that worked for
431
     schemetable.c
432
     */
433
0
  static const struct Curl_scheme * const all_schemes[47] = {
434
0
    &Curl_scheme_mqtt,
435
0
    &Curl_scheme_smtp,
436
0
    &Curl_scheme_tftp,
437
0
    &Curl_scheme_imap, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
438
0
    &Curl_scheme_ldaps,
439
0
    &Curl_scheme_dict, NULL,
440
0
    &Curl_scheme_file, NULL,
441
0
    &Curl_scheme_pop3s,
442
0
    &Curl_scheme_ftp,
443
0
    &Curl_scheme_scp,
444
0
    &Curl_scheme_mqtts,
445
0
    &Curl_scheme_imaps,
446
0
    &Curl_scheme_ldap,
447
0
    &Curl_scheme_http,
448
0
    &Curl_scheme_smb, NULL, NULL,
449
0
    &Curl_scheme_telnet,
450
0
    &Curl_scheme_https,
451
0
    &Curl_scheme_gopher,
452
0
    &Curl_scheme_rtsp, NULL, NULL,
453
0
    &Curl_scheme_wss, NULL,
454
0
    &Curl_scheme_gophers,
455
0
    &Curl_scheme_smtps,
456
0
    &Curl_scheme_pop3,
457
0
    &Curl_scheme_ws, NULL, NULL,
458
0
    &Curl_scheme_sftp,
459
0
    &Curl_scheme_ftps, NULL,
460
0
    &Curl_scheme_smbs, NULL,
461
0
  };
462
463
0
  if(len && (len <= 7)) {
464
0
    const char *s = scheme;
465
0
    size_t l = len;
466
0
    const struct Curl_scheme *h;
467
0
    unsigned int c = 792;
468
0
    while(l) {
469
0
      c <<= 4;
470
0
      c += (unsigned int)Curl_raw_tolower(*s);
471
0
      s++;
472
0
      l--;
473
0
    }
474
475
0
    h = all_schemes[c % 47];
476
0
    if(h && curl_strnequal(scheme, h->name, len) && !h->name[len])
477
0
      return h;
478
0
  }
479
0
  return NULL;
480
0
}
481
482
const struct Curl_scheme *Curl_get_scheme(const char *scheme)
483
0
{
484
0
  return Curl_getn_scheme(scheme, strlen(scheme));
485
0
}