struct curl_pushheaders *headers,
void *userp);
+/*
+ * NAME curl_global_sslset()
+ *
+ * DESCRIPTION
+ *
+ * When built with multiple SSL backends, curl_global_sslset() allows to
+ * choose one. This function can only be called once, and it must be called
+ * *before* curl_global_init().
+ *
+ * The backend can be identified by the id (e.g. CURLSSLBACKEND_OPENSSL). The
+ * backend can also be specified via the name parameter (passing -1 as id).
+ * If both id and name are specified, the name will be ignored. If neither id
+ * nor name are specified, the function will fail with
+ * CURLSSLSET_UNKNOWN_BACKEND and set the "avail" pointer to the
+ * NULL-terminated list of available backends.
+ *
+ * Upon success, the function returns CURLSSLSET_OK.
+ *
+ * If the specified SSL backend is not available, the function returns
+ * CURLSSLSET_UNKNOWN_BACKEND and sets the "avail" pointer to a NULL-terminated
+ * list of available SSL backends.
+ *
+ * The SSL backend can be set only once. If it has already been set, a
+ * subsequent attempt to change it will result in a CURLSSLSET_TOO_LATE.
+ */
+
+typedef struct {
+ curl_sslbackend id;
+ const char *name;
+} curl_ssl_backend;
+
+typedef enum {
+ CURLSSLSET_OK = 0,
+ CURLSSLSET_UNKNOWN_BACKEND,
+ CURLSSLSET_TOO_LATE
+} CURLsslset;
+
+CURL_EXTERN CURLsslset curl_global_sslset(curl_sslbackend id, const char *name,
+ const curl_ssl_backend ***avail);
+
+#ifdef __cplusplus
+}
+#endif
+
#ifdef __cplusplus
} /* end of extern "C" */
#endif
}
#ifdef USE_SSL
-static int multissl_init(void);
+static int multissl_init(const struct Curl_ssl *backend);
#endif
int Curl_ssl_backend(void)
{
#ifdef USE_SSL
- multissl_init();
+ multissl_init(NULL);
return Curl_ssl->info.id;
#else
return (int)CURLSSLBACKEND_NONE;
static int Curl_multissl_init(void)
{
- if(multissl_init())
+ if(multissl_init(NULL))
return 1;
return Curl_ssl->init();
}
static size_t Curl_multissl_version(char *buffer, size_t size)
{
- if(multissl_init())
+ if(multissl_init(NULL))
return 0;
return Curl_ssl->version(buffer, size);
}
static CURLcode Curl_multissl_connect(struct connectdata *conn, int sockindex)
{
- if(multissl_init())
+ if(multissl_init(NULL))
return CURLE_FAILED_INIT;
return Curl_ssl->connect(conn, sockindex);
}
static CURLcode Curl_multissl_connect_nonblocking(struct connectdata *conn,
int sockindex, bool *done)
{
- if(multissl_init())
+ if(multissl_init(NULL))
return CURLE_FAILED_INIT;
return Curl_ssl->connect_nonblocking(conn, sockindex, done);
}
static void *Curl_multissl_get_internals(struct ssl_connect_data *connssl,
CURLINFO info)
{
- if(multissl_init())
+ if(multissl_init(NULL))
return NULL;
return Curl_ssl->get_internals(connssl, info);
}
static void Curl_multissl_close(struct connectdata *conn, int sockindex)
{
- if(multissl_init())
+ if(multissl_init(NULL))
return;
Curl_ssl->close(conn, sockindex);
}
NULL
};
-static int multissl_init(void)
+static int multissl_init(const struct Curl_ssl *backend)
{
const char *env;
int i;
if(Curl_ssl != &Curl_ssl_multi)
return 1;
+ if(backend) {
+ Curl_ssl = backend;
+ return 0;
+ }
+
if(!available_backends[0])
return 1;
return 0;
}
+CURLsslset curl_global_sslset(curl_sslbackend id, const char *name,
+ const curl_ssl_backend ***avail)
+{
+ int i;
+
+ if(Curl_ssl != &Curl_ssl_multi)
+ return id == Curl_ssl->info.id ? CURLSSLSET_OK : CURLSSLSET_TOO_LATE;
+
+ for(i = 0; available_backends[i]; i++)
+ if(available_backends[i]->info.id == id ||
+ (name && !strcmp(available_backends[i]->info.name, name))) {
+ multissl_init(available_backends[i]);
+ return CURLSSLSET_OK;
+ }
+
+ if(avail)
+ *avail = (const curl_ssl_backend **)&available_backends;
+ return CURLSSLSET_UNKNOWN_BACKEND;
+}
+
#endif /* USE_SSL */