diff --git a/include/ap_mmn.h b/include/ap_mmn.h
index a204e438bd5..fdf72547aa0 100644
--- a/include/ap_mmn.h
+++ b/include/ap_mmn.h
@@ -554,6 +554,12 @@
  *                           AP_REQUEST_STRONG_ETAG, AP_REQUEST_GET_BNOTE,
  *                           AP_REQUEST_SET_BNOTE and AP_REQUEST_IS_STRONG_ETAG
  *                           in httpd.h.
+ * 20120211.102 (2.4.47-dev)  Add ap_ssl_conn_is_ssl()/ap_ssl_var_lookup() and hooks
+ * 20120211.103 (2.4.47-dev)  Add ap_ssl_add_cert_files, ap_ssl_add_fallback_cert_files
+ *                          and ap_ssl_answer_challenge and hooks.
+ * 20120211.104 (2.4.47-dev) Move ap_ssl_* into new http_ssl.h header file
+ * 20120211.105 (2.4.47-dev) Add `ap_bytes_t` to httpd.h.
+ *                         Add ap_ssl_ocsp* hooks and functions to http_ssl.h.
  */
 
 #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
@@ -561,7 +567,7 @@
 #ifndef MODULE_MAGIC_NUMBER_MAJOR
 #define MODULE_MAGIC_NUMBER_MAJOR 20120211
 #endif
-#define MODULE_MAGIC_NUMBER_MINOR 101                 /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 105                 /* 0...n */
 
 /**
  * Determine if the server's current MODULE_MAGIC_NUMBER is at least a
diff --git a/include/http_ssl.h b/include/http_ssl.h
new file mode 100644
index 00000000000..d238439e9a0
--- /dev/null
+++ b/include/http_ssl.h
@@ -0,0 +1,279 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file  http_ssl.h
+ * @brief SSL protocol handling
+ *
+ * @defgroup APACHE_CORE_PROTO SSL Protocol Handling
+ * @ingroup  APACHE_CORE
+ * @{
+ */
+
+#ifndef APACHE_HTTP_SSL_H
+#define APACHE_HTTP_SSL_H
+
+#include "httpd.h"
+#include "apr_portable.h"
+#include "apr_mmap.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * This hook allows modules that manage SSL connection to register their
+ * inquiry function for checking if a connection is using SSL from them.
+ * @param c The current connection
+ * @return OK if the connection is using SSL, DECLINED if not.
+ * @ingroup hooks
+ */
+AP_DECLARE_HOOK(int,ssl_conn_is_ssl,(conn_rec *c))
+
+/**
+ * Return != 0 iff the connection is encrypted with SSL.
+ * @param c the connection
+ */
+AP_DECLARE(int) ap_ssl_conn_is_ssl(conn_rec *c);
+
+/**
+ * This hook allows modules to look up SSL related variables for a
+ * server/connection/request, depending on what they inquire. Some
+ * variables will only be available for a connection/request, for example.
+ * @param p The pool to allocate a returned value in, MUST be provided
+ * @param s The server to inquire a value for, maybe NULL
+ * @param c The current connection, maybe NULL
+ * @param r The current request, maybe NULL
+ * @param name The name of the variable to retrieve, MUST be provided
+ * @return value or the variable or NULL if not provided/available
+ * @ingroup hooks
+ */
+AP_DECLARE_HOOK(const char *,ssl_var_lookup,
+    (apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, const char *name))
+
+/**
+ * Lookup an SSL related variable for the server/connection/request or a global
+ * value when all those parameters are set to NULL. Pool and name must always be
+ * provided and the returned value (if not NULL) will be allocated fromt he pool.
+ * @param p The pool to allocate a returned value in, MUST be provided
+ * @param s The server to inquire a value for, maybe NULL
+ * @param c The current connection, maybe NULL
+ * @param r The current request, maybe NULL
+ * @param name The name of the variable to retrieve, MUST be provided
+ * @return value or the variable or NULL if not provided/available
+ */
+AP_DECLARE(const char *) ap_ssl_var_lookup(apr_pool_t *p, server_rec *s,
+                                           conn_rec *c, request_rec *r,
+                                           const char *name);
+
+/**
+ * Register to provide certificate/key files for servers. Certificate files are
+ * exepcted to contain the certificate chain, beginning with the server's certificate,
+ * excluding the trust anchor, in PEM format.
+ * They must be accompanied by a private key file, also in PEM format.
+ *
+ * @param s the server certificates are collected for
+ * @param p the pool to use for allocations
+ * @param cert_file and array of const char* with the path to the certificate chain
+ * @param key_file and array of const char* with the path to the private key file
+ * @return OK if files were added, DECLINED if not, or other for error.
+ */
+
+AP_DECLARE_HOOK(int, ssl_add_cert_files, (server_rec *s, apr_pool_t *p,
+                                          apr_array_header_t *cert_files,
+                                          apr_array_header_t *key_files))
+
+/**
+ * Collect certificate/key files from all providers registered. This includes
+ * providers registered at the global 'ssl_add_cert_files', as well as those
+ * installed in the OPTIONAL 'ssl_add_cert_files' hook as may be provided by
+ * ssl modules.
+ *
+ * @param s the server certificates are collected for
+ * @param p the pool to use for allocations
+ * @param cert_file and array of const char* with the path to the certificate chain
+ * @param key_file and array of const char* with the path to the private key file
+ */
+AP_DECLARE(apr_status_t) ap_ssl_add_cert_files(server_rec *s, apr_pool_t *p,
+                                               apr_array_header_t *cert_files,
+                                               apr_array_header_t *key_files);
+
+
+/**
+ * Register to provide 'fallback' certificates in case no 'real' certificates
+ * have been configured/added by other providers. Modules using these certificates
+ * are encouraged to answer requests to this server with a 503 response code.
+ *
+ * @param s the server certificates are collected for
+ * @param p the pool to use for allocations
+ * @param cert_file and array of const char* with the path to the certificate chain
+ * @param key_file and array of const char* with the path to the private key file
+ * @return OK if files were added, DECLINED if not, or other for error.
+ */
+AP_DECLARE_HOOK(int, ssl_add_fallback_cert_files, (server_rec *s, apr_pool_t *p,
+                                                   apr_array_header_t *cert_files,
+                                                   apr_array_header_t *key_files))
+
+/**
+ * Collect 'fallback' certificate/key files from all registered providers, either
+ * in the global 'ssl_add_fallback_cert_files' hook or the optional one of similar
+ * name as provided by mod_ssl and sorts.
+ * Certificates obtained this way are commonly self signed, temporary crutches.
+ * To be used to the time it takes to retrieve a 'read', trusted certificate.
+ * A module using fallbacks is encouraged to answer all requests with a 503.
+ *
+ * @param s the server certificates are collected for
+ * @param p the pool to use for allocations
+ * @param cert_file and array of const char* with the path to the certificate chain
+ * @param key_file and array of const char* with the path to the private key file
+ */
+AP_DECLARE(apr_status_t) ap_ssl_add_fallback_cert_files(server_rec *s, apr_pool_t *p,
+                                                        apr_array_header_t *cert_files,
+                                                        apr_array_header_t *key_files);
+
+
+/**
+ * On TLS connections that do not relate to a configured virtual host
+ * allow modules to provide a certificate and key to be used on the connection.
+ *
+ * A Certificate PEM added must be accompanied by a private key PEM. The private
+ * key PEM may be given by a NULL pointer, in which case it is expected to be found in
+ * the certificate PEM string.
+ */
+AP_DECLARE_HOOK(int, ssl_answer_challenge, (conn_rec *c, const char *server_name,
+                                            const char **pcert_pem, const char **pkey_pem))
+
+/**
+ * Returns != 0 iff the connection is a challenge to the server, for example
+ * as defined in RFC 8555 for the 'tls-alpn-01' domain verification, and needs
+ * a specific certificate as answer in the handshake.
+ *
+ * ALPN protocol negotiation via the hooks 'protocol_propose' and 'protocol_switch'
+ * need to have run before this call is made.
+ *
+ * Certificate PEMs added must be accompanied by a private key PEM. The private
+ * key PEM may be given by a NULL pointer, in which case it is expected to be found in
+ * the certificate PEM string.
+ *
+ * A certificate provided this way needs to replace any other certificates selected
+ * by configuration or 'ssl_add_cert_pems` on this connection.
+ */
+AP_DECLARE(int) ap_ssl_answer_challenge(conn_rec *c, const char *server_name,
+                                        const char **pcert_pem, const char **pkey_pem);
+
+
+/**
+ * Setup optional functions for ssl related queries so that functions
+ * registered by old-style SSL module functions are interrogated by the
+ * the new ap_is_ssl() and friends. Installs own optional functions, so that
+ * old modules looking for these find one and get the correct results (shadowing).
+ *
+ * Needs to run in core's very early POST_CONFIG hook.
+ * Modules providing such functions register their own optionals during
+ * register_hooks(). Modules using such functions retrieve them often
+ * in their own post-config or in the even later retrieval hook. When shadowing
+ * other modules functions, core's early post-config is a good time.
+ * @param pool The pool to use for allocations
+ */
+AP_DECLARE(void) ap_setup_ssl_optional_fns(apr_pool_t *pool);
+
+/**
+ * Providers of OCSP status responses register at this hook. Installed hooks returning OK
+ * are expected to provide later OCSP responses via a 'ap_ssl_ocsp_get_resp_hook'.
+ * @param s     the server being configured
+ * @params p    a memory pool to use
+ * @param id    opaque data uniquely identifying the certificate, provided by caller
+ * @param pem   PEM data of certificate first, followed by PEM of issuer cert
+ * @return OK iff stapling is being provided
+ */
+AP_DECLARE_HOOK(int, ssl_ocsp_prime_hook, (server_rec *s, apr_pool_t *p,
+                                           const ap_bytes_t *id, const char *pem))
+
+/**
+ * Registering a certificate for Provisioning of OCSP responses. It is the caller's
+ * responsibility to provide a global (apache instance) unique id for the certificate
+ * that is then used later in retrieving the OCSP response.
+ * A certificate can be primed this way more than once, however the same identifier
+ * has to be provided each time (byte-wise same, not pointer same).
+ * The memory pointed to by `id` and `pem` is only valid for the duration of the call.
+ *
+ * @param s     the server being configured
+ * @params p    a memory pool to use
+ * @param id    opaque data uniquely identifying the certificate, provided by caller
+ * @param pem   PEM data of certificate first, followed by chain certs, at least the issuer
+ * @return APR_SUCCESS iff OCSP responses will be provided.
+ *         APR_ENOENT when no provided was found or took responsibility.
+ */
+AP_DECLARE(apr_status_t) ap_ssl_ocsp_prime(server_rec *s, apr_pool_t *p,
+                                           const ap_bytes_t *id,
+                                           const char *pem);
+
+/**
+ * Callback to copy over the OCSP response data. If OCSP response data is not
+ * available, this will be called with NULL, 0 parameters!
+ *
+ * Memory allocation methods and lifetime of data will vary per module and
+ * SSL library used. The caller requesting OCSP data will need to make a copy
+ * for his own use.
+ * Any passed data may only be valid for the duration of the call.
+ */
+typedef void ap_ssl_ocsp_copy_resp(const unsigned char *der, apr_size_t der_len, void *userdata);
+
+/**
+ * Asking for OCSP response DER data for a certificate formerly primed.
+ * @param s     the (SNI selected) server of the connection
+ * @param c     the connection
+ * @param id    identifier for the certifate, as used in ocsp_stapling_prime()
+ * @param cb    callback to invoke when response data is available
+ * @param userdata caller supplied data passed to callback
+ * @return OK iff response data has been provided, DECLINED otherwise
+ */
+AP_DECLARE_HOOK(int, ssl_ocsp_get_resp_hook,
+                (server_rec *s, conn_rec *c, const ap_bytes_t *id,
+                 ap_ssl_ocsp_copy_resp *cb, void *userdata))
+
+/**
+ * Retrieve the OCSP response data for a previously primed certificate. The id needs
+ * to be byte-wise identical to the one used on priming. If the call return ARP_SUCCESS,
+ * the callback has been invoked with the OCSP response DER data.
+ * Otherwise, a different status code must be returned. Callers in SSL connection
+ * handshakes are encouraged to continue the handshake without OCSP data for
+ * server reliability. The decision to accept or reject a handshake with missing
+ * OCSP stapling data needs to be done by the client.
+ * For similar reasons, providers of responses might return seemingly expired ones
+ * if they were unable to refresh a response in time.
+ *
+ * The memory pointed to by `id` is only valid for the duration of the call.
+ * Also, the DER data passed to the callback is only valid for the duration
+ * of the call.
+ *
+ * @param s     the (SNI selected) server of the connection
+ * @param c     the connection
+ * @param id    identifier for the certifate, as used in ocsp_stapling_prime()
+ * @param cb    callback to invoke when response data is available
+ * @param userdata caller supplied data passed to callback
+ * @return APR_SUCCESS iff data has been provided
+ */
+AP_DECLARE(apr_status_t) ap_ssl_ocsp_get_resp(server_rec *s, conn_rec *c,
+                                              const ap_bytes_t *id,
+                                              ap_ssl_ocsp_copy_resp *cb, void *userdata);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* !APACHE_HTTP_SSL_H */
+/** @} */
diff --git a/include/httpd.h b/include/httpd.h
index 14f15b5c9b7..4a33ff14128 100644
--- a/include/httpd.h
+++ b/include/httpd.h
@@ -810,6 +810,8 @@ typedef struct conn_rec conn_rec;
 typedef struct request_rec request_rec;
 /** A structure that represents the status of the current connection */
 typedef struct conn_state_t conn_state_t;
+/** A structure that represents a number of bytes */
+typedef struct ap_bytes_t ap_bytes_t;
 
 /* ### would be nice to not include this from httpd.h ... */
 /* This comes after we have defined the request_rec type */
@@ -1423,6 +1425,15 @@ struct ap_loadavg_t {
     float loadavg15;
 };
 
+/**
+ * @struct ap_bytes_t
+ * @brief A structure to hold a number of bytes
+ */
+struct ap_bytes_t {
+    unsigned char *data;
+    apr_size_t len;
+};
+
 /**
  * Get the context_document_root for a request. This is a generalization of
  * the document root, which is too limited in the presence of mappers like
diff --git a/modules/filters/mod_deflate.c b/modules/filters/mod_deflate.c
index 99aa0a5ed35..46148cd1ea0 100644
--- a/modules/filters/mod_deflate.c
+++ b/modules/filters/mod_deflate.c
@@ -43,10 +43,11 @@
 #include "apr_general.h"
 #include "util_filter.h"
 #include "apr_buckets.h"
+#include "http_protocol.h"
 #include "http_request.h"
+#include "http_ssl.h"
 #define APR_WANT_STRFUNC
 #include "apr_want.h"
-#include "mod_ssl.h"
 
 #include "zlib.h"
 
@@ -94,8 +95,6 @@ static const char deflate_magic[2] = { '\037', '\213' };
 #define DEFAULT_MEMLEVEL 9
 #define DEFAULT_BUFFERSIZE 8096
 
-static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *mod_deflate_ssl_var = NULL;
-
 /* Check whether a request is gzipped, so we can un-gzip it.
  * If a request has multiple encodings, we need the gzip
  * to be the outermost non-identity encoding.
@@ -514,10 +513,8 @@ static int check_ratio(request_rec *r, deflate_ctx *ctx,
 static int have_ssl_compression(request_rec *r)
 {
     const char *comp;
-    if (mod_deflate_ssl_var == NULL)
-        return 0;
-    comp = mod_deflate_ssl_var(r->pool, r->server, r->connection, r,
-                               "SSL_COMPRESS_METHOD");
+    comp = ap_ssl_var_lookup(r->pool, r->server, r->connection, r,
+                             "SSL_COMPRESS_METHOD");
     if (comp == NULL || *comp == '\0' || strcmp(comp, "NULL") == 0)
         return 0;
     return 1;
@@ -1879,7 +1876,6 @@ static apr_status_t inflate_out_filter(ap_filter_t *f,
 static int mod_deflate_post_config(apr_pool_t *pconf, apr_pool_t *plog,
                                    apr_pool_t *ptemp, server_rec *s)
 {
-    mod_deflate_ssl_var = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
     return OK;
 }
 
diff --git a/modules/http2/h2_alt_svc.c b/modules/http2/h2_alt_svc.c
index 2c3253c2cca..c22f7eba836 100644
--- a/modules/http2/h2_alt_svc.c
+++ b/modules/http2/h2_alt_svc.c
@@ -19,6 +19,7 @@
 #include <http_core.h>
 #include <http_connection.h>
 #include <http_protocol.h>
+#include <http_ssl.h>
 #include <http_log.h>
 
 #include "h2_private.h"
@@ -98,7 +99,7 @@ static int h2_alt_svc_handler(request_rec *r)
              */
             const char *alt_svc = "";
             const char *svc_ma = "";
-            int secure = h2_h2_is_tls(r->connection);
+            int secure = ap_ssl_conn_is_ssl(r->connection);
             int ma = h2_config_rgeti(r, H2_CONF_ALT_SVC_MAX_AGE);
             if (ma >= 0) {
                 svc_ma = apr_psprintf(r->pool, "; ma=%d", ma);
diff --git a/modules/http2/h2_conn_io.c b/modules/http2/h2_conn_io.c
index 5f17e85951a..d0e099b421f 100644
--- a/modules/http2/h2_conn_io.c
+++ b/modules/http2/h2_conn_io.c
@@ -22,7 +22,9 @@
 #include <http_core.h>
 #include <http_log.h>
 #include <http_connection.h>
+#include <http_protocol.h>
 #include <http_request.h>
+#include <http_ssl.h>
 
 #include "h2_private.h"
 #include "h2_bucket_eos.h"
@@ -132,7 +134,7 @@ apr_status_t h2_conn_io_init(h2_conn_io *io, conn_rec *c, server_rec *s)
 {
     io->c              = c;
     io->output         = apr_brigade_create(c->pool, c->bucket_alloc);
-    io->is_tls         = h2_h2_is_tls(c);
+    io->is_tls         = ap_ssl_conn_is_ssl(c);
     io->buffer_output  = io->is_tls;
     io->flush_threshold = (apr_size_t)h2_config_sgeti64(s, H2_CONF_STREAM_MAX_MEM);
 
diff --git a/modules/http2/h2_h2.c b/modules/http2/h2_h2.c
index c05b93093d0..1827788eac0 100644
--- a/modules/http2/h2_h2.c
+++ b/modules/http2/h2_h2.c
@@ -26,10 +26,9 @@
 #include <http_connection.h>
 #include <http_protocol.h>
 #include <http_request.h>
+#include <http_ssl.h>
 #include <http_log.h>
 
-#include "mod_ssl.h"
-
 #include "mod_http2.h"
 #include "h2_private.h"
 
@@ -57,13 +56,6 @@ const char *h2_clear_protos[] = {
 
 const char *H2_MAGIC_TOKEN = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n";
 
-/*******************************************************************************
- * The optional mod_ssl functions we need. 
- */
-static APR_OPTIONAL_FN_TYPE(ssl_is_https) *opt_ssl_is_https;
-static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *opt_ssl_var_lookup;
-
-
 /*******************************************************************************
  * HTTP/2 error stuff
  */
@@ -445,27 +437,14 @@ apr_status_t h2_h2_init(apr_pool_t *pool, server_rec *s)
 {
     (void)pool;
     ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s, "h2_h2, child_init");
-    opt_ssl_is_https = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https);
-    opt_ssl_var_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
-    
-    if (!opt_ssl_is_https || !opt_ssl_var_lookup) {
-        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
-                     APLOGNO(02951) "mod_ssl does not seem to be enabled");
-    }
-    
     cipher_init(pool);
     
     return APR_SUCCESS;
 }
 
-int h2_h2_is_tls(conn_rec *c)
-{
-    return opt_ssl_is_https && opt_ssl_is_https(c);
-}
-
 int h2_is_acceptable_connection(conn_rec *c, request_rec *r, int require_all) 
 {
-    int is_tls = h2_h2_is_tls(c);
+    int is_tls = ap_ssl_conn_is_ssl(c);
 
     if (is_tls && h2_config_cgeti(c, H2_CONF_MODERN_TLS_ONLY) > 0) {
         /* Check TLS connection for modern TLS parameters, as defined in
@@ -473,16 +452,11 @@ int h2_is_acceptable_connection(conn_rec *c, request_rec *r, int require_all)
          */
         apr_pool_t *pool = c->pool;
         server_rec *s = c->base_server;
-        char *val;
+        const char *val;
 
-        if (!opt_ssl_var_lookup) {
-            /* unable to check */
-            return 0;
-        }
-        
         /* Need Tlsv1.2 or higher, rfc 7540, ch. 9.2
          */
-        val = opt_ssl_var_lookup(pool, s, c, NULL, (char*)"SSL_PROTOCOL");
+        val = ap_ssl_var_lookup(pool, s, c, NULL, (char*)"SSL_PROTOCOL");
         if (val && *val) {
             if (strncmp("TLS", val, 3) 
                 || !strcmp("TLSv1", val) 
@@ -501,7 +475,7 @@ int h2_is_acceptable_connection(conn_rec *c, request_rec *r, int require_all)
 
         /* Check TLS cipher blacklist
          */
-        val = opt_ssl_var_lookup(pool, s, c, NULL, (char*)"SSL_CIPHER");
+        val = ap_ssl_var_lookup(pool, s, c, NULL, (char*)"SSL_CIPHER");
         if (val && *val) {
             const char *source;
             if (cipher_is_blacklisted(val, &source)) {
@@ -522,7 +496,7 @@ int h2_is_acceptable_connection(conn_rec *c, request_rec *r, int require_all)
 
 static int h2_allows_h2_direct(conn_rec *c)
 {
-    int is_tls = h2_h2_is_tls(c);
+    int is_tls = ap_ssl_conn_is_ssl(c);
     const char *needed_protocol = is_tls? "h2" : "h2c";
     int h2_direct = h2_config_cgeti(c, H2_CONF_DIRECT);
     
@@ -535,7 +509,7 @@ static int h2_allows_h2_direct(conn_rec *c)
 int h2_allows_h2_upgrade(request_rec *r)
 {
     int h2_upgrade = h2_config_rgeti(r, H2_CONF_UPGRADE);
-    return h2_upgrade > 0 || (h2_upgrade < 0 && !h2_h2_is_tls(r->connection));
+    return h2_upgrade > 0 || (h2_upgrade < 0 && !ap_ssl_conn_is_ssl(r->connection));
 }
 
 /*******************************************************************************
@@ -631,7 +605,7 @@ int h2_h2_process_conn(conn_rec* c)
                 if (!ctx) {
                     ctx = h2_ctx_get(c, 1);
                 }
-                h2_ctx_protocol_set(ctx, h2_h2_is_tls(c)? "h2" : "h2c");
+                h2_ctx_protocol_set(ctx, ap_ssl_conn_is_ssl(c)? "h2" : "h2c");
             }
             else if (APLOGctrace2(c)) {
                 ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
diff --git a/modules/http2/h2_h2.h b/modules/http2/h2_h2.h
index 339e898a108..8cfb9864fe8 100644
--- a/modules/http2/h2_h2.h
+++ b/modules/http2/h2_h2.h
@@ -41,10 +41,6 @@ const char *h2_h2_err_description(unsigned int h2_error);
  */
 apr_status_t h2_h2_init(apr_pool_t *pool, server_rec *s);
 
-/* Is the connection a TLS connection?
- */
-int h2_h2_is_tls(conn_rec *c);
-
 /* Register apache hooks for h2 protocol
  */
 void h2_h2_register_hooks(void);
diff --git a/modules/http2/h2_switch.c b/modules/http2/h2_switch.c
index 9ec658b8e17..eb050150c9f 100644
--- a/modules/http2/h2_switch.c
+++ b/modules/http2/h2_switch.c
@@ -25,6 +25,7 @@
 #include <http_config.h>
 #include <http_connection.h>
 #include <http_protocol.h>
+#include <http_ssl.h>
 #include <http_log.h>
 
 #include "h2_private.h"
@@ -52,7 +53,7 @@ static int h2_protocol_propose(conn_rec *c, request_rec *r,
                                apr_array_header_t *proposals)
 {
     int proposed = 0;
-    int is_tls = h2_h2_is_tls(c);
+    int is_tls = ap_ssl_conn_is_ssl(c);
     const char **protos = is_tls? h2_tls_protos : h2_clear_protos;
     
     if (!h2_mpm_supported()) {
@@ -127,7 +128,7 @@ static int h2_protocol_switch(conn_rec *c, request_rec *r, server_rec *s,
                               const char *protocol)
 {
     int found = 0;
-    const char **protos = h2_h2_is_tls(c)? h2_tls_protos : h2_clear_protos;
+    const char **protos = ap_ssl_conn_is_ssl(c)? h2_tls_protos : h2_clear_protos;
     const char **p = protos;
     
     (void)s;
diff --git a/modules/lua/mod_lua.c b/modules/lua/mod_lua.c
index 79d52d2c540..6797c19a883 100644
--- a/modules/lua/mod_lua.c
+++ b/modules/lua/mod_lua.c
@@ -24,7 +24,6 @@
 #include "lua_apr.h"
 #include "lua_config.h"
 #include "apr_optional.h"
-#include "mod_ssl.h"
 #include "mod_auth.h"
 #include "util_mutex.h"
 
@@ -53,8 +52,6 @@ APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ap_lua, AP_LUA, int, lua_open,
 APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ap_lua, AP_LUA, int, lua_request,
                                     (lua_State *L, request_rec *r),
                                     (L, r), OK, DECLINED)
-static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *lua_ssl_val = NULL;
-static APR_OPTIONAL_FN_TYPE(ssl_is_https) *lua_ssl_is_https = NULL;
 
 module AP_MODULE_DECLARE_DATA lua_module;
 
@@ -1688,15 +1685,12 @@ static const char *register_lua_root(cmd_parms *cmd, void *_cfg,
 const char *ap_lua_ssl_val(apr_pool_t *p, server_rec *s, conn_rec *c,
                            request_rec *r, const char *var)
 {
-    if (lua_ssl_val) { 
-        return (const char *)lua_ssl_val(p, s, c, r, (char *)var);
-    }
-    return NULL;
+    return ap_ssl_var_lookup(p, s, c, r, (char *)var);
 }
 
 int ap_lua_ssl_is_https(conn_rec *c)
 {
-    return lua_ssl_is_https ? lua_ssl_is_https(c) : 0;
+    return ap_ssl_conn_is_ssl(c);
 }
 
 /*******************************/
@@ -2002,9 +1996,6 @@ static int lua_post_config(apr_pool_t *pconf, apr_pool_t *plog,
     apr_pool_t **pool;
     apr_status_t rs;
 
-    lua_ssl_val = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
-    lua_ssl_is_https = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https);
-    
     if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG)
         return OK;
 
diff --git a/modules/lua/mod_lua.h b/modules/lua/mod_lua.h
index 0e49cdc0d4b..551e5261a7a 100644
--- a/modules/lua/mod_lua.h
+++ b/modules/lua/mod_lua.h
@@ -26,6 +26,7 @@
 #include "http_request.h"
 #include "http_log.h"
 #include "http_protocol.h"
+#include "http_ssl.h"
 #include "ap_regex.h"
 
 #include "ap_config.h"
diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c
index c0be4f686ba..8c2248fd214 100644
--- a/modules/mappers/mod_rewrite.c
+++ b/modules/mappers/mod_rewrite.c
@@ -93,11 +93,10 @@
 #include "http_core.h"
 #include "http_log.h"
 #include "http_protocol.h"
+#include "http_ssl.h"
 #include "http_vhost.h"
 #include "util_mutex.h"
 
-#include "mod_ssl.h"
-
 #include "mod_rewrite.h"
 #include "ap_expr.h"
 
@@ -421,8 +420,6 @@ static apr_global_mutex_t *rewrite_mapr_lock_acquire = NULL;
 static const char *rewritemap_mutex_type = "rewrite-map";
 
 /* Optional functions imported from mod_ssl when loaded: */
-static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *rewrite_ssl_lookup = NULL;
-static APR_OPTIONAL_FN_TYPE(ssl_is_https) *rewrite_is_https = NULL;
 static char *escape_backref(apr_pool_t *p, const char *path, const char *escapeme, int noplus);
 
 /*
@@ -1864,8 +1861,8 @@ static char *lookup_variable(char *var, rewrite_ctx *ctx)
                 result = getenv(var);
             }
         }
-        else if (var[4] && !strncasecmp(var, "SSL", 3) && rewrite_ssl_lookup) {
-            result = rewrite_ssl_lookup(r->pool, r->server, r->connection, r,
+        else if (var[4] && !strncasecmp(var, "SSL", 3)) {
+            result = ap_ssl_var_lookup(r->pool, r->server, r->connection, r,
                                         var + 4);
         }
     }
@@ -1963,7 +1960,7 @@ static char *lookup_variable(char *var, rewrite_ctx *ctx)
 
         case  5:
             if (!strcmp(var, "HTTPS")) {
-                int flag = rewrite_is_https && rewrite_is_https(r->connection);
+                int flag = ap_ssl_conn_is_ssl(r->connection);
                 return apr_pstrdup(r->pool, flag ? "on" : "off");
             }
             break;
@@ -4523,9 +4520,6 @@ static int post_config(apr_pool_t *p,
         }
     }
 
-    rewrite_ssl_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
-    rewrite_is_https = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https);
-
     return OK;
 }
 
diff --git a/modules/metadata/mod_headers.c b/modules/metadata/mod_headers.c
index f7bda1552a3..ef812cd3edc 100644
--- a/modules/metadata/mod_headers.c
+++ b/modules/metadata/mod_headers.c
@@ -78,13 +78,12 @@
 #include "httpd.h"
 #include "http_config.h"
 #include "http_request.h"
+#include "http_ssl.h"
 #include "http_log.h"
 #include "util_filter.h"
 #include "http_protocol.h"
 #include "ap_expr.h"
 
-#include "mod_ssl.h" /* for the ssl_var_lookup optional function defn */
-
 /* format_tag_hash is initialized during pre-config */
 static apr_hash_t *format_tag_hash;
 
@@ -161,9 +160,6 @@ typedef struct {
 
 module AP_MODULE_DECLARE_DATA headers_module;
 
-/* Pointer to ssl_var_lookup, if available. */
-static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *header_ssl_lookup = NULL;
-
 /*
  * Tag formatting functions
  */
@@ -210,17 +206,12 @@ static const char *header_request_env_var(request_rec *r, char *a)
 
 static const char *header_request_ssl_var(request_rec *r, char *name)
 {
-    if (header_ssl_lookup) {
-        const char *val = header_ssl_lookup(r->pool, r->server,
-                                            r->connection, r, name);
-        if (val && val[0])
-            return unwrap_header(r->pool, val);
-        else
-            return "(null)";
-    }
-    else {
+    const char *val = ap_ssl_var_lookup(r->pool, r->server,
+                                        r->connection, r, name);
+    if (val && val[0])
+        return unwrap_header(r->pool, val);
+    else
         return "(null)";
-    }
 }
 
 static const char *header_request_loadavg(request_rec *r, char *a)
@@ -989,7 +980,6 @@ static int header_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp)
 static int header_post_config(apr_pool_t *pconf, apr_pool_t *plog,
                               apr_pool_t *ptemp, server_rec *s)
 {
-    header_ssl_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
     return OK;
 }
 
diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c
index 3d04dc9cff0..7ca638ee3c4 100644
--- a/modules/proxy/mod_proxy.c
+++ b/modules/proxy/mod_proxy.c
@@ -29,10 +29,6 @@ APR_DECLARE_OPTIONAL_FN(int, ssl_engine_disable, (conn_rec *));
 APR_DECLARE_OPTIONAL_FN(int, ssl_engine_set, (conn_rec *,
                                               ap_conf_vector_t *,
                                               int proxy, int enable));
-APR_DECLARE_OPTIONAL_FN(int, ssl_is_https, (conn_rec *));
-APR_DECLARE_OPTIONAL_FN(char *, ssl_var_lookup,
-                        (apr_pool_t *, server_rec *,
-                         conn_rec *, request_rec *, char *));
 #endif
 
 #ifndef MAX
@@ -2815,8 +2811,6 @@ static const command_rec proxy_cmds[] =
 static APR_OPTIONAL_FN_TYPE(ssl_proxy_enable) *proxy_ssl_enable = NULL;
 static APR_OPTIONAL_FN_TYPE(ssl_engine_disable) *proxy_ssl_disable = NULL;
 static APR_OPTIONAL_FN_TYPE(ssl_engine_set) *proxy_ssl_engine = NULL;
-static APR_OPTIONAL_FN_TYPE(ssl_is_https) *proxy_is_https = NULL;
-static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *proxy_ssl_val = NULL;
 
 PROXY_DECLARE(int) ap_proxy_ssl_enable(conn_rec *c)
 {
@@ -2866,23 +2860,14 @@ PROXY_DECLARE(int) ap_proxy_ssl_engine(conn_rec *c,
 
 PROXY_DECLARE(int) ap_proxy_conn_is_https(conn_rec *c)
 {
-    if (proxy_is_https) {
-        return proxy_is_https(c);
-    }
-    else
-        return 0;
+    return ap_ssl_conn_is_ssl(c);
 }
 
 PROXY_DECLARE(const char *) ap_proxy_ssl_val(apr_pool_t *p, server_rec *s,
                                              conn_rec *c, request_rec *r,
                                              const char *var)
 {
-    if (proxy_ssl_val) {
-        /* XXX Perhaps the casting useless */
-        return (const char *)proxy_ssl_val(p, s, c, r, (char *)var);
-    }
-    else
-        return NULL;
+    return ap_ssl_var_lookup(p, s, c, r, (char *)var);
 }
 
 static int proxy_post_config(apr_pool_t *pconf, apr_pool_t *plog,
@@ -2900,8 +2885,6 @@ static int proxy_post_config(apr_pool_t *pconf, apr_pool_t *plog,
     proxy_ssl_enable = APR_RETRIEVE_OPTIONAL_FN(ssl_proxy_enable);
     proxy_ssl_disable = APR_RETRIEVE_OPTIONAL_FN(ssl_engine_disable);
     proxy_ssl_engine = APR_RETRIEVE_OPTIONAL_FN(ssl_engine_set);
-    proxy_is_https = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https);
-    proxy_ssl_val = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
     ap_proxy_strmatch_path = apr_strmatch_precompile(pconf, "path=", 0);
     ap_proxy_strmatch_domain = apr_strmatch_precompile(pconf, "domain=", 0);
 
diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h
index 1ba54cd49e1..56461707cd2 100644
--- a/modules/proxy/mod_proxy.h
+++ b/modules/proxy/mod_proxy.h
@@ -58,6 +58,7 @@
 #include "http_main.h"
 #include "http_log.h"
 #include "http_connection.h"
+#include "http_ssl.h"
 #include "util_filter.h"
 #include "util_ebcdic.h"
 #include "ap_provider.h"
diff --git a/server/Makefile.in b/server/Makefile.in
index 1fa334467d0..81118775208 100644
--- a/server/Makefile.in
+++ b/server/Makefile.in
@@ -13,7 +13,7 @@ LTLIBRARY_SOURCES = \
 	mpm_common.c mpm_unix.c mpm_fdqueue.c \
 	util_charset.c util_cookies.c util_debug.c util_xml.c \
 	util_filter.c util_pcre.c util_regex.c exports.c \
-	scoreboard.c error_bucket.c protocol.c core.c request.c provider.c \
+	scoreboard.c error_bucket.c protocol.c core.c request.c ssl.c provider.c \
 	eoc_bucket.c eor_bucket.c core_filters.c \
 	util_expr_parse.c util_expr_scan.c util_expr_eval.c
 
diff --git a/server/core.c b/server/core.c
index fe3a16f7fd8..48658002420 100644
--- a/server/core.c
+++ b/server/core.c
@@ -38,6 +38,7 @@
 #include "http_core.h"
 #include "http_protocol.h" /* For index_of_response().  Grump. */
 #include "http_request.h"
+#include "http_ssl.h"
 #include "http_vhost.h"
 #include "http_main.h"     /* For the default_handler below... */
 #include "http_log.h"
@@ -5075,6 +5076,7 @@ static int core_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *pte
     set_banner(pconf);
     ap_setup_make_content_type(pconf);
     ap_setup_auth_internal(ptemp);
+    ap_setup_ssl_optional_fns(pconf);
     if (!sys_privileges) {
         ap_log_error(APLOG_MARK, APLOG_CRIT, 0, NULL, APLOGNO(00136)
                      "Server MUST relinquish startup privileges before "
diff --git a/server/ssl.c b/server/ssl.c
new file mode 100644
index 00000000000..033d95620f4
--- /dev/null
+++ b/server/ssl.c
@@ -0,0 +1,192 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * ssl.c --- routines for SSL/TLS server infrastructure.
+ *
+ */
+
+#include "apr.h"
+#include "apr_strings.h"
+#include "apr_buckets.h"
+#include "apr_lib.h"
+#include "apr_signal.h"
+#include "apr_strmatch.h"
+
+#define APR_WANT_STDIO          /* for sscanf */
+#define APR_WANT_STRFUNC
+#define APR_WANT_MEMFUNC
+#include "apr_want.h"
+
+#include "util_filter.h"
+#include "ap_config.h"
+#include "httpd.h"
+#include "http_config.h"
+#include "http_core.h"
+#include "http_protocol.h"
+#include "http_request.h"
+#include "http_main.h"
+#include "http_ssl.h"
+#include "http_log.h"           /* For errors detected in basic auth common
+                                 * support code... */
+#include "mod_core.h"
+
+
+#if APR_HAVE_STDARG_H
+#include <stdarg.h>
+#endif
+#if APR_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+/* we know core's module_index is 0 */
+#undef APLOG_MODULE_INDEX
+#define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
+
+APR_HOOK_STRUCT(
+    APR_HOOK_LINK(ssl_conn_is_ssl)
+    APR_HOOK_LINK(ssl_var_lookup)
+    APR_HOOK_LINK(ssl_add_cert_files)
+    APR_HOOK_LINK(ssl_add_fallback_cert_files)
+    APR_HOOK_LINK(ssl_answer_challenge)
+    APR_HOOK_LINK(ssl_ocsp_prime_hook)
+    APR_HOOK_LINK(ssl_ocsp_get_resp_hook)
+)
+
+APR_DECLARE_OPTIONAL_FN(int, ssl_is_https, (conn_rec *));
+static APR_OPTIONAL_FN_TYPE(ssl_is_https) *module_ssl_is_https;
+
+static int ssl_is_https(conn_rec *c)
+{
+    /* Someone retrieved the optional function., not knowning about the
+     * new API. We redirect them to what they should have inoked. */
+    return ap_ssl_conn_is_ssl(c);
+}
+
+AP_DECLARE(int) ap_ssl_conn_is_ssl(conn_rec *c)
+{
+    int r = (ap_run_ssl_conn_is_ssl(c) == OK);
+    if (r == 0 && module_ssl_is_https) {
+        r = module_ssl_is_https(c);
+    }
+    return r;
+}
+
+APR_DECLARE_OPTIONAL_FN(const char *, ssl_var_lookup,
+                        (apr_pool_t *p, server_rec *s,
+                         conn_rec *c, request_rec *r,
+                         const char *name));
+static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *module_ssl_var_lookup;
+
+static const char *ssl_var_lookup(apr_pool_t *p, server_rec *s,
+                                  conn_rec *c, request_rec *r,
+                                  const char *name)
+{
+    /* Someone retrieved the optional function., not knowning about the
+     * new API. We redirect them to what they should have inoked. */
+    return ap_ssl_var_lookup(p, s, c, r, name);
+}
+
+AP_DECLARE(const char *) ap_ssl_var_lookup(apr_pool_t *p, server_rec *s,
+                                           conn_rec *c, request_rec *r,
+                                           const char *name)
+{
+    const char *val = ap_run_ssl_var_lookup(p, s, c, r, name);
+    if (val == NULL && module_ssl_is_https) {
+        val = module_ssl_var_lookup(p, s, c, r, name);
+    }
+    return val;
+}
+
+AP_DECLARE(void) ap_setup_ssl_optional_fns(apr_pool_t *pool)
+{
+    /* Run as core's very early 'post config' hook, check for any already
+     * installed optional functions related to SSL and save them. Install
+     * our own instances that invoke the new hooks. */
+    APR_OPTIONAL_FN_TYPE(ssl_is_https) *fn_is_https;
+    APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *fn_ssl_var_lookup;
+
+    fn_is_https = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https);
+    module_ssl_is_https = (fn_is_https
+        && fn_is_https != ssl_is_https)? fn_is_https : NULL;
+    APR_REGISTER_OPTIONAL_FN(ssl_is_https);
+
+    fn_ssl_var_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
+    module_ssl_var_lookup = (fn_ssl_var_lookup
+        && fn_ssl_var_lookup != ssl_var_lookup)? fn_ssl_var_lookup : NULL;
+    APR_REGISTER_OPTIONAL_FN(ssl_var_lookup);
+}
+
+AP_DECLARE(apr_status_t) ap_ssl_add_cert_files(server_rec *s, apr_pool_t *p,
+                                               apr_array_header_t *cert_files,
+                                               apr_array_header_t *key_files)
+{
+    int rv = ap_run_ssl_add_cert_files(s, p, cert_files, key_files);
+    return (rv == OK || rv == DECLINED)? APR_SUCCESS : APR_EGENERAL;
+}
+
+AP_DECLARE(apr_status_t) ap_ssl_add_fallback_cert_files(server_rec *s, apr_pool_t *p,
+                                                        apr_array_header_t *cert_files,
+                                                        apr_array_header_t *key_files)
+{
+    int rv = ap_run_ssl_add_fallback_cert_files(s, p, cert_files, key_files);
+    return (rv == OK || rv == DECLINED)? APR_SUCCESS : APR_EGENERAL;
+}
+
+AP_DECLARE(int) ap_ssl_answer_challenge(conn_rec *c, const char *server_name,
+                                        const char **pcert_pem, const char **pkey_pem)
+{
+    return (ap_run_ssl_answer_challenge(c, server_name, pcert_pem, pkey_pem) == OK);
+}
+
+AP_DECLARE(apr_status_t) ap_ssl_ocsp_prime(server_rec *s, apr_pool_t *p,
+                                           const ap_bytes_t *id,
+                                           const char *pem)
+{
+    int rv = ap_run_ssl_ocsp_prime_hook(s, p, id, pem);
+    return rv == OK? APR_SUCCESS : (rv == DECLINED? APR_ENOENT : APR_EGENERAL);
+}
+
+AP_DECLARE(apr_status_t) ap_ssl_ocsp_get_resp(server_rec *s, conn_rec *c,
+                                              const ap_bytes_t *id,
+                                              ap_ssl_ocsp_copy_resp *cb, void *userdata)
+{
+    int rv = ap_run_ssl_ocsp_get_resp_hook(s, c, id, cb, userdata);
+    return rv == OK? APR_SUCCESS : (rv == DECLINED? APR_ENOENT : APR_EGENERAL);
+}
+
+AP_IMPLEMENT_HOOK_RUN_FIRST(int, ssl_conn_is_ssl,
+                            (conn_rec *c), (c), DECLINED)
+AP_IMPLEMENT_HOOK_RUN_FIRST(const char *,ssl_var_lookup,
+        (apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, const char *name),
+        (p, s, c, r, name), NULL)
+AP_IMPLEMENT_HOOK_RUN_ALL(int, ssl_add_cert_files,
+        (server_rec *s, apr_pool_t *p,
+         apr_array_header_t *cert_files, apr_array_header_t *key_files),
+        (s, p, cert_files, key_files), OK, DECLINED)
+AP_IMPLEMENT_HOOK_RUN_ALL(int, ssl_add_fallback_cert_files,
+        (server_rec *s, apr_pool_t *p,
+         apr_array_header_t *cert_files, apr_array_header_t *key_files),
+        (s, p, cert_files, key_files), OK, DECLINED)
+AP_IMPLEMENT_HOOK_RUN_FIRST(int, ssl_answer_challenge,
+        (conn_rec *c, const char *server_name, const char **pcert_pem, const char **pkey_pem),
+        (c, server_name, pcert_pem, pkey_pem), DECLINED)
+AP_IMPLEMENT_HOOK_RUN_FIRST(int, ssl_ocsp_prime_hook,
+        (server_rec *s, apr_pool_t *p, const ap_bytes_t *id, const char *pem),
+        (s, p, id, pem), DECLINED)
+AP_IMPLEMENT_HOOK_RUN_FIRST(int, ssl_ocsp_get_resp_hook,
+         (server_rec *s, conn_rec *c, const ap_bytes_t *id, ap_ssl_ocsp_copy_resp *cb, void *userdata),
+         (s, c, id, cb, userdata), DECLINED)
diff --git a/server/util_expr_eval.c b/server/util_expr_eval.c
index 85c9c11e275..2e031d0c7be 100644
--- a/server/util_expr_eval.c
+++ b/server/util_expr_eval.c
@@ -23,6 +23,7 @@
 #include "http_core.h"
 #include "http_protocol.h"
 #include "http_request.h"
+#include "http_ssl.h"
 #include "ap_provider.h"
 #include "util_expr_private.h"
 #include "util_md5.h"
@@ -1256,9 +1257,6 @@ static int op_file_subr(ap_expr_eval_ctx_t *ctx, const void *data, const char *a
 }
 
 
-APR_DECLARE_OPTIONAL_FN(int, ssl_is_https, (conn_rec *));
-static APR_OPTIONAL_FN_TYPE(ssl_is_https) *is_https = NULL;
-
 APR_DECLARE_OPTIONAL_FN(int, http2_is_h2, (conn_rec *));
 static APR_OPTIONAL_FN_TYPE(http2_is_h2) *is_http2 = NULL;
 
@@ -1280,7 +1278,7 @@ static const char *conn_var_fn(ap_expr_eval_ctx_t *ctx, const void *data)
 
     switch (index) {
     case 0:
-        if (is_https && is_https(c))
+        if (ap_ssl_conn_is_ssl(c))
             return "on";
         else
             return "off";
@@ -1806,10 +1804,7 @@ static int expr_lookup_not_found(ap_expr_lookup_parms *parms)
 static int ap_expr_post_config(apr_pool_t *pconf, apr_pool_t *plog,
                                apr_pool_t *ptemp, server_rec *s)
 {
-    is_https = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https);
     is_http2 = APR_RETRIEVE_OPTIONAL_FN(http2_is_h2);
-    apr_pool_cleanup_register(pconf, &is_https, ap_pool_cleanup_set_null,
-                              apr_pool_cleanup_null);
     return OK;
 }
 
