]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
lib: separate scheme info from protocol implementation
authorDaniel Stenberg <daniel@haxx.se>
Sun, 18 Jan 2026 23:15:41 +0000 (00:15 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 19 Jan 2026 22:15:13 +0000 (23:15 +0100)
This allows builds know about all schemes - but only have the protocol
implementations for those actually built-in.

It further allows multiple protocols to reuse the same protocol setup
and functions for both TLS and non-TLS implementations instead of
needing two (or more) structs.

The scheme information is now in 'struct Curl_scheme' and all the
function pointers for each scheme/protocol implementation are in struct
Curl_protocol.

The URL API now always work with all known protocols.

Closes #20351

59 files changed:
lib/cf-h1-proxy.c
lib/cf-ip-happy.c
lib/cf-socket.c
lib/cfilters.c
lib/connect.c
lib/cookie.c
lib/cshutdn.c
lib/curl_ldap.h
lib/curl_rtmp.c
lib/curl_rtmp.h
lib/cw-out.c
lib/dict.c
lib/dict.h
lib/doh.c
lib/file.c
lib/file.h
lib/ftp.c
lib/ftp.h
lib/gopher.c
lib/gopher.h
lib/headers.c
lib/http.c
lib/http.h
lib/imap.c
lib/imap.h
lib/ldap.c
lib/mqtt.c
lib/mqtt.h
lib/multi.c
lib/openldap.c
lib/pop3.c
lib/pop3.h
lib/rtsp.c
lib/rtsp.h
lib/sendf.c
lib/setopt.c
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/transfer.c
lib/url.c
lib/url.h
lib/urlapi.c
lib/urldata.h
lib/vauth/vauth.c
lib/vquic/vquic.c
lib/vssh/libssh.c
lib/vssh/libssh2.c
lib/vssh/ssh.h
lib/vssh/vssh.c
lib/vssh/vssh.h
lib/ws.c
lib/ws.h
scripts/schemetable.c

index c41a68dee1d1c915fa991a00b7874bda97e4d94d..fcf2b70ed70627015464990e10c85c8995ebb8f9 100644 (file)
@@ -106,8 +106,8 @@ static CURLcode tunnel_init(struct Curl_cfilter *cf,
 {
   struct h1_tunnel_state *ts;
 
-  if(cf->conn->handler->flags & PROTOPT_NOTCPPROXY) {
-    failf(data, "%s cannot be done over CONNECT", cf->conn->handler->scheme);
+  if(cf->conn->scheme->flags & PROTOPT_NOTCPPROXY) {
+    failf(data, "%s cannot be done over CONNECT", cf->conn->scheme->name);
     return CURLE_UNSUPPORTED_PROTOCOL;
   }
 
index a802ddacb42b0bcb878c2c20321a74a3a5f2d0c6..8db8c15b9f5b18ea484ffba668cb338ba4f3fb06 100644 (file)
@@ -793,7 +793,7 @@ static CURLcode cf_ip_happy_connect(struct Curl_cfilter *cf,
       cf_ip_happy_ctx_clear(cf, data);
       Curl_expire_done(data, EXPIRE_HAPPY_EYEBALLS);
 
-      if(cf->conn->handler->protocol & PROTO_FAMILY_SSH)
+      if(cf->conn->scheme->protocol & PROTO_FAMILY_SSH)
         Curl_pgrsTime(data, TIMER_APPCONNECT); /* we are connected already */
 #ifndef CURL_DISABLE_VERBOSE_STRINGS
       if(Curl_trc_cf_is_verbose(cf, data)) {
index 837f72e9af59a84a36a43fc79e1e109c2a8489aa..17b1a478700d7ce2e572ce2bce94e23a60bbdbad 100644 (file)
@@ -993,7 +993,7 @@ static void set_local_ip(struct Curl_cfilter *cf,
 
 #ifdef HAVE_GETSOCKNAME
   if((ctx->sock != CURL_SOCKET_BAD) &&
-     !(data->conn->handler->protocol & CURLPROTO_TFTP)) {
+     !(data->conn->scheme->protocol & CURLPROTO_TFTP)) {
     /* TFTP does not connect, so it cannot get the IP like this */
 
     char buffer[STRERROR_LEN];
index c6aa06a3b87e750b6583f4344fe47a94e77005e9..47c05c87a29a319b70d0c76aeca5aaba8f7e48f5 100644 (file)
@@ -611,7 +611,7 @@ bool Curl_conn_is_connected(struct connectdata *conn, int sockindex)
   cf = conn->cfilter[sockindex];
   if(cf)
     return (bool)cf->connected;
-  else if(conn->handler->flags & PROTOPT_NONETWORK)
+  else if(conn->scheme->flags & PROTOPT_NONETWORK)
     return TRUE;
   return FALSE;
 }
index c832f86086096ca5ec7e02fff6a390d304b22c87..a13405450bb1f4602cd5d7f43512dd5320d5fb22 100644 (file)
@@ -428,7 +428,7 @@ connect_sub_chain:
 #ifdef USE_SSL
     if((ctx->ssl_mode == CURL_CF_SSL_ENABLE ||
         (ctx->ssl_mode != CURL_CF_SSL_DISABLE &&
-         cf->conn->handler->flags & PROTOPT_SSL))       /* we want SSL */
+         cf->conn->scheme->flags & PROTOPT_SSL))       /* we want SSL */
        && !Curl_conn_is_ssl(cf->conn, cf->sockindex)) { /* it is missing */
       result = Curl_cf_ssl_insert_after(cf, data);
       if(result)
@@ -563,7 +563,7 @@ CURLcode Curl_conn_setup(struct Curl_easy *data,
   CURLcode result = CURLE_OK;
 
   DEBUGASSERT(data);
-  DEBUGASSERT(conn->handler);
+  DEBUGASSERT(conn->scheme);
   DEBUGASSERT(dns);
 
   Curl_resolv_unlink(data, &data->state.dns[sockindex]);
@@ -571,7 +571,7 @@ CURLcode Curl_conn_setup(struct Curl_easy *data,
 
 #ifndef CURL_DISABLE_HTTP
   if(!conn->cfilter[sockindex] &&
-     conn->handler->protocol == CURLPROTO_HTTPS) {
+     conn->scheme->protocol == CURLPROTO_HTTPS) {
     DEBUGASSERT(ssl_mode != CURL_CF_SSL_DISABLE);
     result = Curl_cf_https_setup(data, conn, sockindex);
     if(result)
index e385f6e9e9932f5ea5d0eb9614968d8a80e751f3..2c57226dc5cb4726104f8c7c4b7449595cbc3b3d 100644 (file)
@@ -1234,7 +1234,7 @@ static int cookie_sort_ct(const void *p1, const void *p2)
 
 bool Curl_secure_context(struct connectdata *conn, const char *host)
 {
-  return conn->handler->protocol & (CURLPROTO_HTTPS | CURLPROTO_WSS) ||
+  return conn->scheme->protocol & (CURLPROTO_HTTPS | CURLPROTO_WSS) ||
     curl_strequal("localhost", host) ||
     !strcmp(host, "127.0.0.1") ||
     !strcmp(host, "::1");
index 7de6c07b289efdcefff77cfd8e4930a09c1f95f8..1bd62346f3b189a61acc327b72596c62a9f4a490 100644 (file)
@@ -43,7 +43,7 @@ static void cshutdn_run_conn_handler(struct Curl_easy *data,
 {
   if(!conn->bits.shutdown_handler) {
 
-    if(conn->handler && conn->handler->disconnect) {
+    if(conn->scheme && conn->scheme->run->disconnect) {
       /* Some disconnect handlers do a blocking wait on server responses.
        * FTP/IMAP/SMTP and SFTP are among them. When using the internal
        * handle, set an overall short timeout so we do not hang for the
@@ -59,7 +59,7 @@ static void cshutdn_run_conn_handler(struct Curl_easy *data,
                    conn->connection_id, conn->bits.aborted));
       /* There are protocol handlers that block on retrieving
        * server responses here (FTP). Set a short timeout. */
-      conn->handler->disconnect(data, conn, (bool)conn->bits.aborted);
+      conn->scheme->run->disconnect(data, conn, (bool)conn->bits.aborted);
     }
 
     conn->bits.shutdown_handler = TRUE;
index 5ef32a5a30ae61bce27cc68ac75dbfc46aa634a2..7c1e1c4e9a96f821737592ccb41ebc885c38b27f 100644 (file)
  * SPDX-License-Identifier: curl
  *
  ***************************************************************************/
-#ifndef CURL_DISABLE_LDAP
-extern const struct Curl_handler Curl_handler_ldap;
+extern const struct Curl_protocol Curl_protocol_ldap;
 
-#if !defined(CURL_DISABLE_LDAPS) &&                    \
-  ((defined(USE_OPENLDAP) && defined(USE_SSL)) ||      \
-   (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)))
-extern const struct Curl_handler Curl_handler_ldaps;
-#endif
+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
+
 #endif /* HEADER_CURL_LDAP_H */
index 245ce04f6e8c656e12be355a6df3e9bd58e2dc5e..75b80913d8b94684d7fb86d90d79deff66f0d044 100644 (file)
  ***************************************************************************/
 #include "curl_setup.h"
 
-#ifdef USE_LIBRTMP
-
 #include "curl_rtmp.h"
 #include "urldata.h"
+
+#ifdef USE_LIBRTMP
+
 #include "url.h"
 #include "curlx/nonblock.h"
 #include "progress.h" /* for Curl_pgrsSetUploadSize */
@@ -224,8 +225,7 @@ void Curl_rtmp_version(char *version, size_t len)
  * RTMP protocol handler.h, based on https://rtmpdump.mplayerhq.hu/
  */
 
-const struct Curl_handler Curl_handler_rtmp = {
-  "rtmp",                               /* scheme */
+static const struct Curl_protocol Curl_protocol_rtmp = {
   rtmp_setup_connection,                /* setup_connection */
   rtmp_do,                              /* do_it */
   rtmp_done,                            /* done */
@@ -243,135 +243,84 @@ const struct Curl_handler Curl_handler_rtmp = {
   ZERO_NULL,                            /* connection_check */
   ZERO_NULL,                            /* attach connection */
   ZERO_NULL,                            /* follow */
-  PORT_RTMP,                            /* defport */
+};
+
+#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 */
+  PROTOPT_NONE,                         /* flags */
+  PORT_RTMP,                            /* defport */
 };
 
-const struct Curl_handler Curl_handler_rtmpt = {
+const struct Curl_scheme Curl_scheme_rtmpt = {
   "rtmpt",                              /* scheme */
-  rtmp_setup_connection,                /* setup_connection */
-  rtmp_do,                              /* do_it */
-  rtmp_done,                            /* done */
-  ZERO_NULL,                            /* do_more */
-  rtmp_connect,                         /* connect_it */
-  ZERO_NULL,                            /* connecting */
-  ZERO_NULL,                            /* doing */
-  ZERO_NULL,                            /* proto_pollset */
-  ZERO_NULL,                            /* doing_pollset */
-  ZERO_NULL,                            /* domore_pollset */
-  ZERO_NULL,                            /* perform_pollset */
-  rtmp_disconnect,                      /* disconnect */
-  ZERO_NULL,                            /* write_resp */
-  ZERO_NULL,                            /* write_resp_hd */
-  ZERO_NULL,                            /* connection_check */
-  ZERO_NULL,                            /* attach connection */
-  ZERO_NULL,                            /* follow */
-  PORT_RTMPT,                           /* defport */
+#ifndef USE_LIBRTMP
+  ZERO_NULL,
+#else
+  &Curl_protocol_rtmp,
+#endif
   CURLPROTO_RTMPT,                      /* protocol */
   CURLPROTO_RTMPT,                      /* family */
-  PROTOPT_NONE                          /* flags */
+  PROTOPT_NONE,                         /* flags */
+  PORT_RTMPT,                           /* defport */
 };
 
-const struct Curl_handler Curl_handler_rtmpe = {
+const struct Curl_scheme Curl_scheme_rtmpe = {
   "rtmpe",                              /* scheme */
-  rtmp_setup_connection,                /* setup_connection */
-  rtmp_do,                              /* do_it */
-  rtmp_done,                            /* done */
-  ZERO_NULL,                            /* do_more */
-  rtmp_connect,                         /* connect_it */
-  ZERO_NULL,                            /* connecting */
-  ZERO_NULL,                            /* doing */
-  ZERO_NULL,                            /* proto_pollset */
-  ZERO_NULL,                            /* doing_pollset */
-  ZERO_NULL,                            /* domore_pollset */
-  ZERO_NULL,                            /* perform_pollset */
-  rtmp_disconnect,                      /* disconnect */
-  ZERO_NULL,                            /* write_resp */
-  ZERO_NULL,                            /* write_resp_hd */
-  ZERO_NULL,                            /* connection_check */
-  ZERO_NULL,                            /* attach connection */
-  ZERO_NULL,                            /* follow */
-  PORT_RTMP,                            /* defport */
+#ifndef USE_LIBRTMP
+  ZERO_NULL,
+#else
+  &Curl_protocol_rtmp,
+#endif
   CURLPROTO_RTMPE,                      /* protocol */
   CURLPROTO_RTMPE,                      /* family */
-  PROTOPT_NONE                          /* flags */
+  PROTOPT_NONE,                         /* flags */
+  PORT_RTMP,                            /* defport */
 };
 
-const struct Curl_handler Curl_handler_rtmpte = {
+const struct Curl_scheme Curl_scheme_rtmpte = {
   "rtmpte",                             /* scheme */
-  rtmp_setup_connection,                /* setup_connection */
-  rtmp_do,                              /* do_it */
-  rtmp_done,                            /* done */
-  ZERO_NULL,                            /* do_more */
-  rtmp_connect,                         /* connect_it */
-  ZERO_NULL,                            /* connecting */
-  ZERO_NULL,                            /* doing */
-  ZERO_NULL,                            /* proto_pollset */
-  ZERO_NULL,                            /* doing_pollset */
-  ZERO_NULL,                            /* domore_pollset */
-  ZERO_NULL,                            /* perform_pollset */
-  rtmp_disconnect,                      /* disconnect */
-  ZERO_NULL,                            /* write_resp */
-  ZERO_NULL,                            /* write_resp_hd */
-  ZERO_NULL,                            /* connection_check */
-  ZERO_NULL,                            /* attach connection */
-  ZERO_NULL,                            /* follow */
-  PORT_RTMPT,                           /* defport */
+#ifndef USE_LIBRTMP
+  ZERO_NULL,
+#else
+  &Curl_protocol_rtmp,
+#endif
   CURLPROTO_RTMPTE,                     /* protocol */
   CURLPROTO_RTMPTE,                     /* family */
-  PROTOPT_NONE                          /* flags */
+  PROTOPT_NONE,                         /* flags */
+  PORT_RTMPT,                           /* defport */
 };
 
-const struct Curl_handler Curl_handler_rtmps = {
+const struct Curl_scheme Curl_scheme_rtmps = {
   "rtmps",                              /* scheme */
-  rtmp_setup_connection,                /* setup_connection */
-  rtmp_do,                              /* do_it */
-  rtmp_done,                            /* done */
-  ZERO_NULL,                            /* do_more */
-  rtmp_connect,                         /* connect_it */
-  ZERO_NULL,                            /* connecting */
-  ZERO_NULL,                            /* doing */
-  ZERO_NULL,                            /* proto_pollset */
-  ZERO_NULL,                            /* doing_pollset */
-  ZERO_NULL,                            /* domore_pollset */
-  ZERO_NULL,                            /* perform_pollset */
-  rtmp_disconnect,                      /* disconnect */
-  ZERO_NULL,                            /* write_resp */
-  ZERO_NULL,                            /* write_resp_hd */
-  ZERO_NULL,                            /* connection_check */
-  ZERO_NULL,                            /* attach connection */
-  ZERO_NULL,                            /* follow */
-  PORT_RTMPS,                           /* defport */
+#ifndef USE_LIBRTMP
+  ZERO_NULL,
+#else
+  &Curl_protocol_rtmp,
+#endif
   CURLPROTO_RTMPS,                      /* protocol */
   CURLPROTO_RTMP,                       /* family */
-  PROTOPT_NONE                          /* flags */
+  PROTOPT_NONE,                         /* flags */
+  PORT_RTMPS,                           /* defport */
 };
 
-const struct Curl_handler Curl_handler_rtmpts = {
+const struct Curl_scheme Curl_scheme_rtmpts = {
   "rtmpts",                             /* scheme */
-  rtmp_setup_connection,                /* setup_connection */
-  rtmp_do,                              /* do_it */
-  rtmp_done,                            /* done */
-  ZERO_NULL,                            /* do_more */
-  rtmp_connect,                         /* connect_it */
-  ZERO_NULL,                            /* connecting */
-  ZERO_NULL,                            /* doing */
-  ZERO_NULL,                            /* proto_pollset */
-  ZERO_NULL,                            /* doing_pollset */
-  ZERO_NULL,                            /* domore_pollset */
-  ZERO_NULL,                            /* perform_pollset */
-  rtmp_disconnect,                      /* disconnect */
-  ZERO_NULL,                            /* write_resp */
-  ZERO_NULL,                            /* write_resp_hd */
-  ZERO_NULL,                            /* connection_check */
-  ZERO_NULL,                            /* attach connection */
-  ZERO_NULL,                            /* follow */
-  PORT_RTMPS,                           /* defport */
+#ifndef USE_LIBRTMP
+  ZERO_NULL,
+#else
+  &Curl_protocol_rtmp,
+#endif
   CURLPROTO_RTMPTS,                     /* protocol */
   CURLPROTO_RTMPT,                      /* family */
-  PROTOPT_NONE                          /* flags */
+  PROTOPT_NONE,                         /* flags */
+  PORT_RTMPS,                           /* defport */
 };
-
-#endif /* USE_LIBRTMP */
index 339d3a4384deeadd0178cda87f59f74aa8c1cfe2..e57d20c33a838cd804d2fd4f1327ceccc5d5c932 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_handler Curl_handler_rtmp;
-extern const struct Curl_handler Curl_handler_rtmpt;
-extern const struct Curl_handler Curl_handler_rtmpe;
-extern const struct Curl_handler Curl_handler_rtmpte;
-extern const struct Curl_handler Curl_handler_rtmps;
-extern const struct Curl_handler Curl_handler_rtmpts;
-
 void Curl_rtmp_version(char *version, size_t len);
 #endif
 
index 3936cf0276b32f5d964c769b9f4a7f05b4d77bda..88abbb7758f438e541296548540f27cd250f2f2e 100644 (file)
@@ -191,7 +191,7 @@ static CURLcode cw_out_cb_write(struct cw_out_ctx *ctx,
                  blen, (otype == CW_OUT_HDS) ? "header" : "body",
                  nwritten);
   if(CURL_WRITEFUNC_PAUSE == nwritten) {
-    if(data->conn->handler->flags & PROTOPT_NONETWORK) {
+    if(data->conn->scheme->flags & PROTOPT_NONETWORK) {
       /* Protocols that work without network cannot be paused. This is
          actually only FILE:// just now, and it cannot pause since the
          transfer is not done using the "normal" procedure. */
index 54563b4e45145be86fa724ef8a3316fcc3caa20c..fcdea918cf2b8096fb51c0b94c0cb9d5201a8cf2 100644 (file)
@@ -22,6 +22,8 @@
  *
  ***************************************************************************/
 #include "curl_setup.h"
+#include "urldata.h"
+#include "dict.h"
 
 #ifndef CURL_DISABLE_DICT
 
 #include <unistd.h>
 #endif
 
-#include "urldata.h"
 #include "transfer.h"
 #include "curl_trc.h"
 #include "escape.h"
-#include "dict.h"
 
 #define DICT_MATCH   "/MATCH:"
 #define DICT_MATCH2  "/M:"
@@ -273,10 +273,9 @@ error:
 }
 
 /*
- * DICT protocol handler.
+ * DICT protocol
  */
-const struct Curl_handler Curl_handler_dict = {
-  "dict",                               /* scheme */
+static const struct Curl_protocol Curl_protocol_dict = {
   ZERO_NULL,                            /* setup_connection */
   dict_do,                              /* do_it */
   ZERO_NULL,                            /* done */
@@ -294,10 +293,22 @@ const struct Curl_handler Curl_handler_dict = {
   ZERO_NULL,                            /* connection_check */
   ZERO_NULL,                            /* attach connection */
   ZERO_NULL,                            /* follow */
-  PORT_DICT,                            /* defport */
-  CURLPROTO_DICT,                       /* protocol */
-  CURLPROTO_DICT,                       /* family */
-  PROTOPT_NONE | PROTOPT_NOURLQUERY     /* flags */
 };
 
 #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 4025c8bcdd06962a8c9df34e93f2ebbd67a53284..b5d6947d238622a3fb7a41ca132fcd4b1334d841 100644 (file)
@@ -23,8 +23,6 @@
  * SPDX-License-Identifier: curl
  *
  ***************************************************************************/
-#ifndef CURL_DISABLE_DICT
-extern const struct Curl_handler Curl_handler_dict;
-#endif
+extern const struct Curl_scheme Curl_scheme_dict;
 
 #endif /* HEADER_CURL_DICT_H */
index faf38d7adc1e50309025f35cb488cb609839dfb5..34801c26677533c9a863809f876ef924c755e294 100644 (file)
--- a/lib/doh.c
+++ b/lib/doh.c
@@ -495,7 +495,7 @@ CURLcode Curl_doh(struct Curl_easy *data, const char *hostname,
 #endif
 
 #ifdef USE_HTTPSRR
-  if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
+  if(conn->scheme->protocol & PROTO_FAMILY_HTTP) {
     /* Only use HTTPS RR for HTTP(S) transfers */
     char *qname = NULL;
     if(port != PORT_HTTPS) {
index ef4fc8042f8128f29517c0a29442f3ef6dc8bec3..753aed2dbe30430473f6aafa8c401d5e889e2c4f 100644 (file)
@@ -22,6 +22,8 @@
  *
  ***************************************************************************/
 #include "curl_setup.h"
+#include "urldata.h"
+#include "file.h"
 
 #ifndef CURL_DISABLE_FILE
 
 #include <dirent.h>
 #endif
 
-#include "urldata.h"
 #include "progress.h"
 #include "sendf.h"
 #include "curl_trc.h"
 #include "escape.h"
-#include "file.h"
 #include "multiif.h"
 #include "transfer.h"
 #include "url.h"
@@ -605,11 +605,7 @@ out:
   return result;
 }
 
-/*
- * FILE scheme handler.
- */
-const struct Curl_handler Curl_handler_file = {
-  "file",                               /* scheme */
+static const struct Curl_protocol Curl_protocol_file = {
   file_setup_connection,                /* setup_connection */
   file_do,                              /* do_it */
   file_done,                            /* done */
@@ -627,10 +623,22 @@ const struct Curl_handler Curl_handler_file = {
   ZERO_NULL,                            /* connection_check */
   ZERO_NULL,                            /* attach connection */
   ZERO_NULL,                            /* follow */
-  0,                                    /* defport */
-  CURLPROTO_FILE,                       /* protocol */
-  CURLPROTO_FILE,                       /* family */
-  PROTOPT_NONETWORK | PROTOPT_NOURLQUERY /* flags */
 };
 
 #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 cb3552d924dcb75c1596fd8f36b0cec42c8ecd83..a3065441aee2b735974e113e7647c669f2dd2939 100644 (file)
@@ -23,8 +23,6 @@
  * SPDX-License-Identifier: curl
  *
  ***************************************************************************/
-#ifndef CURL_DISABLE_FILE
-extern const struct Curl_handler Curl_handler_file;
-#endif
+extern const struct Curl_scheme Curl_scheme_file;
 
 #endif /* HEADER_CURL_FILE_H */
index 42ac5f5c74b4811d41dfcc78b2165655fabdf397..fa08b3d5c6c1f875fa8b3353e2ab7134713e0bb4 100644 (file)
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -22,6 +22,7 @@
  *
  ***************************************************************************/
 #include "curl_setup.h"
+#include "urldata.h"
 
 #ifndef CURL_DISABLE_FTP
 
@@ -39,7 +40,6 @@
 #include <inet.h>
 #endif
 
-#include "urldata.h"
 #include "sendf.h"
 #include "curl_addrinfo.h"
 #include "curl_trc.h"
@@ -4340,10 +4340,9 @@ bool ftp_conns_match(struct connectdata *needle, struct connectdata *conn)
 }
 
 /*
- * FTP protocol handler.
+ * FTP protocol.
  */
-const struct Curl_handler Curl_handler_ftp = {
-  "ftp",                           /* scheme */
+static const struct Curl_protocol Curl_protocol_ftp = {
   ftp_setup_connection,            /* setup_connection */
   ftp_do,                          /* do_it */
   ftp_done,                        /* done */
@@ -4361,45 +4360,43 @@ const struct Curl_handler Curl_handler_ftp = {
   ZERO_NULL,                       /* connection_check */
   ZERO_NULL,                       /* attach connection */
   ZERO_NULL,                       /* follow */
-  PORT_FTP,                        /* defport */
+};
+
+#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 */
+  PROTOPT_CONN_REUSE, /* flags */
+  PORT_FTP,                        /* defport */
 };
 
-#ifdef USE_SSL
 /*
  * FTPS protocol handler.
  */
-const struct Curl_handler Curl_handler_ftps = {
+const struct Curl_scheme Curl_scheme_ftps = {
   "ftps",                          /* scheme */
-  ftp_setup_connection,            /* setup_connection */
-  ftp_do,                          /* do_it */
-  ftp_done,                        /* done */
-  ftp_do_more,                     /* do_more */
-  ftp_connect,                     /* connect_it */
-  ftp_multi_statemach,             /* connecting */
-  ftp_doing,                       /* doing */
-  ftp_pollset,                     /* proto_pollset */
-  ftp_pollset,                     /* doing_pollset */
-  ftp_domore_pollset,              /* domore_pollset */
-  ZERO_NULL,                       /* perform_pollset */
-  ftp_disconnect,                  /* disconnect */
-  ZERO_NULL,                       /* write_resp */
-  ZERO_NULL,                       /* write_resp_hd */
-  ZERO_NULL,                       /* connection_check */
-  ZERO_NULL,                       /* attach connection */
-  ZERO_NULL,                       /* follow */
-  PORT_FTPS,                       /* defport */
+#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 */
+  PROTOPT_CONN_REUSE, /* flags */
+  PORT_FTPS,                       /* defport */
 };
-#endif
-
-#endif /* CURL_DISABLE_FTP */
index 0e32d39832dba466e06444a7b46f7ca9f9b24c2c..ef1aacb40c89e42c2ff0f57ebfdc4888bfe1187f 100644 (file)
--- a/lib/ftp.h
+++ b/lib/ftp.h
 
 #include "pingpong.h"
 
-#ifndef CURL_DISABLE_FTP
-extern const struct Curl_handler Curl_handler_ftp;
-
-#ifdef USE_SSL
-extern const struct Curl_handler Curl_handler_ftps;
-#endif
+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 */
index 9d35c68f316a4c3b499a4f7509b45f7c5edf32ad..3ab88ad1532d7778301f835d83b8d962426b681d 100644 (file)
  *
  ***************************************************************************/
 #include "curl_setup.h"
+#include "urldata.h"
+#include "gopher.h"
 
 #ifndef CURL_DISABLE_GOPHER
 
-#include "urldata.h"
 #include "transfer.h"
 #include "sendf.h"
 #include "curl_trc.h"
 #include "cfilters.h"
 #include "connect.h"
-#include "gopher.h"
 #include "select.h"
 #include "url.h"
 #include "escape.h"
@@ -172,8 +172,7 @@ static CURLcode gopher_do(struct Curl_easy *data, bool *done)
  * connect-command-download protocols.
  */
 
-const struct Curl_handler Curl_handler_gopher = {
-  "gopher",                             /* scheme */
+static const struct Curl_protocol Curl_protocol_gopher = {
   ZERO_NULL,                            /* setup_connection */
   gopher_do,                            /* do_it */
   ZERO_NULL,                            /* done */
@@ -191,15 +190,10 @@ const struct Curl_handler Curl_handler_gopher = {
   ZERO_NULL,                            /* connection_check */
   ZERO_NULL,                            /* attach connection */
   ZERO_NULL,                            /* follow */
-  PORT_GOPHER,                          /* defport */
-  CURLPROTO_GOPHER,                     /* protocol */
-  CURLPROTO_GOPHER,                     /* family */
-  PROTOPT_NONE                          /* flags */
 };
 
 #ifdef USE_SSL
-const struct Curl_handler Curl_handler_gophers = {
-  "gophers",                            /* scheme */
+static const struct Curl_protocol Curl_protocol_gophers = {
   ZERO_NULL,                            /* setup_connection */
   gopher_do,                            /* do_it */
   ZERO_NULL,                            /* done */
@@ -217,11 +211,33 @@ const struct Curl_handler Curl_handler_gophers = {
   ZERO_NULL,                            /* connection_check */
   ZERO_NULL,                            /* attach connection */
   ZERO_NULL,                            /* follow */
-  PORT_GOPHER,                          /* defport */
-  CURLPROTO_GOPHERS,                    /* protocol */
-  CURLPROTO_GOPHER,                     /* family */
-  PROTOPT_SSL                           /* flags */
 };
 #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 1e6a5d2d30e6902674e43e29a7d46d2f9a8b2f5d..bc977bc1bcc0de35a0dfae40b67c70e15ac195a6 100644 (file)
  * SPDX-License-Identifier: curl
  *
  ***************************************************************************/
-#ifndef CURL_DISABLE_GOPHER
-extern const struct Curl_handler Curl_handler_gopher;
-#ifdef USE_SSL
-extern const struct Curl_handler Curl_handler_gophers;
-#endif
-#endif
+extern const struct Curl_scheme Curl_scheme_gopher;
+extern const struct Curl_scheme Curl_scheme_gophers;
 
 #endif /* HEADER_CURL_GOPHER_H */
index c1880453540c5aa9b4a3315beb20dfc03040e063..5a6b120c962f175a89ff47168ad7c2e91c020ff7 100644 (file)
@@ -326,7 +326,7 @@ CURLcode Curl_headers_init(struct Curl_easy *data)
   struct Curl_cwriter *writer;
   CURLcode result;
 
-  if(data->conn && (data->conn->handler->protocol & PROTO_FAMILY_HTTP)) {
+  if(data->conn && (data->conn->scheme->protocol & PROTO_FAMILY_HTTP)) {
     /* avoid installing it twice */
     if(Curl_cwriter_get_by_name(data, hds_cw_collect.name))
       return CURLE_OK;
index 4334428bec12af352f99a6e50bf01d769d8a8de7..44e64b1d509e7b763daba66ca33631c0fb24f447 100644 (file)
@@ -22,6 +22,7 @@
  *
  ***************************************************************************/
 #include "curl_setup.h"
+#include "urldata.h"
 
 #ifndef CURL_DISABLE_HTTP
 
@@ -46,7 +47,6 @@
 #include <sys/param.h>
 #endif
 
-#include "urldata.h"
 #include "transfer.h"
 #include "sendf.h"
 #include "curl_trc.h"
@@ -1236,14 +1236,14 @@ CURLcode Curl_http_follow(struct Curl_easy *data, const char *newurl,
       }
       else {
         char *scheme;
-        const struct Curl_handler *p;
+        const struct Curl_scheme *p;
         uc = curl_url_get(data->state.uh, CURLUPART_SCHEME, &scheme, 0);
         if(uc) {
           curlx_free(follow_url);
           return Curl_uc_to_curlcode(uc);
         }
 
-        p = Curl_get_scheme_handler(scheme);
+        p = Curl_get_scheme(scheme);
         if(p && (p->protocol != data->info.conn_protocol)) {
           infof(data, "Clear auth, redirects scheme from %s to %s",
                 data->info.conn_scheme, scheme);
@@ -1930,11 +1930,11 @@ void Curl_http_method(struct Curl_easy *data,
   Curl_HttpReq httpreq = (Curl_HttpReq)data->state.httpreq;
   const char *request;
 #ifndef CURL_DISABLE_WEBSOCKETS
-  if(data->conn->handler->protocol & (CURLPROTO_WS | CURLPROTO_WSS))
+  if(data->conn->scheme->protocol & (CURLPROTO_WS | CURLPROTO_WSS))
     httpreq = HTTPREQ_GET;
   else
 #endif
-  if((data->conn->handler->protocol & (PROTO_FAMILY_HTTP | CURLPROTO_FTP)) &&
+  if((data->conn->scheme->protocol & (PROTO_FAMILY_HTTP | CURLPROTO_FTP)) &&
      data->state.upload)
     httpreq = HTTPREQ_PUT;
 
@@ -1999,7 +1999,7 @@ static CURLcode http_set_aptr_host(struct Curl_easy *data)
       return CURLE_OUT_OF_MEMORY;
 
     data->state.first_remote_port = conn->remote_port;
-    data->state.first_remote_protocol = conn->handler->protocol;
+    data->state.first_remote_protocol = conn->scheme->protocol;
   }
   Curl_safefree(aptr->host);
 
@@ -2971,7 +2971,7 @@ static CURLcode http_add_hd(struct Curl_easy *data,
       result = Curl_http2_request_upgrade(req, data);
     }
 #ifndef CURL_DISABLE_WEBSOCKETS
-    if(!result && conn->handler->protocol & (CURLPROTO_WS | CURLPROTO_WSS))
+    if(!result && conn->scheme->protocol & (CURLPROTO_WS | CURLPROTO_WSS))
       result = Curl_ws_request(data, req);
 #endif
     break;
@@ -3172,7 +3172,7 @@ static statusline checkprotoprefix(struct Curl_easy *data,
                                    const char *s, size_t len)
 {
 #ifndef CURL_DISABLE_RTSP
-  if(conn->handler->protocol & CURLPROTO_RTSP)
+  if(conn->scheme->protocol & CURLPROTO_RTSP)
     return checkrtspprefix(data, s, len);
 #else
   (void)conn;
@@ -3701,7 +3701,7 @@ static CURLcode http_header(struct Curl_easy *data,
 
   if(!result) {
     struct connectdata *conn = data->conn;
-    if(conn->handler->protocol & CURLPROTO_RTSP)
+    if(conn->scheme->protocol & CURLPROTO_RTSP)
       result = Curl_rtsp_parseheader(data, hd);
   }
   return result;
@@ -3993,7 +3993,7 @@ static CURLcode http_on_response(struct Curl_easy *data,
 
   if((k->size == -1) && !k->chunk && !conn->bits.close &&
      (k->httpversion == 11) &&
-     !(conn->handler->protocol & CURLPROTO_RTSP) &&
+     !(conn->scheme->protocol & CURLPROTO_RTSP) &&
      data->state.httpreq != HTTPREQ_HEAD) {
     /* On HTTP 1.1, when connection is not to get closed, but no
        Content-Length nor Transfer-Encoding chunked have been
@@ -4212,7 +4212,7 @@ static CURLcode http_rw_hd(struct Curl_easy *data,
     bool fine_statusline = FALSE;
 
     k->httpversion = 0; /* Do not know yet */
-    if(data->conn->handler->protocol & PROTO_FAMILY_HTTP) {
+    if(data->conn->scheme->protocol & PROTO_FAMILY_HTTP) {
       /*
        * https://datatracker.ietf.org/doc/html/rfc7230#section-3.1.2
        *
@@ -4279,7 +4279,7 @@ static CURLcode http_rw_hd(struct Curl_easy *data,
         }
       }
     }
-    else if(data->conn->handler->protocol & CURLPROTO_RTSP) {
+    else if(data->conn->scheme->protocol & CURLPROTO_RTSP) {
       const char *p = hd;
       struct Curl_str ver;
       curl_off_t status;
@@ -4984,8 +4984,7 @@ void Curl_http_resp_free(struct http_resp *resp)
 /*
  * HTTP handler interface.
  */
-const struct Curl_handler Curl_handler_http = {
-  "http",                               /* scheme */
+static const struct Curl_protocol Curl_protocol_http = {
   Curl_http_setup_conn,                 /* setup_connection */
   Curl_http,                            /* do_it */
   Curl_http_done,                       /* done */
@@ -5003,43 +5002,40 @@ const struct Curl_handler Curl_handler_http = {
   ZERO_NULL,                            /* connection_check */
   ZERO_NULL,                            /* attach connection */
   Curl_http_follow,                     /* follow */
-  PORT_HTTP,                            /* defport */
+};
+
+#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
-
+  PROTOPT_USERPWDCTRL | PROTOPT_CONN_REUSE,
+  PORT_HTTP,                            /* defport */
 };
 
-#ifdef USE_SSL
 /*
  * HTTPS handler interface.
  */
-const struct Curl_handler Curl_handler_https = {
+const struct Curl_scheme Curl_scheme_https = {
   "https",                              /* scheme */
-  Curl_http_setup_conn,                 /* setup_connection */
-  Curl_http,                            /* do_it */
-  Curl_http_done,                       /* done */
-  ZERO_NULL,                            /* do_more */
-  ZERO_NULL,                            /* connect_it */
-  NULL,                                 /* connecting */
-  ZERO_NULL,                            /* doing */
-  NULL,                                 /* proto_pollset */
-  Curl_http_doing_pollset,              /* doing_pollset */
-  ZERO_NULL,                            /* domore_pollset */
-  Curl_http_perform_pollset,            /* perform_pollset */
-  ZERO_NULL,                            /* disconnect */
-  Curl_http_write_resp,                 /* write_resp */
-  Curl_http_write_resp_hd,              /* write_resp_hd */
-  ZERO_NULL,                            /* connection_check */
-  ZERO_NULL,                            /* attach connection */
-  Curl_http_follow,                     /* follow */
-  PORT_HTTPS,                           /* defport */
+#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
+  PROTOPT_USERPWDCTRL | PROTOPT_CONN_REUSE,
+  PORT_HTTPS,                           /* defport */
 };
-#endif
-
-#endif /* CURL_DISABLE_HTTP */
index 89810b1757e197bb1369694cc02a81b351bc906a..c78565bb2090062d278a0db17c0b030ccaad6c92 100644 (file)
@@ -53,17 +53,15 @@ typedef enum {
 /* 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
 
 #ifdef USE_HTTP3
 #include <stdint.h>
 #endif
 
-extern const struct Curl_handler Curl_handler_http;
-
-#ifdef USE_SSL
-extern const struct Curl_handler Curl_handler_https;
-#endif
 
 struct dynhds;
 
index 3a73521ac6ed2eb8da713dfe8d04b997e5b3977d..dc519e8264efc4c2ef84baf5538e90a46a57634e 100644 (file)
@@ -35,6 +35,8 @@
  *
  ***************************************************************************/
 #include "curl_setup.h"
+#include "urldata.h"
+#include "imap.h"
 
 #ifndef CURL_DISABLE_IMAP
 
@@ -53,7 +55,6 @@
 #endif
 
 #include "curlx/dynbuf.h"
-#include "urldata.h"
 #include "sendf.h"
 #include "curl_trc.h"
 #include "hostip.h"
@@ -61,7 +62,6 @@
 #include "transfer.h"
 #include "escape.h"
 #include "pingpong.h"
-#include "imap.h"
 #include "mime.h"
 #include "curlx/strparse.h"
 #include "strcase.h"
@@ -559,7 +559,7 @@ static CURLcode imap_perform_upgrade_tls(struct Curl_easy *data,
     if(result)
       goto out;
     /* Change the connection handler */
-    conn->handler = &Curl_handler_imaps;
+    conn->scheme = &Curl_scheme_imaps;
   }
 
   DEBUGASSERT(!imapc->ssldone);
@@ -2260,10 +2260,9 @@ static CURLcode imap_setup_connection(struct Curl_easy *data,
 }
 
 /*
- * IMAP protocol handler.
+ * IMAP protocol.
  */
-const struct Curl_handler Curl_handler_imap = {
-  "imap",                           /* scheme */
+static const struct Curl_protocol Curl_protocol_imap = {
   imap_setup_connection,            /* setup_connection */
   imap_do,                          /* do_it */
   imap_done,                        /* done */
@@ -2281,43 +2280,42 @@ const struct Curl_handler Curl_handler_imap = {
   ZERO_NULL,                        /* connection_check */
   ZERO_NULL,                        /* attach connection */
   ZERO_NULL,                        /* follow */
-  PORT_IMAP,                        /* defport */
+};
+
+#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
+  PROTOPT_CONN_REUSE,
+  PORT_IMAP,                        /* defport */
 };
 
-#ifdef USE_SSL
 /*
  * IMAPS protocol handler.
  */
-const struct Curl_handler Curl_handler_imaps = {
+const struct Curl_scheme Curl_scheme_imaps = {
   "imaps",                          /* scheme */
-  imap_setup_connection,            /* setup_connection */
-  imap_do,                          /* do_it */
-  imap_done,                        /* done */
-  ZERO_NULL,                        /* do_more */
-  imap_connect,                     /* connect_it */
-  imap_multi_statemach,             /* connecting */
-  imap_doing,                       /* doing */
-  imap_pollset,                     /* proto_pollset */
-  imap_pollset,                     /* doing_pollset */
-  ZERO_NULL,                        /* domore_pollset */
-  ZERO_NULL,                        /* perform_pollset */
-  imap_disconnect,                  /* disconnect */
-  ZERO_NULL,                        /* write_resp */
-  ZERO_NULL,                        /* write_resp_hd */
-  ZERO_NULL,                        /* connection_check */
-  ZERO_NULL,                        /* attach connection */
-  ZERO_NULL,                        /* follow */
-  PORT_IMAPS,                       /* defport */
+#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
+  PROTOPT_URLOPTIONS | PROTOPT_CONN_REUSE,
+  PORT_IMAPS,                       /* defport */
 };
-#endif
-
-#endif /* CURL_DISABLE_IMAP */
index 26306a6a22fc15eedca18503d284ed63ac46572d..f179991a65d29dc2161638cd30b86cdb914a20f6 100644 (file)
@@ -23,8 +23,8 @@
  * SPDX-License-Identifier: curl
  *
  ***************************************************************************/
-extern const struct Curl_handler Curl_handler_imap;
-extern const struct Curl_handler Curl_handler_imaps;
+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)
index e0f233d0c38cca023a5f0d39124fa00ad6f5bb3e..bff1f0f1675622fe6674a5be57fca37e44caa7fd 100644 (file)
@@ -22,6 +22,8 @@
  *
  ***************************************************************************/
 #include "curl_setup.h"
+#include "urldata.h"
+#include "curl_ldap.h"
 
 #if !defined(CURL_DISABLE_LDAP) && !defined(USE_OPENLDAP)
 
@@ -75,7 +77,6 @@
 # endif /* HAVE_LDAP_SSL && HAVE_LDAP_SSL_H */
 #endif
 
-#include "urldata.h"
 #include "cfilters.h"
 #include "sendf.h"
 #include "curl_trc.h"
@@ -84,7 +85,6 @@
 #include "transfer.h"
 #include "curlx/strparse.h"
 #include "bufref.h"
-#include "curl_ldap.h"
 #include "curlx/multibyte.h"
 #include "curlx/base64.h"
 #include "connect.h"
@@ -989,8 +989,7 @@ void Curl_ldap_version(char *buf, size_t bufsz)
 /*
  * LDAP protocol handler.
  */
-const struct Curl_handler Curl_handler_ldap = {
-  "ldap",                               /* scheme */
+const struct Curl_protocol Curl_protocol_ldap = {
   ZERO_NULL,                            /* setup_connection */
   ldap_do,                              /* do_it */
   ZERO_NULL,                            /* done */
@@ -1008,44 +1007,42 @@ const struct Curl_handler Curl_handler_ldap = {
   ZERO_NULL,                            /* connection_check */
   ZERO_NULL,                            /* attach connection */
   ZERO_NULL,                            /* follow */
-  PORT_LDAP,                            /* defport */
+};
+
+#if defined(__GNUC__) && defined(__APPLE__)
+#pragma GCC diagnostic pop
+#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 */
+  PROTOPT_SSL_REUSE,                    /* flags */
+  PORT_LDAP,                            /* defport */
 };
 
-#ifdef HAVE_LDAP_SSL
 /*
- * LDAPS protocol handler.
+ * LDAPS
  */
-const struct Curl_handler Curl_handler_ldaps = {
+const struct Curl_scheme Curl_scheme_ldaps = {
   "ldaps",                              /* scheme */
-  ZERO_NULL,                            /* setup_connection */
-  ldap_do,                              /* do_it */
-  ZERO_NULL,                            /* done */
-  ZERO_NULL,                            /* do_more */
-  ZERO_NULL,                            /* connect_it */
-  ZERO_NULL,                            /* connecting */
-  ZERO_NULL,                            /* doing */
-  ZERO_NULL,                            /* proto_pollset */
-  ZERO_NULL,                            /* doing_pollset */
-  ZERO_NULL,                            /* domore_pollset */
-  ZERO_NULL,                            /* perform_pollset */
-  ZERO_NULL,                            /* disconnect */
-  ZERO_NULL,                            /* write_resp */
-  ZERO_NULL,                            /* write_resp_hd */
-  ZERO_NULL,                            /* connection_check */
-  ZERO_NULL,                            /* attach connection */
-  ZERO_NULL,                            /* follow */
-  PORT_LDAPS,                           /* defport */
+#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 */
+  PROTOPT_SSL,                          /* flags */
+  PORT_LDAPS,                           /* defport */
 };
-#endif
-
-#if defined(__GNUC__) && defined(__APPLE__)
-#pragma GCC diagnostic pop
-#endif
-
-#endif /* !CURL_DISABLE_LDAP && !USE_OPENLDAP */
index 8ad59b8658e8d4047896d51e2772d352e68c8fc1..f5c8353a9f78f1ec1a2499685181dcd0d116f3a7 100644 (file)
  *
  ***************************************************************************/
 #include "curl_setup.h"
+#include "urldata.h"
 
 #ifndef CURL_DISABLE_MQTT
 
-#include "urldata.h"
 #include "transfer.h"
 #include "sendf.h"
 #include "curl_trc.h"
@@ -950,11 +950,10 @@ static CURLcode mqtts_connecting(struct Curl_easy *data, bool *done)
 }
 
 /*
- * MQTTS protocol handler.
+ * MQTTS protocol.
  */
 
-const struct Curl_handler Curl_handler_mqtts = {
-  "mqtts",                            /* scheme */
+static const struct Curl_protocol Curl_protocol_mqtts = {
   mqtt_setup_conn,                    /* setup_connection */
   mqtt_do,                            /* do_it */
   mqtt_done,                          /* done */
@@ -972,20 +971,15 @@ const struct Curl_handler Curl_handler_mqtts = {
   ZERO_NULL,                          /* connection_check */
   ZERO_NULL,                          /* attach connection */
   ZERO_NULL,                          /* follow */
-  PORT_MQTTS,                         /* defport */
-  CURLPROTO_MQTTS,                    /* protocol */
-  CURLPROTO_MQTT,                     /* family */
-  PROTOPT_SSL                         /* flags */
 };
 
 #endif
 
 /*
- * MQTT protocol handler.
+ * MQTT protocol.
  */
 
-const struct Curl_handler Curl_handler_mqtt = {
-  "mqtt",                             /* scheme */
+static const struct Curl_protocol Curl_protocol_mqtt = {
   mqtt_setup_conn,                    /* setup_connection */
   mqtt_do,                            /* do_it */
   mqtt_done,                          /* done */
@@ -1003,10 +997,37 @@ const struct Curl_handler Curl_handler_mqtt = {
   ZERO_NULL,                          /* connection_check */
   ZERO_NULL,                          /* attach connection */
   ZERO_NULL,                          /* follow */
-  PORT_MQTT,                          /* defport */
-  CURLPROTO_MQTT,                     /* protocol */
-  CURLPROTO_MQTT,                     /* family */
-  PROTOPT_NONE                        /* flags */
 };
 
 #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 43040d001bade72e8c1792039db4fa143cd4cf9c..67d1df43dd025945a0fdd99cf54bdce088bebbdc 100644 (file)
  * SPDX-License-Identifier: curl
  *
  ***************************************************************************/
-#ifndef CURL_DISABLE_MQTT
-extern const struct Curl_handler Curl_handler_mqtt;
-#ifdef USE_SSL
-extern const struct Curl_handler Curl_handler_mqtts;
-#endif
-#endif
+extern const struct Curl_scheme Curl_scheme_mqtt;
+extern const struct Curl_scheme Curl_scheme_mqtts;
 
 #endif /* HEADER_CURL_MQTT_H */
index 39cf594c624e03eb62efd0a46357dd8226a2353b..2f8cb055c60c51f64a43e2128bcd9509333bdc3b 100644 (file)
@@ -569,8 +569,8 @@ static bool multi_conn_should_close(struct connectdata *conn,
 
   /* Unless this connection is for a "connect-only" transfer, it
    * needs to be closed if the protocol handler does not support reuse. */
-  if(!data->set.connect_only && conn->handler &&
-     !(conn->handler->flags & PROTOPT_CONN_REUSE))
+  if(!data->set.connect_only && conn->scheme &&
+     !(conn->scheme->flags & PROTOPT_CONN_REUSE))
     return TRUE;
 
   /* if premature is TRUE, it means this connection was said to be DONE before
@@ -699,8 +699,8 @@ static CURLcode multi_done(struct Curl_easy *data,
   }
 
   /* this calls the protocol-specific function pointer previously set */
-  if(conn->handler->done && (data->mstate >= MSTATE_PROTOCONNECT))
-    result = conn->handler->done(data, status, premature);
+  if(conn->scheme->run->done && (data->mstate >= MSTATE_PROTOCONNECT))
+    result = conn->scheme->run->done(data, status, premature);
   else
     result = status;
 
@@ -936,8 +936,8 @@ void Curl_attach_connection(struct Curl_easy *data,
     conn->attached_multi = data->multi;
   DEBUGASSERT(conn->attached_multi == data->multi);
 
-  if(conn->handler && conn->handler->attach)
-    conn->handler->attach(data, conn);
+  if(conn->scheme && conn->scheme->run->attach)
+    conn->scheme->run->attach(data, conn);
 }
 
 /* adjust pollset for rate limits/pauses */
@@ -1015,8 +1015,8 @@ static CURLcode mstate_protocol_pollset(struct Curl_easy *data,
   struct connectdata *conn = data->conn;
   CURLcode result = CURLE_OK;
 
-  if(conn->handler->proto_pollset)
-    result = conn->handler->proto_pollset(data, ps);
+  if(conn->scheme->run->proto_pollset)
+    result = conn->scheme->run->proto_pollset(data, ps);
   else {
     curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
     if(sockfd != CURL_SOCKET_BAD) {
@@ -1037,8 +1037,8 @@ static CURLcode mstate_do_pollset(struct Curl_easy *data,
   struct connectdata *conn = data->conn;
   CURLcode result = CURLE_OK;
 
-  if(conn->handler->doing_pollset)
-    result = conn->handler->doing_pollset(data, ps);
+  if(conn->scheme->run->doing_pollset)
+    result = conn->scheme->run->doing_pollset(data, ps);
   else if(CONN_SOCK_IDX_VALID(conn->send_idx)) {
     /* Default is that we want to send something to the server */
     result = Curl_pollset_add_out(data, ps, conn->sock[conn->send_idx]);
@@ -1056,8 +1056,8 @@ static CURLcode mstate_domore_pollset(struct Curl_easy *data,
   struct connectdata *conn = data->conn;
   CURLcode result = CURLE_OK;
 
-  if(conn->handler->domore_pollset)
-    result = conn->handler->domore_pollset(data, ps);
+  if(conn->scheme->run->domore_pollset)
+    result = conn->scheme->run->domore_pollset(data, ps);
   else if(CONN_SOCK_IDX_VALID(conn->send_idx)) {
     /* Default is that we want to send something to the server */
     result = Curl_pollset_add_out(data, ps, conn->sock[conn->send_idx]);
@@ -1075,8 +1075,8 @@ static CURLcode mstate_perform_pollset(struct Curl_easy *data,
   struct connectdata *conn = data->conn;
   CURLcode result = CURLE_OK;
 
-  if(conn->handler->perform_pollset)
-    result = conn->handler->perform_pollset(data, ps);
+  if(conn->scheme->run->perform_pollset)
+    result = conn->scheme->run->perform_pollset(data, ps);
   else {
     /* Default is to obey the data->req.keepon flags for send/recv */
     if(Curl_req_want_recv(data) && CONN_SOCK_IDX_VALID(conn->recv_idx)) {
@@ -1683,10 +1683,10 @@ static CURLcode multi_do(struct Curl_easy *data, bool *done)
   struct connectdata *conn = data->conn;
 
   DEBUGASSERT(conn);
-  DEBUGASSERT(conn->handler);
+  DEBUGASSERT(conn->scheme);
 
-  if(conn->handler->do_it)
-    result = conn->handler->do_it(data, done);
+  if(conn->scheme->run->do_it)
+    result = conn->scheme->run->do_it(data, done);
 
   return result;
 }
@@ -1707,8 +1707,8 @@ static CURLcode multi_do_more(struct Curl_easy *data, int *complete)
 
   *complete = 0;
 
-  if(conn->handler->do_more)
-    result = conn->handler->do_more(data, complete);
+  if(conn->scheme->run->do_more)
+    result = conn->scheme->run->do_more(data, complete);
 
   return result;
 }
@@ -1781,9 +1781,9 @@ static CURLcode protocol_connecting(struct Curl_easy *data, bool *done)
   CURLcode result = CURLE_OK;
   struct connectdata *conn = data->conn;
 
-  if(conn && conn->handler->connecting) {
+  if(conn && conn->scheme->run->connecting) {
     *done = FALSE;
-    result = conn->handler->connecting(data, done);
+    result = conn->scheme->run->connecting(data, done);
   }
   else
     *done = TRUE;
@@ -1801,9 +1801,9 @@ static CURLcode protocol_doing(struct Curl_easy *data, bool *done)
   CURLcode result = CURLE_OK;
   struct connectdata *conn = data->conn;
 
-  if(conn && conn->handler->doing) {
+  if(conn && conn->scheme->run->doing) {
     *done = FALSE;
-    result = conn->handler->doing(data, done);
+    result = conn->scheme->run->doing(data, done);
   }
   else
     *done = TRUE;
@@ -1827,9 +1827,9 @@ static CURLcode protocol_connect(struct Curl_easy *data, bool *protocol_done)
 
   *protocol_done = FALSE;
   if(!conn->bits.protoconnstart) {
-    if(conn->handler->connect_it) {
+    if(conn->scheme->run->connect_it) {
       /* Call the protocol-specific connect function */
-      result = conn->handler->connect_it(data, protocol_done);
+      result = conn->scheme->run->connect_it(data, protocol_done);
       if(result)
         return result;
     }
@@ -1838,7 +1838,7 @@ static CURLcode protocol_connect(struct Curl_easy *data, bool *protocol_done)
 
   /* Unless this protocol does not have any protocol-connect callback, as
      then we know we are done. */
-  if(!conn->handler->connecting)
+  if(!conn->scheme->run->connecting)
     *protocol_done = TRUE;
   return CURLE_OK;
 }
@@ -1869,12 +1869,12 @@ static void multi_posttransfer(struct Curl_easy *data)
  * This function DOES NOT FREE the given url.
  */
 static CURLcode multi_follow(struct Curl_easy *data,
-                             const struct Curl_handler *handler,
+                             const struct Curl_scheme *handler,
                              const char *newurl, /* the Location: string */
                              followtype type) /* see transfer.h */
 {
-  if(handler && handler->follow)
-    return handler->follow(data, newurl, type);
+  if(handler && handler->run->follow)
+    return handler->run->follow(data, newurl, type);
   return CURLE_TOO_MANY_REDIRECTS;
 }
 
@@ -1996,7 +1996,7 @@ static CURLMcode state_performing(struct Curl_easy *data,
      * connection.
      */
 
-    if(!(data->conn->handler->flags & PROTOPT_DUAL) &&
+    if(!(data->conn->scheme->flags & PROTOPT_DUAL) &&
        result != CURLE_HTTP2_STREAM)
       streamclose(data->conn, "Transfer returned error");
 
@@ -2004,7 +2004,7 @@ static CURLMcode state_performing(struct Curl_easy *data,
     multi_done(data, result, TRUE);
   }
   else if(data->req.done && !Curl_cwriter_is_paused(data)) {
-    const struct Curl_handler *handler = data->conn->handler;
+    const struct Curl_scheme *handler = data->conn->scheme;
 
     /* call this even if the readwrite function returned error */
     multi_posttransfer(data);
@@ -2143,7 +2143,7 @@ static CURLMcode state_do(struct Curl_easy *data,
        * unexpectedly died. If possible, send the connection back to the
        * CONNECT phase so we can try again.
        */
-      const struct Curl_handler *handler = data->conn->handler;
+      const struct Curl_scheme *handler = data->conn->scheme;
       char *newurl = NULL;
       followtype follow = FOLLOW_NONE;
       CURLcode drc;
@@ -2208,7 +2208,7 @@ static CURLMcode state_ratelimiting(struct Curl_easy *data,
   result = Curl_pgrsCheck(data);
 
   if(result) {
-    if(!(data->conn->handler->flags & PROTOPT_DUAL) &&
+    if(!(data->conn->scheme->flags & PROTOPT_DUAL) &&
        result != CURLE_HTTP2_STREAM)
       streamclose(data->conn, "Transfer returned error");
 
@@ -2556,7 +2556,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
       else {
 #ifndef CURL_DISABLE_FTP
         if(data->state.wildcardmatch &&
-           ((data->conn->handler->flags & PROTOPT_WILDCARD) == 0)) {
+           ((data->conn->scheme->flags & PROTOPT_WILDCARD) == 0)) {
           data->wildcard->state = CURLWC_DONE;
         }
 #endif
index 6805efc2423d3b0f10a113c1c648ad41011f8c24..1cb04e7b27cfbe0abdb9a812edb613a58aac9f44 100644 (file)
@@ -615,7 +615,7 @@ static CURLcode oldap_connect(struct Curl_easy *data, bool *done)
     goto out;
 
   hosturl = curl_maprintf("%s://%s%s%s:%d",
-                          conn->handler->scheme,
+                          conn->scheme->name,
                           conn->bits.ipv6_ip ? "[" : "",
                           conn->host.name,
                           conn->bits.ipv6_ip ? "]" : "",
@@ -1261,8 +1261,7 @@ void Curl_ldap_version(char *buf, size_t bufsz)
 /*
  * LDAP protocol handler.
  */
-const struct Curl_handler Curl_handler_ldap = {
-  "ldap",                               /* scheme */
+const struct Curl_protocol Curl_protocol_ldap = {
   oldap_setup_connection,               /* setup_connection */
   oldap_do,                             /* do_it */
   oldap_done,                           /* done */
@@ -1280,42 +1279,8 @@ const struct Curl_handler Curl_handler_ldap = {
   ZERO_NULL,                            /* connection_check */
   ZERO_NULL,                            /* attach connection */
   ZERO_NULL,                            /* follow */
-  PORT_LDAP,                            /* defport */
-  CURLPROTO_LDAP,                       /* protocol */
-  CURLPROTO_LDAP,                       /* family */
-  PROTOPT_SSL_REUSE |                   /* flags */
-    PROTOPT_CONN_REUSE
 };
 
-#ifdef USE_SSL
-/*
- * LDAPS protocol handler.
- */
-const struct Curl_handler Curl_handler_ldaps = {
-  "ldaps",                              /* scheme */
-  oldap_setup_connection,               /* setup_connection */
-  oldap_do,                             /* do_it */
-  oldap_done,                           /* done */
-  ZERO_NULL,                            /* do_more */
-  oldap_connect,                        /* connect_it */
-  oldap_connecting,                     /* connecting */
-  ZERO_NULL,                            /* doing */
-  ZERO_NULL,                            /* proto_pollset */
-  ZERO_NULL,                            /* doing_pollset */
-  ZERO_NULL,                            /* domore_pollset */
-  ZERO_NULL,                            /* perform_pollset */
-  oldap_disconnect,                     /* disconnect */
-  ZERO_NULL,                            /* write_resp */
-  ZERO_NULL,                            /* write_resp_hd */
-  ZERO_NULL,                            /* connection_check */
-  ZERO_NULL,                            /* attach connection */
-  ZERO_NULL,                            /* follow */
-  PORT_LDAPS,                           /* defport */
-  CURLPROTO_LDAPS,                      /* protocol */
-  CURLPROTO_LDAP,                       /* family */
-  PROTOPT_SSL |                         /* flags */
-    PROTOPT_CONN_REUSE
-};
-#endif
-
 #endif /* !CURL_DISABLE_LDAP && USE_OPENLDAP */
+
+/* The LDAP scheme structs are in ldap.c */
index 6faad63c97a6c1bbcc67075ee1889b0f285fa380..089af4890e2fe8826f73bb653d343292d4ff0d80 100644 (file)
@@ -37,6 +37,8 @@
  *
  ***************************************************************************/
 #include "curl_setup.h"
+#include "urldata.h"
+#include "pop3.h"
 
 #ifndef CURL_DISABLE_POP3
 
@@ -54,7 +56,6 @@
 #include <inet.h>
 #endif
 
-#include "urldata.h"
 #include "sendf.h"
 #include "curl_trc.h"
 #include "hostip.h"
@@ -62,7 +63,6 @@
 #include "transfer.h"
 #include "escape.h"
 #include "pingpong.h"
-#include "pop3.h"
 #include "vtls/vtls.h"
 #include "cfilters.h"
 #include "connect.h"
@@ -490,7 +490,7 @@ static CURLcode pop3_perform_upgrade_tls(struct Curl_easy *data,
     if(result)
       goto out;
     /* Change the connection handler */
-    conn->handler = &Curl_handler_pop3s;
+    conn->scheme = &Curl_scheme_pop3s;
   }
 
   DEBUGASSERT(!pop3c->ssldone);
@@ -1691,10 +1691,9 @@ static CURLcode pop3_setup_connection(struct Curl_easy *data,
 }
 
 /*
- * POP3 protocol handler.
+ * POP3 protocol.
  */
-const struct Curl_handler Curl_handler_pop3 = {
-  "pop3",                           /* scheme */
+static const struct Curl_protocol Curl_protocol_pop3 = {
   pop3_setup_connection,            /* setup_connection */
   pop3_do,                          /* do_it */
   pop3_done,                        /* done */
@@ -1712,42 +1711,40 @@ const struct Curl_handler Curl_handler_pop3 = {
   ZERO_NULL,                        /* connection_check */
   ZERO_NULL,                        /* attach connection */
   ZERO_NULL,                        /* follow */
-  PORT_POP3,                        /* defport */
+};
+
+#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
+  PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE | PROTOPT_CONN_REUSE,
+  PORT_POP3,                        /* defport */
 };
 
-#ifdef USE_SSL
 /*
  * POP3S protocol handler.
  */
-const struct Curl_handler Curl_handler_pop3s = {
+const struct Curl_scheme Curl_scheme_pop3s = {
   "pop3s",                          /* scheme */
-  pop3_setup_connection,            /* setup_connection */
-  pop3_do,                          /* do_it */
-  pop3_done,                        /* done */
-  ZERO_NULL,                        /* do_more */
-  pop3_connect,                     /* connect_it */
-  pop3_multi_statemach,             /* connecting */
-  pop3_doing,                       /* doing */
-  pop3_pollset,                     /* proto_pollset */
-  pop3_pollset,                     /* doing_pollset */
-  ZERO_NULL,                        /* domore_pollset */
-  ZERO_NULL,                        /* perform_pollset */
-  pop3_disconnect,                  /* disconnect */
-  pop3_write,                       /* write_resp */
-  ZERO_NULL,                        /* write_resp_hd */
-  ZERO_NULL,                        /* connection_check */
-  ZERO_NULL,                        /* attach connection */
-  ZERO_NULL,                        /* follow */
-  PORT_POP3S,                       /* defport */
+#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
+  PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS | PROTOPT_CONN_REUSE,
+  PORT_POP3S,                       /* defport */
 };
-#endif
-
-#endif /* CURL_DISABLE_POP3 */
index ed00dd15ae46cbd1e0af49a1ca6c4ea53e2dad0e..77e30f832d23215197181ee60d5cc071a6c13609 100644 (file)
@@ -23,7 +23,7 @@
  * SPDX-License-Identifier: curl
  *
  ***************************************************************************/
-extern const struct Curl_handler Curl_handler_pop3;
-extern const struct Curl_handler Curl_handler_pop3s;
+extern const struct Curl_scheme Curl_scheme_pop3;
+extern const struct Curl_scheme Curl_scheme_pop3s;
 
 #endif /* HEADER_CURL_POP3_H */
index c3711caf049e3183aff0555994c37dfacc6f2206..a36ea1cac46ec7a0bcf3d1561ffdfea7f04848d1 100644 (file)
  *
  ***************************************************************************/
 #include "curl_setup.h"
+#include "urldata.h"
 
 #ifndef CURL_DISABLE_RTSP
 
-#include "urldata.h"
 #include "transfer.h"
 #include "sendf.h"
 #include "curl_trc.h"
@@ -316,7 +316,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
       return CURLE_OUT_OF_MEMORY;
 
     data->state.first_remote_port = conn->remote_port;
-    data->state.first_remote_protocol = conn->handler->protocol;
+    data->state.first_remote_protocol = conn->scheme->protocol;
   }
 
   /* Setup the 'p_request' pointer to the proper p_request string
@@ -1045,8 +1045,7 @@ CURLcode Curl_rtsp_parseheader(struct Curl_easy *data, const char *header)
 /*
  * RTSP handler interface.
  */
-const struct Curl_handler Curl_handler_rtsp = {
-  "rtsp",                               /* scheme */
+static const struct Curl_protocol Curl_protocol_rtsp = {
   rtsp_setup_connection,                /* setup_connection */
   rtsp_do,                              /* do_it */
   rtsp_done,                            /* done */
@@ -1064,10 +1063,22 @@ const struct Curl_handler Curl_handler_rtsp = {
   rtsp_conncheck,                       /* connection_check */
   ZERO_NULL,                            /* attach connection */
   Curl_http_follow,                     /* follow */
-  PORT_RTSP,                            /* defport */
-  CURLPROTO_RTSP,                       /* protocol */
-  CURLPROTO_RTSP,                       /* family */
-  PROTOPT_CONN_REUSE                    /* flags */
 };
 
 #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 70ca00f69a8bf7e90f6833b040da6fdf607a9bee..92b28e54f8edf2573019f32773b76ce62d6356ef 100644 (file)
@@ -23,8 +23,8 @@
  * SPDX-License-Identifier: curl
  *
  ***************************************************************************/
+extern const struct Curl_scheme Curl_scheme_rtsp;
 #ifndef CURL_DISABLE_RTSP
-extern const struct Curl_handler Curl_handler_rtsp;
 CURLcode Curl_rtsp_parseheader(struct Curl_easy *data, const char *header);
 #else
 #define Curl_rtsp_parseheader(x, y) CURLE_NOT_BUILT_IN
index 674b0a4573d9c048fa3c91e27c6f6127032265bf..f2d30a4269a1eb8b78a0fadf0290f248564a8c34 100644 (file)
@@ -696,7 +696,7 @@ static CURLcode cr_in_read(struct Curl_easy *data,
     break;
 
   case CURL_READFUNC_PAUSE:
-    if(data->conn->handler->flags & PROTOPT_NONETWORK) {
+    if(data->conn->scheme->flags & PROTOPT_NONETWORK) {
       /* protocols that work without network cannot be paused. This is
          actually only FILE:// just now, and it cannot pause since the transfer
          is not done using the "normal" procedure. */
index c82e8c206b936f942e5ef5acf6d6f71829cfc076..713a6d2d7cd36305a0e3a9994be21915c299497f 100644 (file)
@@ -214,9 +214,9 @@ static CURLcode protocol2num(const char *str, curl_prot_t *val)
     str = strchr(str, ',');
     tlen = str ? (size_t)(str - token) : strlen(token);
     if(tlen) {
-      const struct Curl_handler *h = Curl_getn_scheme_handler(token, tlen);
+      const struct Curl_scheme *h = Curl_getn_scheme(token, tlen);
 
-      if(!h)
+      if(!h || !h->run)
         return CURLE_UNSUPPORTED_PROTOCOL;
 
       *val |= h->protocol;
index e4a1df14121110bab881c84e0eb303487af58fd6..4463719c042c4f35a1684d66ef1da17a43b6bc68 100644 (file)
--- a/lib/smb.c
+++ b/lib/smb.c
  *
  ***************************************************************************/
 #include "curl_setup.h"
+#include "urldata.h"
 
 #if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE)
 
 #include "smb.h"
-#include "urldata.h"
 #include "url.h"
 #include "sendf.h"
 #include "curl_trc.h"
@@ -1201,8 +1201,7 @@ static CURLcode smb_do(struct Curl_easy *data, bool *done)
 /*
  * SMB handler interface
  */
-const struct Curl_handler Curl_handler_smb = {
-  "smb",                                /* scheme */
+static const struct Curl_protocol Curl_protocol_smb = {
   smb_setup_connection,                 /* setup_connection */
   smb_do,                               /* do_it */
   ZERO_NULL,                            /* done */
@@ -1220,40 +1219,39 @@ const struct Curl_handler Curl_handler_smb = {
   ZERO_NULL,                            /* connection_check */
   ZERO_NULL,                            /* attach connection */
   ZERO_NULL,                            /* follow */
-  PORT_SMB,                             /* defport */
+};
+
+#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 */
+  PROTOPT_CONN_REUSE,                   /* flags */
+  PORT_SMB,                             /* defport */
 };
 
-#ifdef USE_SSL
 /*
  * SMBS handler interface
  */
-const struct Curl_handler Curl_handler_smbs = {
+const struct Curl_scheme Curl_scheme_smbs = {
   "smbs",                               /* scheme */
-  smb_setup_connection,                 /* setup_connection */
-  smb_do,                               /* do_it */
-  ZERO_NULL,                            /* done */
-  ZERO_NULL,                            /* do_more */
-  smb_connect,                          /* connect_it */
-  smb_connection_state,                 /* connecting */
-  smb_request_state,                    /* doing */
-  smb_pollset,                          /* proto_pollset */
-  smb_pollset,                          /* doing_pollset */
-  ZERO_NULL,                            /* domore_pollset */
-  ZERO_NULL,                            /* perform_pollset */
-  ZERO_NULL,                            /* disconnect */
-  ZERO_NULL,                            /* write_resp */
-  ZERO_NULL,                            /* write_resp_hd */
-  ZERO_NULL,                            /* connection_check */
-  ZERO_NULL,                            /* attach connection */
-  ZERO_NULL,                            /* follow */
-  PORT_SMBS,                            /* defport */
+#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 */
+  PROTOPT_SSL | PROTOPT_CONN_REUSE,     /* flags */
+  PORT_SMBS,                            /* defport */
 };
-#endif
-
-#endif /* CURL_DISABLE_SMB && USE_CURL_NTLM_CORE && SIZEOF_CURL_OFF_T > 4 */
index 474f8d6a5f7b7cd600c5fbe89bb596a8b25ba039..d3754047a7d2e4e4e3c50481257f314e6d81edd8 100644 (file)
--- a/lib/smb.h
+++ b/lib/smb.h
  * SPDX-License-Identifier: curl
  *
  ***************************************************************************/
-#if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE) && \
-  (SIZEOF_CURL_OFF_T > 4)
-
-extern const struct Curl_handler Curl_handler_smb;
-extern const struct Curl_handler Curl_handler_smbs;
-
-#endif /* CURL_DISABLE_SMB && USE_CURL_NTLM_CORE && SIZEOF_CURL_OFF_T > 4 */
+extern const struct Curl_scheme Curl_scheme_smb;
+extern const struct Curl_scheme Curl_scheme_smbs;
 
 #endif /* HEADER_CURL_SMB_H */
index 70fdba8cc6a00f6300a74761cc07aea4065ab30b..2427fd932d59fcc39b4fb8ea3f7e1e3f9302fa1c 100644 (file)
@@ -39,6 +39,8 @@
  *
  ***************************************************************************/
 #include "curl_setup.h"
+#include "urldata.h"
+#include "smtp.h"
 
 #ifndef CURL_DISABLE_SMTP
 
@@ -56,7 +58,6 @@
 #include <inet.h>
 #endif
 
-#include "urldata.h"
 #include "sendf.h"
 #include "curl_trc.h"
 #include "hostip.h"
@@ -65,7 +66,6 @@
 #include "escape.h"
 #include "pingpong.h"
 #include "mime.h"
-#include "smtp.h"
 #include "vtls/vtls.h"
 #include "cfilters.h"
 #include "connect.h"
@@ -695,7 +695,7 @@ static CURLcode smtp_perform_upgrade_tls(struct Curl_easy *data,
     if(result)
       goto out;
     /* Change the connection handler and SMTP state */
-    conn->handler = &Curl_handler_smtps;
+    conn->scheme = &Curl_scheme_smtps;
   }
 
   DEBUGASSERT(!smtpc->ssldone);
@@ -1987,8 +1987,7 @@ out:
 /*
  * SMTP protocol handler.
  */
-const struct Curl_handler Curl_handler_smtp = {
-  "smtp",                           /* scheme */
+static const struct Curl_protocol Curl_protocol_smtp = {
   smtp_setup_connection,            /* setup_connection */
   smtp_do,                          /* do_it */
   smtp_done,                        /* done */
@@ -2006,42 +2005,40 @@ const struct Curl_handler Curl_handler_smtp = {
   ZERO_NULL,                        /* connection_check */
   ZERO_NULL,                        /* attach connection */
   ZERO_NULL,                        /* follow */
-  PORT_SMTP,                        /* defport */
+};
+
+#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
+  PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE | PROTOPT_CONN_REUSE,
+  PORT_SMTP,                        /* defport */
 };
 
-#ifdef USE_SSL
 /*
  * SMTPS protocol handler.
  */
-const struct Curl_handler Curl_handler_smtps = {
+const struct Curl_scheme Curl_scheme_smtps = {
   "smtps",                          /* scheme */
-  smtp_setup_connection,            /* setup_connection */
-  smtp_do,                          /* do_it */
-  smtp_done,                        /* done */
-  ZERO_NULL,                        /* do_more */
-  smtp_connect,                     /* connect_it */
-  smtp_multi_statemach,             /* connecting */
-  smtp_doing,                       /* doing */
-  smtp_pollset,                     /* proto_pollset */
-  smtp_pollset,                     /* doing_pollset */
-  ZERO_NULL,                        /* domore_pollset */
-  ZERO_NULL,                        /* perform_pollset */
-  smtp_disconnect,                  /* disconnect */
-  ZERO_NULL,                        /* write_resp */
-  ZERO_NULL,                        /* write_resp_hd */
-  ZERO_NULL,                        /* connection_check */
-  ZERO_NULL,                        /* attach connection */
-  ZERO_NULL,                        /* follow */
-  PORT_SMTPS,                       /* defport */
+#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
+  PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS | PROTOPT_CONN_REUSE,
+  PORT_SMTPS,                       /* defport */
 };
-#endif
-
-#endif /* CURL_DISABLE_SMTP */
index 7e3cf774ae88cecf55ff559eb70386d97d909e8f..39f8d78473f14ddcce0035640aae9894f68241b9 100644 (file)
@@ -23,7 +23,7 @@
  * SPDX-License-Identifier: curl
  *
  ***************************************************************************/
-extern const struct Curl_handler Curl_handler_smtp;
-extern const struct Curl_handler Curl_handler_smtps;
+extern const struct Curl_scheme Curl_scheme_smtp;
+extern const struct Curl_scheme Curl_scheme_smtps;
 
 #endif /* HEADER_CURL_SMTP_H */
index 02fc3a1edc1b95d558b8417f55faa22e44c89bcd..4a38bfc6c906b1b49c97946c1a84f38a6c06a5a7 100644 (file)
@@ -22,6 +22,8 @@
  *
  ***************************************************************************/
 #include "curl_setup.h"
+#include "urldata.h"
+#include "telnet.h"
 
 #ifndef CURL_DISABLE_TELNET
 
 #include <sys/param.h>
 #endif
 
-#include "urldata.h"
 #include "url.h"
 #include "transfer.h"
 #include "sendf.h"
 #include "curl_trc.h"
-#include "telnet.h"
 #include "connect.h"
 #include "progress.h"
 #include "arpa_telnet.h"
@@ -1570,8 +1570,7 @@ static CURLcode telnet_do(struct Curl_easy *data, bool *done)
 /*
  * TELNET protocol handler.
  */
-const struct Curl_handler Curl_handler_telnet = {
-  "telnet",                             /* scheme */
+static const struct Curl_protocol Curl_protocol_telnet = {
   ZERO_NULL,                            /* setup_connection */
   telnet_do,                            /* do_it */
   telnet_done,                          /* done */
@@ -1589,10 +1588,22 @@ const struct Curl_handler Curl_handler_telnet = {
   ZERO_NULL,                            /* connection_check */
   ZERO_NULL,                            /* attach connection */
   ZERO_NULL,                            /* follow */
-  PORT_TELNET,                          /* defport */
-  CURLPROTO_TELNET,                     /* protocol */
-  CURLPROTO_TELNET,                     /* family */
-  PROTOPT_NONE | PROTOPT_NOURLQUERY     /* flags */
 };
 
 #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 30782d8375761a016e40ca21a257e93858c7e274..c10617964a8a83137da373ed6cd29b59eaebece1 100644 (file)
@@ -23,8 +23,6 @@
  * SPDX-License-Identifier: curl
  *
  ***************************************************************************/
-#ifndef CURL_DISABLE_TELNET
-extern const struct Curl_handler Curl_handler_telnet;
-#endif
+extern const struct Curl_scheme Curl_scheme_telnet;
 
 #endif /* HEADER_CURL_TELNET_H */
index 584d146a30ff151ad1fd23ac73bd9a25827b0e51..1b882efe377d20407f20fa572bf1b61df754528d 100644 (file)
@@ -22,6 +22,7 @@
  *
  ***************************************************************************/
 #include "curl_setup.h"
+#include "urldata.h"
 
 #ifndef CURL_DISABLE_TFTP
 
@@ -45,7 +46,6 @@
 #include <sys/param.h>
 #endif
 
-#include "urldata.h"
 #include "cfilters.h"
 #include "cf-socket.h"
 #include "transfer.h"
@@ -1338,8 +1338,7 @@ static CURLcode tftp_setup_connection(struct Curl_easy *data,
 /*
  * TFTP protocol handler.
  */
-const struct Curl_handler Curl_handler_tftp = {
-  "tftp",                               /* scheme */
+static const struct Curl_protocol Curl_protocol_tftp = {
   tftp_setup_connection,                /* setup_connection */
   tftp_do,                              /* do_it */
   tftp_done,                            /* done */
@@ -1357,10 +1356,22 @@ const struct Curl_handler Curl_handler_tftp = {
   ZERO_NULL,                            /* connection_check */
   ZERO_NULL,                            /* attach connection */
   ZERO_NULL,                            /* follow */
-  PORT_TFTP,                            /* defport */
-  CURLPROTO_TFTP,                       /* protocol */
-  CURLPROTO_TFTP,                       /* family */
-  PROTOPT_NOTCPPROXY | PROTOPT_NOURLQUERY /* flags */
 };
 
 #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 12404bf6d20d1be96fa35bd670af522171b0f334..91ecd2978af409c3e3a8d4823948955c6ce34548 100644 (file)
  * SPDX-License-Identifier: curl
  *
  ***************************************************************************/
-#ifndef CURL_DISABLE_TFTP
-extern const struct Curl_handler Curl_handler_tftp;
+extern const struct Curl_scheme Curl_scheme_tftp;
 
 #define TFTP_BLKSIZE_MIN 8
 #define TFTP_BLKSIZE_MAX 65464
-#endif
 
 #endif /* HEADER_CURL_TFTP_H */
index fed6a1786e7e8789e79d46c339d6842af3ec231c..63d2e15047d9c26581e48e95078a8d34dbe346f1 100644 (file)
@@ -104,13 +104,13 @@ static int data_pending(struct Curl_easy *data, bool rcvd_eagain)
 {
   struct connectdata *conn = data->conn;
 
-  if(conn->handler->protocol & PROTO_FAMILY_FTP)
+  if(conn->scheme->protocol & PROTO_FAMILY_FTP)
     return Curl_conn_data_pending(data, SECONDARYSOCKET);
 
   /* in the case of libssh2, we can never be really sure that we have emptied
      its internal buffers so we MUST always try until we get EAGAIN back */
   return (!rcvd_eagain &&
-          conn->handler->protocol & (CURLPROTO_SCP | CURLPROTO_SFTP)) ||
+          conn->scheme->protocol & (CURLPROTO_SCP | CURLPROTO_SFTP)) ||
          Curl_conn_data_pending(data, FIRSTSOCKET);
 }
 
@@ -623,13 +623,13 @@ CURLcode Curl_retry_request(struct Curl_easy *data, char **url)
      protocol is HTTP as when uploading over HTTP we will still get a
      response */
   if(data->state.upload &&
-     !(conn->handler->protocol & (PROTO_FAMILY_HTTP | CURLPROTO_RTSP)))
+     !(conn->scheme->protocol & (PROTO_FAMILY_HTTP | CURLPROTO_RTSP)))
     return CURLE_OK;
 
   if(conn->bits.reuse &&
      (data->req.bytecount + data->req.headerbytecount == 0) &&
      ((!data->req.no_body && !data->req.done) ||
-      (conn->handler->protocol & PROTO_FAMILY_HTTP))
+      (conn->scheme->protocol & PROTO_FAMILY_HTTP))
 #ifndef CURL_DISABLE_RTSP
      && (data->set.rtspreq != RTSPREQ_RECEIVE)
 #endif
@@ -701,7 +701,7 @@ static void xfer_setup(
   /* without receiving, there should be not recv_size */
   DEBUGASSERT((conn->recv_idx >= 0) || (recv_size == -1));
   k->size = recv_size;
-  k->header = !!conn->handler->write_resp_hd;
+  k->header = !!conn->scheme->run->write_resp_hd;
   /* by default, we do not shutdown at the end of the transfer */
   k->shutdown = FALSE;
   k->shutdown_err_ignore = FALSE;
@@ -713,7 +713,7 @@ static void xfer_setup(
     Curl_pgrsSetDownloadSize(data, recv_size);
 
   /* we want header and/or body, if neither then do not do this! */
-  if(conn->handler->write_resp_hd || !data->req.no_body) {
+  if(conn->scheme->run->write_resp_hd || !data->req.no_body) {
 
     if(conn->recv_idx != -1)
       k->keepon |= KEEP_RECV;
@@ -768,10 +768,10 @@ CURLcode Curl_xfer_write_resp(struct Curl_easy *data,
 {
   CURLcode result = CURLE_OK;
 
-  if(data->conn->handler->write_resp) {
+  if(data->conn->scheme->run->write_resp) {
     /* protocol handlers offering this function take full responsibility
      * for writing all received download data to the client. */
-    result = data->conn->handler->write_resp(data, buf, blen, is_eos);
+    result = data->conn->scheme->run->write_resp(data, buf, blen, is_eos);
   }
   else {
     /* No special handling by protocol handler, write all received data
@@ -802,11 +802,11 @@ bool Curl_xfer_write_is_paused(struct Curl_easy *data)
 CURLcode Curl_xfer_write_resp_hd(struct Curl_easy *data,
                                  const char *hd0, size_t hdlen, bool is_eos)
 {
-  if(data->conn->handler->write_resp_hd) {
+  if(data->conn->scheme->run->write_resp_hd) {
     DEBUGASSERT(!hd0[hdlen]); /* null terminated */
     /* protocol handlers offering this function take full responsibility
      * for writing all received download data to the client. */
-    return data->conn->handler->write_resp_hd(data, hd0, hdlen, is_eos);
+    return data->conn->scheme->run->write_resp_hd(data, hd0, hdlen, is_eos);
   }
   /* No special handling by protocol handler, write as response bytes */
   return Curl_xfer_write_resp(data, hd0, hdlen, is_eos);
index dd1bc2aed88c49b68cb5342e92fdc12c33b5acc8..99efe38631b4c400f63f3640b4b7360f8335215e 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -71,6 +71,7 @@
 #include "mime.h"
 #include "bufref.h"
 #include "vtls/vtls.h"
+#include "vssh/vssh.h"
 #include "hostip.h"
 #include "transfer.h"
 #include "curl_addrinfo.h"
@@ -148,15 +149,15 @@ static void data_priority_cleanup(struct Curl_easy *data);
  *
  * Parameters:
  *
- * 'h'  [in]  - struct Curl_handler pointer.
+ * 's'  [in]  - struct Curl_scheme pointer.
  *
  * Returns the family as a single bit protocol identifier.
  */
-static curl_prot_t get_protocol_family(const struct Curl_handler *h)
+static curl_prot_t get_protocol_family(const struct Curl_scheme *s)
 {
-  DEBUGASSERT(h);
-  DEBUGASSERT(h->family);
-  return h->family;
+  DEBUGASSERT(s);
+  DEBUGASSERT(s->family);
+  return s->family;
 }
 
 void Curl_freeset(struct Curl_easy *data)
@@ -519,9 +520,9 @@ void Curl_conn_free(struct Curl_easy *data, struct connectdata *conn)
 
   DEBUGASSERT(conn);
 
-  if(conn->handler && conn->handler->disconnect &&
+  if(conn->scheme && conn->scheme->run->disconnect &&
      !conn->bits.shutdown_handler)
-    conn->handler->disconnect(data, conn, TRUE);
+    conn->scheme->run->disconnect(data, conn, TRUE);
 
   for(i = 0; i < CURL_ARRAYSIZE(conn->cfilter); ++i) {
     Curl_conn_cf_discard_all(data, conn, (int)i);
@@ -571,7 +572,7 @@ static bool xfer_may_multiplex(const struct Curl_easy *data,
 {
 #ifndef CURL_DISABLE_HTTP
   /* If an HTTP protocol and multiplexing is enabled */
-  if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
+  if((conn->scheme->protocol & PROTO_FAMILY_HTTP) &&
      (!conn->bits.protoconnstart || !conn->bits.close)) {
 
     if(Curl_multiplex_wanted(data->multi) &&
@@ -670,7 +671,7 @@ bool Curl_conn_seems_dead(struct connectdata *conn,
       /* avoid check if already too old */
       dead = TRUE;
     }
-    else if(conn->handler->connection_check) {
+    else if(conn->scheme->run->connection_check) {
       /* The protocol has a special method for checking the state of the
          connection. Use it to check if the connection is dead. */
       unsigned int state;
@@ -679,7 +680,8 @@ bool Curl_conn_seems_dead(struct connectdata *conn,
          checking it */
       Curl_attach_connection(data, conn);
 
-      state = conn->handler->connection_check(data, conn, CONNCHECK_ISDEAD);
+      state = conn->scheme->run->connection_check(data, conn,
+                                                     CONNCHECK_ISDEAD);
       dead = (state & CONNRESULT_DEAD);
       /* detach the connection again */
       Curl_detach_connection(data);
@@ -724,10 +726,11 @@ CURLcode Curl_conn_upkeep(struct Curl_easy *data,
 
   /* briefly attach for action */
   Curl_attach_connection(data, conn);
-  if(conn->handler->connection_check) {
+  if(conn->scheme->run->connection_check) {
     /* Do a protocol-specific keepalive check on the connection. */
     unsigned int rc;
-    rc = conn->handler->connection_check(data, conn, CONNCHECK_KEEPALIVE);
+    rc = conn->scheme->run->connection_check(data, conn,
+                                                CONNCHECK_KEEPALIVE);
     if(rc & CONNRESULT_DEAD)
       result = CURLE_RECV_ERROR;
   }
@@ -901,7 +904,7 @@ static bool url_match_multiplex_limits(struct connectdata *conn,
 static bool url_match_ssl_use(struct connectdata *conn,
                               struct url_conn_match *m)
 {
-  if(m->needle->handler->flags & PROTOPT_SSL) {
+  if(m->needle->scheme->flags & PROTOPT_SSL) {
     /* We are looking for SSL, if `conn` does not do it, not a match. */
     if(!Curl_conn_is_ssl(conn, FIRSTSOCKET))
       return FALSE;
@@ -909,8 +912,8 @@ static bool url_match_ssl_use(struct connectdata *conn,
   else if(Curl_conn_is_ssl(conn, FIRSTSOCKET)) {
     /* If the protocol does not allow reuse of SSL connections OR
        is of another protocol family, not a match. */
-    if(!(m->needle->handler->flags & PROTOPT_SSL_REUSE) ||
-       (get_protocol_family(conn->handler) != m->needle->handler->protocol))
+    if(!(m->needle->scheme->flags & PROTOPT_SSL_REUSE) ||
+       (get_protocol_family(conn->scheme) != m->needle->scheme->protocol))
       return FALSE;
   }
   return TRUE;
@@ -963,7 +966,7 @@ static bool url_match_http_multiplex(struct connectdata *conn,
 {
   if(m->may_multiplex &&
      (m->data->state.http_neg.allowed & (CURL_HTTP_V2x | CURL_HTTP_V3x)) &&
-     (m->needle->handler->protocol & CURLPROTO_HTTP) &&
+     (m->needle->scheme->protocol & CURLPROTO_HTTP) &&
      !conn->httpversion_seen) {
     if(m->data->set.pipewait) {
       infof(m->data, "Server upgrade does not support multiplex yet, wait");
@@ -982,7 +985,7 @@ static bool url_match_http_version(struct connectdata *conn,
 {
   /* If looking for HTTP and the HTTP versions allowed do not include
    * the HTTP version of conn, continue looking. */
-  if((m->needle->handler->protocol & PROTO_FAMILY_HTTP)) {
+  if((m->needle->scheme->protocol & PROTO_FAMILY_HTTP)) {
     switch(Curl_conn_http_version(m->data, conn)) {
     case 30:
       if(!(m->data->state.http_neg.allowed & CURL_HTTP_V3x)) {
@@ -1021,13 +1024,13 @@ static bool url_match_proto_config(struct connectdata *conn,
     return FALSE;
 
 #ifdef USE_SSH
-  if(get_protocol_family(m->needle->handler) & PROTO_FAMILY_SSH) {
+  if(get_protocol_family(m->needle->scheme) & PROTO_FAMILY_SSH) {
     if(!ssh_config_matches(m->needle, conn))
       return FALSE;
   }
 #endif
 #ifndef CURL_DISABLE_FTP
-  else if(get_protocol_family(m->needle->handler) & PROTO_FAMILY_FTP) {
+  else if(get_protocol_family(m->needle->scheme) & PROTO_FAMILY_FTP) {
     if(!ftp_conns_match(m->needle, conn))
       return FALSE;
   }
@@ -1038,7 +1041,7 @@ static bool url_match_proto_config(struct connectdata *conn,
 static bool url_match_auth(struct connectdata *conn,
                            struct url_conn_match *m)
 {
-  if(!(m->needle->handler->flags & PROTOPT_CREDSPERREQUEST)) {
+  if(!(m->needle->scheme->flags & PROTOPT_CREDSPERREQUEST)) {
     /* This protocol requires credentials per connection,
        so verify that we are using the same name and password as well */
     if(Curl_timestrcmp(m->needle->user, conn->user) ||
@@ -1064,14 +1067,14 @@ static bool url_match_destination(struct connectdata *conn,
 {
   /* Additional match requirements if talking TLS OR
    * not talking to an HTTP proxy OR using a tunnel through a proxy */
-  if((m->needle->handler->flags & PROTOPT_SSL)
+  if((m->needle->scheme->flags & PROTOPT_SSL)
 #ifndef CURL_DISABLE_PROXY
      || !m->needle->bits.httpproxy || m->needle->bits.tunnel_proxy
 #endif
     ) {
-    if(!curl_strequal(m->needle->handler->scheme, conn->handler->scheme)) {
+    if(!curl_strequal(m->needle->scheme->name, conn->scheme->name)) {
       /* `needle` and `conn` do not have the same scheme... */
-      if(get_protocol_family(conn->handler) != m->needle->handler->protocol) {
+      if(get_protocol_family(conn->scheme) != m->needle->scheme->protocol) {
         /* and `conn`s protocol family is not the protocol `needle` wants.
          * IMAPS would work for IMAP, but no vice versa. */
         return FALSE;
@@ -1104,7 +1107,7 @@ static bool url_match_ssl_config(struct connectdata *conn,
                                  struct url_conn_match *m)
 {
   /* If talking TLS, conn needs to use the same SSL options. */
-  if((m->needle->handler->flags & PROTOPT_SSL) &&
+  if((m->needle->scheme->flags & PROTOPT_SSL) &&
      !Curl_ssl_conn_config_match(m->data, conn, FALSE)) {
     DEBUGF(infof(m->data,
                  "Connection #%" FMT_OFF_T
@@ -1292,12 +1295,12 @@ static bool ConnectionExists(struct Curl_easy *data,
 
 #ifdef USE_NTLM
   match.want_ntlm_http = ((data->state.authhost.want & CURLAUTH_NTLM) &&
-                          (needle->handler->protocol & PROTO_FAMILY_HTTP));
+                          (needle->scheme->protocol & PROTO_FAMILY_HTTP));
 #ifndef CURL_DISABLE_PROXY
   match.want_proxy_ntlm_http =
     (needle->bits.proxy_user_passwd &&
      (data->state.authproxy.want & CURLAUTH_NTLM) &&
-     (needle->handler->protocol & PROTO_FAMILY_HTTP));
+     (needle->scheme->protocol & PROTO_FAMILY_HTTP));
 #endif
 #endif
 
@@ -1398,14 +1401,15 @@ error:
   return NULL;
 }
 
-const struct Curl_handler *Curl_get_scheme_handler(const char *scheme)
+const struct Curl_scheme *Curl_get_scheme(const char *scheme)
 {
-  return Curl_getn_scheme_handler(scheme, strlen(scheme));
+  return Curl_getn_scheme(scheme, strlen(scheme));
 }
 
-/* returns the handler if the given scheme is built-in */
-const struct Curl_handler *Curl_getn_scheme_handler(const char *scheme,
-                                                    size_t len)
+/* 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
@@ -1415,199 +1419,47 @@ const struct Curl_handler *Curl_getn_scheme_handler(const char *scheme,
      5. copy the table into this source code
      6. make sure this function uses the same hash function that worked for
      schemetable.c
-     7. if needed, adjust the #ifdefs in schemetable.c and rerun
      */
-  static const struct Curl_handler * const protocols[67] = {
-#ifndef CURL_DISABLE_FILE
-    &Curl_handler_file,
-#else
-    NULL,
-#endif
-#if defined(USE_SSL) && !defined(CURL_DISABLE_MQTT)
-    &Curl_handler_mqtts,
-#else
-    NULL,
-#endif
-    NULL,
-#if defined(USE_SSL) && !defined(CURL_DISABLE_GOPHER)
-    &Curl_handler_gophers,
-#else
-    NULL,
-#endif
-    NULL,
-#ifdef USE_LIBRTMP
-    &Curl_handler_rtmpe,
-#else
-    NULL,
-#endif
-#ifndef CURL_DISABLE_SMTP
-    &Curl_handler_smtp,
-#else
-    NULL,
-#endif
-#ifdef USE_SSH
-    &Curl_handler_sftp,
-#else
-    NULL,
-#endif
-#if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE) && \
-  (SIZEOF_CURL_OFF_T > 4)
-    &Curl_handler_smb,
-#else
-    NULL,
-#endif
-#if defined(USE_SSL) && !defined(CURL_DISABLE_SMTP)
-    &Curl_handler_smtps,
-#else
-    NULL,
-#endif
-#ifndef CURL_DISABLE_TELNET
-    &Curl_handler_telnet,
-#else
-    NULL,
-#endif
-#ifndef CURL_DISABLE_GOPHER
-    &Curl_handler_gopher,
-#else
-    NULL,
-#endif
-#ifndef CURL_DISABLE_TFTP
-    &Curl_handler_tftp,
-#else
-    NULL,
-#endif
-    NULL, NULL, NULL,
-#if defined(USE_SSL) && !defined(CURL_DISABLE_FTP)
-    &Curl_handler_ftps,
-#else
-    NULL,
-#endif
-#ifndef CURL_DISABLE_HTTP
-    &Curl_handler_http,
-#else
-    NULL,
-#endif
-#ifndef CURL_DISABLE_IMAP
-    &Curl_handler_imap,
-#else
-    NULL,
-#endif
-#ifdef USE_LIBRTMP
-    &Curl_handler_rtmps,
-#else
-    NULL,
-#endif
-#ifdef USE_LIBRTMP
-    &Curl_handler_rtmpt,
-#else
-    NULL,
-#endif
-    NULL, NULL, NULL,
-#if !defined(CURL_DISABLE_LDAP) && \
-  !defined(CURL_DISABLE_LDAPS) && \
-  ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \
-   (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)))
-    &Curl_handler_ldaps,
-#else
-    NULL,
-#endif
-#if !defined(CURL_DISABLE_WEBSOCKETS) &&                \
-  defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)
-    &Curl_handler_wss,
-#else
-    NULL,
-#endif
-#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)
-    &Curl_handler_https,
-#else
-    NULL,
-#endif
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-#ifndef CURL_DISABLE_RTSP
-    &Curl_handler_rtsp,
-#else
-    NULL,
-#endif
-#if defined(USE_SSL) && !defined(CURL_DISABLE_SMB) && \
-  defined(USE_CURL_NTLM_CORE) && (SIZEOF_CURL_OFF_T > 4)
-    &Curl_handler_smbs,
-#else
-    NULL,
-#endif
-#ifdef USE_SSH
-    &Curl_handler_scp,
-#else
-    NULL,
-#endif
-    NULL, NULL, NULL,
-#ifndef CURL_DISABLE_POP3
-    &Curl_handler_pop3,
-#else
-    NULL,
-#endif
-    NULL, NULL,
-#ifdef USE_LIBRTMP
-    &Curl_handler_rtmp,
-#else
-    NULL,
-#endif
-    NULL, NULL, NULL,
-#ifdef USE_LIBRTMP
-    &Curl_handler_rtmpte,
-#else
-    NULL,
-#endif
-    NULL, NULL, NULL,
-#ifndef CURL_DISABLE_DICT
-    &Curl_handler_dict,
-#else
-    NULL,
-#endif
-    NULL, NULL, NULL,
-#ifndef CURL_DISABLE_MQTT
-    &Curl_handler_mqtt,
-#else
-    NULL,
-#endif
-#if defined(USE_SSL) && !defined(CURL_DISABLE_POP3)
-    &Curl_handler_pop3s,
-#else
-    NULL,
-#endif
-#if defined(USE_SSL) && !defined(CURL_DISABLE_IMAP)
-    &Curl_handler_imaps,
-#else
-    NULL,
-#endif
-    NULL,
-#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)
-    &Curl_handler_ws,
-#else
-    NULL,
-#endif
-    NULL,
-#ifdef USE_LIBRTMP
-    &Curl_handler_rtmpts,
-#else
-    NULL,
-#endif
-#ifndef CURL_DISABLE_LDAP
-    &Curl_handler_ldap,
-#else
-    NULL,
-#endif
-    NULL, NULL,
-#ifndef CURL_DISABLE_FTP
-    &Curl_handler_ftp,
-#else
-    NULL,
-#endif
+  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_handler *h;
+    const struct Curl_scheme *h;
     unsigned int c = 978;
     while(l) {
       c <<= 5;
@@ -1616,8 +1468,8 @@ const struct Curl_handler *Curl_getn_scheme_handler(const char *scheme,
       l--;
     }
 
-    h = protocols[c % 67];
-    if(h && curl_strnequal(scheme, h->scheme, len) && !h->scheme[len])
+    h = all_schemes[c % 67];
+    if(h && curl_strnequal(scheme, h->name, len) && !h->name[len])
       return h;
   }
   return NULL;
@@ -1627,9 +1479,9 @@ static CURLcode findprotocol(struct Curl_easy *data,
                              struct connectdata *conn,
                              const char *protostr)
 {
-  const struct Curl_handler *p = Curl_get_scheme_handler(protostr);
+  const struct Curl_scheme *p = Curl_get_scheme(protostr);
 
-  if(p && /* Protocol found in table. Check if allowed */
+  if(p && p->run && /* Protocol found supported. Check if allowed */
      (data->set.allowed_protocols & p->protocol)) {
 
     /* it is allowed for "normal" request, now do an extra check if this is
@@ -1640,7 +1492,7 @@ static CURLcode findprotocol(struct Curl_easy *data,
       ;
     else {
       /* Perform setup complement if some. */
-      conn->handler = conn->given = p;
+      conn->scheme = conn->given = p;
       /* 'port' and 'remote_port' are set in setup_connection_internals() */
       return CURLE_OK;
     }
@@ -1850,7 +1702,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
     if(!uc) {
       char *decoded;
       result = Curl_urldecode(data->state.up.password, 0, &decoded, NULL,
-                              conn->handler->flags&PROTOPT_USERPWDCTRL ?
+                              conn->scheme->flags&PROTOPT_USERPWDCTRL ?
                               REJECT_ZERO : REJECT_CTRL);
       if(result)
         return result;
@@ -1872,7 +1724,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
     if(!uc) {
       char *decoded;
       result = Curl_urldecode(data->state.up.user, 0, &decoded, NULL,
-                              conn->handler->flags&PROTOPT_USERPWDCTRL ?
+                              conn->scheme->flags&PROTOPT_USERPWDCTRL ?
                               REJECT_ZERO : REJECT_CTRL);
       if(result)
         return result;
@@ -1982,8 +1834,8 @@ static CURLcode setup_connection_internals(struct Curl_easy *data,
   CURLcode result;
 
   DEBUGF(infof(data, "setup connection, bits.close=%d", conn->bits.close));
-  if(conn->handler->setup_connection) {
-    result = conn->handler->setup_connection(data, conn);
+  if(conn->scheme->run->setup_connection) {
+    result = conn->scheme->run->setup_connection(data, conn);
     if(result)
       return result;
   }
@@ -2054,7 +1906,7 @@ static char *detect_proxy(struct Curl_easy *data,
   const char *envp = proxy_env;
 
   curl_msnprintf(proxy_env, sizeof(proxy_env), "%s_proxy",
-                 conn->handler->scheme);
+                 conn->scheme->name);
 
   /* read the protocol proxy: */
   proxy = curl_getenv(proxy_env);
@@ -2415,13 +2267,13 @@ static CURLcode create_conn_helper_init_proxy(struct Curl_easy *data,
   }
 #endif
 
-  if(proxy && (!*proxy || (conn->handler->flags & PROTOPT_NONETWORK))) {
+  if(proxy && (!*proxy || (conn->scheme->flags & PROTOPT_NONETWORK))) {
     curlx_free(proxy);  /* Do not bother with an empty proxy string
                            or if the protocol does not work with network */
     proxy = NULL;
   }
   if(socksproxy && (!*socksproxy ||
-                    (conn->handler->flags & PROTOPT_NONETWORK))) {
+                    (conn->scheme->flags & PROTOPT_NONETWORK))) {
     curlx_free(socksproxy);  /* Do not bother with an empty socks proxy string
                                 or if the protocol does not work with
                                 network */
@@ -2457,10 +2309,10 @@ static CURLcode create_conn_helper_init_proxy(struct Curl_easy *data,
       goto out;
 #else
       /* force this connection's protocol to become HTTP if compatible */
-      if(!(conn->handler->protocol & PROTO_FAMILY_HTTP)) {
-        if((conn->handler->flags & PROTOPT_PROXY_AS_HTTP) &&
+      if(!(conn->scheme->protocol & PROTO_FAMILY_HTTP)) {
+        if((conn->scheme->flags & PROTOPT_PROXY_AS_HTTP) &&
            !conn->bits.tunnel_proxy)
-          conn->handler = &Curl_handler_http;
+          conn->scheme = &Curl_scheme_http;
         else
           /* if not converting to HTTP over the proxy, enforce tunneling */
           conn->bits.tunnel_proxy = TRUE;
@@ -2705,7 +2557,7 @@ static CURLcode override_login(struct Curl_easy *data,
         return CURLE_READ_ERROR;
       }
       else {
-        if(!(conn->handler->flags & PROTOPT_USERPWDCTRL)) {
+        if(!(conn->scheme->flags & PROTOPT_USERPWDCTRL)) {
           /* if the protocol cannot handle control codes in credentials, make
              sure there are none */
           if(str_has_ctrl(*userp) || str_has_ctrl(*passwdp)) {
@@ -2788,7 +2640,7 @@ static CURLcode set_login(struct Curl_easy *data,
   const char *setpasswd = CURL_DEFAULT_PASSWORD;
 
   /* If our protocol needs a password and we have none, use the defaults */
-  if((conn->handler->flags & PROTOPT_NEEDSPWD) && !data->state.aptr.user)
+  if((conn->scheme->flags & PROTOPT_NEEDSPWD) && !data->state.aptr.user)
     ;
   else {
     setuser = "";
@@ -3025,7 +2877,7 @@ static CURLcode parse_connect_to_slist(struct Curl_easy *data,
 
 #ifndef CURL_DISABLE_ALTSVC
   if(data->asi && !host && (port == -1) &&
-     ((conn->handler->protocol == CURLPROTO_HTTPS) ||
+     ((conn->scheme->protocol == CURLPROTO_HTTPS) ||
 #ifdef DEBUGBUILD
       /* allow debug builds to circumvent the HTTPS restriction */
       getenv("CURL_ALTSVC_HTTP")
@@ -3533,15 +3385,15 @@ static CURLcode create_conn(struct Curl_easy *data,
    * file: is a special case in that it does not need a network connection
    ***********************************************************************/
 #ifndef CURL_DISABLE_FILE
-  if(conn->handler->flags & PROTOPT_NONETWORK) {
+  if(conn->scheme->flags & PROTOPT_NONETWORK) {
     bool done;
     /* this is supposed to be the connect function so we better at least check
        that the file is present here! */
-    DEBUGASSERT(conn->handler->connect_it);
-    data->info.conn_scheme = conn->handler->scheme;
+    DEBUGASSERT(conn->scheme->run->connect_it);
+    data->info.conn_scheme = conn->scheme->name;
     /* conn_protocol can only provide "old" protocols */
-    data->info.conn_protocol = (conn->handler->protocol) & CURLPROTO_MASK;
-    result = conn->handler->connect_it(data, &done);
+    data->info.conn_protocol = (conn->scheme->protocol) & CURLPROTO_MASK;
+    result = conn->scheme->run->connect_it(data, &done);
     if(result)
       goto out;
 
@@ -3558,9 +3410,9 @@ static CURLcode create_conn(struct Curl_easy *data,
     }
 
     if(result) {
-      DEBUGASSERT(conn->handler->done);
+      DEBUGASSERT(conn->scheme->run->done);
       /* we ignore the return code for the protocol-specific DONE */
-      (void)conn->handler->done(data, result, FALSE);
+      (void)conn->scheme->run->done(data, result, FALSE);
     }
     goto out;
   }
@@ -3614,7 +3466,7 @@ static CURLcode create_conn(struct Curl_easy *data,
 
 #ifndef CURL_DISABLE_PROXY
     infof(data, "Reusing existing %s: connection%s with %s %s",
-          conn->given->scheme,
+          conn->given->name,
           tls_upgraded ? " (upgraded to SSL)" : "",
           conn->bits.proxy ? "proxy" : "host",
           conn->socks_proxy.host.name ? conn->socks_proxy.host.dispname :
@@ -3622,7 +3474,7 @@ static CURLcode create_conn(struct Curl_easy *data,
           conn->host.dispname);
 #else
     infof(data, "Reusing existing %s: connection%s with host %s",
-          conn->given->scheme,
+          conn->given->name,
           tls_upgraded ? " (upgraded to SSL)" : "",
           conn->host.dispname);
 #endif
@@ -3633,7 +3485,7 @@ static CURLcode create_conn(struct Curl_easy *data,
        connections we are allowed to open. */
     DEBUGF(infof(data, "new connection, bits.close=%d", conn->bits.close));
 
-    if(conn->handler->flags & PROTOPT_ALPN) {
+    if(conn->scheme->flags & PROTOPT_ALPN) {
       /* The protocol wants it, so set the bits if enabled in the easy handle
          (default) */
       if(data->set.ssl_enable_alpn)
@@ -3733,9 +3585,9 @@ static CURLcode create_conn(struct Curl_easy *data,
   }
 
   /* persist the scheme and handler the transfer is using */
-  data->info.conn_scheme = conn->handler->scheme;
+  data->info.conn_scheme = conn->scheme->name;
   /* conn_protocol can only provide "old" protocols */
-  data->info.conn_protocol = (conn->handler->protocol) & CURLPROTO_MASK;
+  data->info.conn_protocol = (conn->scheme->protocol) & CURLPROTO_MASK;
   data->info.used_proxy =
 #ifdef CURL_DISABLE_PROXY
     0
@@ -3808,7 +3660,7 @@ CURLcode Curl_connect(struct Curl_easy *data,
         /* multiplexed */
         *protocol_done = TRUE;
     }
-    else if(conn->handler->flags & PROTOPT_NONETWORK) {
+    else if(conn->scheme->flags & PROTOPT_NONETWORK) {
       *asyncp = FALSE;
       Curl_pgrsTime(data, TIMER_NAMELOOKUP);
       *protocol_done = TRUE;
@@ -3859,7 +3711,7 @@ CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn)
                                    use */
     /* if the protocol used does not support wildcards, switch it off */
     if(data->state.wildcardmatch &&
-       !(conn->handler->flags & PROTOPT_WILDCARD))
+       !(conn->scheme->flags & PROTOPT_WILDCARD))
       data->state.wildcardmatch = FALSE;
   }
 
index df80b93ab8928805270ebab6c414445f2467f406..1e44ebe43bb0d94309e27a15486fc1d040dab958 100644 (file)
--- a/lib/url.h
+++ b/lib/url.h
@@ -71,9 +71,8 @@ void *Curl_conn_meta_get(struct connectdata *conn, const char *key);
  * @param scheme URI scheme, case-insensitive
  * @return NULL of handler not found
  */
-const struct Curl_handler *Curl_get_scheme_handler(const char *scheme);
-const struct Curl_handler *Curl_getn_scheme_handler(const char *scheme,
-                                                    size_t len);
+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
index c7c48ed79892994078875566513230eb5c9ca001..9899f6aff39ec209960ec52655bf4fc1505d2213 100644 (file)
@@ -256,7 +256,7 @@ static CURLUcode parse_hostname_login(struct Curl_URL *u,
   char *userp = NULL;
   char *passwdp = NULL;
   char *optionsp = NULL;
-  const struct Curl_handler *h = NULL;
+  const struct Curl_scheme *h = NULL;
 
   /* At this point, we assume all the other special cases have been taken
    * care of, so the host is at most
@@ -281,7 +281,7 @@ static CURLUcode parse_hostname_login(struct Curl_URL *u,
 
   /* if this is a known scheme, get some details */
   if(u->scheme)
-    h = Curl_get_scheme_handler(u->scheme);
+    h = Curl_get_scheme(u->scheme);
 
   /* We could use the login information in the URL so extract it. Only parse
      options if the handler says we should. Note that 'h' might be NULL! */
@@ -948,7 +948,7 @@ static CURLUcode parse_scheme(const char *url, CURLU *u, char *schemebuf,
     }
 
     schemep = schemebuf;
-    if(!Curl_get_scheme_handler(schemep) &&
+    if(!Curl_get_scheme(schemep) &&
        !(flags & CURLU_NON_SUPPORT_SCHEME))
       return CURLUE_UNSUPPORTED_SCHEME;
 
@@ -1448,7 +1448,7 @@ static CURLUcode urlget_url(const CURLU *u, char **part, unsigned int flags)
   else if(!u->host)
     return CURLUE_NO_HOST;
   else {
-    const struct Curl_handler *h = NULL;
+    const struct Curl_scheme *h = NULL;
     char schemebuf[MAX_SCHEME_LEN + 5];
     if(u->scheme)
       scheme = u->scheme;
@@ -1457,7 +1457,7 @@ static CURLUcode urlget_url(const CURLU *u, char **part, unsigned int flags)
     else
       return CURLUE_NO_SCHEME;
 
-    h = Curl_get_scheme_handler(scheme);
+    h = Curl_get_scheme(scheme);
     if(!port && (flags & CURLU_DEFAULT_PORT)) {
       /* there is no stored port number, but asked to deliver
          a default one for the scheme */
@@ -1586,7 +1586,7 @@ CURLUcode curl_url_get(const CURLU *u, CURLUPart what,
     if(!ptr && (flags & CURLU_DEFAULT_PORT) && u->scheme) {
       /* there is no stored port number, but asked to deliver
          a default one for the scheme */
-      const struct Curl_handler *h = Curl_get_scheme_handler(u->scheme);
+      const struct Curl_scheme *h = Curl_get_scheme(u->scheme);
       if(h) {
         curl_msnprintf(portbuf, sizeof(portbuf), "%u", h->defport);
         ptr = portbuf;
@@ -1595,7 +1595,7 @@ CURLUcode curl_url_get(const CURLU *u, CURLUPart what,
     else if(ptr && u->scheme) {
       /* there is a stored port number, but ask to inhibit if
          it matches the default one for the scheme */
-      const struct Curl_handler *h = Curl_get_scheme_handler(u->scheme);
+      const struct Curl_scheme *h = Curl_get_scheme(u->scheme);
       if(h && (h->defport == u->portnum) &&
          (flags & CURLU_NO_DEFAULT_PORT))
         ptr = NULL;
@@ -1637,16 +1637,16 @@ static CURLUcode set_url_scheme(CURLU *u, const char *scheme,
                                 unsigned int flags)
 {
   size_t plen = strlen(scheme);
-  const struct Curl_handler *h = NULL;
+  const struct Curl_scheme *h = NULL;
   if((plen > MAX_SCHEME_LEN) || (plen < 1))
     /* too long or too short */
     return CURLUE_BAD_SCHEME;
   /* verify that it is a fine scheme */
-  h = Curl_get_scheme_handler(scheme);
+  h = Curl_get_scheme(scheme);
+  if(!(flags & CURLU_NON_SUPPORT_SCHEME) && (!h || !h->run))
+    return CURLUE_UNSUPPORTED_SCHEME;
   if(!h) {
     const char *s = scheme;
-    if(!(flags & CURLU_NON_SUPPORT_SCHEME))
-      return CURLUE_UNSUPPORTED_SCHEME;
     if(ISALPHA(*s)) {
       /* ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */
       while(--plen) {
index a3a37a8e039e1626e37efe6472d83e71944b71cd..f423d3376739d2e371df754e4269fd1f1165a023 100644 (file)
@@ -427,9 +427,7 @@ struct hostname {
  * Specific protocol handler.
  */
 
-struct Curl_handler {
-  const char *scheme;        /* URL scheme name in lowercase */
-
+struct Curl_protocol {
   /* Complement to setup_connection_internals(). This is done before the
      transfer "owns" the connection. */
   CURLcode (*setup_connection)(struct Curl_easy *data,
@@ -514,14 +512,17 @@ struct Curl_handler {
      the way the follow request is performed. */
   CURLcode (*follow)(struct Curl_easy *data, const char *newurl,
                      followtype type);
+};
 
-  uint16_t defport;       /* Default port. */
+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; basically the
                              non-TLS name of the protocol this is */
-  uint32_t flags;     /* Extra particular characteristics, see PROTOPT_* */
-
+  uint32_t flags;         /* Extra particular characteristics, see PROTOPT_* */
+  uint16_t defport;       /* Default port. */
 };
 
 #define PROTOPT_NONE 0             /* nothing extra */
@@ -659,8 +660,8 @@ struct connectdata {
 #endif
   struct ConnectBits bits;    /* various state-flags for this connection */
 
-  const struct Curl_handler *handler; /* Connection's protocol handler */
-  const struct Curl_handler *given;   /* The protocol first given */
+  const struct Curl_scheme *scheme; /* Connection's protocol handler */
+  const struct Curl_scheme *given;   /* The protocol first given */
 
   /* Protocols can use a custom keepalive mechanism to keep connections alive.
      This allows those protocols to track the last time the keepalive mechanism
index 5c2ae8db1e23c96e619abce1cbdbd785bbe254f9..112838b0ccafd307cc9e9a2cf3e4f5e1f7fd4ceb 100644 (file)
@@ -143,7 +143,7 @@ bool Curl_auth_allowed_to_host(struct Curl_easy *data)
          (data->state.first_host &&
           curl_strequal(data->state.first_host, conn->host.name) &&
           (data->state.first_remote_port == conn->remote_port) &&
-          (data->state.first_remote_protocol == conn->handler->protocol));
+          (data->state.first_remote_protocol == conn->scheme->protocol));
 }
 
 #ifdef USE_NTLM
index 9d45833820d73fafdddc9ab9e3fca03b7a9669c5..3cc2eb98a3bc248e8a57720b29b04136b03314c5 100644 (file)
@@ -719,7 +719,7 @@ CURLcode Curl_conn_may_http3(struct Curl_easy *data,
     /* cannot do QUIC over a Unix domain socket */
     return CURLE_QUIC_CONNECT_ERROR;
   }
-  if(!(conn->handler->flags & PROTOPT_SSL)) {
+  if(!(conn->scheme->flags & PROTOPT_SSL)) {
     failf(data, "HTTP/3 requested for non-HTTPS URL");
     return CURLE_URL_MALFORMAT;
   }
index 52063445283c6e7e6f5688f8ca53c4c159cfeaa1..5a2c9203f2da97f2bbd1c2770e252fd024d1c524 100644 (file)
@@ -1034,7 +1034,7 @@ static int myssh_in_AUTH_DONE(struct Curl_easy *data,
   conn->recv_idx = FIRSTSOCKET;
   conn->send_idx = -1;
 
-  if(conn->handler->protocol == CURLPROTO_SFTP) {
+  if(conn->scheme->protocol == CURLPROTO_SFTP) {
     myssh_to(data, sshc, SSH_SFTP_INIT);
     return SSH_NO_ERROR;
   }
@@ -2501,7 +2501,7 @@ static CURLcode myssh_connect(struct Curl_easy *data, bool *done)
     return CURLE_FAILED_INIT;
 
   CURL_TRC_SSH(data, "myssh_connect");
-  if(conn->handler->protocol & CURLPROTO_SCP) {
+  if(conn->scheme->protocol & CURLPROTO_SCP) {
     conn->recv[FIRSTSOCKET] = scp_recv;
     conn->send[FIRSTSOCKET] = scp_send;
   }
@@ -3034,7 +3034,7 @@ static CURLcode myssh_do_it(struct Curl_easy *data, bool *done)
 
   Curl_pgrsReset(data);
 
-  if(conn->handler->protocol & CURLPROTO_SCP)
+  if(conn->scheme->protocol & CURLPROTO_SCP)
     result = scp_perform(data, &connected, done);
   else
     result = sftp_perform(data, &connected, done);
@@ -3062,10 +3062,9 @@ void Curl_ssh_version(char *buffer, size_t buflen)
 }
 
 /*
- * SCP protocol handler.
+ * SCP.
  */
-const struct Curl_handler Curl_handler_scp = {
-  "SCP",                        /* scheme */
+const struct Curl_protocol Curl_protocol_scp = {
   myssh_setup_connection,       /* setup_connection */
   myssh_do_it,                  /* do_it */
   scp_done,                     /* done */
@@ -3083,18 +3082,12 @@ const struct Curl_handler Curl_handler_scp = {
   ZERO_NULL,                    /* connection_check */
   ZERO_NULL,                    /* attach connection */
   ZERO_NULL,                    /* follow */
-  PORT_SSH,                     /* defport */
-  CURLPROTO_SCP,                /* protocol */
-  CURLPROTO_SCP,                /* family */
-  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | /* flags */
-  PROTOPT_NOURLQUERY | PROTOPT_CONN_REUSE
 };
 
 /*
- * SFTP protocol handler.
+ * SFTP.
  */
-const struct Curl_handler Curl_handler_sftp = {
-  "SFTP",                               /* scheme */
+const struct Curl_protocol Curl_protocol_sftp = {
   myssh_setup_connection,               /* setup_connection */
   myssh_do_it,                          /* do_it */
   sftp_done,                            /* done */
@@ -3112,11 +3105,6 @@ const struct Curl_handler Curl_handler_sftp = {
   ZERO_NULL,                            /* connection_check */
   ZERO_NULL,                            /* attach connection */
   ZERO_NULL,                            /* follow */
-  PORT_SSH,                             /* defport */
-  CURLPROTO_SFTP,                       /* protocol */
-  CURLPROTO_SFTP,                       /* family */
-  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | /* flags */
-  PROTOPT_NOURLQUERY | PROTOPT_CONN_REUSE
 };
 
 #endif /* USE_LIBSSH */
index 7362b420d30f3e56c8980e666bc1f52b6bca3fb7..a0f6cd243c050b4aa0850eb11f8e5626fde01c8d 100644 (file)
@@ -1858,7 +1858,7 @@ static CURLcode ssh_state_auth_done(struct Curl_easy *data,
   data->conn->recv_idx = FIRSTSOCKET;
   conn->send_idx = -1;
 
-  if(conn->handler->protocol == CURLPROTO_SFTP) {
+  if(conn->scheme->protocol == CURLPROTO_SFTP) {
     myssh_state(data, sshc, SSH_SFTP_INIT);
     return CURLE_OK;
   }
@@ -3478,7 +3478,7 @@ static CURLcode ssh_connect(struct Curl_easy *data, bool *done)
   }
 
 #endif /* CURL_DISABLE_PROXY */
-  if(conn->handler->protocol & CURLPROTO_SCP) {
+  if(conn->scheme->protocol & CURLPROTO_SCP) {
     conn->recv[FIRSTSOCKET] = scp_recv;
     conn->send[FIRSTSOCKET] = scp_send;
   }
@@ -3867,7 +3867,7 @@ static CURLcode ssh_do(struct Curl_easy *data, bool *done)
 
   Curl_pgrsReset(data);
 
-  if(conn->handler->protocol & CURLPROTO_SCP)
+  if(conn->scheme->protocol & CURLPROTO_SCP)
     result = scp_perform(data, &connected, done);
   else
     result = sftp_perform(data, &connected, done);
@@ -3902,7 +3902,7 @@ static void ssh_attach(struct Curl_easy *data, struct connectdata *conn)
 {
   DEBUGASSERT(data);
   DEBUGASSERT(conn);
-  if(conn->handler->protocol & PROTO_FAMILY_SSH) {
+  if(conn->scheme->protocol & PROTO_FAMILY_SSH) {
     struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN);
     if(sshc && sshc->ssh_session) {
       /* only re-attach if the session already exists */
@@ -3915,8 +3915,7 @@ static void ssh_attach(struct Curl_easy *data, struct connectdata *conn)
 /*
  * SCP protocol handler.
  */
-const struct Curl_handler Curl_handler_scp = {
-  "SCP",                                /* scheme */
+const struct Curl_protocol Curl_protocol_scp = {
   ssh_setup_connection,                 /* setup_connection */
   ssh_do,                               /* do_it */
   scp_done,                             /* done */
@@ -3934,18 +3933,12 @@ const struct Curl_handler Curl_handler_scp = {
   ZERO_NULL,                            /* connection_check */
   ssh_attach,                           /* attach */
   ZERO_NULL,                            /* follow */
-  PORT_SSH,                             /* defport */
-  CURLPROTO_SCP,                        /* protocol */
-  CURLPROTO_SCP,                        /* family */
-  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | /* flags */
-  PROTOPT_NOURLQUERY | PROTOPT_CONN_REUSE
 };
 
 /*
  * SFTP protocol handler.
  */
-const struct Curl_handler Curl_handler_sftp = {
-  "SFTP",                               /* scheme */
+const struct Curl_protocol Curl_protocol_sftp = {
   ssh_setup_connection,                 /* setup_connection */
   ssh_do,                               /* do_it */
   sftp_done,                            /* done */
@@ -3963,11 +3956,6 @@ const struct Curl_handler Curl_handler_sftp = {
   ZERO_NULL,                            /* connection_check */
   ssh_attach,                           /* attach */
   ZERO_NULL,                            /* follow */
-  PORT_SSH,                             /* defport */
-  CURLPROTO_SFTP,                       /* protocol */
-  CURLPROTO_SFTP,                       /* family */
-  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | /* flags */
-  PROTOPT_NOURLQUERY | PROTOPT_CONN_REUSE
 };
 
 #endif /* USE_LIBSSH2 */
index 6fdf3f794bc1543ddc6ee7334c2ddf850d6c64df..d98070856c809435906c9af552c3578e29ac5e07 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef HEADER_CURL_SSH_H
-#define HEADER_CURL_SSH_H
+#ifndef HEADER_CURL_VSSH_SSH_H
+#define HEADER_CURL_VSSH_SSH_H
 /***************************************************************************
  *                                  _   _ ____  _
  *  Project                     ___| | | |  _ \| |
  ***************************************************************************/
 #include "../curl_setup.h"
 
+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_LIBSSH2
 #include <libssh2.h>
 #include <libssh2_sftp.h>
@@ -232,9 +238,6 @@ struct ssh_conn {
 
 #ifdef USE_SSH
 
-extern const struct Curl_handler Curl_handler_scp;
-extern const struct Curl_handler Curl_handler_sftp;
-
 /* generic SSH backend functions */
 CURLcode Curl_ssh_init(void);
 void Curl_ssh_cleanup(void);
index 77fa89b557e670cf7ffe2036738296cf84d64e0b..f51669906b976f06be7c9062b01a6f5321d1b8b0 100644 (file)
@@ -23,9 +23,9 @@
  ***************************************************************************/
 #include "../curl_setup.h"
 
-#ifdef USE_SSH
-
 #include "vssh.h"
+#include "ssh.h"
+#ifdef USE_SSH
 #include "../curlx/strparse.h"
 #include "../curl_trc.h"
 #include "../escape.h"
@@ -51,7 +51,7 @@ CURLcode Curl_getworkingpath(struct Curl_easy *data,
   curlx_dyn_init(&npath, MAX_SSHPATH_LEN);
 
   /* Check for /~/, indicating relative to the user's home directory */
-  if((data->conn->handler->protocol & CURLPROTO_SCP) &&
+  if((data->conn->scheme->protocol & CURLPROTO_SCP) &&
      (working_path_len > 3) && (!memcmp(working_path, "/~/", 3))) {
     /* It is referenced to the home directory, so strip the leading '/~/' */
     if(curlx_dyn_addn(&npath, &working_path[3], working_path_len - 3)) {
@@ -59,7 +59,7 @@ CURLcode Curl_getworkingpath(struct Curl_easy *data,
       return CURLE_OUT_OF_MEMORY;
     }
   }
-  else if((data->conn->handler->protocol & CURLPROTO_SFTP) &&
+  else if((data->conn->scheme->protocol & CURLPROTO_SFTP) &&
           (!strcmp("/~", working_path) ||
            ((working_path_len > 2) && !memcmp(working_path, "/~/", 3)))) {
     if(curlx_dyn_add(&npath, homedir)) {
@@ -239,3 +239,34 @@ 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 4bc6d808074a75b73ab90634127637168e35d0b8..f3a4873e7f3ed50eab154e716b31f102692f8f96 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef HEADER_CURL_PATH_H
-#define HEADER_CURL_PATH_H
+#ifndef HEADER_CURL_VSSH_VSSH_H
+#define HEADER_CURL_VSSH_VSSH_H
 /***************************************************************************
  *                                  _   _ ____  _
  *  Project                     ___| | | |  _ \| |
@@ -37,4 +37,4 @@ CURLcode Curl_ssh_range(struct Curl_easy *data,
                         const char *range, curl_off_t filesize,
                         curl_off_t *startp, curl_off_t *sizep);
 
-#endif /* HEADER_CURL_PATH_H */
+#endif /* HEADER_CURL_VSSH_VSSH_H */
index d3e004fcf079ac4eac153cca1ed51e30cafd7982..f9075f518f0142441db3ded990ee07c75c23d594 100644 (file)
--- a/lib/ws.c
+++ b/lib/ws.c
  *
  ***************************************************************************/
 #include "curl_setup.h"
+#include "urldata.h"
 
-#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)
+#ifdef CURL_DISABLE_HTTP
+/* no WebSockets without HTTP present */
+#undef CURL_DISABLE_WEBSOCKETS
+#define CURL_DISABLE_WEBSOCKETS 1
+#endif
+
+#ifndef CURL_DISABLE_WEBSOCKETS
 
-#include "urldata.h"
 #include "url.h"
 #include "bufq.h"
 #include "curlx/dynbuf.h"
@@ -1904,8 +1910,7 @@ out:
   return result;
 }
 
-const struct Curl_handler Curl_handler_ws = {
-  "WS",                                 /* scheme */
+static const struct Curl_protocol Curl_protocol_ws = {
   ws_setup_conn,                        /* setup_connection */
   Curl_http,                            /* do_it */
   Curl_http_done,                       /* done */
@@ -1923,40 +1928,7 @@ const struct Curl_handler Curl_handler_ws = {
   ZERO_NULL,                            /* connection_check */
   ZERO_NULL,                            /* attach connection */
   Curl_http_follow,                     /* follow */
-  PORT_HTTP,                            /* defport */
-  CURLPROTO_WS,                         /* protocol */
-  CURLPROTO_HTTP,                       /* family */
-  PROTOPT_CREDSPERREQUEST |             /* flags */
-  PROTOPT_USERPWDCTRL
-};
-
-#ifdef USE_SSL
-const struct Curl_handler Curl_handler_wss = {
-  "WSS",                                /* scheme */
-  ws_setup_conn,                        /* setup_connection */
-  Curl_http,                            /* do_it */
-  Curl_http_done,                       /* done */
-  ZERO_NULL,                            /* do_more */
-  ZERO_NULL,                            /* connect_it */
-  NULL,                                 /* connecting */
-  ZERO_NULL,                            /* doing */
-  NULL,                                 /* proto_pollset */
-  Curl_http_doing_pollset,              /* doing_pollset */
-  ZERO_NULL,                            /* domore_pollset */
-  Curl_http_perform_pollset,            /* perform_pollset */
-  ZERO_NULL,                            /* disconnect */
-  Curl_http_write_resp,                 /* write_resp */
-  Curl_http_write_resp_hd,              /* write_resp_hd */
-  ZERO_NULL,                            /* connection_check */
-  ZERO_NULL,                            /* attach connection */
-  Curl_http_follow,                     /* follow */
-  PORT_HTTPS,                           /* defport */
-  CURLPROTO_WSS,                        /* protocol */
-  CURLPROTO_HTTP,                       /* family */
-  PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | /* flags */
-    PROTOPT_USERPWDCTRL
 };
-#endif
 
 #else
 
@@ -2002,4 +1974,33 @@ CURL_EXTERN CURLcode curl_ws_start_frame(CURL *curl,
   return CURLE_NOT_BUILT_IN;
 }
 
-#endif /* !CURL_DISABLE_WEBSOCKETS && !CURL_DISABLE_HTTP */
+#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 a6e770694deea6ee0c5d14bd75fabc0919207bc8..d4d6d46f3a51d788c3b51343508fa7ede68bebef 100644 (file)
--- a/lib/ws.h
+++ b/lib/ws.h
@@ -25,6 +25,9 @@
  ***************************************************************************/
 #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)
 
 /* meta key for storing protocol meta at connection */
 CURLcode Curl_ws_request(struct Curl_easy *data, struct dynbuf *req);
 CURLcode Curl_ws_accept(struct Curl_easy *data, const char *mem, size_t len);
 
-extern const struct Curl_handler Curl_handler_ws;
-#ifdef USE_SSL
-extern const struct Curl_handler Curl_handler_wss;
-#endif
-
 #else
 #define Curl_ws_request(x, y) CURLE_OK
 #define Curl_ws_free(x)       Curl_nop_stmt
index dded8dc753faf3a2bf0b60532fa1d4f60fcc2c5d..49660c94d3262b7af9d9c2c05659c283991c8c2d 100644 (file)
  * function in url.c.
  */
 
-struct detail {
-  const char *n;
-  const char *ifdef;
-};
-
-static const struct detail scheme[] = {
-  { "dict", "#ifndef CURL_DISABLE_DICT" },
-  { "file", "#ifndef CURL_DISABLE_FILE" },
-  { "ftp", "#ifndef CURL_DISABLE_FTP" },
-  { "ftps", "#if defined(USE_SSL) && !defined(CURL_DISABLE_FTP)" },
-  { "gopher", "#ifndef CURL_DISABLE_GOPHER" },
-  { "gophers", "#if defined(USE_SSL) && !defined(CURL_DISABLE_GOPHER)" },
-  { "http", "#ifndef CURL_DISABLE_HTTP" },
-  { "https", "#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)" },
-  { "imap", "#ifndef CURL_DISABLE_IMAP" },
-  { "imaps", "#if defined(USE_SSL) && !defined(CURL_DISABLE_IMAP)" },
-  { "ldap", "#ifndef CURL_DISABLE_LDAP" },
-  { "ldaps", "#if !defined(CURL_DISABLE_LDAP) && \\\n"
-             "  !defined(CURL_DISABLE_LDAPS) && \\\n"
-             "  ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \\\n"
-             "   (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)))" },
-  { "mqtt", "#ifndef CURL_DISABLE_MQTT" },
-  { "mqtts", "#if defined(USE_SSL) && !defined(CURL_DISABLE_MQTT)" },
-  { "pop3", "#ifndef CURL_DISABLE_POP3" },
-  { "pop3s", "#if defined(USE_SSL) && !defined(CURL_DISABLE_POP3)" },
-  { "rtmp", "#ifdef USE_LIBRTMP" },
-  { "rtmpt", "#ifdef USE_LIBRTMP" },
-  { "rtmpe", "#ifdef USE_LIBRTMP" },
-  { "rtmpte", "#ifdef USE_LIBRTMP" },
-  { "rtmps", "#ifdef USE_LIBRTMP" },
-  { "rtmpts", "#ifdef USE_LIBRTMP" },
-  { "rtsp", "#ifndef CURL_DISABLE_RTSP" },
-  { "scp", "#ifdef USE_SSH" },
-  { "sftp", "#ifdef USE_SSH" },
-  { "smb", "#if !defined(CURL_DISABLE_SMB) && \\\n"
-           "  defined(USE_CURL_NTLM_CORE) && (SIZEOF_CURL_OFF_T > 4)" },
-  { "smbs", "#if defined(USE_SSL) && !defined(CURL_DISABLE_SMB) && \\\n"
-            "  defined(USE_CURL_NTLM_CORE) && (SIZEOF_CURL_OFF_T > 4)" },
-  { "smtp", "#ifndef CURL_DISABLE_SMTP" },
-  { "smtps", "#if defined(USE_SSL) && !defined(CURL_DISABLE_SMTP)" },
-  { "telnet", "#ifndef CURL_DISABLE_TELNET" },
-  { "tftp", "#ifndef CURL_DISABLE_TFTP" },
-  { "ws",
-    "#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)" },
-  { "wss", "#if !defined(CURL_DISABLE_WEBSOCKETS) && \\\n"
-           "  defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)" },
-  { NULL, NULL }
+static const char *scheme[] = {
+  "dict",
+  "file",
+  "ftp",
+  "ftps",
+  "gopher",
+  "gophers",
+  "http",
+  "https",
+  "imap",
+  "imaps",
+  "ldap",
+  "ldaps",
+  "mqtt",
+  "mqtts",
+  "pop3",
+  "pop3s",
+  "rtmp",
+  "rtmpt",
+  "rtmpe",
+  "rtmpte",
+  "rtmps",
+  "rtmpts",
+  "rtsp",
+  "scp",
+  "sftp",
+  "smb",
+  "smbs",
+  "smtp",
+  "smtps",
+  "telnet",
+  "tftp",
+  "ws",
+  "wss",
+  NULL,
 };
 
 unsigned int calc(const char *s, int add, int shift)
@@ -97,9 +85,9 @@ static void showtable(int try, int init, int shift)
 {
   int nulls = 0;
   int i;
-  for(i = 0; scheme[i].n; ++i)
-    num[i] = calc(scheme[i].n, init, shift);
-  for(i = 0; scheme[i].n; ++i)
+  for(i = 0; scheme[i]; ++i)
+    num[i] = calc(scheme[i], init, shift);
+  for(i = 0; scheme[i]; ++i)
     ix[i] = num[i] % try;
   printf("/*\n"
          "   unsigned int c = %d\n"
@@ -112,32 +100,22 @@ static void showtable(int try, int init, int shift)
          "*/\n",
          init, shift);
 
-  printf("  static const struct Curl_handler * const protocols[%d] = {", try);
+  printf("  static const struct Curl_scheme * const all_schemes[%d] = {", try);
 
   /* generate table */
   for(i = 0; i < try; i++) {
     int match = 0;
     int j;
-    for(j = 0; scheme[j].n; j++) {
+    for(j = 0; scheme[j]; j++) {
       if(ix[j] == i) {
-        printf("\n");
-        printf("%s\n", scheme[j].ifdef);
-        printf("    &Curl_handler_%s,\n", scheme[j].n);
-        printf("#else\n    NULL,\n");
-        printf("#endif");
+        printf("\n    &Curl_scheme_%s,", scheme[j]);
         match = 1;
         nulls = 0;
         break;
       }
     }
-    if(!match) {
-      if(!nulls || (nulls > 10)) {
-        printf("\n   ");
-        nulls = 0;
-      }
-      printf(" NULL,", nulls);
-      nulls++;
-    }
+    if(!match)
+      printf(" NULL,");
   }
   printf("\n  };\n");
 }
@@ -153,8 +131,8 @@ int main(void)
   int shift;
   for(shift = 0; shift < 8; shift++) {
     for(add = 0; add < 999; add++) {
-      for(i = 0; scheme[i].n; ++i) {
-        unsigned int v = calc(scheme[i].n, add, shift);
+      for(i = 0; scheme[i]; ++i) {
+        unsigned int v = calc(scheme[i], add, shift);
         int j;
         int badcombo = 0;
         for(j = 0; j < i; j++) {
@@ -180,11 +158,11 @@ int main(void)
       /* try different remainders to find smallest possible table */
       for(try = 28; try < 199; try++) {
         int good = 1;
-        for(i = 0; scheme[i].n; ++i) {
+        for(i = 0; scheme[i]; ++i) {
           ix[i] = num[i] % try;
         }
         /* check for dupes */
-        for(i = 0; scheme[i].n && good; ++i) {
+        for(i = 0; scheme[i] && good; ++i) {
           int j;
           for(j = 0; j < i; j++) {
             if(ix[j] == ix[i]) {