On Tue, Apr 19, 2016 at 9:36 PM, Yann Ylavic <ylavic....@gmail.com> wrote:
>
> What changed is:
> 1. SSLProxy* directives are now per directory (restricted to
> Server/VirtualHost and <Proxy>), so all the internal struct members
> have been move from SSLSrvConfigRec to SSLDirConfigRec;
> 2. The merge happens from main server to VirtualHosts (if any) to
> <Proxy> sections (if any), as usual;
> 3. The proxies SSL_CTX are still created once at startup, in the
> post_config hook, by retrieving all the dc->proxy and initializing
> them (the one associated with the server_rec and the ones of the
> <Proxy> sections, with the help of a new mod_proxy optional function:
> ap_proxy_get_sections_configs());
> 4. At runtime, the new ssl_proxy_{enable,disable}_ex() optional
> functions are used by mod_proxy to indicate the per dir (proxy
> worker's) configuration to mod_ssl.

I did even more testing with this new (attached) patch and it works for me.

>
> Feedbacks and more testing welcome :)

Let me known if it's suitable for trunk...
Index: include/http_config.h
===================================================================
--- include/http_config.h	(revision 1740086)
+++ include/http_config.h	(working copy)
@@ -923,9 +923,10 @@ AP_DECLARE(const char *) ap_check_cmd_context(cmd_
 #define  NOT_IN_LOCATION        0x08 /**< Forbidden in &lt;Location&gt; */
 #define  NOT_IN_FILES           0x10 /**< Forbidden in &lt;Files&gt; or &lt;If&gt;*/
 #define  NOT_IN_HTACCESS        0x20 /**< Forbidden in .htaccess files */
-/** Forbidden in &lt;Directory&gt;/&lt;Location&gt;/&lt;Files&gt;&lt;If&gt;*/
-#define  NOT_IN_DIR_LOC_FILE    (NOT_IN_DIRECTORY|NOT_IN_LOCATION|NOT_IN_FILES)
-/** Forbidden in &lt;VirtualHost&gt;/&lt;Limit&gt;/&lt;Directory&gt;/&lt;Location&gt;/&lt;Files&gt;/&lt;If&gt; */
+#define  NOT_IN_PROXY           0x40 /**< Forbidden in &lt;Proxy&gt; */
+/** Forbidden in &lt;Directory&gt;/&lt;Location&gt;/&lt;Files&gt;&lt;If&gt;&lt;Proxy&gt;*/
+#define  NOT_IN_DIR_LOC_FILE    (NOT_IN_DIRECTORY|NOT_IN_LOCATION|NOT_IN_FILES|NOT_IN_PROXY)
+/** Forbidden in &lt;VirtualHost&gt;/&lt;Limit&gt;/&lt;Directory&gt;/&lt;Location&gt;/&lt;Files&gt;/&lt;If&gt;&lt;Proxy&gt;*/
 #define  GLOBAL_ONLY            (NOT_IN_VIRTUALHOST|NOT_IN_LIMIT|NOT_IN_DIR_LOC_FILE)
 
 /** @} */
Index: modules/http2/h2_h2.c
===================================================================
--- modules/http2/h2_h2.c	(revision 1740086)
+++ modules/http2/h2_h2.c	(working copy)
@@ -56,7 +56,6 @@ const char *H2_MAGIC_TOKEN = "PRI * HTTP/2.0\r\n\r
 /*******************************************************************************
  * The optional mod_ssl functions we need. 
  */
-static APR_OPTIONAL_FN_TYPE(ssl_engine_disable) *opt_ssl_engine_disable;
 static APR_OPTIONAL_FN_TYPE(ssl_is_https) *opt_ssl_is_https;
 static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *opt_ssl_var_lookup;
 
@@ -441,7 +440,6 @@ apr_status_t h2_h2_init(apr_pool_t *pool, server_r
 {
     (void)pool;
     ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s, "h2_h2, child_init");
-    opt_ssl_engine_disable = APR_RETRIEVE_OPTIONAL_FN(ssl_engine_disable);
     opt_ssl_is_https = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https);
     opt_ssl_var_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
     
Index: modules/http2/mod_proxy_http2.c
===================================================================
--- modules/http2/mod_proxy_http2.c	(revision 1740086)
+++ modules/http2/mod_proxy_http2.c	(working copy)
@@ -563,9 +563,9 @@ run_connect:
                       "setup new connection: is_ssl=%d %s %s %s", 
                       ctx->p_conn->is_ssl, ctx->p_conn->ssl_hostname, 
                       locurl, ctx->p_conn->hostname);
-        if ((status = ap_proxy_connection_create(ctx->proxy_func, ctx->p_conn,
-                                                 ctx->owner, 
-                                                 ctx->server)) != OK) {
+        status = ap_proxy_connection_create_ex(ctx->proxy_func,
+                                               ctx->p_conn, ctx->rbase);
+        if (status != OK) {
             goto cleanup;
         }
         
Index: modules/proxy/mod_proxy.c
===================================================================
--- modules/proxy/mod_proxy.c	(revision 1740086)
+++ modules/proxy/mod_proxy.c	(working copy)
@@ -26,6 +26,10 @@
 #else
 APR_DECLARE_OPTIONAL_FN(int, ssl_proxy_enable, (conn_rec *));
 APR_DECLARE_OPTIONAL_FN(int, ssl_engine_disable, (conn_rec *));
+APR_DECLARE_OPTIONAL_FN(int, ssl_proxy_enable_ex,
+                        (conn_rec *, ap_conf_vector_t *));
+APR_DECLARE_OPTIONAL_FN(int, ssl_proxy_disable_ex,
+                        (conn_rec *, ap_conf_vector_t *));
 APR_DECLARE_OPTIONAL_FN(int, ssl_is_https, (conn_rec *));
 APR_DECLARE_OPTIONAL_FN(char *, ssl_var_lookup,
                         (apr_pool_t *, server_rec *,
@@ -2313,6 +2317,9 @@ static const char *add_member(cmd_parms *cmd, void
                      "Sharing worker '%s' instead of creating new worker '%s'",
                      ap_proxy_worker_name(cmd->pool, worker), name);
     }
+    if (!worker->section_config) {
+        worker->section_config = balancer->section_config;
+    }
 
     arr = apr_table_elts(params);
     elts = (const apr_table_entry_t *)arr->elts;
@@ -2427,6 +2434,13 @@ static void ap_add_per_proxy_conf(server_rec *s, a
     *new_space = dir_config;
 }
 
+static apr_array_header_t *ap_proxy_get_sections_configs(server_rec *s)
+{
+    proxy_server_conf *sconf = ap_get_module_config(s->module_config,
+                                                    &proxy_module);
+    return sconf->sec_proxy;
+}
+
 static const char *proxysection(cmd_parms *cmd, void *mconfig, const char *arg)
 {
     const char *errmsg;
@@ -2521,6 +2535,9 @@ static const char *proxysection(cmd_parms *cmd, vo
                     return apr_pstrcat(cmd->temp_pool, thiscmd->name,
                                        " ", err, NULL);
             }
+            if (!balancer->section_config) {
+                balancer->section_config = new_dir_conf;
+            }
         }
         else {
             worker = ap_proxy_get_worker(cmd->temp_pool, NULL, sconf,
@@ -2544,6 +2561,9 @@ static const char *proxysection(cmd_parms *cmd, vo
                                    "altogether with the same worker name ",
                                    "(", worker->s->name, ")", NULL);
             }
+            if (!worker->section_config) {
+                worker->section_config = new_dir_conf;
+            }
         }
         if (worker == NULL && balancer == NULL) {
             return apr_pstrcat(cmd->pool, thiscmd->name,
@@ -2651,6 +2671,8 @@ 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_proxy_enable_ex) *proxy_ssl_enable_ex = NULL;
+static APR_OPTIONAL_FN_TYPE(ssl_proxy_disable_ex) *proxy_ssl_disable_ex = 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;
 
@@ -2676,6 +2698,34 @@ PROXY_DECLARE(int) ap_proxy_ssl_disable(conn_rec *
     return 0;
 }
 
+PROXY_DECLARE(int) ap_proxy_ssl_enable_ex(conn_rec *c,
+                                          ap_conf_vector_t *per_dir_config)
+{
+    /*
+     * if c == NULL just check if the optional function was imported
+     * else run the optional function so ssl filters are inserted
+     */
+    if (proxy_ssl_enable_ex) {
+        return c ? proxy_ssl_enable_ex(c, per_dir_config) : 1;
+    }
+
+    return ap_proxy_ssl_enable(c);
+}
+
+PROXY_DECLARE(int) ap_proxy_ssl_disable_ex(conn_rec *c,
+                                           ap_conf_vector_t *per_dir_config)
+{
+    /*
+     * if c == NULL just check if the optional function was imported
+     * else run the optional function so ssl filters are inserted
+     */
+    if (proxy_ssl_disable_ex) {
+        return c ? proxy_ssl_disable_ex(c, per_dir_config) : 1;
+    }
+
+    return ap_proxy_ssl_disable(c);
+}
+
 PROXY_DECLARE(int) ap_proxy_conn_is_https(conn_rec *c)
 {
     if (proxy_is_https) {
@@ -2710,6 +2760,8 @@ static int proxy_post_config(apr_pool_t *pconf, ap
 
     proxy_ssl_enable = APR_RETRIEVE_OPTIONAL_FN(ssl_proxy_enable);
     proxy_ssl_disable = APR_RETRIEVE_OPTIONAL_FN(ssl_engine_disable);
+    proxy_ssl_enable_ex = APR_RETRIEVE_OPTIONAL_FN(ssl_proxy_enable_ex);
+    proxy_ssl_disable_ex = APR_RETRIEVE_OPTIONAL_FN(ssl_proxy_disable_ex);
     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);
@@ -2955,6 +3007,8 @@ static void register_hooks(apr_pool_t *p)
     /* child init handling */
     ap_hook_child_init(child_init, aszPred, NULL, APR_HOOK_MIDDLE);
 
+    APR_REGISTER_OPTIONAL_FN(ap_proxy_get_sections_configs);
+
     /* register optional functions within proxy_util.c */
     proxy_util_register_hooks(p);
 }
Index: modules/proxy/mod_proxy.h
===================================================================
--- modules/proxy/mod_proxy.h	(revision 1740086)
+++ modules/proxy/mod_proxy.h	(working copy)
@@ -459,6 +459,7 @@ struct proxy_worker {
     proxy_balancer  *balancer;  /* which balancer am I in? */
     apr_thread_mutex_t  *tmutex; /* Thread lock for updating address cache */
     void            *context;   /* general purpose storage */
+    ap_conf_vector_t *section_config;   /* Per <Proxy>-section config */
 };
 
 /* default to health check every 30 seconds */
@@ -523,6 +524,7 @@ struct proxy_balancer {
     unsigned int failontimeout_set:1;
     unsigned int growth_set:1;
     unsigned int lbmethod_set:1;
+    ap_conf_vector_t *section_config;   /* Per <Proxy>-section config */
 };
 
 struct proxy_balancer_method {
@@ -664,6 +666,10 @@ PROXY_DECLARE(apr_status_t) ap_proxy_ssl_connectio
                                                             request_rec *r);
 PROXY_DECLARE(int) ap_proxy_ssl_enable(conn_rec *c);
 PROXY_DECLARE(int) ap_proxy_ssl_disable(conn_rec *c);
+PROXY_DECLARE(int) ap_proxy_ssl_enable_ex(conn_rec *c,
+                                          ap_conf_vector_t *per_dir_config);
+PROXY_DECLARE(int) ap_proxy_ssl_disable_ex(conn_rec *c,
+                                           ap_conf_vector_t *per_dir_config);
 PROXY_DECLARE(int) ap_proxy_conn_is_https(conn_rec *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);
 
@@ -991,7 +997,7 @@ PROXY_DECLARE(apr_status_t) ap_proxy_connect_uds(a
  * Make a connection record for backend connection
  * @param proxy_function calling proxy scheme (http, ajp, ...)
  * @param conn    acquired connection
- * @param c       client connection record
+ * @param c       client connection record (unused, deprecated)
  * @param s       current server record
  * @return        OK or HTTP_XXX error
  * @note The function will return immediately if conn->connection
@@ -1002,6 +1008,18 @@ PROXY_DECLARE(int) ap_proxy_connection_create(cons
                                               conn_rec *c, server_rec *s);
 
 /**
+ * Make a connection record for backend connection, using request dir config
+ * @param proxy_function calling proxy scheme (http, ajp, ...)
+ * @param conn    acquired connection
+ * @param r       current request record
+ * @return        OK or HTTP_XXX error
+ * @note The function will return immediately if conn->connection
+ * is already set,
+ */
+PROXY_DECLARE(int) ap_proxy_connection_create_ex(const char *proxy_function,
+                                                 proxy_conn_rec *conn,
+                                                 request_rec *r);
+/**
  * Determine if proxy connection can potentially be reused at the
  * end of this request.
  * @param conn proxy connection
@@ -1226,5 +1244,8 @@ PROXY_DECLARE(apr_status_t) ap_proxy_transfer_betw
 
 extern module PROXY_DECLARE_DATA proxy_module;
 
+APR_DECLARE_OPTIONAL_FN(apr_array_header_t *, ap_proxy_get_sections_configs,
+                        (server_rec *s));
+
 #endif /*MOD_PROXY_H*/
 /** @} */
Index: modules/proxy/mod_proxy_connect.c
===================================================================
--- modules/proxy/mod_proxy_connect.c	(revision 1740086)
+++ modules/proxy/mod_proxy_connect.c	(working copy)
@@ -299,7 +299,7 @@ static int proxy_connect_handler(request_rec *r, p
         apr_socket_close(sock);
         return HTTP_INTERNAL_SERVER_ERROR;
     }
-    ap_proxy_ssl_disable(backconn);
+    ap_proxy_ssl_disable_ex(backconn, r->per_dir_config);
     rc = ap_run_pre_connection(backconn, sock);
     if (rc != OK && rc != DONE) {
         backconn->aborted = 1;
Index: modules/proxy/mod_proxy_ftp.c
===================================================================
--- modules/proxy/mod_proxy_ftp.c	(revision 1740086)
+++ modules/proxy/mod_proxy_ftp.c	(working copy)
@@ -1189,7 +1189,7 @@ static int proxy_ftp_handler(request_rec *r, proxy
     }
 
     if (!backend->connection) {
-        status = ap_proxy_connection_create("FTP", backend, c, r->server);
+        status = ap_proxy_connection_create_ex("FTP", backend, r);
         if (status != OK) {
             proxy_ftp_cleanup(r, backend);
             return status;
@@ -2035,7 +2035,7 @@ static int proxy_ftp_handler(request_rec *r, proxy
      * We do not do SSL over the data connection, even if the virtual host we
      * are in might have SSL enabled
      */
-    ap_proxy_ssl_disable(data);
+    ap_proxy_ssl_disable_ex(data, r->per_dir_config);
     /* set up the connection filters */
     rc = ap_run_pre_connection(data, data_sock);
     if (rc != OK && rc != DONE) {
Index: modules/proxy/mod_proxy_http.c
===================================================================
--- modules/proxy/mod_proxy_http.c	(revision 1740086)
+++ modules/proxy/mod_proxy_http.c	(working copy)
@@ -2083,8 +2083,8 @@ static int proxy_http_handler(request_rec *r, prox
         /* Step Three: Create conn_rec */
         backconn = backend->connection;
         if (!backconn) {
-            if ((status = ap_proxy_connection_create(proxy_function, backend,
-                                                     c, r->server)) != OK)
+            if ((status = ap_proxy_connection_create_ex(proxy_function,
+                                                        backend, r)) != OK)
                 break;
             backconn = backend->connection;
 
Index: modules/proxy/mod_proxy_wstunnel.c
===================================================================
--- modules/proxy/mod_proxy_wstunnel.c	(revision 1740086)
+++ modules/proxy/mod_proxy_wstunnel.c	(working copy)
@@ -447,7 +447,6 @@ static int proxy_wstunnel_handler(request_rec *r,
     proxy_conn_rec *backend = NULL;
     const char *upgrade;
     char *scheme;
-    conn_rec *c = r->connection;
     apr_pool_t *p = r->pool;
     char *locurl = url;
     apr_uri_t *uri;
@@ -504,7 +503,7 @@ static int proxy_wstunnel_handler(request_rec *r,
 
     /* Step Three: Create conn_rec */
     if (!backend->connection) {
-        status = ap_proxy_connection_create(scheme, backend, c, r->server);
+        status = ap_proxy_connection_create_ex(scheme, backend, r);
         if (status  != OK) {
             goto cleanup;
         }
Index: modules/proxy/proxy_util.c
===================================================================
--- modules/proxy/proxy_util.c	(revision 1740086)
+++ modules/proxy/proxy_util.c	(working copy)
@@ -2982,11 +2982,12 @@ static apr_status_t connection_shutdown(void *thec
 }
 
 
-PROXY_DECLARE(int) ap_proxy_connection_create(const char *proxy_function,
-                                              proxy_conn_rec *conn,
-                                              conn_rec *c,
-                                              server_rec *s)
+static int proxy_connection_create(const char *proxy_function,
+                                   proxy_conn_rec *conn,
+                                   request_rec *r, server_rec *s)
 {
+    ap_conf_vector_t *per_dir_config = (r) ? r->per_dir_config
+                                           : conn->worker->section_config;
     apr_sockaddr_t *backend_addr = conn->addr;
     int rc;
     apr_interval_time_t current_timeout;
@@ -3020,7 +3021,7 @@ static apr_status_t connection_shutdown(void *thec
 
     /* For ssl connection to backend */
     if (conn->is_ssl) {
-        if (!ap_proxy_ssl_enable(conn->connection)) {
+        if (!ap_proxy_ssl_enable_ex(conn->connection, per_dir_config)) {
             ap_log_error(APLOG_MARK, APLOG_ERR, 0,
                          s, APLOGNO(00961) "%s: failed to enable ssl support "
                          "for %pI (%s)", proxy_function,
@@ -3030,7 +3031,7 @@ static apr_status_t connection_shutdown(void *thec
     }
     else {
         /* TODO: See if this will break FTP */
-        ap_proxy_ssl_disable(conn->connection);
+        ap_proxy_ssl_disable_ex(conn->connection, per_dir_config);
     }
 
     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00962)
@@ -3062,6 +3063,21 @@ static apr_status_t connection_shutdown(void *thec
     return OK;
 }
 
+PROXY_DECLARE(int) ap_proxy_connection_create_ex(const char *proxy_function,
+                                                 proxy_conn_rec *conn,
+                                                 request_rec *r)
+{
+    return proxy_connection_create(proxy_function, conn, r, r->server);
+}
+
+PROXY_DECLARE(int) ap_proxy_connection_create(const char *proxy_function,
+                                              proxy_conn_rec *conn,
+                                              conn_rec *c, server_rec *s)
+{
+    (void) c; /* unused */
+    return proxy_connection_create(proxy_function, conn, NULL, s);
+}
+
 int ap_proxy_lb_workers(void)
 {
     /*
Index: modules/ssl/mod_ssl.c
===================================================================
--- modules/ssl/mod_ssl.c	(revision 1740086)
+++ modules/ssl/mod_ssl.c	(working copy)
@@ -175,50 +175,50 @@ static const command_rec ssl_config_cmds[] = {
     /*
      * Proxy configuration for remote SSL connections
      */
-    SSL_CMD_SRV(ProxyEngine, FLAG,
+    SSL_CMD_ALL(ProxyEngine, FLAG,
                 "SSL switch for the proxy protocol engine "
                 "('on', 'off')")
-    SSL_CMD_SRV(ProxyProtocol, RAW_ARGS,
+    SSL_CMD_ALL(ProxyProtocol, RAW_ARGS,
                "SSL Proxy: enable or disable SSL protocol flavors "
                 "('[+-][" SSL_PROTOCOLS "] ...' - see manual)")
-    SSL_CMD_SRV(ProxyCipherSuite, TAKE1,
+    SSL_CMD_ALL(ProxyCipherSuite, TAKE1,
                "SSL Proxy: colon-delimited list of permitted SSL ciphers "
                "('XXX:...:XXX' - see manual)")
-    SSL_CMD_SRV(ProxyVerify, TAKE1,
+    SSL_CMD_ALL(ProxyVerify, TAKE1,
                "SSL Proxy: whether to verify the remote certificate "
                "('on' or 'off')")
-    SSL_CMD_SRV(ProxyVerifyDepth, TAKE1,
+    SSL_CMD_ALL(ProxyVerifyDepth, TAKE1,
                "SSL Proxy: maximum certificate verification depth "
                "('N' - number of intermediate certificates)")
-    SSL_CMD_SRV(ProxyCACertificateFile, TAKE1,
+    SSL_CMD_ALL(ProxyCACertificateFile, TAKE1,
                "SSL Proxy: file containing server certificates "
                "('/path/to/file' - PEM encoded certificates)")
-    SSL_CMD_SRV(ProxyCACertificatePath, TAKE1,
+    SSL_CMD_ALL(ProxyCACertificatePath, TAKE1,
                "SSL Proxy: directory containing server certificates "
                "('/path/to/dir' - contains PEM encoded certificates)")
-    SSL_CMD_SRV(ProxyCARevocationPath, TAKE1,
+    SSL_CMD_ALL(ProxyCARevocationPath, TAKE1,
                 "SSL Proxy: CA Certificate Revocation List (CRL) path "
                 "('/path/to/dir' - contains PEM encoded files)")
-    SSL_CMD_SRV(ProxyCARevocationFile, TAKE1,
+    SSL_CMD_ALL(ProxyCARevocationFile, TAKE1,
                 "SSL Proxy: CA Certificate Revocation List (CRL) file "
                 "('/path/to/file' - PEM encoded)")
-    SSL_CMD_SRV(ProxyCARevocationCheck, RAW_ARGS,
+    SSL_CMD_ALL(ProxyCARevocationCheck, RAW_ARGS,
                 "SSL Proxy: CA Certificate Revocation List (CRL) checking mode")
-    SSL_CMD_SRV(ProxyMachineCertificateFile, TAKE1,
+    SSL_CMD_ALL(ProxyMachineCertificateFile, TAKE1,
                "SSL Proxy: file containing client certificates "
                "('/path/to/file' - PEM encoded certificates)")
-    SSL_CMD_SRV(ProxyMachineCertificatePath, TAKE1,
+    SSL_CMD_ALL(ProxyMachineCertificatePath, TAKE1,
                "SSL Proxy: directory containing client certificates "
                "('/path/to/dir' - contains PEM encoded certificates)")
-    SSL_CMD_SRV(ProxyMachineCertificateChainFile, TAKE1,
+    SSL_CMD_ALL(ProxyMachineCertificateChainFile, TAKE1,
                "SSL Proxy: file containing issuing certificates "
                "of the client certificate "
                "(`/path/to/file' - PEM encoded certificates)")
-    SSL_CMD_SRV(ProxyCheckPeerExpire, FLAG,
+    SSL_CMD_ALL(ProxyCheckPeerExpire, FLAG,
                 "SSL Proxy: check the peer certificate's expiration date")
-    SSL_CMD_SRV(ProxyCheckPeerCN, FLAG,
+    SSL_CMD_ALL(ProxyCheckPeerCN, FLAG,
                 "SSL Proxy: check the peer certificate's CN")
-    SSL_CMD_SRV(ProxyCheckPeerName, FLAG,
+    SSL_CMD_ALL(ProxyCheckPeerName, FLAG,
                 "SSL Proxy: check the peer certificate's name "
                 "(must be present in subjectAltName extension or CN")
 
@@ -403,8 +403,21 @@ static int ssl_hook_pre_config(apr_pool_t *pconf,
     return OK;
 }
 
-static SSLConnRec *ssl_init_connection_ctx(conn_rec *c)
+static SSLDirConfigRec *ssl_get_dir_config(conn_rec *c,
+                                           ap_conf_vector_t *per_dir_config)
 {
+    if (per_dir_config) {
+        return ap_get_module_config(per_dir_config, &ssl_module);
+    }
+    else {
+        return ap_get_module_config(c->base_server->lookup_defaults,
+                                    &ssl_module);
+    }
+}
+
+static SSLConnRec *ssl_init_connection_ctx(conn_rec *c,
+                                           ap_conf_vector_t *per_dir_config)
+{
     SSLConnRec *sslconn = myConnConfig(c);
     SSLSrvConfigRec *sc;
 
@@ -418,6 +431,7 @@ static int ssl_hook_pre_config(apr_pool_t *pconf,
     sslconn->verify_depth = UNSET;
     sc = mySrvConfig(c->base_server);
     sslconn->cipher_suite = sc->server->auth.cipher_suite;
+    sslconn->dc = ssl_get_dir_config(c, per_dir_config);
 
     myConnConfigSet(c, sslconn);
 
@@ -424,63 +438,64 @@ static int ssl_hook_pre_config(apr_pool_t *pconf,
     return sslconn;
 }
 
-static int ssl_proxy_enable(conn_rec *c)
+static int ssl_proxy_enable_ex(conn_rec *c, ap_conf_vector_t *per_dir_config)
 {
-    SSLSrvConfigRec *sc;
+    SSLConnRec *sslconn = ssl_init_connection_ctx(c, per_dir_config);
 
-    SSLConnRec *sslconn = ssl_init_connection_ctx(c);
-    sc = mySrvConfig(sslconn->server);
+    sslconn->is_proxy = 1;
 
-    if (!sc->proxy_enabled) {
+    if (!sslconn->dc->proxy_enabled) {
+        SSLSrvConfigRec *sc = mySrvConfig(sslconn->server);
         ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(01961)
                       "SSL Proxy requested for %s but not enabled "
                       "[Hint: SSLProxyEngine]", sc->vhost_id);
 
+        sslconn->disabled = 1;
+
         return 0;
     }
 
-    sslconn->is_proxy = 1;
     sslconn->disabled = 0;
 
     return 1;
 }
 
-static int ssl_engine_disable(conn_rec *c)
+static int ssl_proxy_disable_ex(conn_rec *c, ap_conf_vector_t *per_dir_config)
 {
-    SSLSrvConfigRec *sc;
+    SSLDirConfigRec *dc = ssl_get_dir_config(c, per_dir_config);
+    SSLConnRec *sslconn;
 
-    SSLConnRec *sslconn = myConnConfig(c);
-
-    if (sslconn) {
-        sc = mySrvConfig(sslconn->server);
-    }
-    else {
-        sc = mySrvConfig(c->base_server);
-    }
-    if (sc->enabled == SSL_ENABLED_FALSE) {
+    if (!dc->proxy_enabled) {
         return 0;
     }
 
-    sslconn = ssl_init_connection_ctx(c);
-
+    sslconn = ssl_init_connection_ctx(c, per_dir_config);
     sslconn->disabled = 1;
 
     return 1;
 }
 
+static int ssl_proxy_enable(conn_rec *c)
+{
+    return ssl_proxy_enable_ex(c, NULL);
+}
+
+static int ssl_engine_disable(conn_rec *c)
+{
+    return ssl_proxy_disable_ex(c, NULL);
+}
+
 int ssl_init_ssl_connection(conn_rec *c, request_rec *r)
 {
     SSLSrvConfigRec *sc;
     SSL *ssl;
-    SSLConnRec *sslconn = myConnConfig(c);
+    SSLConnRec *sslconn;
     char *vhost_md5;
     int rc;
     modssl_ctx_t *mctx;
     server_rec *server;
 
-    if (!sslconn) {
-        sslconn = ssl_init_connection_ctx(c);
-    }
+    sslconn = ssl_init_connection_ctx(c, r ? r->per_dir_config : NULL);
     server = sslconn->server;
     sc = mySrvConfig(server);
 
@@ -489,7 +504,7 @@ int ssl_init_ssl_connection(conn_rec *c, request_r
      */
     ssl_rand_seed(server, c->pool, SSL_RSCTX_CONNECT, "");
 
-    mctx = sslconn->is_proxy ? sc->proxy : sc->server;
+    mctx = myCtxConfig(sslconn, sc);
 
     /*
      * Create a new SSL connection with the configured server SSL context and
@@ -584,7 +599,7 @@ static int ssl_hook_pre_connection(conn_rec *c, vo
      * Create SSL context
      */
     if (!sslconn) {
-        sslconn = ssl_init_connection_ctx(c);
+        sslconn = ssl_init_connection_ctx(c, NULL);
     }
 
     if (sslconn->disabled) {
@@ -657,6 +672,8 @@ static void ssl_register_hooks(apr_pool_t *p)
 
     APR_REGISTER_OPTIONAL_FN(ssl_proxy_enable);
     APR_REGISTER_OPTIONAL_FN(ssl_engine_disable);
+    APR_REGISTER_OPTIONAL_FN(ssl_proxy_enable_ex);
+    APR_REGISTER_OPTIONAL_FN(ssl_proxy_disable_ex);
 
     ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ssl",
                               AUTHZ_PROVIDER_VERSION,
@@ -667,7 +684,6 @@ static void ssl_register_hooks(apr_pool_t *p)
                               AUTHZ_PROVIDER_VERSION,
                               &ssl_authz_provider_verify_client,
                               AP_AUTH_INTERNAL_PER_CONF);
-
 }
 
 module AP_MODULE_DECLARE_DATA ssl_module = {
Index: modules/ssl/mod_ssl.h
===================================================================
--- modules/ssl/mod_ssl.h	(revision 1740086)
+++ modules/ssl/mod_ssl.h	(working copy)
@@ -85,13 +85,16 @@ APR_DECLARE_OPTIONAL_FN(apr_status_t, ssl_get_tls_
                         (apr_pool_t *p, conn_rec *c, const char *type,
                          unsigned char **buf, apr_size_t *size));
 
-/** The ssl_proxy_enable() and ssl_engine_disable() optional functions
- * are used by mod_proxy to enable use of SSL for outgoing
+/** The ssl_proxy_{enable,disable}[_dir]() and ssl_engine_disable() optional
+ * functions are used by mod_proxy to enable use of SSL for outgoing
  * connections. */
 
 APR_DECLARE_OPTIONAL_FN(int, ssl_proxy_enable, (conn_rec *));
-
 APR_DECLARE_OPTIONAL_FN(int, ssl_engine_disable, (conn_rec *));
+APR_DECLARE_OPTIONAL_FN(int, ssl_proxy_enable_ex,
+                        (conn_rec *c, ap_conf_vector_t *dir_config));
+APR_DECLARE_OPTIONAL_FN(int, ssl_proxy_disable_ex,
+                        (conn_rec *c, ap_conf_vector_t *dir_config));
 
 #endif /* __MOD_SSL_H__ */
 /** @} */
Index: modules/ssl/ssl_engine_config.c
===================================================================
--- modules/ssl/ssl_engine_config.c	(revision 1740086)
+++ modules/ssl/ssl_engine_config.c	(working copy)
@@ -162,24 +162,10 @@ static void modssl_ctx_init(modssl_ctx_t *mctx, ap
     SSL_CONF_CTX_set_flags(mctx->ssl_ctx_config, SSL_CONF_FLAG_CERTIFICATE);
     mctx->ssl_ctx_param = apr_array_make(p, 5, sizeof(ssl_ctx_param_t));
 #endif
-}
 
-static void modssl_ctx_init_proxy(SSLSrvConfigRec *sc,
-                                  apr_pool_t *p)
-{
-    modssl_ctx_t *mctx;
-
-    mctx = sc->proxy = apr_palloc(p, sizeof(*sc->proxy));
-
-    modssl_ctx_init(mctx, p);
-
-    mctx->pkp = apr_palloc(p, sizeof(*mctx->pkp));
-
-    mctx->pkp->cert_file = NULL;
-    mctx->pkp->cert_path = NULL;
-    mctx->pkp->ca_cert_file = NULL;
-    mctx->pkp->certs     = NULL;
-    mctx->pkp->ca_certs  = NULL;
+    mctx->ssl_check_peer_cn     = UNSET;
+    mctx->ssl_check_peer_name   = UNSET;
+    mctx->ssl_check_peer_expire = UNSET;
 }
 
 static void modssl_ctx_init_server(SSLSrvConfigRec *sc,
@@ -207,15 +193,11 @@ static SSLSrvConfigRec *ssl_config_server_new(apr_
 
     sc->mc                     = NULL;
     sc->enabled                = SSL_ENABLED_UNSET;
-    sc->proxy_enabled          = UNSET;
     sc->vhost_id               = NULL;  /* set during module init */
     sc->vhost_id_len           = 0;     /* set during module init */
     sc->session_cache_timeout  = UNSET;
     sc->cipher_server_pref     = UNSET;
     sc->insecure_reneg         = UNSET;
-    sc->proxy_ssl_check_peer_expire = SSL_ENABLED_UNSET;
-    sc->proxy_ssl_check_peer_cn     = SSL_ENABLED_UNSET;
-    sc->proxy_ssl_check_peer_name   = SSL_ENABLED_UNSET;
 #ifdef HAVE_TLSEXT
     sc->strict_sni_vhost_check = SSL_ENABLED_UNSET;
 #endif
@@ -227,8 +209,6 @@ static SSLSrvConfigRec *ssl_config_server_new(apr_
 #endif
     sc->session_tickets        = UNSET;
 
-    modssl_ctx_init_proxy(sc, p);
-
     modssl_ctx_init_server(sc, p);
 
     return sc;
@@ -252,6 +232,10 @@ void *ssl_config_server_create(apr_pool_t *p, serv
 #define cfgMergeBool(el)    cfgMerge(el, UNSET)
 #define cfgMergeInt(el)     cfgMerge(el, UNSET)
 
+/*
+ *  Merge per-server SSL configurations
+ */
+
 static void modssl_ctx_cfg_merge(apr_pool_t *p,
                                  modssl_ctx_t *base,
                                  modssl_ctx_t *add,
@@ -309,18 +293,6 @@ static void modssl_ctx_cfg_merge(apr_pool_t *p,
 #endif
 }
 
-static void modssl_ctx_cfg_merge_proxy(apr_pool_t *p,
-                                       modssl_ctx_t *base,
-                                       modssl_ctx_t *add,
-                                       modssl_ctx_t *mrg)
-{
-    modssl_ctx_cfg_merge(p, base, add, mrg);
-
-    cfgMergeString(pkp->cert_file);
-    cfgMergeString(pkp->cert_path);
-    cfgMergeString(pkp->ca_cert_file);
-}
-
 static void modssl_ctx_cfg_merge_server(apr_pool_t *p,
                                         modssl_ctx_t *base,
                                         modssl_ctx_t *add,
@@ -339,9 +311,6 @@ static void modssl_ctx_cfg_merge_server(apr_pool_t
 #endif
 }
 
-/*
- *  Merge per-server SSL configurations
- */
 void *ssl_config_server_merge(apr_pool_t *p, void *basev, void *addv)
 {
     SSLSrvConfigRec *base = (SSLSrvConfigRec *)basev;
@@ -350,13 +319,9 @@ void *ssl_config_server_merge(apr_pool_t *p, void
 
     cfgMerge(mc, NULL);
     cfgMerge(enabled, SSL_ENABLED_UNSET);
-    cfgMergeBool(proxy_enabled);
     cfgMergeInt(session_cache_timeout);
     cfgMergeBool(cipher_server_pref);
     cfgMergeBool(insecure_reneg);
-    cfgMerge(proxy_ssl_check_peer_expire, SSL_ENABLED_UNSET);
-    cfgMerge(proxy_ssl_check_peer_cn, SSL_ENABLED_UNSET);
-    cfgMerge(proxy_ssl_check_peer_name, SSL_ENABLED_UNSET);
 #ifdef HAVE_TLSEXT
     cfgMerge(strict_sni_vhost_check, SSL_ENABLED_UNSET);
 #endif
@@ -368,8 +333,6 @@ void *ssl_config_server_merge(apr_pool_t *p, void
 #endif
     cfgMergeBool(session_tickets);
 
-    modssl_ctx_cfg_merge_proxy(p, base->proxy, add->proxy, mrg->proxy);
-
     modssl_ctx_cfg_merge_server(p, base->server, add->server, mrg->server);
 
     return mrg;
@@ -378,6 +341,25 @@ void *ssl_config_server_merge(apr_pool_t *p, void
 /*
  *  Create per-directory SSL configuration
  */
+
+static void modssl_ctx_init_proxy(SSLDirConfigRec *dc,
+                                  apr_pool_t *p)
+{
+    modssl_ctx_t *mctx;
+
+    mctx = dc->proxy = apr_palloc(p, sizeof(*dc->proxy));
+
+    modssl_ctx_init(mctx, p);
+
+    mctx->pkp = apr_palloc(p, sizeof(*mctx->pkp));
+
+    mctx->pkp->cert_file = NULL;
+    mctx->pkp->cert_path = NULL;
+    mctx->pkp->ca_cert_file = NULL;
+    mctx->pkp->certs     = NULL;
+    mctx->pkp->ca_certs  = NULL;
+}
+
 void *ssl_config_perdir_create(apr_pool_t *p, char *dir)
 {
     SSLDirConfigRec *dc = apr_palloc(p, sizeof(*dc));
@@ -392,12 +374,14 @@ void *ssl_config_perdir_create(apr_pool_t *p, char
     dc->nVerifyClient          = SSL_CVERIFY_UNSET;
     dc->nVerifyDepth           = UNSET;
 
-    dc->szCACertificatePath    = NULL;
-    dc->szCACertificateFile    = NULL;
     dc->szUserName             = NULL;
 
     dc->nRenegBufferSize = UNSET;
 
+    dc->proxy_enabled = UNSET;
+    modssl_ctx_init_proxy(dc, p);
+    dc->proxy_post_config = FALSE;
+
     return dc;
 }
 
@@ -404,6 +388,23 @@ void *ssl_config_perdir_create(apr_pool_t *p, char
 /*
  *  Merge per-directory SSL configurations
  */
+
+static void modssl_ctx_cfg_merge_proxy(apr_pool_t *p,
+                                       modssl_ctx_t *base,
+                                       modssl_ctx_t *add,
+                                       modssl_ctx_t *mrg)
+{
+    modssl_ctx_cfg_merge(p, base, add, mrg);
+
+    cfgMergeString(pkp->cert_file);
+    cfgMergeString(pkp->cert_path);
+    cfgMergeString(pkp->ca_cert_file);
+
+    cfgMergeBool(ssl_check_peer_cn);
+    cfgMergeBool(ssl_check_peer_name);
+    cfgMergeBool(ssl_check_peer_expire);
+}
+
 void *ssl_config_perdir_merge(apr_pool_t *p, void *basev, void *addv)
 {
     SSLDirConfigRec *base = (SSLDirConfigRec *)basev;
@@ -431,19 +432,43 @@ void *ssl_config_perdir_merge(apr_pool_t *p, void
     cfgMerge(nVerifyClient, SSL_CVERIFY_UNSET);
     cfgMergeInt(nVerifyDepth);
 
-    cfgMergeString(szCACertificatePath);
-    cfgMergeString(szCACertificateFile);
     cfgMergeString(szUserName);
 
     cfgMergeInt(nRenegBufferSize);
 
+    if (!add->proxy_post_config) {
+        cfgMergeBool(proxy_enabled);
+        modssl_ctx_init_proxy(mrg, p);
+        modssl_ctx_cfg_merge_proxy(p, base->proxy, add->proxy, mrg->proxy);
+    }
+    else {
+        /* post_config hook has already merged and initialized the
+         * proxy context, use it.
+         */
+        mrg->proxy_enabled = add->proxy_enabled;
+        mrg->proxy = add->proxy;
+    }
+
     return mrg;
 }
 
+/* Simply merge conf with base into conf, no third party. */
+void ssl_config_proxy_merge(apr_pool_t *p,
+                            SSLDirConfigRec *base,
+                            SSLDirConfigRec *conf)
+{
+    if (conf->proxy_enabled == UNSET) {
+        conf->proxy_enabled = base->proxy_enabled;
+    }
+    modssl_ctx_cfg_merge_proxy(p, base->proxy, conf->proxy, conf->proxy);
+}
+
 /*
  *  Configuration functions for particular directives
  */
 
+#define SERVER_OR_PROXY_ONLY (NOT_IN_DIR_LOC_FILE & ~NOT_IN_PROXY)
+
 const char *ssl_cmd_SSLPassPhraseDialog(cmd_parms *cmd,
                                         void *dcfg,
                                         const char *arg)
@@ -1393,10 +1418,15 @@ const char *ssl_cmd_SSLProtocol(cmd_parms *cmd,
 
 const char *ssl_cmd_SSLProxyEngine(cmd_parms *cmd, void *dcfg, int flag)
 {
-    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
+    const char *err;
 
-    sc->proxy_enabled = flag ? TRUE : FALSE;
+    if ((err = ap_check_cmd_context(cmd, SERVER_OR_PROXY_ONLY))) {
+        return err;
+    }
 
+    dc->proxy_enabled = flag ? TRUE : FALSE;
+
     return NULL;
 }
 
@@ -1404,10 +1434,15 @@ const char *ssl_cmd_SSLProxyProtocol(cmd_parms *cm
                                      void *dcfg,
                                      const char *arg)
 {
-    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
+    const char *err;
 
-    sc->proxy->protocol_set = 1;
-    return ssl_cmd_protocol_parse(cmd, arg, &sc->proxy->protocol);
+    if ((err = ap_check_cmd_context(cmd, SERVER_OR_PROXY_ONLY))) {
+        return err;
+    }
+
+    dc->proxy->protocol_set = 1;
+    return ssl_cmd_protocol_parse(cmd, arg, &dc->proxy->protocol);
 }
 
 const char *ssl_cmd_SSLProxyCipherSuite(cmd_parms *cmd,
@@ -1414,13 +1449,16 @@ const char *ssl_cmd_SSLProxyCipherSuite(cmd_parms
                                         void *dcfg,
                                         const char *arg)
 {
-    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
+    const char *err;
 
+    if ((err = ap_check_cmd_context(cmd, SERVER_OR_PROXY_ONLY))) {
+        return err;
+    }
+
     /* always disable null and export ciphers */
     arg = apr_pstrcat(cmd->pool, arg, ":!aNULL:!eNULL:!EXP", NULL);
-
-    sc->proxy->auth.cipher_suite = arg;
-
+    dc->proxy->auth.cipher_suite = arg;
     return NULL;
 }
 
@@ -1428,16 +1466,16 @@ const char *ssl_cmd_SSLProxyVerify(cmd_parms *cmd,
                                    void *dcfg,
                                    const char *arg)
 {
-    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
     ssl_verify_t mode;
     const char *err;
 
-    if ((err = ssl_cmd_verify_parse(cmd, arg, &mode))) {
+    if ((err = ap_check_cmd_context(cmd, SERVER_OR_PROXY_ONLY)) ||
+        (err = ssl_cmd_verify_parse(cmd, arg, &mode))) {
         return err;
     }
 
-    sc->proxy->auth.verify_mode = mode;
-
+    dc->proxy->auth.verify_mode = mode;
     return NULL;
 }
 
@@ -1445,16 +1483,16 @@ const char *ssl_cmd_SSLProxyVerifyDepth(cmd_parms
                                         void *dcfg,
                                         const char *arg)
 {
-    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
     int depth;
     const char *err;
 
-    if ((err = ssl_cmd_verify_depth_parse(cmd, arg, &depth))) {
+    if ((err = ap_check_cmd_context(cmd, SERVER_OR_PROXY_ONLY)) ||
+        (err = ssl_cmd_verify_depth_parse(cmd, arg, &depth))) {
         return err;
     }
 
-    sc->proxy->auth.verify_depth = depth;
-
+    dc->proxy->auth.verify_depth = depth;
     return NULL;
 }
 
@@ -1462,15 +1500,15 @@ const char *ssl_cmd_SSLProxyCACertificateFile(cmd_
                                               void *dcfg,
                                               const char *arg)
 {
-    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
     const char *err;
 
-    if ((err = ssl_cmd_check_file(cmd, &arg))) {
+    if ((err = ap_check_cmd_context(cmd, SERVER_OR_PROXY_ONLY)) ||
+        (err = ssl_cmd_check_file(cmd, &arg))) {
         return err;
     }
 
-    sc->proxy->auth.ca_cert_file = arg;
-
+    dc->proxy->auth.ca_cert_file = arg;
     return NULL;
 }
 
@@ -1478,15 +1516,15 @@ const char *ssl_cmd_SSLProxyCACertificatePath(cmd_
                                               void *dcfg,
                                               const char *arg)
 {
-    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
     const char *err;
 
-    if ((err = ssl_cmd_check_dir(cmd, &arg))) {
+    if ((err = ap_check_cmd_context(cmd, SERVER_OR_PROXY_ONLY)) ||
+        (err = ssl_cmd_check_dir(cmd, &arg))) {
         return err;
     }
 
-    sc->proxy->auth.ca_cert_path = arg;
-
+    dc->proxy->auth.ca_cert_path = arg;
     return NULL;
 }
 
@@ -1494,15 +1532,15 @@ const char *ssl_cmd_SSLProxyCARevocationPath(cmd_p
                                              void *dcfg,
                                              const char *arg)
 {
-    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
     const char *err;
 
-    if ((err = ssl_cmd_check_dir(cmd, &arg))) {
+    if ((err = ap_check_cmd_context(cmd, SERVER_OR_PROXY_ONLY)) ||
+        (err = ssl_cmd_check_dir(cmd, &arg))) {
         return err;
     }
 
-    sc->proxy->crl_path = arg;
-
+    dc->proxy->crl_path = arg;
     return NULL;
 }
 
@@ -1510,15 +1548,15 @@ const char *ssl_cmd_SSLProxyCARevocationFile(cmd_p
                                              void *dcfg,
                                              const char *arg)
 {
-    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
     const char *err;
 
-    if ((err = ssl_cmd_check_file(cmd, &arg))) {
+    if ((err = ap_check_cmd_context(cmd, SERVER_OR_PROXY_ONLY)) ||
+        (err = ssl_cmd_check_file(cmd, &arg))) {
         return err;
     }
 
-    sc->proxy->crl_file = arg;
-
+    dc->proxy->crl_file = arg;
     return NULL;
 }
 
@@ -1526,9 +1564,14 @@ const char *ssl_cmd_SSLProxyCARevocationCheck(cmd_
                                               void *dcfg,
                                               const char *arg)
 {
-    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
+    const char *err;
 
-    return ssl_cmd_crlcheck_parse(cmd, arg, &sc->proxy->crl_check_mask);
+    if ((err = ap_check_cmd_context(cmd, SERVER_OR_PROXY_ONLY))) {
+        return err;
+    }
+
+    return ssl_cmd_crlcheck_parse(cmd, arg, &dc->proxy->crl_check_mask);
 }
 
 const char *ssl_cmd_SSLProxyMachineCertificateFile(cmd_parms *cmd,
@@ -1535,15 +1578,15 @@ const char *ssl_cmd_SSLProxyMachineCertificateFile
                                                    void *dcfg,
                                                    const char *arg)
 {
-    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
     const char *err;
 
-    if ((err = ssl_cmd_check_file(cmd, &arg))) {
+    if ((err = ap_check_cmd_context(cmd, SERVER_OR_PROXY_ONLY)) ||
+        (err = ssl_cmd_check_file(cmd, &arg))) {
         return err;
     }
 
-    sc->proxy->pkp->cert_file = arg;
-
+    dc->proxy->pkp->cert_file = arg;
     return NULL;
 }
 
@@ -1551,15 +1594,15 @@ const char *ssl_cmd_SSLProxyMachineCertificatePath
                                                    void *dcfg,
                                                    const char *arg)
 {
-    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
     const char *err;
 
-    if ((err = ssl_cmd_check_dir(cmd, &arg))) {
+    if ((err = ap_check_cmd_context(cmd, SERVER_OR_PROXY_ONLY)) ||
+        (err = ssl_cmd_check_dir(cmd, &arg))) {
         return err;
     }
 
-    sc->proxy->pkp->cert_path = arg;
-
+    dc->proxy->pkp->cert_path = arg;
     return NULL;
 }
 
@@ -1567,15 +1610,15 @@ const char *ssl_cmd_SSLProxyMachineCertificateChai
                                                    void *dcfg,
                                                    const char *arg)
 {
-    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
     const char *err;
 
-    if ((err = ssl_cmd_check_file(cmd, &arg))) {
+    if ((err = ap_check_cmd_context(cmd, SERVER_OR_PROXY_ONLY)) ||
+        (err = ssl_cmd_check_file(cmd, &arg))) {
         return err;
     }
 
-    sc->proxy->pkp->ca_cert_file = arg;
-
+    dc->proxy->pkp->ca_cert_file = arg;
     return NULL;
 }
 
@@ -1674,28 +1717,40 @@ const char *ssl_cmd_SSLOCSPProxyURL(cmd_parms *cmd
 
 const char *ssl_cmd_SSLProxyCheckPeerExpire(cmd_parms *cmd, void *dcfg, int flag)
 {
-    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
+    const char *err;
 
-    sc->proxy_ssl_check_peer_expire = flag ? SSL_ENABLED_TRUE : SSL_ENABLED_FALSE;
+    if ((err = ap_check_cmd_context(cmd, SERVER_OR_PROXY_ONLY))) {
+        return err;
+    }
 
+    dc->proxy->ssl_check_peer_expire = flag ? TRUE : FALSE;
     return NULL;
 }
 
 const char *ssl_cmd_SSLProxyCheckPeerCN(cmd_parms *cmd, void *dcfg, int flag)
 {
-    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
+    const char *err;
 
-    sc->proxy_ssl_check_peer_cn = flag ? SSL_ENABLED_TRUE : SSL_ENABLED_FALSE;
+    if ((err = ap_check_cmd_context(cmd, SERVER_OR_PROXY_ONLY))) {
+        return err;
+    }
 
+    dc->proxy->ssl_check_peer_cn = flag ? TRUE : FALSE;
     return NULL;
 }
 
 const char *ssl_cmd_SSLProxyCheckPeerName(cmd_parms *cmd, void *dcfg, int flag)
 {
-    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
+    const char *err;
 
-    sc->proxy_ssl_check_peer_name = flag ? SSL_ENABLED_TRUE : SSL_ENABLED_FALSE;
+    if ((err = ap_check_cmd_context(cmd, SERVER_OR_PROXY_ONLY))) {
+        return err;
+    }
 
+    dc->proxy->ssl_check_peer_name = flag ? TRUE : FALSE;
     return NULL;
 }
 
Index: modules/ssl/ssl_engine_init.c
===================================================================
--- modules/ssl/ssl_engine_init.c	(revision 1740086)
+++ modules/ssl/ssl_engine_init.c	(working copy)
@@ -31,6 +31,8 @@
 #include "mod_ssl_openssl.h"
 #include "mpm_common.h"
 
+#include "mod_proxy.h" /* for optional ap_proxy_get_sections_configs() */
+
 static apr_status_t ssl_init_ca_cert_path(server_rec *, apr_pool_t *, const char *,
                                           STACK_OF(X509_NAME) *, STACK_OF(X509_INFO) *);
 
@@ -38,6 +40,9 @@ APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int,
                                     (server_rec *s,apr_pool_t *p,int is_proxy,SSL_CTX *ctx),
                                     (s,p,is_proxy,ctx), OK, DECLINED)
 
+static APR_OPTIONAL_FN_TYPE(ap_proxy_get_sections_configs)
+    *ssl_proxy_get_sections_configs = NULL;
+
 /*  _________________________________________________________________
 **
 **  Module Initialization
@@ -218,10 +223,6 @@ apr_status_t ssl_init_Module(apr_pool_t *p, apr_po
             sc->server->sc = sc;
         }
 
-        if (sc->proxy) {
-            sc->proxy->sc = sc;
-        }
-
         /*
          * Create the server host:port string because we need it a lot
          */
@@ -241,9 +242,6 @@ apr_status_t ssl_init_Module(apr_pool_t *p, apr_po
         if (sc->enabled == SSL_ENABLED_UNSET) {
             sc->enabled = SSL_ENABLED_FALSE;
         }
-        if (sc->proxy_enabled == UNSET) {
-            sc->proxy_enabled = FALSE;
-        }
 
         if (sc->session_cache_timeout == UNSET) {
             sc->session_cache_timeout = SSL_SESSION_CACHE_TIMEOUT;
@@ -330,6 +328,9 @@ apr_status_t ssl_init_Module(apr_pool_t *p, apr_po
     ap_log_error(APLOG_MARK, APLOG_INFO, 0, base_server, APLOGNO(01887)
                  "Init: Initializing (virtual) servers for SSL");
 
+    ssl_proxy_get_sections_configs =
+        APR_RETRIEVE_OPTIONAL_FN(ap_proxy_get_sections_configs);
+
     for (s = base_server; s; s = s->next) {
         sc = mySrvConfig(s);
         /*
@@ -362,6 +363,9 @@ apr_status_t ssl_init_Module(apr_pool_t *p, apr_po
     }
 
     for (s = base_server; s; s = s->next) {
+        SSLDirConfigRec *sdc = ap_get_module_config(s->lookup_defaults,
+                                                    &ssl_module);
+        apr_array_header_t *proxy_configs;
         sc = mySrvConfig(s);
 
         if (sc->enabled == SSL_ENABLED_TRUE || sc->enabled == SSL_ENABLED_OPTIONAL) {
@@ -369,11 +373,31 @@ apr_status_t ssl_init_Module(apr_pool_t *p, apr_po
                 return rv;
             }
         }
-        else if (sc->proxy_enabled == SSL_ENABLED_TRUE) {
-            if ((rv = ssl_run_init_server(s, p, 1, sc->proxy->ssl_ctx)) != APR_SUCCESS) {
+
+        if (sdc->proxy_enabled) {
+            rv = ssl_run_init_server(s, p, 1, sdc->proxy->ssl_ctx);
+            if (rv != APR_SUCCESS) {
                 return rv;
             }
         }
+
+        if (ssl_proxy_get_sections_configs &&
+                (proxy_configs = ssl_proxy_get_sections_configs(s))) {
+            ap_conf_vector_t **proxy_config =
+                (ap_conf_vector_t **)proxy_configs->elts;
+            int i;
+
+            for (i = 0; i < proxy_configs->nelts; ++i) {
+                SSLDirConfigRec *pdc = ap_get_module_config(proxy_config[i],
+                                                            &ssl_module);
+                if (pdc && pdc->proxy_enabled) {
+                    rv = ssl_run_init_server(s, p, 1, pdc->proxy->ssl_ctx);
+                    if (rv != APR_SUCCESS) {
+                        return rv;
+                    }
+                }
+            }
+        }
     }
 
     /*
@@ -1565,18 +1589,65 @@ static apr_status_t ssl_init_proxy_certs(server_re
     return APR_SUCCESS;
 }
 
+#define MODSSL_CFG_ITEM_FREE(func, item) \
+    if (item) { \
+        func(item); \
+        item = NULL; \
+    }
+
+static void ssl_init_ctx_cleanup(modssl_ctx_t *mctx)
+{
+    MODSSL_CFG_ITEM_FREE(SSL_CTX_free, mctx->ssl_ctx);
+
+#ifdef HAVE_SRP
+    if (mctx->srp_vbase != NULL) {
+        SRP_VBASE_free(mctx->srp_vbase);
+        mctx->srp_vbase = NULL;
+    }
+#endif
+}
+
+static apr_status_t ssl_cleanup_proxy_ctx(void *data)
+{
+    modssl_ctx_t *mctx = data;
+
+    ssl_init_ctx_cleanup(mctx);
+
+    if (mctx->pkp->certs) {
+        int i = 0;
+        int ncerts = sk_X509_INFO_num(mctx->pkp->certs);
+
+        if (mctx->pkp->ca_certs) {
+            for (i = 0; i < ncerts; i++) {
+                if (mctx->pkp->ca_certs[i] != NULL) {
+                    sk_X509_pop_free(mctx->pkp->ca_certs[i], X509_free);
+                }
+            }
+        }
+
+        sk_X509_INFO_pop_free(mctx->pkp->certs, X509_INFO_free);
+        mctx->pkp->certs = NULL;
+    }
+
+    return APR_SUCCESS;
+}
+
 static apr_status_t ssl_init_proxy_ctx(server_rec *s,
                                        apr_pool_t *p,
                                        apr_pool_t *ptemp,
-                                       SSLSrvConfigRec *sc)
+                                       modssl_ctx_t *proxy)
 {
     apr_status_t rv;
 
-    if ((rv = ssl_init_ctx(s, p, ptemp, sc->proxy)) != APR_SUCCESS) {
+    apr_pool_cleanup_register(p, proxy,
+                              ssl_cleanup_proxy_ctx,
+                              apr_pool_cleanup_null);
+
+    if ((rv = ssl_init_ctx(s, p, ptemp, proxy)) != APR_SUCCESS) {
         return rv;
     }
 
-    if ((rv = ssl_init_proxy_certs(s, p, ptemp, sc->proxy)) != APR_SUCCESS) {
+    if ((rv = ssl_init_proxy_certs(s, p, ptemp, proxy)) != APR_SUCCESS) {
         return rv;
     }
 
@@ -1698,6 +1769,9 @@ apr_status_t ssl_init_ConfigureServer(server_rec *
                                       SSLSrvConfigRec *sc,
                                       apr_array_header_t *pphrases)
 {
+    SSLDirConfigRec *sdc = ap_get_module_config(s->lookup_defaults,
+                                                &ssl_module);
+    apr_array_header_t *proxy_configs;
     apr_status_t rv;
 
     /* Initialize the server if SSL is enabled or optional.
@@ -1711,12 +1785,41 @@ apr_status_t ssl_init_ConfigureServer(server_rec *
         }
     }
 
-    if (sc->proxy_enabled) {
-        if ((rv = ssl_init_proxy_ctx(s, p, ptemp, sc)) != APR_SUCCESS) {
+    sdc->proxy->sc = sc;
+    if (sdc->proxy_enabled == TRUE) {
+        rv = ssl_init_proxy_ctx(s, p, ptemp, sdc->proxy);
+        if (rv != APR_SUCCESS) {
             return rv;
         }
     }
+    else {
+        sdc->proxy_enabled = FALSE;
+    }
+    sdc->proxy_post_config = 1;
 
+    if (ssl_proxy_get_sections_configs &&
+            (proxy_configs = ssl_proxy_get_sections_configs(s))) {
+        ap_conf_vector_t **proxy_config =
+            (ap_conf_vector_t **)proxy_configs->elts;
+        int i;
+
+        for (i = 0; i < proxy_configs->nelts; ++i) {
+            SSLDirConfigRec *pdc = ap_get_module_config(proxy_config[i],
+                                                        &ssl_module);
+            if (pdc) {
+                pdc->proxy->sc = sc;
+                ssl_config_proxy_merge(p, sdc, pdc);
+                if (pdc->proxy_enabled) {
+                    rv = ssl_init_proxy_ctx(s, p, ptemp, pdc->proxy);
+                    if (rv != APR_SUCCESS) {
+                        return rv;
+                    }
+                }
+                pdc->proxy_post_config = 1;
+            }
+        }
+    }
+
     return APR_SUCCESS;
 }
 
@@ -1954,45 +2057,6 @@ void ssl_init_Child(apr_pool_t *p, server_rec *s)
 #endif
 }
 
-#define MODSSL_CFG_ITEM_FREE(func, item) \
-    if (item) { \
-        func(item); \
-        item = NULL; \
-    }
-
-static void ssl_init_ctx_cleanup(modssl_ctx_t *mctx)
-{
-    MODSSL_CFG_ITEM_FREE(SSL_CTX_free, mctx->ssl_ctx);
-
-#ifdef HAVE_SRP
-    if (mctx->srp_vbase != NULL) {
-        SRP_VBASE_free(mctx->srp_vbase);
-        mctx->srp_vbase = NULL;
-    }
-#endif
-}
-
-static void ssl_init_ctx_cleanup_proxy(modssl_ctx_t *mctx)
-{
-    ssl_init_ctx_cleanup(mctx);
-
-    if (mctx->pkp->certs) {
-        int i = 0;
-        int ncerts = sk_X509_INFO_num(mctx->pkp->certs);
-
-        if (mctx->pkp->ca_certs) {
-            for (i = 0; i < ncerts; i++) {
-                if (mctx->pkp->ca_certs[i] != NULL) {
-                    sk_X509_pop_free(mctx->pkp->ca_certs[i], X509_free);
-                }
-            }
-        }
-
-        sk_X509_INFO_pop_free(mctx->pkp->certs, X509_INFO_free);
-        mctx->pkp->certs = NULL;
-    }
-}
-
 apr_status_t ssl_init_ModuleKill(void *data)
 {
     SSLSrvConfigRec *sc;
@@ -2011,8 +2075,6 @@ apr_status_t ssl_init_ModuleKill(void *data)
     for (s = base_server; s; s = s->next) {
         sc = mySrvConfig(s);
 
-        ssl_init_ctx_cleanup_proxy(sc->proxy);
-
         ssl_init_ctx_cleanup(sc->server);
     }
 
Index: modules/ssl/ssl_engine_io.c
===================================================================
--- modules/ssl/ssl_engine_io.c	(revision 1740086)
+++ modules/ssl/ssl_engine_io.c	(working copy)
@@ -1191,7 +1191,9 @@ static apr_status_t ssl_io_filter_handshake(ssl_fi
 #endif
         BOOL proxy_ssl_check_peer_ok = TRUE;
         int post_handshake_rc = OK;
+        SSLDirConfigRec *dc;
 
+        dc = sslconn->dc;
         sc = mySrvConfig(server);
 
 #ifdef HAVE_TLSEXT
@@ -1239,7 +1241,7 @@ static apr_status_t ssl_io_filter_handshake(ssl_fi
          */
         if (hostname_note &&
 #ifndef OPENSSL_NO_SSL3
-            sc->proxy->protocol != SSL_PROTOCOL_SSLV3 &&
+            dc->proxy->protocol != SSL_PROTOCOL_SSLV3 &&
 #endif
             apr_ipsubnet_create(&ip, hostname_note, NULL,
                                 c->pool) != APR_SUCCESS) {
@@ -1268,7 +1270,7 @@ static apr_status_t ssl_io_filter_handshake(ssl_fi
 
         cert = SSL_get_peer_certificate(filter_ctx->pssl);
 
-        if (sc->proxy_ssl_check_peer_expire != SSL_ENABLED_FALSE) {
+        if (dc->proxy->ssl_check_peer_expire != FALSE) {
             if (!cert
                 || (X509_cmp_current_time(
                      X509_get_notBefore(cert)) >= 0)
@@ -1279,7 +1281,7 @@ static apr_status_t ssl_io_filter_handshake(ssl_fi
                               "SSL Proxy: Peer certificate is expired");
             }
         }
-        if ((sc->proxy_ssl_check_peer_name != SSL_ENABLED_FALSE) &&
+        if ((dc->proxy->ssl_check_peer_name != FALSE) &&
             hostname_note) {
             apr_table_unset(c->notes, "proxy-request-hostname");
             if (!cert
@@ -1291,7 +1293,7 @@ static apr_status_t ssl_io_filter_handshake(ssl_fi
                               "for hostname %s", hostname_note);
             }
         }
-        else if ((sc->proxy_ssl_check_peer_cn != SSL_ENABLED_FALSE) &&
+        else if ((dc->proxy->ssl_check_peer_cn != FALSE) &&
             hostname_note) {
             const char *hostname;
             int match = 0;
Index: modules/ssl/ssl_engine_kernel.c
===================================================================
--- modules/ssl/ssl_engine_kernel.c	(revision 1740086)
+++ modules/ssl/ssl_engine_kernel.c	(working copy)
@@ -1566,8 +1566,8 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX
     server_rec *s       = r ? r->server : mySrvFromConn(conn);
 
     SSLSrvConfigRec *sc = mySrvConfig(s);
-    SSLDirConfigRec *dc = r ? myDirConfig(r) : NULL;
     SSLConnRec *sslconn = myConnConfig(conn);
+    SSLDirConfigRec *dc = r ? myDirConfig(r) : sslconn->dc;
     modssl_ctx_t *mctx  = myCtxConfig(sslconn, sc);
     int crl_check_mode  = mctx->crl_check_mask & ~SSL_CRLCHECK_FLAGS;
 
@@ -1759,11 +1759,13 @@ int ssl_callback_proxy_cert(SSL *ssl, X509 **x509,
     conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
     server_rec *s = mySrvFromConn(c);
     SSLSrvConfigRec *sc = mySrvConfig(s);
+    SSLConnRec *sslconn = myConnConfig(c);
+    SSLDirConfigRec *dc = sslconn->dc;
     X509_NAME *ca_name, *issuer, *ca_issuer;
     X509_INFO *info;
     X509 *ca_cert;
     STACK_OF(X509_NAME) *ca_list;
-    STACK_OF(X509_INFO) *certs = sc->proxy->pkp->certs;
+    STACK_OF(X509_INFO) *certs;
     STACK_OF(X509) *ca_certs;
     STACK_OF(X509) **ca_cert_chains;
     int i, j, k;
@@ -1772,6 +1774,7 @@ int ssl_callback_proxy_cert(SSL *ssl, X509 **x509,
                  SSLPROXY_CERT_CB_LOG_FMT "entered",
                  sc->vhost_id);
 
+    certs = (dc && dc->proxy) ? dc->proxy->pkp->certs : NULL;
     if (!certs || (sk_X509_INFO_num(certs) <= 0)) {
         ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(02268)
                      SSLPROXY_CERT_CB_LOG_FMT
@@ -1796,7 +1799,7 @@ int ssl_callback_proxy_cert(SSL *ssl, X509 **x509,
         return TRUE;
     }
 
-    ca_cert_chains = sc->proxy->pkp->ca_certs;
+    ca_cert_chains = dc->proxy->pkp->ca_certs;
     for (i = 0; i < sk_X509_NAME_num(ca_list); i++) {
         ca_name = sk_X509_NAME_value(ca_list, i);
 
Index: modules/ssl/ssl_private.h
===================================================================
--- modules/ssl/ssl_private.h	(revision 1740086)
+++ modules/ssl/ssl_private.h	(working copy)
@@ -259,14 +259,18 @@ APLOG_USE_MODULE(ssl);
 #define strIsEmpty(s)    (s == NULL || s[0] == NUL)
 
 #define myConnConfig(c) \
-(SSLConnRec *)ap_get_module_config(c->conn_config, &ssl_module)
-#define myCtxConfig(sslconn, sc) (sslconn->is_proxy ? sc->proxy : sc->server)
+    ((SSLConnRec *)ap_get_module_config(c->conn_config, &ssl_module))
 #define myConnConfigSet(c, val) \
-ap_set_module_config(c->conn_config, &ssl_module, val)
-#define mySrvConfig(srv) (SSLSrvConfigRec *)ap_get_module_config(srv->module_config,  &ssl_module)
-#define myDirConfig(req) (SSLDirConfigRec *)ap_get_module_config(req->per_dir_config, &ssl_module)
-#define myModConfig(srv) (mySrvConfig((srv)))->mc
-#define mySrvFromConn(c) (myConnConfig(c))->server
+    ap_set_module_config(c->conn_config, &ssl_module, val)
+#define mySrvConfig(srv) \
+    ((SSLSrvConfigRec *)ap_get_module_config(srv->module_config,  &ssl_module))
+#define myDirConfig(req) \
+    ((SSLDirConfigRec *)ap_get_module_config(req->per_dir_config, &ssl_module))
+#define myCtxConfig(sslconn, sc) \
+    (sslconn->is_proxy ? sslconn->dc->proxy : sc->server)
+#define myModConfig(srv) mySrvConfig((srv))->mc
+#define mySrvFromConn(c) myConnConfig(c)->server
+#define myDirConfigFromConn(c) myConnConfig(c)->dc
 #define mySrvConfigFromConn(c) mySrvConfig(mySrvFromConn(c))
 #define myModConfigFromConn(c) myModConfig(mySrvFromConn(c))
 
@@ -437,6 +441,9 @@ typedef struct {
  * (i.e. the global configuration for each httpd process)
  */
 
+typedef struct SSLSrvConfigRec SSLSrvConfigRec;
+typedef struct SSLDirConfigRec SSLDirConfigRec;
+
 typedef enum {
     SSL_SHUTDOWN_TYPE_UNSET,
     SSL_SHUTDOWN_TYPE_STANDARD,
@@ -475,6 +482,7 @@ typedef struct {
     } reneg_state;
 
     server_rec *server;
+    SSLDirConfigRec *dc;
     
     const char *cipher_suite; /* cipher suite used in last reneg */
 } SSLConnRec;
@@ -595,8 +603,6 @@ typedef struct {
 } ssl_ctx_param_t;
 #endif
 
-typedef struct SSLSrvConfigRec SSLSrvConfigRec;
-
 typedef struct {
     SSLSrvConfigRec *sc; /** pointer back to server config */
     SSL_CTX *ssl_ctx;
@@ -658,12 +664,15 @@ typedef struct {
     SSL_CONF_CTX *ssl_ctx_config; /* Configuration context */
     apr_array_header_t *ssl_ctx_param; /* parameters to pass to SSL_CTX */
 #endif
+
+    BOOL ssl_check_peer_cn;
+    BOOL ssl_check_peer_name;
+    BOOL ssl_check_peer_expire;
 } modssl_ctx_t;
 
 struct SSLSrvConfigRec {
     SSLModConfigRec *mc;
     ssl_enabled_t    enabled;
-    BOOL             proxy_enabled;
     const char      *vhost_id;
     int              vhost_id_len;
     int              session_cache_timeout;
@@ -670,10 +679,6 @@ struct SSLSrvConfigRec {
     BOOL             cipher_server_pref;
     BOOL             insecure_reneg;
     modssl_ctx_t    *server;
-    modssl_ctx_t    *proxy;
-    ssl_enabled_t    proxy_ssl_check_peer_expire;
-    ssl_enabled_t    proxy_ssl_check_peer_cn;
-    ssl_enabled_t    proxy_ssl_check_peer_name;
 #ifdef HAVE_TLSEXT
     ssl_enabled_t    strict_sni_vhost_check;
 #endif
@@ -691,7 +696,7 @@ struct SSLSrvConfigRec {
  * (i.e. the local configuration for all &lt;Directory>
  *  and .htaccess contexts)
  */
-typedef struct {
+struct SSLDirConfigRec {
     BOOL          bSSLRequired;
     apr_array_header_t *aRequirement;
     ssl_opt_t     nOptions;
@@ -700,12 +705,14 @@ struct SSLSrvConfigRec {
     const char   *szCipherSuite;
     ssl_verify_t  nVerifyClient;
     int           nVerifyDepth;
-    const char   *szCACertificatePath;
-    const char   *szCACertificateFile;
     const char   *szUserName;
     apr_size_t    nRenegBufferSize;
-} SSLDirConfigRec;
 
+    modssl_ctx_t *proxy;
+    BOOL          proxy_enabled;
+    BOOL          proxy_post_config;
+};
+
 /**
  *  function prototypes
  */
@@ -721,6 +728,8 @@ void        *ssl_config_server_create(apr_pool_t *
 void        *ssl_config_server_merge(apr_pool_t *, void *, void *);
 void        *ssl_config_perdir_create(apr_pool_t *, char *);
 void        *ssl_config_perdir_merge(apr_pool_t *, void *, void *);
+void         ssl_config_proxy_merge(apr_pool_t *,
+                                    SSLDirConfigRec *, SSLDirConfigRec *);
 const char  *ssl_cmd_SSLPassPhraseDialog(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLCryptoDevice(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLRandomSeed(cmd_parms *, void *, const char *, const char *, const char *);
Index: server/core.c
===================================================================
--- server/core.c	(revision 1740086)
+++ server/core.c	(working copy)
@@ -1312,7 +1312,10 @@ AP_DECLARE(const char *) ap_check_cmd_context(cmd_
                 || (found = find_parent(cmd->directive, "<FilesMatch"))
                 || (found = find_parent(cmd->directive, "<If"))
                 || (found = find_parent(cmd->directive, "<ElseIf"))
-                || (found = find_parent(cmd->directive, "<Else"))))) {
+                || (found = find_parent(cmd->directive, "<Else"))))
+        || ((forbidden & NOT_IN_PROXY)
+            && ((found = find_parent(cmd->directive, "<Proxy"))
+                || (found = find_parent(cmd->directive, "<ProxyMatch"))))) {
         return apr_pstrcat(cmd->pool, cmd->cmd->name, gt,
                            " cannot occur within ", found->directive,
                            "> section", NULL);

Reply via email to