lib: SSL connection reuse
No binary (build failed)
—
(log yok)
| @@ -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 */ |
| }; | |
| @@ -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 | |
| @@ -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 | |
| @@ -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 | |
| @@ -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 | |
| @@ -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 | |
| @@ -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; | |
| @@ -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. */ | |
| @@ -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()}' |