]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
protocol source, all about protocols and uri schemes
authorStefan Eissing <stefan@eissing.org>
Thu, 12 Mar 2026 12:11:38 +0000 (13:11 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 16 Mar 2026 07:39:02 +0000 (08:39 +0100)
Add protocol.h and protocol.c containing all about libcurl's
known URI schemes and their protocol handlers (so they exist).

Moves the scheme definitions from the various sources files into
protocol.c. Schemes are known and used, even of the protocol
handler is not build or just not implemented at all.

Closes #20906

42 files changed:
lib/Makefile.inc
lib/curl_ldap.h
lib/curl_rtmp.c
lib/curl_rtmp.h
lib/dict.c
lib/dict.h
lib/file.c
lib/file.h
lib/ftp-int.h [new file with mode: 0644]
lib/ftp.c
lib/ftp.h
lib/ftplistparser.c
lib/gopher.c
lib/gopher.h
lib/http.c
lib/http.h
lib/imap.c
lib/imap.h
lib/ldap.c
lib/mqtt.c
lib/mqtt.h
lib/pop3.c
lib/pop3.h
lib/protocol.c [new file with mode: 0644]
lib/protocol.h [new file with mode: 0644]
lib/rtsp.c
lib/rtsp.h
lib/smb.c
lib/smb.h
lib/smtp.c
lib/smtp.h
lib/telnet.c
lib/telnet.h
lib/tftp.c
lib/tftp.h
lib/url.c
lib/url.h
lib/urldata.h
lib/vssh/ssh.h
lib/vssh/vssh.c
lib/ws.c
lib/ws.h

index 84b4e5425b90d48b8527e10d3d907d9280463e17..1b75dc42edc7663d30f98ee556de8cc633137fb7 100644 (file)
@@ -236,6 +236,7 @@ LIB_CFILES =         \
   pingpong.c         \
   pop3.c             \
   progress.c         \
+  protocol.c         \
   psl.c              \
   rand.c             \
   ratelimit.c        \
@@ -327,6 +328,7 @@ LIB_HFILES =         \
   fileinfo.h         \
   formdata.h         \
   ftp.h              \
+  ftp-int.h          \
   ftplistparser.h    \
   functypes.h        \
   getinfo.h          \
@@ -362,6 +364,7 @@ LIB_HFILES =         \
   pingpong.h         \
   pop3.h             \
   progress.h         \
+  protocol.h         \
   psl.h              \
   rand.h             \
   ratelimit.h        \
index 7c1e1c4e9a96f821737592ccb41ebc885c38b27f..0ccc1289e2f221963e4e107a25fae8e85a888d3c 100644 (file)
@@ -25,9 +25,6 @@
  ***************************************************************************/
 extern const struct Curl_protocol Curl_protocol_ldap;
 
-extern const struct Curl_scheme Curl_scheme_ldap;
-extern const struct Curl_scheme Curl_scheme_ldaps;
-
 void Curl_ldap_version(char *buf, size_t bufsz);
 
 #endif /* HEADER_CURL_LDAP_H */
index 7c152e787c86be1a0eb68a6ba8150d11f93a1a07..7e3c0bfa2102fb2d09f6547bc617ffa9d6fdada3 100644 (file)
@@ -225,7 +225,7 @@ void Curl_rtmp_version(char *version, size_t len)
  * RTMP protocol handler.h, based on https://rtmpdump.mplayerhq.hu/
  */
 
-static const struct Curl_protocol Curl_protocol_rtmp = {
+const struct Curl_protocol Curl_protocol_rtmp = {
   rtmp_setup_connection,                /* setup_connection */
   rtmp_do,                              /* do_it */
   rtmp_done,                            /* done */
@@ -246,81 +246,3 @@ static const struct Curl_protocol Curl_protocol_rtmp = {
 };
 
 #endif /* USE_LIBRTMP */
-
-const struct Curl_scheme Curl_scheme_rtmp = {
-  "rtmp",                               /* scheme */
-#ifndef USE_LIBRTMP
-  ZERO_NULL,
-#else
-  &Curl_protocol_rtmp,
-#endif
-  CURLPROTO_RTMP,                       /* protocol */
-  CURLPROTO_RTMP,                       /* family */
-  PROTOPT_NONE,                         /* flags */
-  PORT_RTMP,                            /* defport */
-};
-
-const struct Curl_scheme Curl_scheme_rtmpt = {
-  "rtmpt",                              /* scheme */
-#ifndef USE_LIBRTMP
-  ZERO_NULL,
-#else
-  &Curl_protocol_rtmp,
-#endif
-  CURLPROTO_RTMPT,                      /* protocol */
-  CURLPROTO_RTMPT,                      /* family */
-  PROTOPT_NONE,                         /* flags */
-  PORT_RTMPT,                           /* defport */
-};
-
-const struct Curl_scheme Curl_scheme_rtmpe = {
-  "rtmpe",                              /* scheme */
-#ifndef USE_LIBRTMP
-  ZERO_NULL,
-#else
-  &Curl_protocol_rtmp,
-#endif
-  CURLPROTO_RTMPE,                      /* protocol */
-  CURLPROTO_RTMPE,                      /* family */
-  PROTOPT_NONE,                         /* flags */
-  PORT_RTMP,                            /* defport */
-};
-
-const struct Curl_scheme Curl_scheme_rtmpte = {
-  "rtmpte",                             /* scheme */
-#ifndef USE_LIBRTMP
-  ZERO_NULL,
-#else
-  &Curl_protocol_rtmp,
-#endif
-  CURLPROTO_RTMPTE,                     /* protocol */
-  CURLPROTO_RTMPTE,                     /* family */
-  PROTOPT_NONE,                         /* flags */
-  PORT_RTMPT,                           /* defport */
-};
-
-const struct Curl_scheme Curl_scheme_rtmps = {
-  "rtmps",                              /* scheme */
-#ifndef USE_LIBRTMP
-  ZERO_NULL,
-#else
-  &Curl_protocol_rtmp,
-#endif
-  CURLPROTO_RTMPS,                      /* protocol */
-  CURLPROTO_RTMP,                       /* family */
-  PROTOPT_NONE,                         /* flags */
-  PORT_RTMPS,                           /* defport */
-};
-
-const struct Curl_scheme Curl_scheme_rtmpts = {
-  "rtmpts",                             /* scheme */
-#ifndef USE_LIBRTMP
-  ZERO_NULL,
-#else
-  &Curl_protocol_rtmp,
-#endif
-  CURLPROTO_RTMPTS,                     /* protocol */
-  CURLPROTO_RTMPT,                      /* family */
-  PROTOPT_NONE,                         /* flags */
-  PORT_RTMPS,                           /* defport */
-};
index e57d20c33a838cd804d2fd4f1327ceccc5d5c932..5c2f8180615891a5d42626f79ec8631d44cf9f8d 100644 (file)
  * SPDX-License-Identifier: curl
  *
  ***************************************************************************/
-extern const struct Curl_scheme Curl_scheme_rtmp;
-extern const struct Curl_scheme Curl_scheme_rtmpt;
-extern const struct Curl_scheme Curl_scheme_rtmpe;
-extern const struct Curl_scheme Curl_scheme_rtmpte;
-extern const struct Curl_scheme Curl_scheme_rtmps;
-extern const struct Curl_scheme Curl_scheme_rtmpts;
 #ifdef USE_LIBRTMP
+extern const struct Curl_protocol Curl_protocol_rtmp;
 void Curl_rtmp_version(char *version, size_t len);
 #endif
 
index f99feff45bb4699380c6398381ed0c5bee62bd8a..433d1553ec243dbda3c279c7aacefcf9f95df1c2 100644 (file)
@@ -275,7 +275,7 @@ error:
 /*
  * DICT protocol
  */
-static const struct Curl_protocol Curl_protocol_dict = {
+const struct Curl_protocol Curl_protocol_dict = {
   ZERO_NULL,                            /* setup_connection */
   dict_do,                              /* do_it */
   ZERO_NULL,                            /* done */
@@ -296,19 +296,3 @@ static const struct Curl_protocol Curl_protocol_dict = {
 };
 
 #endif /* CURL_DISABLE_DICT */
-
-/*
- * DICT protocol handler.
- */
-const struct Curl_scheme Curl_scheme_dict = {
-  "dict",                               /* scheme */
-#ifdef CURL_DISABLE_DICT
-  ZERO_NULL,
-#else
-  &Curl_protocol_dict,
-#endif
-  CURLPROTO_DICT,                       /* protocol */
-  CURLPROTO_DICT,                       /* family */
-  PROTOPT_NONE | PROTOPT_NOURLQUERY,    /* flags */
-  PORT_DICT,                            /* defport */
-};
index b5d6947d238622a3fb7a41ca132fcd4b1334d841..5bdfcff8162a5374b48f9c6b9283129aa44c53c8 100644 (file)
@@ -23,6 +23,8 @@
  * SPDX-License-Identifier: curl
  *
  ***************************************************************************/
-extern const struct Curl_scheme Curl_scheme_dict;
+#ifndef CURL_DISABLE_DICT
+extern const struct Curl_protocol Curl_protocol_dict;
+#endif
 
 #endif /* HEADER_CURL_DICT_H */
index 6bc3b440e0f15a418a44807dbd422a3491a70027..29cf743e09c6a94637f0d9c66aca2a723a1621f4 100644 (file)
@@ -598,7 +598,7 @@ out:
   return result;
 }
 
-static const struct Curl_protocol Curl_protocol_file = {
+const struct Curl_protocol Curl_protocol_file = {
   file_setup_connection,                /* setup_connection */
   file_do,                              /* do_it */
   file_done,                            /* done */
@@ -619,19 +619,3 @@ static const struct Curl_protocol Curl_protocol_file = {
 };
 
 #endif
-
-/*
- * FILE scheme handler.
- */
-const struct Curl_scheme Curl_scheme_file = {
-  "file",                               /* scheme */
-#ifdef CURL_DISABLE_FILE
-  ZERO_NULL,
-#else
-  &Curl_protocol_file,
-#endif
-  CURLPROTO_FILE,                       /* protocol */
-  CURLPROTO_FILE,                       /* family */
-  PROTOPT_NONETWORK | PROTOPT_NOURLQUERY, /* flags */
-  0                                     /* defport */
-};
index a3065441aee2b735974e113e7647c669f2dd2939..0aa411b19fcd41ba53904c831868dc6bef1928dc 100644 (file)
@@ -23,6 +23,8 @@
  * SPDX-License-Identifier: curl
  *
  ***************************************************************************/
-extern const struct Curl_scheme Curl_scheme_file;
+#ifndef CURL_DISABLE_FILE
+extern const struct Curl_protocol Curl_protocol_file;
+#endif
 
 #endif /* HEADER_CURL_FILE_H */
diff --git a/lib/ftp-int.h b/lib/ftp-int.h
new file mode 100644 (file)
index 0000000..68d26f3
--- /dev/null
@@ -0,0 +1,160 @@
+#ifndef HEADER_CURL_FTP_INT_H
+#define HEADER_CURL_FTP_INT_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#include "pingpong.h"
+
+#ifndef CURL_DISABLE_FTP
+
+/****************************************************************************
+ * FTP unique setup
+ ***************************************************************************/
+enum {
+  FTP_STOP,    /* do nothing state, stops the state machine */
+  FTP_WAIT220, /* waiting for the initial 220 response immediately after
+                  a connect */
+  FTP_AUTH,
+  FTP_USER,
+  FTP_PASS,
+  FTP_ACCT,
+  FTP_PBSZ,
+  FTP_PROT,
+  FTP_CCC,
+  FTP_PWD,
+  FTP_SYST,
+  FTP_NAMEFMT,
+  FTP_QUOTE, /* waiting for a response to a command sent in a quote list */
+  FTP_RETR_PREQUOTE,
+  FTP_STOR_PREQUOTE,
+  FTP_LIST_PREQUOTE,
+  FTP_POSTQUOTE,
+  FTP_CWD,  /* change directory */
+  FTP_MKD,  /* if the directory did not exist */
+  FTP_MDTM, /* to figure out the datestamp */
+  FTP_TYPE, /* to set type when doing a head-like request */
+  FTP_LIST_TYPE, /* set type when about to do a directory list */
+  FTP_RETR_LIST_TYPE,
+  FTP_RETR_TYPE, /* set type when about to RETR a file */
+  FTP_STOR_TYPE, /* set type when about to STOR a file */
+  FTP_SIZE, /* get the remote file's size for head-like request */
+  FTP_RETR_SIZE, /* get the remote file's size for RETR */
+  FTP_STOR_SIZE, /* get the size for STOR */
+  FTP_REST, /* when used to check if the server supports it in head-like */
+  FTP_RETR_REST, /* when asking for "resume" in for RETR */
+  FTP_PORT, /* generic state for PORT, LPRT and EPRT, check count1 */
+  FTP_PRET, /* generic state for PRET RETR, PRET STOR and PRET LIST/NLST */
+  FTP_PASV, /* generic state for PASV and EPSV, check count1 */
+  FTP_LIST, /* generic state for LIST, NLST or a custom list command */
+  FTP_RETR,
+  FTP_STOR, /* generic state for STOR and APPE */
+  FTP_QUIT,
+  FTP_LAST  /* never used */
+};
+typedef unsigned char ftpstate; /* use the enum values */
+
+struct ftp_parselist_data; /* defined later in ftplistparser.c */
+
+struct ftp_wc {
+  struct ftp_parselist_data *parser;
+
+  struct {
+    curl_write_callback write_function;
+    FILE *file_descriptor;
+  } backup;
+};
+
+/* This FTP struct is used in the Curl_easy. All FTP data that is
+   connection-oriented must be in FTP_conn to properly deal with the fact that
+   perhaps the Curl_easy is changed between the times the connection is
+   used. */
+struct FTP {
+  char *path;    /* points to the urlpieces struct field */
+  char *pathalloc; /* if non-NULL a pointer to an allocated path */
+
+  /* transfer a file/body or not, done as a typedefed enum to make debuggers
+     display the full symbol and not the numerical value */
+  curl_pp_transfer transfer;
+  curl_off_t downloadsize;
+};
+
+/* one struct entry for each path component (of 'rawpath') */
+struct pathcomp {
+  int start; /* start column */
+  int len;   /* length in bytes */
+};
+
+/* ftp_conn is used for struct connection-oriented data in the connectdata
+   struct */
+struct ftp_conn {
+  struct pingpong pp;
+  char *account;
+  char *alternative_to_user;
+  char *entrypath; /* the PWD reply when we logged on */
+  const char *file; /* url-decoded filename (or path), points into rawpath */
+  char *rawpath; /* URL decoded, allocated, version of the path */
+  struct pathcomp *dirs; /* allocated array for path components */
+  char *prevpath;   /* url-decoded conn->path from the previous transfer */
+  char transfertype; /* set by ftp_transfertype for use by Curl_client_write()a
+                        and others (A/I or zero) */
+  char *server_os;     /* The target server operating system. */
+  curl_off_t known_filesize; /* file size is different from -1, if wildcard
+                                LIST parsing was done and wc_statemach set
+                                it */
+  int count1; /* general purpose counter for the state machine */
+  int count2; /* general purpose counter for the state machine */
+  int count3; /* general purpose counter for the state machine */
+  unsigned short dirdepth;  /* number of entries used in the 'dirs' array,
+                               < FTP_MAX_DIR_DEPTH */
+  unsigned short cwdcount;  /* number of CWD commands issued,
+                               < FTP_MAX_DIR_DEPTH */
+  unsigned char state; /* (ftpstate enum) always use ftp.c:state() to change
+                          state! */
+  unsigned char use_ssl;   /* if AUTH TLS is to be attempted etc, for FTP or
+                              IMAP or POP3 or others! (type: curl_usessl)*/
+  unsigned char ccc;       /* ccc level for this connection */
+  BIT(ftp_trying_alternative);
+  BIT(dont_check);  /* Set to TRUE to prevent the final (post-transfer)
+                       file size and 226/250 status check. It should still
+                       read the line, ignore the result. */
+  BIT(ctl_valid);   /* Tells Curl_ftp_quit() whether or not to do anything. If
+                       the connection has timed out or been closed, this
+                       should be FALSE when it gets to Curl_ftp_quit() */
+  BIT(cwddone);     /* if it has been determined that the proper CWD combo
+                       already has been done */
+  BIT(cwdfail);     /* set TRUE if a CWD command fails, as then we must prevent
+                       caching the current directory */
+  BIT(wait_data_conn); /* this is set TRUE if data connection is waited */
+  BIT(shutdown);    /* connection is being shutdown, e.g. QUIT */
+};
+
+/* meta key for storing `struct FTP` as easy meta data */
+#define CURL_META_FTP_EASY   "meta:proto:ftp:easy"
+/* meta key for storing `struct ftp_conn` as connection meta data */
+#define CURL_META_FTP_CONN   "meta:proto:ftp:conn"
+
+#endif /* CURL_DISABLE_FTP */
+
+#endif /* HEADER_CURL_FTP_INT_H */
index 2fbf53d4e96b2035bf43908632366062b24aa28a..4d9c2bcb714594acd49e89a3445e4210cb9e4cf9 100644 (file)
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -49,6 +49,7 @@
 #include "transfer.h"
 #include "escape.h"
 #include "ftp.h"
+#include "ftp-int.h"
 #include "ftplistparser.h"
 #include "curl_range.h"
 #include "strcase.h"
@@ -4456,7 +4457,7 @@ bool ftp_conns_match(struct connectdata *needle, struct connectdata *conn)
 /*
  * FTP protocol.
  */
-static const struct Curl_protocol Curl_protocol_ftp = {
+const struct Curl_protocol Curl_protocol_ftp = {
   ftp_setup_connection,            /* setup_connection */
   ftp_do,                          /* do_it */
   ftp_done,                        /* done */
@@ -4477,40 +4478,3 @@ static const struct Curl_protocol Curl_protocol_ftp = {
 };
 
 #endif /* CURL_DISABLE_FTP */
-
-/*
- * FTP protocol handler.
- */
-const struct Curl_scheme Curl_scheme_ftp = {
-  "ftp",                           /* scheme */
-#ifdef CURL_DISABLE_FTP
-  ZERO_NULL,
-#else
-  &Curl_protocol_ftp,
-#endif
-  CURLPROTO_FTP,                   /* protocol */
-  CURLPROTO_FTP,                   /* family */
-  PROTOPT_DUAL | PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD |
-  PROTOPT_NOURLQUERY | PROTOPT_PROXY_AS_HTTP |
-  PROTOPT_WILDCARD | PROTOPT_SSL_REUSE |
-  PROTOPT_CONN_REUSE, /* flags */
-  PORT_FTP,                        /* defport */
-};
-
-/*
- * FTPS protocol handler.
- */
-const struct Curl_scheme Curl_scheme_ftps = {
-  "ftps",                          /* scheme */
-#if defined(CURL_DISABLE_FTP) || !defined(USE_SSL)
-  ZERO_NULL,
-#else
-  &Curl_protocol_ftp,
-#endif
-  CURLPROTO_FTPS,                  /* protocol */
-  CURLPROTO_FTP,                   /* family */
-  PROTOPT_SSL | PROTOPT_DUAL | PROTOPT_CLOSEACTION |
-  PROTOPT_NEEDSPWD | PROTOPT_NOURLQUERY | PROTOPT_WILDCARD |
-  PROTOPT_CONN_REUSE, /* flags */
-  PORT_FTPS,                       /* defport */
-};
index 20b360033e05dfddf23b5eaec31f7b7847cd660b..257f5958267c155ec5fc9b75968e8f77b9771b1b 100644 (file)
--- a/lib/ftp.h
+++ b/lib/ftp.h
  ***************************************************************************/
 #include "curl_setup.h"
 
-#include "pingpong.h"
-
-extern const struct Curl_scheme Curl_scheme_ftp;
-extern const struct Curl_scheme Curl_scheme_ftps;
-
 #ifndef CURL_DISABLE_FTP
-bool ftp_conns_match(struct connectdata *needle, struct connectdata *conn);
-
-#endif /* CURL_DISABLE_FTP */
-
-/****************************************************************************
- * FTP unique setup
- ***************************************************************************/
-enum {
-  FTP_STOP,    /* do nothing state, stops the state machine */
-  FTP_WAIT220, /* waiting for the initial 220 response immediately after
-                  a connect */
-  FTP_AUTH,
-  FTP_USER,
-  FTP_PASS,
-  FTP_ACCT,
-  FTP_PBSZ,
-  FTP_PROT,
-  FTP_CCC,
-  FTP_PWD,
-  FTP_SYST,
-  FTP_NAMEFMT,
-  FTP_QUOTE, /* waiting for a response to a command sent in a quote list */
-  FTP_RETR_PREQUOTE,
-  FTP_STOR_PREQUOTE,
-  FTP_LIST_PREQUOTE,
-  FTP_POSTQUOTE,
-  FTP_CWD,  /* change directory */
-  FTP_MKD,  /* if the directory did not exist */
-  FTP_MDTM, /* to figure out the datestamp */
-  FTP_TYPE, /* to set type when doing a head-like request */
-  FTP_LIST_TYPE, /* set type when about to do a directory list */
-  FTP_RETR_LIST_TYPE,
-  FTP_RETR_TYPE, /* set type when about to RETR a file */
-  FTP_STOR_TYPE, /* set type when about to STOR a file */
-  FTP_SIZE, /* get the remote file's size for head-like request */
-  FTP_RETR_SIZE, /* get the remote file's size for RETR */
-  FTP_STOR_SIZE, /* get the size for STOR */
-  FTP_REST, /* when used to check if the server supports it in head-like */
-  FTP_RETR_REST, /* when asking for "resume" in for RETR */
-  FTP_PORT, /* generic state for PORT, LPRT and EPRT, check count1 */
-  FTP_PRET, /* generic state for PRET RETR, PRET STOR and PRET LIST/NLST */
-  FTP_PASV, /* generic state for PASV and EPSV, check count1 */
-  FTP_LIST, /* generic state for LIST, NLST or a custom list command */
-  FTP_RETR,
-  FTP_STOR, /* generic state for STOR and APPE */
-  FTP_QUIT,
-  FTP_LAST  /* never used */
-};
-typedef unsigned char ftpstate; /* use the enum values */
-
-struct ftp_parselist_data; /* defined later in ftplistparser.c */
+extern const struct Curl_protocol Curl_protocol_ftp;
 
-struct ftp_wc {
-  struct ftp_parselist_data *parser;
-
-  struct {
-    curl_write_callback write_function;
-    FILE *file_descriptor;
-  } backup;
-};
+bool ftp_conns_match(struct connectdata *needle, struct connectdata *conn);
 
 typedef enum {
   FTPFILE_MULTICWD  = 1, /* as defined by RFC1738 */
@@ -99,74 +37,7 @@ typedef enum {
                             file */
 } curl_ftpfile;
 
-/* This FTP struct is used in the Curl_easy. All FTP data that is
-   connection-oriented must be in FTP_conn to properly deal with the fact that
-   perhaps the Curl_easy is changed between the times the connection is
-   used. */
-struct FTP {
-  char *path;    /* points to the urlpieces struct field */
-  char *pathalloc; /* if non-NULL a pointer to an allocated path */
-
-  /* transfer a file/body or not, done as a typedefed enum to make debuggers
-     display the full symbol and not the numerical value */
-  curl_pp_transfer transfer;
-  curl_off_t downloadsize;
-};
-
-/* one struct entry for each path component (of 'rawpath') */
-struct pathcomp {
-  int start; /* start column */
-  int len;   /* length in bytes */
-};
-
-/* ftp_conn is used for struct connection-oriented data in the connectdata
-   struct */
-struct ftp_conn {
-  struct pingpong pp;
-  char *account;
-  char *alternative_to_user;
-  char *entrypath; /* the PWD reply when we logged on */
-  const char *file; /* url-decoded filename (or path), points into rawpath */
-  char *rawpath; /* URL decoded, allocated, version of the path */
-  struct pathcomp *dirs; /* allocated array for path components */
-  char *prevpath;   /* url-decoded conn->path from the previous transfer */
-  char transfertype; /* set by ftp_transfertype for use by Curl_client_write()a
-                        and others (A/I or zero) */
-  char *server_os;     /* The target server operating system. */
-  curl_off_t known_filesize; /* file size is different from -1, if wildcard
-                                LIST parsing was done and wc_statemach set
-                                it */
-  int count1; /* general purpose counter for the state machine */
-  int count2; /* general purpose counter for the state machine */
-  int count3; /* general purpose counter for the state machine */
-  unsigned short dirdepth;  /* number of entries used in the 'dirs' array,
-                               < FTP_MAX_DIR_DEPTH */
-  unsigned short cwdcount;  /* number of CWD commands issued,
-                               < FTP_MAX_DIR_DEPTH */
-  unsigned char state; /* (ftpstate enum) always use ftp.c:state() to change
-                          state! */
-  unsigned char use_ssl;   /* if AUTH TLS is to be attempted etc, for FTP or
-                              IMAP or POP3 or others! (type: curl_usessl)*/
-  unsigned char ccc;       /* ccc level for this connection */
-  BIT(ftp_trying_alternative);
-  BIT(dont_check);  /* Set to TRUE to prevent the final (post-transfer)
-                       file size and 226/250 status check. It should still
-                       read the line, ignore the result. */
-  BIT(ctl_valid);   /* Tells Curl_ftp_quit() whether or not to do anything. If
-                       the connection has timed out or been closed, this
-                       should be FALSE when it gets to Curl_ftp_quit() */
-  BIT(cwddone);     /* if it has been determined that the proper CWD combo
-                       already has been done */
-  BIT(cwdfail);     /* set TRUE if a CWD command fails, as then we must prevent
-                       caching the current directory */
-  BIT(wait_data_conn); /* this is set TRUE if data connection is waited */
-  BIT(shutdown);    /* connection is being shutdown, e.g. QUIT */
-};
-
-/* meta key for storing `struct FTP` as easy meta data */
-#define CURL_META_FTP_EASY   "meta:proto:ftp:easy"
-/* meta key for storing `struct ftp_conn` as connection meta data */
-#define CURL_META_FTP_CONN   "meta:proto:ftp:conn"
+#endif /* CURL_DISABLE_FTP */
 
 #define DEFAULT_ACCEPT_TIMEOUT   60000 /* milliseconds == one minute */
 
index f82895d57a233e90a531656ef0ec6de2f590840e..f53c68aa72fbb5416da76f703ac26759aa20714d 100644 (file)
@@ -44,6 +44,7 @@
 #include "fileinfo.h"
 #include "llist.h"
 #include "ftp.h"
+#include "ftp-int.h"
 #include "ftplistparser.h"
 #include "curl_fnmatch.h"
 #include "multiif.h"
index b4945c0c9d74f70379b0caf4c53984903d97f0fe..f087121d0784fee65aae0f5d527a95671a08ca7d 100644 (file)
@@ -172,7 +172,7 @@ static CURLcode gopher_do(struct Curl_easy *data, bool *done)
  * connect-command-download protocols.
  */
 
-static const struct Curl_protocol Curl_protocol_gopher = {
+const struct Curl_protocol Curl_protocol_gopher = {
   ZERO_NULL,                            /* setup_connection */
   gopher_do,                            /* do_it */
   ZERO_NULL,                            /* done */
@@ -193,7 +193,7 @@ static const struct Curl_protocol Curl_protocol_gopher = {
 };
 
 #ifdef USE_SSL
-static const struct Curl_protocol Curl_protocol_gophers = {
+const struct Curl_protocol Curl_protocol_gophers = {
   ZERO_NULL,                            /* setup_connection */
   gopher_do,                            /* do_it */
   ZERO_NULL,                            /* done */
@@ -215,29 +215,3 @@ static const struct Curl_protocol Curl_protocol_gophers = {
 #endif
 
 #endif /* CURL_DISABLE_GOPHER */
-
-const struct Curl_scheme Curl_scheme_gopher = {
-  "gopher",                             /* scheme */
-#ifdef CURL_DISABLE_GOPHER
-  ZERO_NULL,
-#else
-  &Curl_protocol_gopher,
-#endif
-  CURLPROTO_GOPHER,                     /* protocol */
-  CURLPROTO_GOPHER,                     /* family */
-  PROTOPT_NONE,                         /* flags */
-  PORT_GOPHER,                          /* defport */
-};
-
-const struct Curl_scheme Curl_scheme_gophers = {
-  "gophers",                            /* scheme */
-#if defined(CURL_DISABLE_GOPHER) || !defined(USE_SSL)
-  ZERO_NULL,
-#else
-  &Curl_protocol_gophers,
-#endif
-  CURLPROTO_GOPHERS,                    /* protocol */
-  CURLPROTO_GOPHER,                     /* family */
-  PROTOPT_SSL,                          /* flags */
-  PORT_GOPHER,                          /* defport */
-};
index bc977bc1bcc0de35a0dfae40b67c70e15ac195a6..1c126be16a3d2c6f68f4136891d020e2b1888970 100644 (file)
@@ -23,7 +23,9 @@
  * SPDX-License-Identifier: curl
  *
  ***************************************************************************/
-extern const struct Curl_scheme Curl_scheme_gopher;
-extern const struct Curl_scheme Curl_scheme_gophers;
+#ifndef CURL_DISABLE_GOPHER
+extern const struct Curl_protocol Curl_protocol_gopher;
+extern const struct Curl_protocol Curl_protocol_gophers;
+#endif
 
 #endif /* HEADER_CURL_GOPHER_H */
index 23de72bd0bc67902c41181c2a9e5965af59b8aeb..37a7aa98b7c53ff8b37348b610134d62636db5f0 100644 (file)
@@ -4996,7 +4996,7 @@ void Curl_http_resp_free(struct http_resp *resp)
 /*
  * HTTP handler interface.
  */
-static const struct Curl_protocol Curl_protocol_http = {
+const struct Curl_protocol Curl_protocol_http = {
   Curl_http_setup_conn,                 /* setup_connection */
   Curl_http,                            /* do_it */
   Curl_http_done,                       /* done */
@@ -5017,37 +5017,3 @@ static const struct Curl_protocol Curl_protocol_http = {
 };
 
 #endif /* CURL_DISABLE_HTTP */
-
-/*
- * HTTP handler interface.
- */
-const struct Curl_scheme Curl_scheme_http = {
-  "http",                               /* scheme */
-#ifdef CURL_DISABLE_HTTP
-  ZERO_NULL,
-#else
-  &Curl_protocol_http,
-#endif
-  CURLPROTO_HTTP,                       /* protocol */
-  CURLPROTO_HTTP,                       /* family */
-  PROTOPT_CREDSPERREQUEST |             /* flags */
-  PROTOPT_USERPWDCTRL | PROTOPT_CONN_REUSE,
-  PORT_HTTP,                            /* defport */
-};
-
-/*
- * HTTPS handler interface.
- */
-const struct Curl_scheme Curl_scheme_https = {
-  "https",                              /* scheme */
-#if defined(CURL_DISABLE_HTTP) || !defined(USE_SSL)
-  ZERO_NULL,
-#else
-  &Curl_protocol_http,
-#endif
-  CURLPROTO_HTTPS,                      /* protocol */
-  CURLPROTO_HTTP,                       /* family */
-  PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN | /* flags */
-  PROTOPT_USERPWDCTRL | PROTOPT_CONN_REUSE,
-  PORT_HTTPS,                           /* defport */
-};
index bb535955d1f016a272982689f8a24ab4706c4c79..85d1c6c56050014237bd7e99594acc67cc43fab9 100644 (file)
@@ -37,27 +37,16 @@ typedef enum {
   HTTPREQ_HEAD
 } Curl_HttpReq;
 
-/* When redirecting transfers. */
-typedef enum {
-  FOLLOW_NONE,  /* not used within the function, a placeholder to allow
-                   initing to this */
-  FOLLOW_FAKE,  /* only records stuff, not actually following */
-  FOLLOW_RETRY, /* set if this is a request retry as opposed to a real
-                   redirect following */
-  FOLLOW_REDIR /* a full true redirect */
-} followtype;
-
 #define CURL_HTTP_V1x   (1 << 0)
 #define CURL_HTTP_V2x   (1 << 1)
 #define CURL_HTTP_V3x   (1 << 2)
 /* bitmask of CURL_HTTP_V* values */
 typedef unsigned char http_majors;
 
-extern const struct Curl_scheme Curl_scheme_http;
-extern const struct Curl_scheme Curl_scheme_https;
-
 #ifndef CURL_DISABLE_HTTP
 
+extern const struct Curl_protocol Curl_protocol_http;
+
 struct dynhds;
 
 struct http_negotiation {
index a4d3138383631291123b65e527c923dda4f2a16d..8b224d4b53bd22c6f7e83278ef2519ff3636b9c7 100644 (file)
@@ -2302,7 +2302,7 @@ static CURLcode imap_setup_connection(struct Curl_easy *data,
 /*
  * IMAP protocol.
  */
-static const struct Curl_protocol Curl_protocol_imap = {
+const struct Curl_protocol Curl_protocol_imap = {
   imap_setup_connection,            /* setup_connection */
   imap_do,                          /* do_it */
   imap_done,                        /* done */
@@ -2323,38 +2323,3 @@ static const struct Curl_protocol Curl_protocol_imap = {
 };
 
 #endif /* CURL_DISABLE_IMAP */
-
-/*
- * IMAP protocol handler.
- */
-const struct Curl_scheme Curl_scheme_imap = {
-  "imap",                           /* scheme */
-#ifdef CURL_DISABLE_IMAP
-  ZERO_NULL,
-#else
-  &Curl_protocol_imap,
-#endif
-  CURLPROTO_IMAP,                   /* protocol */
-  CURLPROTO_IMAP,                   /* family */
-  PROTOPT_CLOSEACTION |             /* flags */
-  PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE |
-  PROTOPT_CONN_REUSE,
-  PORT_IMAP,                        /* defport */
-};
-
-/*
- * IMAPS protocol handler.
- */
-const struct Curl_scheme Curl_scheme_imaps = {
-  "imaps",                          /* scheme */
-#if defined(CURL_DISABLE_IMAP) || !defined(USE_SSL)
-  ZERO_NULL,
-#else
-  &Curl_protocol_imap,
-#endif
-  CURLPROTO_IMAPS,                  /* protocol */
-  CURLPROTO_IMAP,                   /* family */
-  PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */
-  PROTOPT_URLOPTIONS | PROTOPT_CONN_REUSE,
-  PORT_IMAPS,                       /* defport */
-};
index f179991a65d29dc2161638cd30b86cdb914a20f6..ecfb1ec9b93f5508fc12d6c6b45cb02ceeab38a8 100644 (file)
@@ -23,8 +23,6 @@
  * SPDX-License-Identifier: curl
  *
  ***************************************************************************/
-extern const struct Curl_scheme Curl_scheme_imap;
-extern const struct Curl_scheme Curl_scheme_imaps;
 
 /* Authentication type flags */
 #define IMAP_TYPE_CLEARTEXT (1 << 0)
@@ -34,4 +32,8 @@ extern const struct Curl_scheme Curl_scheme_imaps;
 #define IMAP_TYPE_NONE      0
 #define IMAP_TYPE_ANY       (IMAP_TYPE_CLEARTEXT | IMAP_TYPE_SASL)
 
+#ifndef CURL_DISABLE_IMAP
+extern const struct Curl_protocol Curl_protocol_imap;
+#endif
+
 #endif /* HEADER_CURL_IMAP_H */
index c43e6cd4f764235fa18194e34466cc41de65d7b4..16a8f60e22732a5e2a892322ddedd8f3259bf9c9 100644 (file)
@@ -1001,35 +1001,3 @@ const struct Curl_protocol Curl_protocol_ldap = {
 #endif
 
 #endif /* !CURL_DISABLE_LDAP && !USE_OPENLDAP */
-
-/*
- * LDAP
- */
-const struct Curl_scheme Curl_scheme_ldap = {
-  "ldap",                               /* scheme */
-#ifdef CURL_DISABLE_LDAP
-  ZERO_NULL,
-#else
-  &Curl_protocol_ldap,
-#endif
-  CURLPROTO_LDAP,                       /* protocol */
-  CURLPROTO_LDAP,                       /* family */
-  PROTOPT_SSL_REUSE,                    /* flags */
-  PORT_LDAP,                            /* defport */
-};
-
-/*
- * LDAPS
- */
-const struct Curl_scheme Curl_scheme_ldaps = {
-  "ldaps",                              /* scheme */
-#if defined(CURL_DISABLE_LDAP) || !defined(HAVE_LDAP_SSL)
-  ZERO_NULL,
-#else
-  &Curl_protocol_ldap,
-#endif
-  CURLPROTO_LDAPS,                      /* protocol */
-  CURLPROTO_LDAP,                       /* family */
-  PROTOPT_SSL,                          /* flags */
-  PORT_LDAPS,                           /* defport */
-};
index 0fb7bd35299a54b033361841755c2d0c95bf8ac9..8e57eabc727b1c96911ce9271e3386fea71cac67 100644 (file)
@@ -964,7 +964,7 @@ static CURLcode mqtts_connecting(struct Curl_easy *data, bool *done)
 /*
  * MQTTS protocol.
  */
-static const struct Curl_protocol Curl_protocol_mqtts = {
+const struct Curl_protocol Curl_protocol_mqtts = {
   mqtt_setup_conn,                    /* setup_connection */
   mqtt_do,                            /* do_it */
   mqtt_done,                          /* done */
@@ -989,7 +989,7 @@ static const struct Curl_protocol Curl_protocol_mqtts = {
 /*
  * MQTT protocol.
  */
-static const struct Curl_protocol Curl_protocol_mqtt = {
+const struct Curl_protocol Curl_protocol_mqtt = {
   mqtt_setup_conn,                    /* setup_connection */
   mqtt_do,                            /* do_it */
   mqtt_done,                          /* done */
@@ -1010,32 +1010,3 @@ static const struct Curl_protocol Curl_protocol_mqtt = {
 };
 
 #endif /* CURL_DISABLE_MQTT */
-
-const struct Curl_scheme Curl_scheme_mqtts = {
-  "mqtts",                            /* scheme */
-#if defined(CURL_DISABLE_MQTT) || !defined(USE_SSL)
-  ZERO_NULL,
-#else
-  &Curl_protocol_mqtts,
-#endif
-  CURLPROTO_MQTTS,                    /* protocol */
-  CURLPROTO_MQTT,                     /* family */
-  PROTOPT_SSL,                        /* flags */
-  PORT_MQTTS,                         /* defport */
-};
-
-/*
- * MQTT protocol.
- */
-const struct Curl_scheme Curl_scheme_mqtt = {
-  "mqtt",                             /* scheme */
-#ifdef CURL_DISABLE_MQTT
-  ZERO_NULL,
-#else
-  &Curl_protocol_mqtt,
-#endif
-  CURLPROTO_MQTT,                     /* protocol */
-  CURLPROTO_MQTT,                     /* family */
-  PROTOPT_NONE,                       /* flags */
-  PORT_MQTT,                          /* defport */
-};
index 67d1df43dd025945a0fdd99cf54bdce088bebbdc..3d95293f12ec6e2e6cb8037189df8dc907a0491c 100644 (file)
  * SPDX-License-Identifier: curl
  *
  ***************************************************************************/
-extern const struct Curl_scheme Curl_scheme_mqtt;
-extern const struct Curl_scheme Curl_scheme_mqtts;
+#ifndef CURL_DISABLE_MQTT
+extern const struct Curl_protocol Curl_protocol_mqtt;
+#ifdef USE_SSL
+extern const struct Curl_protocol Curl_protocol_mqtts;
+#endif
+#endif
 
 #endif /* HEADER_CURL_MQTT_H */
index f3926009f6b119e46e56522951f3bb49066fa17f..19997948df9f396ad72dcd9455f23eefcfb28aff 100644 (file)
@@ -1691,7 +1691,7 @@ static CURLcode pop3_setup_connection(struct Curl_easy *data,
 /*
  * POP3 protocol.
  */
-static const struct Curl_protocol Curl_protocol_pop3 = {
+const struct Curl_protocol Curl_protocol_pop3 = {
   pop3_setup_connection,            /* setup_connection */
   pop3_do,                          /* do_it */
   pop3_done,                        /* done */
@@ -1712,37 +1712,3 @@ static const struct Curl_protocol Curl_protocol_pop3 = {
 };
 
 #endif /* CURL_DISABLE_POP3 */
-
-/*
- * POP3 protocol handler.
- */
-const struct Curl_scheme Curl_scheme_pop3 = {
-  "pop3",                           /* scheme */
-#ifdef CURL_DISABLE_POP3
-  ZERO_NULL,
-#else
-  &Curl_protocol_pop3,
-#endif
-  CURLPROTO_POP3,                   /* protocol */
-  CURLPROTO_POP3,                   /* family */
-  PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */
-  PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE | PROTOPT_CONN_REUSE,
-  PORT_POP3,                        /* defport */
-};
-
-/*
- * POP3S protocol handler.
- */
-const struct Curl_scheme Curl_scheme_pop3s = {
-  "pop3s",                          /* scheme */
-#if defined(CURL_DISABLE_POP3) || !defined(USE_SSL)
-  ZERO_NULL,
-#else
-  &Curl_protocol_pop3,
-#endif
-  CURLPROTO_POP3S,                  /* protocol */
-  CURLPROTO_POP3,                   /* family */
-  PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */
-  PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS | PROTOPT_CONN_REUSE,
-  PORT_POP3S,                       /* defport */
-};
index 77e30f832d23215197181ee60d5cc071a6c13609..75c3a67da7839e7815f47055648f1a2f19659081 100644 (file)
@@ -23,7 +23,8 @@
  * SPDX-License-Identifier: curl
  *
  ***************************************************************************/
-extern const struct Curl_scheme Curl_scheme_pop3;
-extern const struct Curl_scheme Curl_scheme_pop3s;
+#ifndef CURL_DISABLE_POP3
+extern const struct Curl_protocol Curl_protocol_pop3;
+#endif
 
 #endif /* HEADER_CURL_POP3_H */
diff --git a/lib/protocol.c b/lib/protocol.c
new file mode 100644 (file)
index 0000000..194634e
--- /dev/null
@@ -0,0 +1,571 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#include "protocol.h"
+#include "strcase.h"
+
+#include "dict.h"
+#include "file.h"
+#include "ftp.h"
+#include "gopher.h"
+#include "http.h"
+#include "imap.h"
+#include "curl_ldap.h"
+#include "mqtt.h"
+#include "pop3.h"
+#include "curl_rtmp.h"
+#include "rtsp.h"
+#include "smb.h"
+#include "smtp.h"
+#include "telnet.h"
+#include "tftp.h"
+#include "ws.h"
+#include "vssh/ssh.h"
+
+
+/* All URI schemes known to libcurl, but not necessarily implemented
+ * by protocol handlers. */
+const struct Curl_scheme Curl_scheme_dict = {
+  "dict",                               /* scheme */
+#ifdef CURL_DISABLE_DICT
+  ZERO_NULL,
+#else
+  &Curl_protocol_dict,
+#endif
+  CURLPROTO_DICT,                       /* protocol */
+  CURLPROTO_DICT,                       /* family */
+  PROTOPT_NONE | PROTOPT_NOURLQUERY,    /* flags */
+  PORT_DICT,                            /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_file = {
+  "file",                               /* scheme */
+#ifdef CURL_DISABLE_FILE
+  ZERO_NULL,
+#else
+  &Curl_protocol_file,
+#endif
+  CURLPROTO_FILE,                       /* protocol */
+  CURLPROTO_FILE,                       /* family */
+  PROTOPT_NONETWORK | PROTOPT_NOURLQUERY, /* flags */
+  0                                     /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_ftp = {
+  "ftp",                           /* scheme */
+#ifdef CURL_DISABLE_FTP
+  ZERO_NULL,
+#else
+  &Curl_protocol_ftp,
+#endif
+  CURLPROTO_FTP,                   /* protocol */
+  CURLPROTO_FTP,                   /* family */
+  PROTOPT_DUAL | PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD |
+  PROTOPT_NOURLQUERY | PROTOPT_PROXY_AS_HTTP |
+  PROTOPT_WILDCARD | PROTOPT_SSL_REUSE |
+  PROTOPT_CONN_REUSE, /* flags */
+  PORT_FTP,                        /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_ftps = {
+  "ftps",                          /* scheme */
+#if defined(CURL_DISABLE_FTP) || !defined(USE_SSL)
+  ZERO_NULL,
+#else
+  &Curl_protocol_ftp,
+#endif
+  CURLPROTO_FTPS,                  /* protocol */
+  CURLPROTO_FTP,                   /* family */
+  PROTOPT_SSL | PROTOPT_DUAL | PROTOPT_CLOSEACTION |
+  PROTOPT_NEEDSPWD | PROTOPT_NOURLQUERY | PROTOPT_WILDCARD |
+  PROTOPT_CONN_REUSE, /* flags */
+  PORT_FTPS,                       /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_gopher = {
+  "gopher",                             /* scheme */
+#ifdef CURL_DISABLE_GOPHER
+  ZERO_NULL,
+#else
+  &Curl_protocol_gopher,
+#endif
+  CURLPROTO_GOPHER,                     /* protocol */
+  CURLPROTO_GOPHER,                     /* family */
+  PROTOPT_NONE,                         /* flags */
+  PORT_GOPHER,                          /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_gophers = {
+  "gophers",                            /* scheme */
+#if defined(CURL_DISABLE_GOPHER) || !defined(USE_SSL)
+  ZERO_NULL,
+#else
+  &Curl_protocol_gophers,
+#endif
+  CURLPROTO_GOPHERS,                    /* protocol */
+  CURLPROTO_GOPHER,                     /* family */
+  PROTOPT_SSL,                          /* flags */
+  PORT_GOPHER,                          /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_http = {
+  "http",                               /* scheme */
+#ifdef CURL_DISABLE_HTTP
+  ZERO_NULL,
+#else
+  &Curl_protocol_http,
+#endif
+  CURLPROTO_HTTP,                       /* protocol */
+  CURLPROTO_HTTP,                       /* family */
+  PROTOPT_CREDSPERREQUEST |             /* flags */
+  PROTOPT_USERPWDCTRL | PROTOPT_CONN_REUSE,
+  PORT_HTTP,                            /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_https = {
+  "https",                              /* scheme */
+#if defined(CURL_DISABLE_HTTP) || !defined(USE_SSL)
+  ZERO_NULL,
+#else
+  &Curl_protocol_http,
+#endif
+  CURLPROTO_HTTPS,                      /* protocol */
+  CURLPROTO_HTTP,                       /* family */
+  PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN | /* flags */
+  PROTOPT_USERPWDCTRL | PROTOPT_CONN_REUSE,
+  PORT_HTTPS,                           /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_imap = {
+  "imap",                           /* scheme */
+#ifdef CURL_DISABLE_IMAP
+  ZERO_NULL,
+#else
+  &Curl_protocol_imap,
+#endif
+  CURLPROTO_IMAP,                   /* protocol */
+  CURLPROTO_IMAP,                   /* family */
+  PROTOPT_CLOSEACTION |             /* flags */
+  PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE |
+  PROTOPT_CONN_REUSE,
+  PORT_IMAP,                        /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_imaps = {
+  "imaps",                          /* scheme */
+#if defined(CURL_DISABLE_IMAP) || !defined(USE_SSL)
+  ZERO_NULL,
+#else
+  &Curl_protocol_imap,
+#endif
+  CURLPROTO_IMAPS,                  /* protocol */
+  CURLPROTO_IMAP,                   /* family */
+  PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */
+  PROTOPT_URLOPTIONS | PROTOPT_CONN_REUSE,
+  PORT_IMAPS,                       /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_ldap = {
+  "ldap",                               /* scheme */
+#ifdef CURL_DISABLE_LDAP
+  ZERO_NULL,
+#else
+  &Curl_protocol_ldap,
+#endif
+  CURLPROTO_LDAP,                       /* protocol */
+  CURLPROTO_LDAP,                       /* family */
+  PROTOPT_SSL_REUSE,                    /* flags */
+  PORT_LDAP,                            /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_ldaps = {
+  "ldaps",                              /* scheme */
+#if defined(CURL_DISABLE_LDAP) || !defined(HAVE_LDAP_SSL)
+  ZERO_NULL,
+#else
+  &Curl_protocol_ldap,
+#endif
+  CURLPROTO_LDAPS,                      /* protocol */
+  CURLPROTO_LDAP,                       /* family */
+  PROTOPT_SSL,                          /* flags */
+  PORT_LDAPS,                           /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_mqtt = {
+  "mqtt",                             /* scheme */
+#ifdef CURL_DISABLE_MQTT
+  ZERO_NULL,
+#else
+  &Curl_protocol_mqtt,
+#endif
+  CURLPROTO_MQTT,                     /* protocol */
+  CURLPROTO_MQTT,                     /* family */
+  PROTOPT_NONE,                       /* flags */
+  PORT_MQTT,                          /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_mqtts = {
+  "mqtts",                            /* scheme */
+#if defined(CURL_DISABLE_MQTT) || !defined(USE_SSL)
+  ZERO_NULL,
+#else
+  &Curl_protocol_mqtts,
+#endif
+  CURLPROTO_MQTTS,                    /* protocol */
+  CURLPROTO_MQTT,                     /* family */
+  PROTOPT_SSL,                        /* flags */
+  PORT_MQTTS,                         /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_pop3 = {
+  "pop3",                           /* scheme */
+#ifdef CURL_DISABLE_POP3
+  ZERO_NULL,
+#else
+  &Curl_protocol_pop3,
+#endif
+  CURLPROTO_POP3,                   /* protocol */
+  CURLPROTO_POP3,                   /* family */
+  PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */
+  PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE | PROTOPT_CONN_REUSE,
+  PORT_POP3,                        /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_pop3s = {
+  "pop3s",                          /* scheme */
+#if defined(CURL_DISABLE_POP3) || !defined(USE_SSL)
+  ZERO_NULL,
+#else
+  &Curl_protocol_pop3,
+#endif
+  CURLPROTO_POP3S,                  /* protocol */
+  CURLPROTO_POP3,                   /* family */
+  PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */
+  PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS | PROTOPT_CONN_REUSE,
+  PORT_POP3S,                       /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_rtmp = {
+  "rtmp",                               /* scheme */
+#ifndef USE_LIBRTMP
+  ZERO_NULL,
+#else
+  &Curl_protocol_rtmp,
+#endif
+  CURLPROTO_RTMP,                       /* protocol */
+  CURLPROTO_RTMP,                       /* family */
+  PROTOPT_NONE,                         /* flags */
+  PORT_RTMP,                            /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_rtmpt = {
+  "rtmpt",                              /* scheme */
+#ifndef USE_LIBRTMP
+  ZERO_NULL,
+#else
+  &Curl_protocol_rtmp,
+#endif
+  CURLPROTO_RTMPT,                      /* protocol */
+  CURLPROTO_RTMPT,                      /* family */
+  PROTOPT_NONE,                         /* flags */
+  PORT_RTMPT,                           /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_rtmpe = {
+  "rtmpe",                              /* scheme */
+#ifndef USE_LIBRTMP
+  ZERO_NULL,
+#else
+  &Curl_protocol_rtmp,
+#endif
+  CURLPROTO_RTMPE,                      /* protocol */
+  CURLPROTO_RTMPE,                      /* family */
+  PROTOPT_NONE,                         /* flags */
+  PORT_RTMP,                            /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_rtmpte = {
+  "rtmpte",                             /* scheme */
+#ifndef USE_LIBRTMP
+  ZERO_NULL,
+#else
+  &Curl_protocol_rtmp,
+#endif
+  CURLPROTO_RTMPTE,                     /* protocol */
+  CURLPROTO_RTMPTE,                     /* family */
+  PROTOPT_NONE,                         /* flags */
+  PORT_RTMPT,                           /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_rtmps = {
+  "rtmps",                              /* scheme */
+#ifndef USE_LIBRTMP
+  ZERO_NULL,
+#else
+  &Curl_protocol_rtmp,
+#endif
+  CURLPROTO_RTMPS,                      /* protocol */
+  CURLPROTO_RTMP,                       /* family */
+  PROTOPT_NONE,                         /* flags */
+  PORT_RTMPS,                           /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_rtmpts = {
+  "rtmpts",                             /* scheme */
+#ifndef USE_LIBRTMP
+  ZERO_NULL,
+#else
+  &Curl_protocol_rtmp,
+#endif
+  CURLPROTO_RTMPTS,                     /* protocol */
+  CURLPROTO_RTMPT,                      /* family */
+  PROTOPT_NONE,                         /* flags */
+  PORT_RTMPS,                           /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_rtsp = {
+  "rtsp",                               /* scheme */
+#ifdef CURL_DISABLE_RTSP
+  ZERO_NULL,
+#else
+  &Curl_protocol_rtsp,
+#endif
+  CURLPROTO_RTSP,                       /* protocol */
+  CURLPROTO_RTSP,                       /* family */
+  PROTOPT_CONN_REUSE,                   /* flags */
+  PORT_RTSP,                            /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_sftp = {
+  "SFTP",                               /* scheme */
+#ifndef USE_SSH
+  NULL,
+#else
+  &Curl_protocol_sftp,
+#endif
+  CURLPROTO_SFTP,                       /* protocol */
+  CURLPROTO_SFTP,                       /* family */
+  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | /* flags */
+  PROTOPT_NOURLQUERY | PROTOPT_CONN_REUSE,
+  PORT_SSH                              /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_scp = {
+  "SCP",                                /* scheme */
+#ifndef USE_SSH
+  NULL,
+#else
+  &Curl_protocol_scp,
+#endif
+  CURLPROTO_SCP,                        /* protocol */
+  CURLPROTO_SCP,                        /* family */
+  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | /* flags */
+  PROTOPT_NOURLQUERY | PROTOPT_CONN_REUSE,
+  PORT_SSH,                             /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_smb = {
+  "smb",                                /* scheme */
+#if defined(CURL_DISABLE_SMB) || !defined(USE_CURL_NTLM_CORE)
+  ZERO_NULL,
+#else
+  &Curl_protocol_smb,
+#endif
+  CURLPROTO_SMB,                        /* protocol */
+  CURLPROTO_SMB,                        /* family */
+  PROTOPT_CONN_REUSE,                   /* flags */
+  PORT_SMB,                             /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_smbs = {
+  "smbs",                               /* scheme */
+#if defined(CURL_DISABLE_SMB) || !defined(USE_CURL_NTLM_CORE) || \
+  !defined(USE_SSL)
+  ZERO_NULL,
+#else
+  &Curl_protocol_smb,
+#endif
+  CURLPROTO_SMBS,                       /* protocol */
+  CURLPROTO_SMB,                        /* family */
+  PROTOPT_SSL | PROTOPT_CONN_REUSE,     /* flags */
+  PORT_SMBS,                            /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_smtp = {
+  "smtp",                           /* scheme */
+#ifdef CURL_DISABLE_SMTP
+  ZERO_NULL,
+#else
+  &Curl_protocol_smtp,
+#endif
+  CURLPROTO_SMTP,                   /* protocol */
+  CURLPROTO_SMTP,                   /* family */
+  PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */
+  PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE | PROTOPT_CONN_REUSE,
+  PORT_SMTP,                        /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_smtps = {
+  "smtps",                          /* scheme */
+#if defined(CURL_DISABLE_SMTP) || !defined(USE_SSL)
+  ZERO_NULL,
+#else
+  &Curl_protocol_smtp,
+#endif
+  CURLPROTO_SMTPS,                  /* protocol */
+  CURLPROTO_SMTP,                   /* family */
+  PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */
+  PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS | PROTOPT_CONN_REUSE,
+  PORT_SMTPS,                       /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_telnet = {
+  "telnet",                             /* scheme */
+#ifdef CURL_DISABLE_TELNET
+  ZERO_NULL,
+#else
+  &Curl_protocol_telnet,
+#endif
+  CURLPROTO_TELNET,                     /* protocol */
+  CURLPROTO_TELNET,                     /* family */
+  PROTOPT_NONE | PROTOPT_NOURLQUERY,    /* flags */
+  PORT_TELNET,                          /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_tftp = {
+  "tftp",                               /* scheme */
+#ifdef CURL_DISABLE_TFTP
+  ZERO_NULL,
+#else
+  &Curl_protocol_tftp,
+#endif
+  CURLPROTO_TFTP,                       /* protocol */
+  CURLPROTO_TFTP,                       /* family */
+  PROTOPT_NOTCPPROXY | PROTOPT_NOURLQUERY, /* flags */
+  PORT_TFTP,                            /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_ws = {
+  "WS",                                 /* scheme */
+#if defined(CURL_DISABLE_WEBSOCKETS) || defined(CURL_DISABLE_HTTP)
+  ZERO_NULL,
+#else
+  &Curl_protocol_ws,
+#endif
+  CURLPROTO_WS,                         /* protocol */
+  CURLPROTO_HTTP,                       /* family */
+  PROTOPT_CREDSPERREQUEST |             /* flags */
+  PROTOPT_USERPWDCTRL,
+  PORT_HTTP                             /* defport */
+};
+
+const struct Curl_scheme Curl_scheme_wss = {
+  "WSS",                                /* scheme */
+#if defined(CURL_DISABLE_WEBSOCKETS) || defined(CURL_DISABLE_HTTP) || \
+    !defined(USE_SSL)
+  ZERO_NULL,
+#else
+  &Curl_protocol_ws,
+#endif
+  CURLPROTO_WSS,                        /* protocol */
+  CURLPROTO_HTTP,                       /* family */
+  PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | /* flags */
+  PROTOPT_USERPWDCTRL,
+  PORT_HTTPS                            /* defport */
+};
+
+/* Returns a struct scheme pointer if the name is a known scheme. Check the
+   ->run struct field for non-NULL to figure out if an implementation is
+   present. */
+const struct Curl_scheme *Curl_getn_scheme(const char *scheme, size_t len)
+{
+  /* table generated by schemetable.c:
+     1. gcc schemetable.c && ./a.out
+     2. check how small the table gets
+     3. tweak the hash algorithm, then rerun from 1
+     4. when the table is good enough
+     5. copy the table into this source code
+     6. make sure this function uses the same hash function that worked for
+     schemetable.c
+     */
+  static const struct Curl_scheme * const all_schemes[67] = {
+    &Curl_scheme_file,
+    &Curl_scheme_mqtts, NULL,
+    &Curl_scheme_gophers, NULL,
+    &Curl_scheme_rtmpe,
+    &Curl_scheme_smtp,
+    &Curl_scheme_sftp,
+    &Curl_scheme_smb,
+    &Curl_scheme_smtps,
+    &Curl_scheme_telnet,
+    &Curl_scheme_gopher,
+    &Curl_scheme_tftp, NULL, NULL, NULL,
+    &Curl_scheme_ftps,
+    &Curl_scheme_http,
+    &Curl_scheme_imap,
+    &Curl_scheme_rtmps,
+    &Curl_scheme_rtmpt, NULL, NULL, NULL,
+    &Curl_scheme_ldaps,
+    &Curl_scheme_wss,
+    &Curl_scheme_https, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    &Curl_scheme_rtsp,
+    &Curl_scheme_smbs,
+    &Curl_scheme_scp, NULL, NULL, NULL,
+    &Curl_scheme_pop3, NULL, NULL,
+    &Curl_scheme_rtmp, NULL, NULL, NULL,
+    &Curl_scheme_rtmpte, NULL, NULL, NULL,
+    &Curl_scheme_dict, NULL, NULL, NULL,
+    &Curl_scheme_mqtt,
+    &Curl_scheme_pop3s,
+    &Curl_scheme_imaps, NULL,
+    &Curl_scheme_ws, NULL,
+    &Curl_scheme_rtmpts,
+    &Curl_scheme_ldap, NULL, NULL,
+    &Curl_scheme_ftp,
+  };
+
+  if(len && (len <= 7)) {
+    const char *s = scheme;
+    size_t l = len;
+    const struct Curl_scheme *h;
+    unsigned int c = 978;
+    while(l) {
+      c <<= 5;
+      c += (unsigned int)Curl_raw_tolower(*s);
+      s++;
+      l--;
+    }
+
+    h = all_schemes[c % 67];
+    if(h && curl_strnequal(scheme, h->name, len) && !h->name[len])
+      return h;
+  }
+  return NULL;
+}
+
+const struct Curl_scheme *Curl_get_scheme(const char *scheme)
+{
+  return Curl_getn_scheme(scheme, strlen(scheme));
+}
diff --git a/lib/protocol.h b/lib/protocol.h
new file mode 100644 (file)
index 0000000..0d41b86
--- /dev/null
@@ -0,0 +1,291 @@
+#ifndef HEADER_CURL_PROTOCOL_H
+#define HEADER_CURL_PROTOCOL_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+/* This file is for lib internal stuff */
+#include "curl_setup.h"
+
+struct Curl_easy;
+struct connectdata;
+struct easy_pollset;
+
+/* Known protocol default port numbers */
+#define PORT_FTP    21
+#define PORT_FTPS   990
+#define PORT_TELNET 23
+#define PORT_HTTP   80
+#define PORT_HTTPS  443
+#define PORT_DICT   2628
+#define PORT_LDAP   389
+#define PORT_LDAPS  636
+#define PORT_TFTP   69
+#define PORT_SSH    22
+#define PORT_IMAP   143
+#define PORT_IMAPS  993
+#define PORT_POP3   110
+#define PORT_POP3S  995
+#define PORT_SMB    445
+#define PORT_SMBS   445
+#define PORT_SMTP   25
+#define PORT_SMTPS  465 /* sometimes called SSMTP */
+#define PORT_RTSP   554
+#define PORT_RTMP   1935
+#define PORT_RTMPT  PORT_HTTP
+#define PORT_RTMPS  PORT_HTTPS
+#define PORT_GOPHER 70
+#define PORT_MQTT   1883
+#define PORT_MQTTS  8883
+
+#ifndef CURL_DISABLE_WEBSOCKETS
+/* CURLPROTO_GOPHERS (29) is the highest publicly used protocol bit number,
+ * the rest are internal information. If we use higher bits we only do this on
+ * platforms that have a >= 64-bit type and then we use such a type for the
+ * protocol fields in the scheme definition.
+ */
+#define CURLPROTO_WS     (1L << 30)
+#define CURLPROTO_WSS    ((curl_prot_t)1 << 31)
+#else
+#define CURLPROTO_WS     0L
+#define CURLPROTO_WSS    0L
+#endif
+
+#define CURLPROTO_MQTTS  (1LL << 32)
+
+#define CURLPROTO_64ALL ((uint64_t)0xffffffffffffffff)
+
+/* the default protocols accepting a redirect to */
+#define CURLPROTO_REDIR (CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_FTP | \
+                         CURLPROTO_FTPS)
+
+typedef curl_off_t curl_prot_t;
+
+/* This mask is for all the old protocols that are provided and defined in the
+   public header and shall exclude protocols added since which are not exposed
+   in the API */
+#define CURLPROTO_MASK   0x3ffffff
+
+/* Convenience defines for checking protocols or their SSL based version. Each
+   protocol scheme should only ever have a single CURLPROTO_ in its protocol
+   field. */
+#define PROTO_FAMILY_HTTP (CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_WS | \
+                           CURLPROTO_WSS)
+#define PROTO_FAMILY_FTP  (CURLPROTO_FTP | CURLPROTO_FTPS)
+#define PROTO_FAMILY_POP3 (CURLPROTO_POP3 | CURLPROTO_POP3S)
+#define PROTO_FAMILY_SMB  (CURLPROTO_SMB | CURLPROTO_SMBS)
+#define PROTO_FAMILY_SMTP (CURLPROTO_SMTP | CURLPROTO_SMTPS)
+#define PROTO_FAMILY_SSH  (CURLPROTO_SCP | CURLPROTO_SFTP)
+
+#if !defined(CURL_DISABLE_FTP) || defined(USE_SSH) || \
+  !defined(CURL_DISABLE_POP3)
+/* these protocols support CURLOPT_DIRLISTONLY */
+#define CURL_LIST_ONLY_PROTOCOL 1
+#endif
+
+/* When redirecting transfers. */
+typedef enum {
+  FOLLOW_NONE,  /* not used within the function, a placeholder to allow
+                   initing to this */
+  FOLLOW_FAKE,  /* only records stuff, not actually following */
+  FOLLOW_RETRY, /* set if this is a request retry as opposed to a real
+                   redirect following */
+  FOLLOW_REDIR /* a full true redirect */
+} followtype;
+
+/*
+ * Specific protocol handler, an implementation of one or more URI schemes.
+ */
+struct Curl_protocol {
+  /* Complement to setup_connection_internals(). This is done before the
+     transfer "owns" the connection. */
+  CURLcode (*setup_connection)(struct Curl_easy *data,
+                               struct connectdata *conn);
+
+  /* These two functions MUST be set to be protocol dependent */
+  CURLcode (*do_it)(struct Curl_easy *data, bool *done);
+  CURLcode (*done)(struct Curl_easy *, CURLcode, bool);
+
+  /* If the curl_do() function is better made in two halves, this
+   * curl_do_more() function will be called afterwards, if set. For example
+   * for doing the FTP stuff after the PASV/PORT command.
+   */
+  CURLcode (*do_more)(struct Curl_easy *, int *);
+
+  /* This function *MAY* be set to a protocol-dependent function that is run
+   * after the connect() and everything is done, as a step in the connection.
+   * The 'done' pointer points to a bool that should be set to TRUE if the
+   * function completes before return. If it does not complete, the caller
+   * should call the ->connecting() function until it is.
+   */
+  CURLcode (*connect_it)(struct Curl_easy *data, bool *done);
+
+  /* See above. */
+  CURLcode (*connecting)(struct Curl_easy *data, bool *done);
+  CURLcode (*doing)(struct Curl_easy *data, bool *done);
+
+  /* Called from the multi interface during the PROTOCONNECT phase, and it
+     should then return a proper fd set */
+  CURLcode (*proto_pollset)(struct Curl_easy *data,
+                            struct easy_pollset *ps);
+
+  /* Called from the multi interface during the DOING phase, and it should
+     then return a proper fd set */
+  CURLcode (*doing_pollset)(struct Curl_easy *data,
+                            struct easy_pollset *ps);
+
+  /* Called from the multi interface during the DO_MORE phase, and it should
+     then return a proper fd set */
+  CURLcode (*domore_pollset)(struct Curl_easy *data,
+                            struct easy_pollset *ps);
+
+  /* Called from the multi interface during the DO_DONE, PERFORM and
+     WAITPERFORM phases, and it should then return a proper fd set. Not setting
+     this will make libcurl use the generic default one. */
+  CURLcode (*perform_pollset)(struct Curl_easy *data,
+                              struct easy_pollset *ps);
+
+  /* This function *MAY* be set to a protocol-dependent function that is run
+   * by the curl_disconnect(), as a step in the disconnection. If the handler
+   * is called because the connection has been considered dead,
+   * dead_connection is set to TRUE. The connection is (again) associated with
+   * the transfer here.
+   */
+  CURLcode (*disconnect)(struct Curl_easy *, struct connectdata *,
+                         bool dead_connection);
+
+  /* If used, this function gets called from transfer.c to
+     allow the protocol to do extra handling in writing response to
+     the client. */
+  CURLcode (*write_resp)(struct Curl_easy *data, const char *buf, size_t blen,
+                         bool is_eos);
+
+  /* If used, this function gets called from transfer.c to
+     allow the protocol to do extra handling in writing a single response
+     header line to the client. */
+  CURLcode (*write_resp_hd)(struct Curl_easy *data,
+                            const char *hd, size_t hdlen, bool is_eos);
+
+  /* If used, this function checks for a connection managed by this
+    protocol and currently not in use, if it should be considered dead. */
+  bool (*connection_is_dead)(struct Curl_easy *data,
+                             struct connectdata *conn);
+
+  /* attach() attaches this transfer to this connection */
+  void (*attach)(struct Curl_easy *data, struct connectdata *conn);
+
+  /* return CURLE_OK if a redirect to `newurl` should be followed,
+     CURLE_TOO_MANY_REDIRECTS otherwise. May alter `data` to change
+     the way the follow request is performed. */
+  CURLcode (*follow)(struct Curl_easy *data, const char *newurl,
+                     followtype type);
+};
+
+#define PROTOPT_NONE 0             /* nothing extra */
+#define PROTOPT_SSL (1 << 0)       /* uses SSL */
+#define PROTOPT_DUAL (1 << 1)      /* this protocol uses two connections */
+#define PROTOPT_CLOSEACTION (1 << 2) /* need action before socket close */
+/* some protocols will have to call the underlying functions without regard to
+   what exact state the socket signals. IE even if the socket says "readable",
+   the send function might need to be called while uploading, or vice versa.
+*/
+#define PROTOPT_DIRLOCK (1 << 3)
+#define PROTOPT_NONETWORK (1 << 4) /* protocol does not use the network! */
+#define PROTOPT_NEEDSPWD (1 << 5)  /* needs a password, and if none is set it
+                                      gets a default */
+#define PROTOPT_NOURLQUERY (1 << 6)  /* protocol cannot handle
+                                        URL query strings (?foo=bar) ! */
+#define PROTOPT_CREDSPERREQUEST (1 << 7) /* requires login credentials per
+                                            request instead of per
+                                            connection */
+#define PROTOPT_ALPN (1 << 8) /* set ALPN for this */
+/* (1 << 9) was PROTOPT_STREAM, now free */
+#define PROTOPT_URLOPTIONS (1 << 10) /* allow options part in the userinfo
+                                        field of the URL */
+#define PROTOPT_PROXY_AS_HTTP (1 << 11) /* allow this non-HTTP scheme over a
+                                           HTTP proxy as HTTP proxies may know
+                                           this protocol and act as
+                                           a gateway */
+#define PROTOPT_WILDCARD (1 << 12)  /* protocol supports wildcard matching */
+#define PROTOPT_USERPWDCTRL (1 << 13) /* Allow "control bytes" (< 32 ASCII) in
+                                         username and password */
+#define PROTOPT_NOTCPPROXY (1 << 14)  /* this protocol cannot proxy over TCP */
+#define PROTOPT_SSL_REUSE (1 << 15)   /* this protocol may reuse an existing
+                                         SSL connection in the same family
+                                         without having PROTOPT_SSL. */
+#define PROTOPT_CONN_REUSE (1 << 16)  /* this protocol can reuse connections */
+
+/* Everything about a URI scheme. */
+struct Curl_scheme {
+  const char *name;       /* URL scheme name in lowercase */
+  const struct Curl_protocol *run; /* implementation, optional */
+  curl_prot_t protocol;   /* See CURLPROTO_* - this needs to be the single
+                             specific protocol bit */
+  curl_prot_t family;     /* single bit for protocol family; the non-TLS name
+                             of the protocol this is */
+  uint32_t flags;         /* Extra particular characteristics, see PROTOPT_* */
+  uint16_t defport;       /* Default port. */
+};
+
+/* Get scheme definition for a URI scheme name
+ * @param scheme URI scheme name, case-insensitive
+ * @return NULL if scheme is not known
+ */
+const struct Curl_scheme *Curl_get_scheme(const char *scheme);
+const struct Curl_scheme *Curl_getn_scheme(const char *scheme, size_t len);
+
+/* For direct access to a URI scheme */
+extern const struct Curl_scheme Curl_scheme_dict;
+extern const struct Curl_scheme Curl_scheme_file;
+extern const struct Curl_scheme Curl_scheme_ftp;
+extern const struct Curl_scheme Curl_scheme_ftps;
+extern const struct Curl_scheme Curl_scheme_gopher;
+extern const struct Curl_scheme Curl_scheme_gophers;
+extern const struct Curl_scheme Curl_scheme_http;
+extern const struct Curl_scheme Curl_scheme_https;
+extern const struct Curl_scheme Curl_scheme_imap;
+extern const struct Curl_scheme Curl_scheme_imaps;
+extern const struct Curl_scheme Curl_scheme_ldap;
+extern const struct Curl_scheme Curl_scheme_ldaps;
+extern const struct Curl_scheme Curl_scheme_mqtt;
+extern const struct Curl_scheme Curl_scheme_mqtts;
+extern const struct Curl_scheme Curl_scheme_pop3;
+extern const struct Curl_scheme Curl_scheme_pop3s;
+extern const struct Curl_scheme Curl_scheme_rtmp;
+extern const struct Curl_scheme Curl_scheme_rtmpe;
+extern const struct Curl_scheme Curl_scheme_rtmpt;
+extern const struct Curl_scheme Curl_scheme_rtmpte;
+extern const struct Curl_scheme Curl_scheme_rtmps;
+extern const struct Curl_scheme Curl_scheme_rtmpts;
+extern const struct Curl_scheme Curl_scheme_rtsp;
+extern const struct Curl_scheme Curl_scheme_scp;
+extern const struct Curl_scheme Curl_scheme_sftp;
+extern const struct Curl_scheme Curl_scheme_smb;
+extern const struct Curl_scheme Curl_scheme_smbs;
+extern const struct Curl_scheme Curl_scheme_smtp;
+extern const struct Curl_scheme Curl_scheme_smtps;
+extern const struct Curl_scheme Curl_scheme_telnet;
+extern const struct Curl_scheme Curl_scheme_tftp;
+extern const struct Curl_scheme Curl_scheme_ws;
+extern const struct Curl_scheme Curl_scheme_wss;
+
+#endif /* HEADER_CURL_PROTOCOL_H */
index d957eb1d448acb81c00a0089f28629a88b064c42..078f5993c65aab234ad01175b415bd9bdd256238 100644 (file)
@@ -1051,7 +1051,7 @@ CURLcode Curl_rtsp_parseheader(struct Curl_easy *data, const char *header)
 /*
  * RTSP handler interface.
  */
-static const struct Curl_protocol Curl_protocol_rtsp = {
+const struct Curl_protocol Curl_protocol_rtsp = {
   rtsp_setup_connection,                /* setup_connection */
   rtsp_do,                              /* do_it */
   rtsp_done,                            /* done */
@@ -1072,19 +1072,3 @@ static const struct Curl_protocol Curl_protocol_rtsp = {
 };
 
 #endif /* CURL_DISABLE_RTSP */
-
-/*
- * RTSP handler interface.
- */
-const struct Curl_scheme Curl_scheme_rtsp = {
-  "rtsp",                               /* scheme */
-#ifdef CURL_DISABLE_RTSP
-  ZERO_NULL,
-#else
-  &Curl_protocol_rtsp,
-#endif
-  CURLPROTO_RTSP,                       /* protocol */
-  CURLPROTO_RTSP,                       /* family */
-  PROTOPT_CONN_REUSE,                   /* flags */
-  PORT_RTSP,                            /* defport */
-};
index 92b28e54f8edf2573019f32773b76ce62d6356ef..dd5df3ff73c5529bad536a91d5f9d0637a4149e9 100644 (file)
@@ -23,9 +23,9 @@
  * SPDX-License-Identifier: curl
  *
  ***************************************************************************/
-extern const struct Curl_scheme Curl_scheme_rtsp;
 #ifndef CURL_DISABLE_RTSP
 CURLcode Curl_rtsp_parseheader(struct Curl_easy *data, const char *header);
+extern const struct Curl_protocol Curl_protocol_rtsp;
 #else
 #define Curl_rtsp_parseheader(x, y) CURLE_NOT_BUILT_IN
 #endif
index 439d035527664edb255f1b752a345147a2e56eed..08192b90ac23ad91beb67084b5acae4188ad404f 100644 (file)
--- a/lib/smb.c
+++ b/lib/smb.c
@@ -1208,7 +1208,7 @@ static CURLcode smb_do(struct Curl_easy *data, bool *done)
 /*
  * SMB handler interface
  */
-static const struct Curl_protocol Curl_protocol_smb = {
+const struct Curl_protocol Curl_protocol_smb = {
   smb_setup_connection,                 /* setup_connection */
   smb_do,                               /* do_it */
   ZERO_NULL,                            /* done */
@@ -1229,36 +1229,3 @@ static const struct Curl_protocol Curl_protocol_smb = {
 };
 
 #endif /* CURL_DISABLE_SMB && USE_CURL_NTLM_CORE && SIZEOF_CURL_OFF_T > 4 */
-
-/*
- * SMB handler interface
- */
-const struct Curl_scheme Curl_scheme_smb = {
-  "smb",                                /* scheme */
-#if defined(CURL_DISABLE_SMB) || !defined(USE_CURL_NTLM_CORE)
-  ZERO_NULL,
-#else
-  &Curl_protocol_smb,
-#endif
-  CURLPROTO_SMB,                        /* protocol */
-  CURLPROTO_SMB,                        /* family */
-  PROTOPT_CONN_REUSE,                   /* flags */
-  PORT_SMB,                             /* defport */
-};
-
-/*
- * SMBS handler interface
- */
-const struct Curl_scheme Curl_scheme_smbs = {
-  "smbs",                               /* scheme */
-#if defined(CURL_DISABLE_SMB) || !defined(USE_CURL_NTLM_CORE) || \
-  !defined(USE_SSL)
-  ZERO_NULL,
-#else
-  &Curl_protocol_smb,
-#endif
-  CURLPROTO_SMBS,                       /* protocol */
-  CURLPROTO_SMB,                        /* family */
-  PROTOPT_SSL | PROTOPT_CONN_REUSE,     /* flags */
-  PORT_SMBS,                            /* defport */
-};
index d3754047a7d2e4e4e3c50481257f314e6d81edd8..cbcef11a1269be278b8819679bb1c22695772a1f 100644 (file)
--- a/lib/smb.h
+++ b/lib/smb.h
@@ -24,7 +24,8 @@
  * SPDX-License-Identifier: curl
  *
  ***************************************************************************/
-extern const struct Curl_scheme Curl_scheme_smb;
-extern const struct Curl_scheme Curl_scheme_smbs;
+#if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE)
+extern const struct Curl_protocol Curl_protocol_smb;
+#endif
 
 #endif /* HEADER_CURL_SMB_H */
index e5b26b51c2c698f32908a7033375d1d32b05340c..3f71ee97b1236afcac1e09c8cf132e5557554432 100644 (file)
@@ -1984,7 +1984,7 @@ out:
 /*
  * SMTP protocol handler.
  */
-static const struct Curl_protocol Curl_protocol_smtp = {
+const struct Curl_protocol Curl_protocol_smtp = {
   smtp_setup_connection,            /* setup_connection */
   smtp_do,                          /* do_it */
   smtp_done,                        /* done */
@@ -2005,37 +2005,3 @@ static const struct Curl_protocol Curl_protocol_smtp = {
 };
 
 #endif /* CURL_DISABLE_SMTP */
-
-/*
- * SMTP protocol handler.
- */
-const struct Curl_scheme Curl_scheme_smtp = {
-  "smtp",                           /* scheme */
-#ifdef CURL_DISABLE_SMTP
-  ZERO_NULL,
-#else
-  &Curl_protocol_smtp,
-#endif
-  CURLPROTO_SMTP,                   /* protocol */
-  CURLPROTO_SMTP,                   /* family */
-  PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */
-  PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE | PROTOPT_CONN_REUSE,
-  PORT_SMTP,                        /* defport */
-};
-
-/*
- * SMTPS protocol handler.
- */
-const struct Curl_scheme Curl_scheme_smtps = {
-  "smtps",                          /* scheme */
-#if defined(CURL_DISABLE_SMTP) || !defined(USE_SSL)
-  ZERO_NULL,
-#else
-  &Curl_protocol_smtp,
-#endif
-  CURLPROTO_SMTPS,                  /* protocol */
-  CURLPROTO_SMTP,                   /* family */
-  PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */
-  PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS | PROTOPT_CONN_REUSE,
-  PORT_SMTPS,                       /* defport */
-};
index 39f8d78473f14ddcce0035640aae9894f68241b9..75b81979c26ab99815803c9788ffb1b8a868799a 100644 (file)
@@ -23,7 +23,8 @@
  * SPDX-License-Identifier: curl
  *
  ***************************************************************************/
-extern const struct Curl_scheme Curl_scheme_smtp;
-extern const struct Curl_scheme Curl_scheme_smtps;
+#ifndef CURL_DISABLE_SMTP
+extern const struct Curl_protocol Curl_protocol_smtp;
+#endif
 
 #endif /* HEADER_CURL_SMTP_H */
index 0cac1f2af1ba1d20d4ccf65e087460a770e7f257..df82870900698ba99afbf7ae392a9baed9f4bd82 100644 (file)
@@ -1569,7 +1569,7 @@ static CURLcode telnet_do(struct Curl_easy *data, bool *done)
 /*
  * TELNET protocol handler.
  */
-static const struct Curl_protocol Curl_protocol_telnet = {
+const struct Curl_protocol Curl_protocol_telnet = {
   ZERO_NULL,                            /* setup_connection */
   telnet_do,                            /* do_it */
   telnet_done,                          /* done */
@@ -1590,19 +1590,3 @@ static const struct Curl_protocol Curl_protocol_telnet = {
 };
 
 #endif /* !CURL_DISABLE_TELNET */
-
-/*
- * TELNET protocol handler.
- */
-const struct Curl_scheme Curl_scheme_telnet = {
-  "telnet",                             /* scheme */
-#ifdef CURL_DISABLE_TELNET
-  ZERO_NULL,
-#else
-  &Curl_protocol_telnet,
-#endif
-  CURLPROTO_TELNET,                     /* protocol */
-  CURLPROTO_TELNET,                     /* family */
-  PROTOPT_NONE | PROTOPT_NOURLQUERY,    /* flags */
-  PORT_TELNET,                          /* defport */
-};
index c10617964a8a83137da373ed6cd29b59eaebece1..3848fff3ba3f4087d934e4b96053bf6d1f2a67ef 100644 (file)
@@ -23,6 +23,8 @@
  * SPDX-License-Identifier: curl
  *
  ***************************************************************************/
-extern const struct Curl_scheme Curl_scheme_telnet;
+#ifndef CURL_DISABLE_TELNET
+extern const struct Curl_protocol Curl_protocol_telnet;
+#endif
 
 #endif /* HEADER_CURL_TELNET_H */
index a1fab62f50c8d26d2c1101926993d57404305bc0..16746ab68fc7b988a882dbe2aacb19be598933a9 100644 (file)
@@ -1332,7 +1332,7 @@ static CURLcode tftp_setup_connection(struct Curl_easy *data,
 /*
  * TFTP protocol handler.
  */
-static const struct Curl_protocol Curl_protocol_tftp = {
+const struct Curl_protocol Curl_protocol_tftp = {
   tftp_setup_connection,                /* setup_connection */
   tftp_do,                              /* do_it */
   tftp_done,                            /* done */
@@ -1353,19 +1353,3 @@ static const struct Curl_protocol Curl_protocol_tftp = {
 };
 
 #endif
-
-/*
- * TFTP protocol handler.
- */
-const struct Curl_scheme Curl_scheme_tftp = {
-  "tftp",                               /* scheme */
-#ifdef CURL_DISABLE_TFTP
-  ZERO_NULL,
-#else
-  &Curl_protocol_tftp,
-#endif
-  CURLPROTO_TFTP,                       /* protocol */
-  CURLPROTO_TFTP,                       /* family */
-  PROTOPT_NOTCPPROXY | PROTOPT_NOURLQUERY, /* flags */
-  PORT_TFTP,                            /* defport */
-};
index 91ecd2978af409c3e3a8d4823948955c6ce34548..32310103b0b6988a6d5f5d8dec9b22e7ef8bb245 100644 (file)
@@ -23,7 +23,9 @@
  * SPDX-License-Identifier: curl
  *
  ***************************************************************************/
-extern const struct Curl_scheme Curl_scheme_tftp;
+#ifndef CURL_DISABLE_TFTP
+extern const struct Curl_protocol Curl_protocol_tftp;
+#endif
 
 #define TFTP_BLKSIZE_MIN 8
 #define TFTP_BLKSIZE_MAX 65464
index 4aca5d504fc00ca4b6f9ee936be66a65e4e9cc11..b9a1a7b6811232cda84e1e850b3430ca028d40bb 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -1433,80 +1433,6 @@ error:
   return NULL;
 }
 
-const struct Curl_scheme *Curl_get_scheme(const char *scheme)
-{
-  return Curl_getn_scheme(scheme, strlen(scheme));
-}
-
-/* Returns a struct scheme pointer if the name is a known scheme. Check the
-   ->run struct field for non-NULL to figure out if an implementation is
-   present. */
-const struct Curl_scheme *Curl_getn_scheme(const char *scheme, size_t len)
-{
-  /* table generated by schemetable.c:
-     1. gcc schemetable.c && ./a.out
-     2. check how small the table gets
-     3. tweak the hash algorithm, then rerun from 1
-     4. when the table is good enough
-     5. copy the table into this source code
-     6. make sure this function uses the same hash function that worked for
-     schemetable.c
-     */
-  static const struct Curl_scheme * const all_schemes[67] = {
-    &Curl_scheme_file,
-    &Curl_scheme_mqtts, NULL,
-    &Curl_scheme_gophers, NULL,
-    &Curl_scheme_rtmpe,
-    &Curl_scheme_smtp,
-    &Curl_scheme_sftp,
-    &Curl_scheme_smb,
-    &Curl_scheme_smtps,
-    &Curl_scheme_telnet,
-    &Curl_scheme_gopher,
-    &Curl_scheme_tftp, NULL, NULL, NULL,
-    &Curl_scheme_ftps,
-    &Curl_scheme_http,
-    &Curl_scheme_imap,
-    &Curl_scheme_rtmps,
-    &Curl_scheme_rtmpt, NULL, NULL, NULL,
-    &Curl_scheme_ldaps,
-    &Curl_scheme_wss,
-    &Curl_scheme_https, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    &Curl_scheme_rtsp,
-    &Curl_scheme_smbs,
-    &Curl_scheme_scp, NULL, NULL, NULL,
-    &Curl_scheme_pop3, NULL, NULL,
-    &Curl_scheme_rtmp, NULL, NULL, NULL,
-    &Curl_scheme_rtmpte, NULL, NULL, NULL,
-    &Curl_scheme_dict, NULL, NULL, NULL,
-    &Curl_scheme_mqtt,
-    &Curl_scheme_pop3s,
-    &Curl_scheme_imaps, NULL,
-    &Curl_scheme_ws, NULL,
-    &Curl_scheme_rtmpts,
-    &Curl_scheme_ldap, NULL, NULL,
-    &Curl_scheme_ftp,
-  };
-
-  if(len && (len <= 7)) {
-    const char *s = scheme;
-    size_t l = len;
-    const struct Curl_scheme *h;
-    unsigned int c = 978;
-    while(l) {
-      c <<= 5;
-      c += (unsigned int)Curl_raw_tolower(*s);
-      s++;
-      l--;
-    }
-
-    h = all_schemes[c % 67];
-    if(h && curl_strnequal(scheme, h->name, len) && !h->name[len])
-      return h;
-  }
-  return NULL;
-}
-
 static CURLcode findprotocol(struct Curl_easy *data,
                              struct connectdata *conn,
                              const char *protostr)
index 409d571b9726043fddfa86a057bcad35f272aec5..09bc33390f8ae4273614fb80e06c3ef17047b20a 100644 (file)
--- a/lib/url.h
+++ b/lib/url.h
@@ -69,13 +69,6 @@ CURLcode Curl_conn_meta_set(struct connectdata *conn, const char *key,
 void Curl_conn_meta_remove(struct connectdata *conn, const char *key);
 void *Curl_conn_meta_get(struct connectdata *conn, const char *key);
 
-/* Get protocol handler for a URI scheme
- * @param scheme URI scheme, case-insensitive
- * @return NULL of handler not found
- */
-const struct Curl_scheme *Curl_get_scheme(const char *scheme);
-const struct Curl_scheme *Curl_getn_scheme(const char *scheme, size_t len);
-
 #define CURL_DEFAULT_PROXY_PORT 1080 /* default proxy port unless specified */
 #define CURL_DEFAULT_HTTPS_PROXY_PORT 443 /* default https proxy port unless
                                              specified */
index 23e5597f9736aeb8d5380d6ac13ddc244470e790..2509e12e8a6d8d6d16409d1cc24cce5e20214804 100644 (file)
 /* This file is for lib internal stuff */
 #include "curl_setup.h"
 
-#define PORT_FTP    21
-#define PORT_FTPS   990
-#define PORT_TELNET 23
-#define PORT_HTTP   80
-#define PORT_HTTPS  443
-#define PORT_DICT   2628
-#define PORT_LDAP   389
-#define PORT_LDAPS  636
-#define PORT_TFTP   69
-#define PORT_SSH    22
-#define PORT_IMAP   143
-#define PORT_IMAPS  993
-#define PORT_POP3   110
-#define PORT_POP3S  995
-#define PORT_SMB    445
-#define PORT_SMBS   445
-#define PORT_SMTP   25
-#define PORT_SMTPS  465 /* sometimes called SSMTP */
-#define PORT_RTSP   554
-#define PORT_RTMP   1935
-#define PORT_RTMPT  PORT_HTTP
-#define PORT_RTMPS  PORT_HTTPS
-#define PORT_GOPHER 70
-#define PORT_MQTT   1883
-#define PORT_MQTTS  8883
-
-#ifndef CURL_DISABLE_WEBSOCKETS
-/* CURLPROTO_GOPHERS (29) is the highest publicly used protocol bit number,
- * the rest are internal information. If we use higher bits we only do this on
- * platforms that have a >= 64-bit type and then we use such a type for the
- * protocol fields in the protocol handler.
- */
-#define CURLPROTO_WS     (1L << 30)
-#define CURLPROTO_WSS    ((curl_prot_t)1 << 31)
-#else
-#define CURLPROTO_WS     0L
-#define CURLPROTO_WSS    0L
-#endif
-
-#define CURLPROTO_MQTTS  (1LL << 32)
-
-#define CURLPROTO_64ALL ((uint64_t)0xffffffffffffffff)
-
-/* the default protocols accepting a redirect to */
-#define CURLPROTO_REDIR (CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_FTP | \
-                         CURLPROTO_FTPS)
-
-typedef curl_off_t curl_prot_t;
-
-/* This mask is for all the old protocols that are provided and defined in the
-   public header and shall exclude protocols added since which are not exposed
-   in the API */
-#define CURLPROTO_MASK   0x3ffffff
-
 #define CURL_DEFAULT_USER "anonymous"
 #define CURL_DEFAULT_PASSWORD "ftp@example.com"
 
@@ -89,23 +35,6 @@ typedef curl_off_t curl_prot_t;
 #define CURL_PREFER_LF_LINEENDS
 #endif
 
-/* Convenience defines for checking protocols or their SSL based version. Each
-   protocol handler should only ever have a single CURLPROTO_ in its protocol
-   field. */
-#define PROTO_FAMILY_HTTP (CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_WS | \
-                           CURLPROTO_WSS)
-#define PROTO_FAMILY_FTP  (CURLPROTO_FTP | CURLPROTO_FTPS)
-#define PROTO_FAMILY_POP3 (CURLPROTO_POP3 | CURLPROTO_POP3S)
-#define PROTO_FAMILY_SMB  (CURLPROTO_SMB | CURLPROTO_SMBS)
-#define PROTO_FAMILY_SMTP (CURLPROTO_SMTP | CURLPROTO_SMTPS)
-#define PROTO_FAMILY_SSH  (CURLPROTO_SCP | CURLPROTO_SFTP)
-
-#if !defined(CURL_DISABLE_FTP) || defined(USE_SSH) || \
-  !defined(CURL_DISABLE_POP3)
-/* these protocols support CURLOPT_DIRLISTONLY */
-#define CURL_LIST_ONLY_PROTOCOL 1
-#endif
-
 #define DEFAULT_CONNCACHE_SIZE 5
 
 /* length of longest IPv6 address string including the trailing null */
@@ -155,6 +84,7 @@ typedef CURLcode (Curl_recv)(struct Curl_easy *data,   /* transfer */
                              size_t *pnread);          /* how much received */
 
 #include "mime.h"
+#include "protocol.h"
 #include "ftp.h"
 #include "http.h"
 #include "smb.h"
@@ -391,140 +321,6 @@ struct hostname {
 #define FIRSTSOCKET     0
 #define SECONDARYSOCKET 1
 
-/*
- * Specific protocol handler.
- */
-
-struct Curl_protocol {
-  /* Complement to setup_connection_internals(). This is done before the
-     transfer "owns" the connection. */
-  CURLcode (*setup_connection)(struct Curl_easy *data,
-                               struct connectdata *conn);
-
-  /* These two functions MUST be set to be protocol dependent */
-  CURLcode (*do_it)(struct Curl_easy *data, bool *done);
-  CURLcode (*done)(struct Curl_easy *, CURLcode, bool);
-
-  /* If the curl_do() function is better made in two halves, this
-   * curl_do_more() function will be called afterwards, if set. For example
-   * for doing the FTP stuff after the PASV/PORT command.
-   */
-  CURLcode (*do_more)(struct Curl_easy *, int *);
-
-  /* This function *MAY* be set to a protocol-dependent function that is run
-   * after the connect() and everything is done, as a step in the connection.
-   * The 'done' pointer points to a bool that should be set to TRUE if the
-   * function completes before return. If it does not complete, the caller
-   * should call the ->connecting() function until it is.
-   */
-  CURLcode (*connect_it)(struct Curl_easy *data, bool *done);
-
-  /* See above. */
-  CURLcode (*connecting)(struct Curl_easy *data, bool *done);
-  CURLcode (*doing)(struct Curl_easy *data, bool *done);
-
-  /* Called from the multi interface during the PROTOCONNECT phase, and it
-     should then return a proper fd set */
-  CURLcode (*proto_pollset)(struct Curl_easy *data,
-                            struct easy_pollset *ps);
-
-  /* Called from the multi interface during the DOING phase, and it should
-     then return a proper fd set */
-  CURLcode (*doing_pollset)(struct Curl_easy *data,
-                            struct easy_pollset *ps);
-
-  /* Called from the multi interface during the DO_MORE phase, and it should
-     then return a proper fd set */
-  CURLcode (*domore_pollset)(struct Curl_easy *data,
-                            struct easy_pollset *ps);
-
-  /* Called from the multi interface during the DO_DONE, PERFORM and
-     WAITPERFORM phases, and it should then return a proper fd set. Not setting
-     this will make libcurl use the generic default one. */
-  CURLcode (*perform_pollset)(struct Curl_easy *data,
-                              struct easy_pollset *ps);
-
-  /* This function *MAY* be set to a protocol-dependent function that is run
-   * by the curl_disconnect(), as a step in the disconnection. If the handler
-   * is called because the connection has been considered dead,
-   * dead_connection is set to TRUE. The connection is (again) associated with
-   * the transfer here.
-   */
-  CURLcode (*disconnect)(struct Curl_easy *, struct connectdata *,
-                         bool dead_connection);
-
-  /* If used, this function gets called from transfer.c to
-     allow the protocol to do extra handling in writing response to
-     the client. */
-  CURLcode (*write_resp)(struct Curl_easy *data, const char *buf, size_t blen,
-                         bool is_eos);
-
-  /* If used, this function gets called from transfer.c to
-     allow the protocol to do extra handling in writing a single response
-     header line to the client. */
-  CURLcode (*write_resp_hd)(struct Curl_easy *data,
-                            const char *hd, size_t hdlen, bool is_eos);
-
-  /* If used, this function checks for a connection managed by this
-    protocol and currently not in use, if it should be considered dead. */
-  bool (*connection_is_dead)(struct Curl_easy *data,
-                             struct connectdata *conn);
-
-  /* attach() attaches this transfer to this connection */
-  void (*attach)(struct Curl_easy *data, struct connectdata *conn);
-
-  /* return CURLE_OK if a redirect to `newurl` should be followed,
-     CURLE_TOO_MANY_REDIRECTS otherwise. May alter `data` to change
-     the way the follow request is performed. */
-  CURLcode (*follow)(struct Curl_easy *data, const char *newurl,
-                     followtype type);
-};
-
-struct Curl_scheme {
-  const char *name;       /* URL scheme name in lowercase */
-  const struct Curl_protocol *run; /* implementation */
-  curl_prot_t protocol;   /* See CURLPROTO_* - this needs to be the single
-                             specific protocol bit */
-  curl_prot_t family;     /* single bit for protocol family; the non-TLS name
-                             of the protocol this is */
-  uint32_t flags;         /* Extra particular characteristics, see PROTOPT_* */
-  uint16_t defport;       /* Default port. */
-};
-
-#define PROTOPT_NONE 0             /* nothing extra */
-#define PROTOPT_SSL (1 << 0)       /* uses SSL */
-#define PROTOPT_DUAL (1 << 1)      /* this protocol uses two connections */
-#define PROTOPT_CLOSEACTION (1 << 2) /* need action before socket close */
-/* some protocols will have to call the underlying functions without regard to
-   what exact state the socket signals. IE even if the socket says "readable",
-   the send function might need to be called while uploading, or vice versa.
-*/
-#define PROTOPT_DIRLOCK (1 << 3)
-#define PROTOPT_NONETWORK (1 << 4) /* protocol does not use the network! */
-#define PROTOPT_NEEDSPWD (1 << 5)  /* needs a password, and if none is set it
-                                      gets a default */
-#define PROTOPT_NOURLQUERY (1 << 6)  /* protocol cannot handle
-                                        URL query strings (?foo=bar) ! */
-#define PROTOPT_CREDSPERREQUEST (1 << 7) /* requires login credentials per
-                                            request instead of per
-                                            connection */
-#define PROTOPT_ALPN (1 << 8) /* set ALPN for this */
-/* (1 << 9) was PROTOPT_STREAM, now free */
-#define PROTOPT_URLOPTIONS (1 << 10) /* allow options part in the userinfo
-                                        field of the URL */
-#define PROTOPT_PROXY_AS_HTTP (1 << 11) /* allow this non-HTTP scheme over a
-                                           HTTP proxy as HTTP proxies may know
-                                           this protocol and act as
-                                           a gateway */
-#define PROTOPT_WILDCARD (1 << 12)  /* protocol supports wildcard matching */
-#define PROTOPT_USERPWDCTRL (1 << 13) /* Allow "control bytes" (< 32 ASCII) in
-                                         username and password */
-#define PROTOPT_NOTCPPROXY (1 << 14)  /* this protocol cannot proxy over TCP */
-#define PROTOPT_SSL_REUSE (1 << 15)   /* this protocol may reuse an existing
-                                         SSL connection in the same family
-                                         without having PROTOPT_SSL. */
-#define PROTOPT_CONN_REUSE (1 << 16)  /* this protocol can reuse connections */
-
 #define TRNSPRT_NONE 0
 #define TRNSPRT_TCP  3
 #define TRNSPRT_UDP  4
index 88584704b542dccfc48151de4ac200157d0de520..44e72ab802bf44388d2c69de7f2e32e6a4e3bf4e 100644 (file)
@@ -29,9 +29,6 @@
 extern const struct Curl_protocol Curl_protocol_sftp;
 extern const struct Curl_protocol Curl_protocol_scp;
 
-extern const struct Curl_scheme Curl_scheme_sftp;
-extern const struct Curl_scheme Curl_scheme_scp;
-
 #ifdef USE_SSH
 
 #ifdef USE_LIBSSH2
index d499a633af4bdff71738d7d1905639c2accdae99..0ba4a9e690781977ec4d1b2e637372632e7db514 100644 (file)
@@ -331,34 +331,3 @@ CURLcode Curl_ssh_range(struct Curl_easy *data,
 }
 
 #endif /* USE_SSH */
-
-/*
- * SFTP protocol handler.
- */
-const struct Curl_scheme Curl_scheme_sftp = {
-  "SFTP",                               /* scheme */
-#ifndef USE_SSH
-  NULL,
-#else
-  &Curl_protocol_sftp,
-#endif
-  CURLPROTO_SFTP,                       /* protocol */
-  CURLPROTO_SFTP,                       /* family */
-  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | /* flags */
-  PROTOPT_NOURLQUERY | PROTOPT_CONN_REUSE,
-  PORT_SSH                              /* defport */
-};
-
-const struct Curl_scheme Curl_scheme_scp = {
-  "SCP",                                /* scheme */
-#ifndef USE_SSH
-  NULL,
-#else
-  &Curl_protocol_scp,
-#endif
-  CURLPROTO_SCP,                        /* protocol */
-  CURLPROTO_SCP,                        /* family */
-  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | /* flags */
-  PROTOPT_NOURLQUERY | PROTOPT_CONN_REUSE,
-  PORT_SSH,                             /* defport */
-};
index 496eb1f8e1b22d8b6bc915bec15bb84a3bcea6c3..ee399ef7479e11309244d2b96a4f443b23d45e99 100644 (file)
--- a/lib/ws.c
+++ b/lib/ws.c
@@ -1915,7 +1915,7 @@ out:
   return result;
 }
 
-static const struct Curl_protocol Curl_protocol_ws = {
+const struct Curl_protocol Curl_protocol_ws = {
   ws_setup_conn,                        /* setup_connection */
   Curl_http,                            /* do_it */
   Curl_http_done,                       /* done */
@@ -1980,32 +1980,3 @@ CURL_EXTERN CURLcode curl_ws_start_frame(CURL *curl,
 }
 
 #endif /* !CURL_DISABLE_WEBSOCKETS */
-
-const struct Curl_scheme Curl_scheme_ws = {
-  "WS",                                 /* scheme */
-#ifdef CURL_DISABLE_WEBSOCKETS
-  ZERO_NULL,
-#else
-  &Curl_protocol_ws,
-#endif
-  CURLPROTO_WS,                         /* protocol */
-  CURLPROTO_HTTP,                       /* family */
-  PROTOPT_CREDSPERREQUEST |             /* flags */
-  PROTOPT_USERPWDCTRL,
-  PORT_HTTP                             /* defport */
-}
-;
-
-const struct Curl_scheme Curl_scheme_wss = {
-  "WSS",                                /* scheme */
-#if defined(CURL_DISABLE_WEBSOCKETS) || !defined(USE_SSL)
-  ZERO_NULL,
-#else
-  &Curl_protocol_ws,
-#endif
-  CURLPROTO_WSS,                        /* protocol */
-  CURLPROTO_HTTP,                       /* family */
-  PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | /* flags */
-  PROTOPT_USERPWDCTRL,
-  PORT_HTTPS                            /* defport */
-};
index 757eae0f0f69f898821ad80a622be2fdd4aa4b90..71b5b3fff0b59531a1fad5b3219041219b03a569 100644 (file)
--- a/lib/ws.h
+++ b/lib/ws.h
  ***************************************************************************/
 #include "curl_setup.h"
 
-extern const struct Curl_scheme Curl_scheme_ws;
-extern const struct Curl_scheme Curl_scheme_wss;
-
 #if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)
 
+extern const struct Curl_protocol Curl_protocol_ws;
+
 /* meta key for storing protocol meta at connection */
 #define CURL_META_PROTO_WS_CONN   "meta:proto:ws:conn"