← Commit list

6e35eb4879

Stefan Eissing
Stefan Eissing
2025-10-12
SUCCESS Duration: 165s

Subject

lib: SSL connection reuse

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

lib/ftp.c+1 -1
@@ -271,7 +271,7 @@ const struct Curl_handler Curl_handler_ftp = {
CURLPROTO_FTP, /* family */
PROTOPT_DUAL | PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD |
PROTOPT_NOURLQUERY | PROTOPT_PROXY_AS_HTTP |
- PROTOPT_WILDCARD /* flags */
+ PROTOPT_WILDCARD | PROTOPT_SSL_REUSE /* flags */
};
lib/imap.c+2 -1
@@ -209,7 +209,8 @@ const struct Curl_handler Curl_handler_imap = {
CURLPROTO_IMAP, /* protocol */
CURLPROTO_IMAP, /* family */
PROTOPT_CLOSEACTION| /* flags */
- PROTOPT_URLOPTIONS
+ PROTOPT_URLOPTIONS|
+ PROTOPT_SSL_REUSE
};
#ifdef USE_SSL
lib/ldap.c+1 -1
@@ -199,7 +199,7 @@ const struct Curl_handler Curl_handler_ldap = {
PORT_LDAP, /* defport */
CURLPROTO_LDAP, /* protocol */
CURLPROTO_LDAP, /* family */
- PROTOPT_NONE /* flags */
+ PROTOPT_SSL_REUSE /* flags */
};
#ifdef HAVE_LDAP_SSL
lib/openldap.c+1 -1
@@ -139,7 +139,7 @@ const struct Curl_handler Curl_handler_ldap = {
PORT_LDAP, /* defport */
CURLPROTO_LDAP, /* protocol */
CURLPROTO_LDAP, /* family */
- PROTOPT_NONE /* flags */
+ PROTOPT_SSL_REUSE /* flags */
};
#ifdef USE_SSL
lib/pop3.c+1 -1
@@ -200,7 +200,7 @@ const struct Curl_handler Curl_handler_pop3 = {
CURLPROTO_POP3, /* protocol */
CURLPROTO_POP3, /* family */
PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */
- PROTOPT_URLOPTIONS
+ PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE
};
#ifdef USE_SSL
lib/smtp.c+1 -1
@@ -205,7 +205,7 @@ const struct Curl_handler Curl_handler_smtp = {
CURLPROTO_SMTP, /* protocol */
CURLPROTO_SMTP, /* family */
PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */
- PROTOPT_URLOPTIONS
+ PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE
};
#ifdef USE_SSL
lib/url.c+5 -4
@@ -932,15 +932,16 @@ 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->handler->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;
}
else if(Curl_conn_is_ssl(conn, FIRSTSOCKET)) {
- /* We are not *requiring* SSL, however `conn` has it. If the
- * protocol *family* is not the same, not a match. */
- if(get_protocol_family(conn->handler) != m->needle->handler->protocol)
+ /* 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))
return FALSE;
}
return TRUE;
lib/urldata.h+3 -0
@@ -578,6 +578,9 @@ struct Curl_handler {
#define PROTOPT_USERPWDCTRL (1<<13) /* Allow "control bytes" (< 32 ASCII) in
username and password */
#define PROTOPT_NOTCPPROXY (1<<14) /* this protocol cannot proxy over TCP */
+#define PROTOPT_SSL_REUSE (1<<15) /* this protocol may reuse an existing
+ SSL connection in the same family
+ without having PROTOPT_SSL. */
#define CONNCHECK_NONE 0 /* No checks */
#define CONNCHECK_ISDEAD (1<<0) /* Check if the connection is dead. */
tests/http/test_01_basic.py+20 -0
@@ -273,3 +273,23 @@ class TestBasic:
assert r.responses[0]['header']['request-te'] == te_out, f'{r.responses[0]}'
else:
assert 'request-te' not in r.responses[0]['header'], f'{r.responses[0]}'
+
+ # check that an existing https: connection is not reused for http:
+ def test_01_18_tls_reuse(self, env: Env, httpd):
+ proto = 'h2'
+ curl = CurlClient(env=env)
+ url1 = f'https://{env.authority_for(env.domain1, proto)}/data.json'
+ url2 = f'http://{env.authority_for(env.domain1, proto)}/data.json'
+ r = curl.http_download(urls=[url1, url2], alpn_proto=proto, with_stats=True)
+ assert len(r.stats) == 2
+ assert r.total_connects == 2, f'{r.dump_logs()}'
+
+ # check that an existing http: connection is not reused for https:
+ def test_01_19_plain_reuse(self, env: Env, httpd):
+ proto = 'h2'
+ curl = CurlClient(env=env)
+ url1 = f'http://{env.domain1}:{env.http_port}/data.json'
+ url2 = f'https://{env.domain1}:{env.http_port}/data.json'
+ r = curl.http_download(urls=[url1, url2], alpn_proto=proto, with_stats=True)
+ assert len(r.stats) == 2
+ assert r.total_connects == 2, f'{r.dump_logs()}'