upstream keepalive - call for testing

Maxim Dounin mdounin at mdounin.ru
Thu Aug 25 00:05:22 UTC 2011


Hello!

On Wed, Aug 24, 2011 at 01:11:43PM -0400, magicbear wrote:

> Thanks for your hard work, I have found that if using https backend, it
> won't work, server will direct close the connection.
> 
> curl --head 'http://localhost/track.js'
> curl: (52) Empty reply from server

Yes, thank you for report.

Keeping https connections will require additional support both in 
nginx core and upstream keepalive module.  You may try the 
attached patches, also available here:

http://mdounin.ru/files/patch-nginx-keepalive-https.txt
http://mdounin.ru/files/patch-nginx-keepalive-https-module.txt

The first one is for nginx itself, should be applied after 
keepalive patch.

The second one (actually, two grouped in one file) for upstream 
keepalive module. 

Maxim Dounin
-------------- next part --------------
# HG changeset patch
# User Maxim Dounin <mdounin at mdounin.ru>
# Date 1314229425 -14400
# Node ID ac0a7fd4de491e64d42f218691b681f7b3fa931b
# Parent  e865cb2cc06a88c01a439bfdd0d0d7dec54713f0
Upstream: create separate pool for peer connections.

This is required to support persistant https connections as various ssl
structures are allocated from connection's pool.

diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -1146,8 +1146,17 @@ ngx_http_upstream_connect(ngx_http_reque
     c->sendfile &= r->connection->sendfile;
     u->output.sendfile = c->sendfile;
 
-    c->pool = r->pool;
+    if (c->pool == NULL) {
+        c->pool = ngx_create_pool(128, r->connection->log);
+        if (c->pool == NULL) {
+            ngx_http_upstream_finalize_request(r, u,
+                                               NGX_HTTP_INTERNAL_SERVER_ERROR);
+            return;
+        }
+    }
+
     c->log = r->connection->log;
+    c->pool->log = c->log;
     c->read->log = c->log;
     c->write->log = c->log;
 
@@ -2912,6 +2921,7 @@ ngx_http_upstream_next(ngx_http_request_
         }
 #endif
 
+        ngx_destroy_pool(u->peer.connection->pool);
         ngx_close_connection(u->peer.connection);
     }
 
@@ -3006,6 +3016,7 @@ ngx_http_upstream_finalize_request(ngx_h
                        "close http upstream connection: %d",
                        u->peer.connection->fd);
 
+        ngx_destroy_pool(u->peer.connection->pool);
         ngx_close_connection(u->peer.connection);
     }
 
-------------- next part --------------
# HG changeset patch
# User Maxim Dounin <mdounin at mdounin.ru>
# Date 1314229646 -14400
# Node ID 67b12141506c6be2115b6b0aa151068188b97975
# Parent  f3b50effc1d476b040908700bb772197d31fbd80
Keepalive: set_session and save_session callbacks.

diff --git a/ngx_http_upstream_keepalive_module.c b/ngx_http_upstream_keepalive_module.c
--- a/ngx_http_upstream_keepalive_module.c
+++ b/ngx_http_upstream_keepalive_module.c
@@ -32,6 +32,11 @@ typedef struct {
     ngx_event_get_peer_pt              original_get_peer;
     ngx_event_free_peer_pt             original_free_peer;
 
+#if (NGX_HTTP_SSL)
+    ngx_event_set_peer_session_pt      original_set_session;
+    ngx_event_save_peer_session_pt     original_save_session;
+#endif
+
     ngx_uint_t                         failed;       /* unsigned:1 */
 
 } ngx_http_upstream_keepalive_peer_data_t;
@@ -59,6 +64,13 @@ static void ngx_http_upstream_free_keepa
 static void ngx_http_upstream_keepalive_dummy_handler(ngx_event_t *ev);
 static void ngx_http_upstream_keepalive_close_handler(ngx_event_t *ev);
 
+#if (NGX_HTTP_SSL)
+static ngx_int_t ngx_http_upstream_keepalive_set_session(
+    ngx_peer_connection_t *pc, void *data);
+static void ngx_http_upstream_keepalive_save_session(ngx_peer_connection_t *pc,
+    void *data);
+#endif
+
 static void *ngx_http_upstream_keepalive_create_conf(ngx_conf_t *cf);
 static char *ngx_http_upstream_keepalive(ngx_conf_t *cf, ngx_command_t *cmd,
     void *conf);
@@ -182,6 +194,13 @@ ngx_http_upstream_init_keepalive_peer(ng
     r->upstream->peer.get = ngx_http_upstream_get_keepalive_peer;
     r->upstream->peer.free = ngx_http_upstream_free_keepalive_peer;
 
+#if (NGX_HTTP_SSL)
+    kp->original_set_session = r->upstream->peer.set_session;
+    kp->original_save_session = r->upstream->peer.save_session;
+    r->upstream->peer.set_session = ngx_http_upstream_keepalive_set_session;
+    r->upstream->peer.save_session = ngx_http_upstream_keepalive_save_session;
+#endif
+
     return NGX_OK;
 }
 
@@ -423,6 +442,29 @@ close:
 }
 
 
+#if (NGX_HTTP_SSL)
+
+static ngx_int_t
+ngx_http_upstream_keepalive_set_session(ngx_peer_connection_t *pc, void *data)
+{
+    ngx_http_upstream_keepalive_peer_data_t  *kp = data;
+
+    return kp->original_set_session(pc, kp->data);
+}
+
+
+static void
+ngx_http_upstream_keepalive_save_session(ngx_peer_connection_t *pc, void *data)
+{
+    ngx_http_upstream_keepalive_peer_data_t  *kp = data;
+
+    kp->original_save_session(pc, kp->data);
+    return;
+}
+
+#endif
+
+
 static void *
 ngx_http_upstream_keepalive_create_conf(ngx_conf_t *cf)
 {
# HG changeset patch
# User Maxim Dounin <mdounin at mdounin.ru>
# Date 1314229663 -14400
# Node ID 3affea1af30649ac1934b01ab30d175abd4fb3be
# Parent  67b12141506c6be2115b6b0aa151068188b97975
Keepalive: destroy connection pool.

diff --git a/ngx_http_upstream_keepalive_module.c b/ngx_http_upstream_keepalive_module.c
--- a/ngx_http_upstream_keepalive_module.c
+++ b/ngx_http_upstream_keepalive_module.c
@@ -353,6 +353,7 @@ ngx_http_upstream_free_keepalive_peer(ng
             item = ngx_queue_data(q, ngx_http_upstream_keepalive_cache_t,
                                   queue);
 
+            ngx_destroy_pool(item->connection->pool);
             ngx_close_connection(item->connection);
 
         } else {
@@ -437,6 +438,7 @@ close:
     conf = item->conf;
 
     ngx_queue_remove(&item->queue);
+    ngx_destroy_pool(item->connection->pool);
     ngx_close_connection(item->connection);
     ngx_queue_insert_head(&conf->free, &item->queue);
 }


More information about the nginx mailing list