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 | | PROTOPT_HTTP_PROXY_TUNNEL, |
158 | | PORT_HTTPS, /* defport */ |
159 | | }; |
160 | | |
161 | | const struct Curl_scheme Curl_scheme_imap = { |
162 | | "imap", /* scheme */ |
163 | | #ifdef CURL_DISABLE_IMAP |
164 | | ZERO_NULL, |
165 | | #else |
166 | | &Curl_protocol_imap, |
167 | | #endif |
168 | | CURLPROTO_IMAP, /* protocol */ |
169 | | CURLPROTO_IMAP, /* family */ |
170 | | PROTOPT_CLOSEACTION | /* flags */ |
171 | | PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE | |
172 | | PROTOPT_CONN_REUSE, |
173 | | PORT_IMAP, /* defport */ |
174 | | }; |
175 | | |
176 | | const struct Curl_scheme Curl_scheme_imaps = { |
177 | | "imaps", /* scheme */ |
178 | | #if defined(CURL_DISABLE_IMAP) || !defined(USE_SSL) |
179 | | ZERO_NULL, |
180 | | #else |
181 | | &Curl_protocol_imap, |
182 | | #endif |
183 | | CURLPROTO_IMAPS, /* protocol */ |
184 | | CURLPROTO_IMAP, /* family */ |
185 | | PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */ |
186 | | PROTOPT_URLOPTIONS | PROTOPT_CONN_REUSE, |
187 | | PORT_IMAPS, /* defport */ |
188 | | }; |
189 | | |
190 | | const struct Curl_scheme Curl_scheme_ldap = { |
191 | | "ldap", /* scheme */ |
192 | | #ifdef CURL_DISABLE_LDAP |
193 | | ZERO_NULL, |
194 | | #else |
195 | | &Curl_protocol_ldap, |
196 | | #endif |
197 | | CURLPROTO_LDAP, /* protocol */ |
198 | | CURLPROTO_LDAP, /* family */ |
199 | | PROTOPT_SSL_REUSE, /* flags */ |
200 | | PORT_LDAP, /* defport */ |
201 | | }; |
202 | | |
203 | | const struct Curl_scheme Curl_scheme_ldaps = { |
204 | | "ldaps", /* scheme */ |
205 | | #if defined(CURL_DISABLE_LDAP) || !defined(HAVE_LDAP_SSL) |
206 | | ZERO_NULL, |
207 | | #else |
208 | | &Curl_protocol_ldap, |
209 | | #endif |
210 | | CURLPROTO_LDAPS, /* protocol */ |
211 | | CURLPROTO_LDAP, /* family */ |
212 | | PROTOPT_SSL, /* flags */ |
213 | | PORT_LDAPS, /* defport */ |
214 | | }; |
215 | | |
216 | | const struct Curl_scheme Curl_scheme_mqtt = { |
217 | | "mqtt", /* scheme */ |
218 | | #ifdef CURL_DISABLE_MQTT |
219 | | ZERO_NULL, |
220 | | #else |
221 | | &Curl_protocol_mqtt, |
222 | | #endif |
223 | | CURLPROTO_MQTT, /* protocol */ |
224 | | CURLPROTO_MQTT, /* family */ |
225 | | PROTOPT_NONE, /* flags */ |
226 | | PORT_MQTT, /* defport */ |
227 | | }; |
228 | | |
229 | | const struct Curl_scheme Curl_scheme_mqtts = { |
230 | | "mqtts", /* scheme */ |
231 | | #if defined(CURL_DISABLE_MQTT) || !defined(USE_SSL) |
232 | | ZERO_NULL, |
233 | | #else |
234 | | &Curl_protocol_mqtts, |
235 | | #endif |
236 | | CURLPROTO_MQTTS, /* protocol */ |
237 | | CURLPROTO_MQTT, /* family */ |
238 | | PROTOPT_SSL, /* flags */ |
239 | | PORT_MQTTS, /* defport */ |
240 | | }; |
241 | | |
242 | | const struct Curl_scheme Curl_scheme_pop3 = { |
243 | | "pop3", /* scheme */ |
244 | | #ifdef CURL_DISABLE_POP3 |
245 | | ZERO_NULL, |
246 | | #else |
247 | | &Curl_protocol_pop3, |
248 | | #endif |
249 | | CURLPROTO_POP3, /* protocol */ |
250 | | CURLPROTO_POP3, /* family */ |
251 | | PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */ |
252 | | PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE | PROTOPT_CONN_REUSE, |
253 | | PORT_POP3, /* defport */ |
254 | | }; |
255 | | |
256 | | const struct Curl_scheme Curl_scheme_pop3s = { |
257 | | "pop3s", /* scheme */ |
258 | | #if defined(CURL_DISABLE_POP3) || !defined(USE_SSL) |
259 | | ZERO_NULL, |
260 | | #else |
261 | | &Curl_protocol_pop3, |
262 | | #endif |
263 | | CURLPROTO_POP3S, /* protocol */ |
264 | | CURLPROTO_POP3, /* family */ |
265 | | PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */ |
266 | | PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS | PROTOPT_CONN_REUSE, |
267 | | PORT_POP3S, /* defport */ |
268 | | }; |
269 | | |
270 | | const struct Curl_scheme Curl_scheme_rtsp = { |
271 | | "rtsp", /* scheme */ |
272 | | #ifdef CURL_DISABLE_RTSP |
273 | | ZERO_NULL, |
274 | | #else |
275 | | &Curl_protocol_rtsp, |
276 | | #endif |
277 | | CURLPROTO_RTSP, /* protocol */ |
278 | | CURLPROTO_RTSP, /* family */ |
279 | | PROTOPT_CONN_REUSE, /* flags */ |
280 | | PORT_RTSP, /* defport */ |
281 | | }; |
282 | | |
283 | | const struct Curl_scheme Curl_scheme_sftp = { |
284 | | "sftp", /* scheme */ |
285 | | #ifndef USE_SSH |
286 | | NULL, |
287 | | #else |
288 | | &Curl_protocol_sftp, |
289 | | #endif |
290 | | CURLPROTO_SFTP, /* protocol */ |
291 | | CURLPROTO_SFTP, /* family */ |
292 | | PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | /* flags */ |
293 | | PROTOPT_NOURLQUERY | PROTOPT_CONN_REUSE, |
294 | | PORT_SSH /* defport */ |
295 | | }; |
296 | | |
297 | | const struct Curl_scheme Curl_scheme_scp = { |
298 | | "scp", /* scheme */ |
299 | | #ifndef USE_SSH |
300 | | NULL, |
301 | | #else |
302 | | &Curl_protocol_scp, |
303 | | #endif |
304 | | CURLPROTO_SCP, /* protocol */ |
305 | | CURLPROTO_SCP, /* family */ |
306 | | PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | /* flags */ |
307 | | PROTOPT_NOURLQUERY | PROTOPT_CONN_REUSE, |
308 | | PORT_SSH, /* defport */ |
309 | | }; |
310 | | |
311 | | const struct Curl_scheme Curl_scheme_smb = { |
312 | | "smb", /* scheme */ |
313 | | #if defined(CURL_ENABLE_SMB) && defined(USE_CURL_NTLM_CORE) |
314 | | &Curl_protocol_smb, |
315 | | #else |
316 | | ZERO_NULL, |
317 | | #endif |
318 | | CURLPROTO_SMB, /* protocol */ |
319 | | CURLPROTO_SMB, /* family */ |
320 | | PROTOPT_NONE, /* flags */ |
321 | | PORT_SMB, /* defport */ |
322 | | }; |
323 | | |
324 | | const struct Curl_scheme Curl_scheme_smbs = { |
325 | | "smbs", /* scheme */ |
326 | | #if defined(CURL_ENABLE_SMB) && defined(USE_CURL_NTLM_CORE) && defined(USE_SSL) |
327 | | &Curl_protocol_smb, |
328 | | #else |
329 | | ZERO_NULL, |
330 | | #endif |
331 | | CURLPROTO_SMBS, /* protocol */ |
332 | | CURLPROTO_SMB, /* family */ |
333 | | PROTOPT_SSL, /* flags */ |
334 | | PORT_SMBS, /* defport */ |
335 | | }; |
336 | | |
337 | | const struct Curl_scheme Curl_scheme_smtp = { |
338 | | "smtp", /* scheme */ |
339 | | #ifdef CURL_DISABLE_SMTP |
340 | | ZERO_NULL, |
341 | | #else |
342 | | &Curl_protocol_smtp, |
343 | | #endif |
344 | | CURLPROTO_SMTP, /* protocol */ |
345 | | CURLPROTO_SMTP, /* family */ |
346 | | PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */ |
347 | | PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE | PROTOPT_CONN_REUSE, |
348 | | PORT_SMTP, /* defport */ |
349 | | }; |
350 | | |
351 | | const struct Curl_scheme Curl_scheme_smtps = { |
352 | | "smtps", /* scheme */ |
353 | | #if defined(CURL_DISABLE_SMTP) || !defined(USE_SSL) |
354 | | ZERO_NULL, |
355 | | #else |
356 | | &Curl_protocol_smtp, |
357 | | #endif |
358 | | CURLPROTO_SMTPS, /* protocol */ |
359 | | CURLPROTO_SMTP, /* family */ |
360 | | PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */ |
361 | | PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS | PROTOPT_CONN_REUSE, |
362 | | PORT_SMTPS, /* defport */ |
363 | | }; |
364 | | |
365 | | const struct Curl_scheme Curl_scheme_socks = { |
366 | | "socks", /* scheme */ |
367 | | ZERO_NULL, |
368 | | CURLPROTO_SOCKS, /* protocol */ |
369 | | CURLPROTO_SOCKS, /* family */ |
370 | | PROTOPT_NO_TRANSFER, /* flags */ |
371 | | PORT_SOCKS, /* defport */ |
372 | | }; |
373 | | |
374 | | const struct Curl_scheme Curl_scheme_socks4 = { |
375 | | "socks4", /* scheme */ |
376 | | ZERO_NULL, |
377 | | CURLPROTO_SOCKS, /* protocol */ |
378 | | CURLPROTO_SOCKS, /* family */ |
379 | | PROTOPT_NO_TRANSFER, /* flags */ |
380 | | PORT_SOCKS, /* defport */ |
381 | | }; |
382 | | |
383 | | const struct Curl_scheme Curl_scheme_socks4a = { |
384 | | "socks4a", /* scheme */ |
385 | | ZERO_NULL, |
386 | | CURLPROTO_SOCKS, /* protocol */ |
387 | | CURLPROTO_SOCKS, /* family */ |
388 | | PROTOPT_NO_TRANSFER, /* flags */ |
389 | | PORT_SOCKS, /* defport */ |
390 | | }; |
391 | | |
392 | | const struct Curl_scheme Curl_scheme_socks5 = { |
393 | | "socks5", /* scheme */ |
394 | | ZERO_NULL, |
395 | | CURLPROTO_SOCKS, /* protocol */ |
396 | | CURLPROTO_SOCKS, /* family */ |
397 | | PROTOPT_NO_TRANSFER, /* flags */ |
398 | | PORT_SOCKS, /* defport */ |
399 | | }; |
400 | | |
401 | | const struct Curl_scheme Curl_scheme_socks5h = { |
402 | | "socks5h", /* scheme */ |
403 | | ZERO_NULL, |
404 | | CURLPROTO_SOCKS, /* protocol */ |
405 | | CURLPROTO_SOCKS, /* family */ |
406 | | PROTOPT_NO_TRANSFER, /* flags */ |
407 | | PORT_SOCKS, /* defport */ |
408 | | }; |
409 | | |
410 | | const struct Curl_scheme Curl_scheme_telnet = { |
411 | | "telnet", /* scheme */ |
412 | | #ifdef CURL_DISABLE_TELNET |
413 | | ZERO_NULL, |
414 | | #else |
415 | | &Curl_protocol_telnet, |
416 | | #endif |
417 | | CURLPROTO_TELNET, /* protocol */ |
418 | | CURLPROTO_TELNET, /* family */ |
419 | | PROTOPT_NONE | PROTOPT_NOURLQUERY, /* flags */ |
420 | | PORT_TELNET, /* defport */ |
421 | | }; |
422 | | |
423 | | const struct Curl_scheme Curl_scheme_tftp = { |
424 | | "tftp", /* scheme */ |
425 | | #ifdef CURL_DISABLE_TFTP |
426 | | ZERO_NULL, |
427 | | #else |
428 | | &Curl_protocol_tftp, |
429 | | #endif |
430 | | CURLPROTO_TFTP, /* protocol */ |
431 | | CURLPROTO_TFTP, /* family */ |
432 | | PROTOPT_NOTCPPROXY | PROTOPT_NOURLQUERY, /* flags */ |
433 | | PORT_TFTP, /* defport */ |
434 | | }; |
435 | | |
436 | | const struct Curl_scheme Curl_scheme_ws = { |
437 | | "ws", /* scheme */ |
438 | | #if defined(CURL_DISABLE_WEBSOCKETS) || defined(CURL_DISABLE_HTTP) |
439 | | ZERO_NULL, |
440 | | #else |
441 | | &Curl_protocol_ws, |
442 | | #endif |
443 | | CURLPROTO_WS, /* protocol */ |
444 | | CURLPROTO_HTTP, /* family */ |
445 | | PROTOPT_CREDSPERREQUEST | /* flags */ |
446 | | PROTOPT_USERPWDCTRL | PROTOPT_HTTP_PROXY_TUNNEL, |
447 | | PORT_HTTP /* defport */ |
448 | | }; |
449 | | |
450 | | const struct Curl_scheme Curl_scheme_wss = { |
451 | | "wss", /* scheme */ |
452 | | #if defined(CURL_DISABLE_WEBSOCKETS) || defined(CURL_DISABLE_HTTP) || \ |
453 | | !defined(USE_SSL) |
454 | | ZERO_NULL, |
455 | | #else |
456 | | &Curl_protocol_ws, |
457 | | #endif |
458 | | CURLPROTO_WSS, /* protocol */ |
459 | | CURLPROTO_HTTP, /* family */ |
460 | | PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | /* flags */ |
461 | | PROTOPT_USERPWDCTRL | PROTOPT_HTTP_PROXY_TUNNEL, |
462 | | PORT_HTTPS /* defport */ |
463 | | }; |
464 | | |
465 | | /* Returns a struct scheme pointer if the name is a known scheme. Check the |
466 | | ->run struct field for non-NULL to figure out if an implementation is |
467 | | present. */ |
468 | | const struct Curl_scheme *Curl_getn_scheme(const char *scheme, size_t len) |
469 | 0 | { |
470 | | /* table generated by schemetable.c: |
471 | | 1. gcc schemetable.c && ./a.out |
472 | | 2. check how small the table gets |
473 | | 3. tweak the hash algorithm, then rerun from 1 |
474 | | 4. when the table is good enough |
475 | | 5. copy the table into this source code |
476 | | 6. make sure this function uses the same hash function that worked for |
477 | | schemetable.c |
478 | | */ |
479 | 0 | static const struct Curl_scheme * const all_schemes[59] = { NULL, |
480 | 0 | &Curl_scheme_pop3, NULL, |
481 | 0 | &Curl_scheme_smtps, |
482 | 0 | &Curl_scheme_socks, |
483 | 0 | &Curl_scheme_socks4, |
484 | 0 | &Curl_scheme_socks5, NULL, NULL, |
485 | 0 | &Curl_scheme_gophers, |
486 | 0 | &Curl_scheme_ws, |
487 | 0 | &Curl_scheme_sftp, |
488 | 0 | &Curl_scheme_socks4a, |
489 | 0 | &Curl_scheme_scp, |
490 | 0 | &Curl_scheme_rtsp, |
491 | 0 | &Curl_scheme_dict, NULL, NULL, |
492 | 0 | &Curl_scheme_gopher, NULL, NULL, NULL, |
493 | 0 | &Curl_scheme_wss, NULL, |
494 | 0 | &Curl_scheme_smb, NULL, |
495 | 0 | &Curl_scheme_ldap, |
496 | 0 | &Curl_scheme_ldaps, |
497 | 0 | &Curl_scheme_imap, NULL, NULL, NULL, |
498 | 0 | &Curl_scheme_imaps, |
499 | 0 | &Curl_scheme_https, |
500 | 0 | &Curl_scheme_tftp, |
501 | 0 | &Curl_scheme_telnet, NULL, NULL, NULL, |
502 | 0 | &Curl_scheme_file, |
503 | 0 | &Curl_scheme_smtp, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
504 | 0 | &Curl_scheme_ftp, |
505 | 0 | &Curl_scheme_mqtt, NULL, |
506 | 0 | &Curl_scheme_socks5h, |
507 | 0 | &Curl_scheme_http, |
508 | 0 | &Curl_scheme_pop3s, NULL, |
509 | 0 | &Curl_scheme_mqtts, NULL, |
510 | 0 | &Curl_scheme_smbs, |
511 | 0 | &Curl_scheme_ftps, |
512 | 0 | }; |
513 | |
|
514 | 0 | if(len && (len <= 7)) { |
515 | 0 | const char *s = scheme; |
516 | 0 | size_t l = len; |
517 | 0 | const struct Curl_scheme *h; |
518 | 0 | unsigned int c = 443; |
519 | 0 | while(l) { |
520 | 0 | c <<= 5; |
521 | 0 | c += (unsigned int)Curl_raw_tolower(*s); |
522 | 0 | s++; |
523 | 0 | l--; |
524 | 0 | } |
525 | |
|
526 | 0 | h = all_schemes[c % 59]; |
527 | 0 | if(h && curl_strnequal(scheme, h->name, len) && !h->name[len]) |
528 | 0 | return h; |
529 | 0 | } |
530 | 0 | return NULL; |
531 | 0 | } |
532 | | |
533 | | const struct Curl_scheme *Curl_get_scheme(const char *scheme) |
534 | 0 | { |
535 | 0 | return Curl_getn_scheme(scheme, strlen(scheme)); |
536 | 0 | } |