diff --git a/configure.ac b/configure.ac index 39bdb5ef1..733c3f973 100755 --- a/configure.ac +++ b/configure.ac @@ -5111,6 +5111,9 @@ if test "x$CURL_DISABLE_TFTP" != "x1"; then fi if test "x$CURL_DISABLE_GOPHER" != "x1"; then SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS GOPHER" + if test "x$SSL_ENABLED" = "x1"; then + SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS GOPHERS" + fi fi if test "x$CURL_DISABLE_MQTT" != "x1"; then SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS MQTT" diff --git a/lib/gopher.c b/lib/gopher.c index b101c0ab6..c02436d4a 100644 --- a/lib/gopher.c +++ b/lib/gopher.c @@ -33,6 +33,7 @@ #include "gopher.h" #include "select.h" #include "strdup.h" +#include "vtls/vtls.h" #include "url.h" #include "escape.h" #include "warnless.h" @@ -46,6 +47,10 @@ */ static CURLcode gopher_do(struct connectdata *conn, bool *done); +#ifdef USE_SSL +static CURLcode gopher_connect(struct connectdata *conn, bool *done); +static CURLcode gopher_connecting(struct connectdata *conn, bool *done); +#endif /* * Gopher protocol handler. @@ -75,6 +80,46 @@ const struct Curl_handler Curl_handler_gopher = { PROTOPT_NONE /* flags */ }; +#ifdef USE_SSL +const struct Curl_handler Curl_handler_gophers = { + "GOPHERS", /* scheme */ + ZERO_NULL, /* setup_connection */ + gopher_do, /* do_it */ + ZERO_NULL, /* done */ + ZERO_NULL, /* do_more */ + gopher_connect, /* connect_it */ + gopher_connecting, /* connecting */ + ZERO_NULL, /* doing */ + ZERO_NULL, /* proto_getsock */ + ZERO_NULL, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + ZERO_NULL, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_GOPHER, /* defport */ + CURLPROTO_GOPHER, /* protocol */ + CURLPROTO_GOPHER, /* family */ + PROTOPT_SSL /* flags */ +}; + +static CURLcode gopher_connect(struct connectdata *conn, bool *done) +{ + (void)conn; + (void)done; + return CURLE_OK; +} + +static CURLcode gopher_connecting(struct connectdata *conn, bool *done) +{ + CURLcode result = Curl_ssl_connect(conn, FIRSTSOCKET); + if(result) + connclose(conn, "Failed TLS connection"); + *done = TRUE; + return result; +} +#endif + static CURLcode gopher_do(struct connectdata *conn, bool *done) { CURLcode result = CURLE_OK; @@ -127,6 +172,11 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done) k = curlx_uztosz(len); for(;;) { + /* Break out of the loop if the selector is empty because OpenSSL and/or + LibreSSL fail with errno 0 if this is the case. */ + if(strlen(sel) < 1) + break; + result = Curl_write(conn, sockfd, sel, k, &amount); if(!result) { /* Which may not have written it all! */ result = Curl_client_write(conn, CLIENTWRITE_HEADER, sel, amount); diff --git a/lib/gopher.h b/lib/gopher.h index b35fa4509..6b8bd554a 100644 --- a/lib/gopher.h +++ b/lib/gopher.h @@ -24,6 +24,9 @@ #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 #endif /* HEADER_CURL_GOPHER_H */ diff --git a/lib/url.c b/lib/url.c index 2b0ba87ba..a340213ad 100644 --- a/lib/url.c +++ b/lib/url.c @@ -251,6 +251,9 @@ static const struct Curl_handler * const protocols[] = { #ifndef CURL_DISABLE_GOPHER &Curl_handler_gopher, +#ifdef USE_SSL + &Curl_handler_gophers, +#endif #endif #ifdef USE_LIBRTMP diff --git a/lib/version.c b/lib/version.c index 7064c20d2..ab2c0d812 100644 --- a/lib/version.c +++ b/lib/version.c @@ -274,6 +274,9 @@ static const char * const protocols[] = { #ifndef CURL_DISABLE_GOPHER "gopher", #endif +#if defined(USE_SSL) && !defined(CURL_DISABLE_GOPHER) + "gophers", +#endif #ifndef CURL_DISABLE_HTTP "http", #endif