# HG changeset patch
# User Pavel Pautov <p.pautov@f5.com>
# Date 1653458099 25200
#      Tue May 24 22:54:59 2022 -0700
# Node ID 2c2f075f8a77687e62823bfb523418840b426283
# Parent  35afae4b3dffff6718c0cab3ceb16b9de207c20a
SSL: reuse parent location context (ticket #1234).

diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -125,6 +125,7 @@ typedef struct {
     ngx_str_t                      ssl_trusted_certificate;
     ngx_str_t                      ssl_crl;
     ngx_array_t                   *ssl_conf_commands;
+    ngx_ssl_t                     *shared_ssl;
 #endif
 } ngx_http_proxy_loc_conf_t;
 
@@ -3440,6 +3441,7 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t
 
     u_char                     *p;
     size_t                      size;
+    unsigned                    reuse_ssl;
     ngx_int_t                   rc;
     ngx_hash_init_t             hash;
     ngx_http_core_loc_conf_t   *clcf;
@@ -3720,6 +3722,18 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t
 
 #if (NGX_HTTP_SSL)
 
+    reuse_ssl = conf->upstream.ssl_session_reuse == NGX_CONF_UNSET
+        && conf->ssl_protocols                == 0
+        && conf->ssl_ciphers.data             == NULL
+        && conf->upstream.ssl_verify          == NGX_CONF_UNSET
+        && conf->ssl_verify_depth             == NGX_CONF_UNSET_UINT
+        && conf->ssl_trusted_certificate.data == NULL
+        && conf->ssl_crl.data                 == NULL
+        && conf->upstream.ssl_certificate     == NGX_CONF_UNSET_PTR
+        && conf->upstream.ssl_certificate_key == NGX_CONF_UNSET_PTR
+        && conf->upstream.ssl_passwords       == NGX_CONF_UNSET_PTR
+        && conf->ssl_conf_commands            == NGX_CONF_UNSET_PTR;
+
     ngx_conf_merge_value(conf->upstream.ssl_session_reuse,
                               prev->upstream.ssl_session_reuse, 1);
 
@@ -3752,10 +3766,29 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t
     ngx_conf_merge_ptr_value(conf->ssl_conf_commands,
                               prev->ssl_conf_commands, NULL);
 
-    if (conf->ssl && ngx_http_proxy_set_ssl(cf, conf) != NGX_OK) {
+    if (prev->shared_ssl == NULL) {
+        prev->shared_ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
+        if (prev->shared_ssl == NULL) {
+            return NGX_CONF_ERROR;
+        }
+    }
+
+    conf->shared_ssl = reuse_ssl ? prev->shared_ssl :
+                                   ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
+    if (conf->shared_ssl == NULL) {
         return NGX_CONF_ERROR;
     }
 
+    if (conf->ssl) {
+        conf->upstream.ssl = conf->shared_ssl;
+
+        if (conf->upstream.ssl->ctx == NULL) {
+            if (ngx_http_proxy_set_ssl(cf, conf) != NGX_OK) {
+                return NGX_CONF_ERROR;
+            }
+        }
+    }
+
 #endif
 
     ngx_conf_merge_ptr_value(conf->method, prev->method, NULL);
@@ -4923,11 +4956,6 @@ ngx_http_proxy_set_ssl(ngx_conf_t *cf, n
 {
     ngx_pool_cleanup_t  *cln;
 
-    plcf->upstream.ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
-    if (plcf->upstream.ssl == NULL) {
-        return NGX_ERROR;
-    }
-
     plcf->upstream.ssl->log = cf->log;
 
     if (ngx_ssl_create(plcf->upstream.ssl, plcf->ssl_protocols, NULL)
