Skip to content

Commit 90708be

Browse files
committed
- Resurect pending reconnect connections when needed
- Fixes support of Nginx 1.23.0
1 parent 221529c commit 90708be

File tree

2 files changed

+86
-19
lines changed

2 files changed

+86
-19
lines changed

README.md

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,17 @@ This project is a clone of [nginx-auth-ldap](https://github.com/kvspb/nginx-auth
77

88
The reasons for this fork are:
99

10-
* The original project seems abondonned (no commit since 2 years)
11-
* Inherit from other contributors fixes/features
12-
* [Pull request #237](https://github.com/kvspb/nginx-auth-ldap/pull/237) from [mmguero-dev](https://github.com/mmguero-dev/nginx-auth-ldap)
13-
* Add new features
14-
* Add the use of `resolver` to resolve hostname of the LDAP server
15-
* Support LDAP attributes fecthing during search
16-
* Added an `encoding` attribute to the binddn_passwd parameter
10+
* The original project seems abondonned (no commit since 2 years).
11+
* Inherit from other contributors fixes/features:
12+
* [Pull request #237](https://github.com/kvspb/nginx-auth-ldap/pull/237) from [mmguero-dev](https://github.com/mmguero-dev/nginx-auth-ldap).
13+
* Compatible with Nginx 1.23.0 (http headers are now linked).
14+
* Add new features:
15+
* Add the use of `resolver` to resolve hostname of the LDAP server.
16+
* Support LDAP attributes fecthing during search.
17+
* Added an `encoding` attribute to the binddn_passwd parameter.
18+
* Manage connections waiting a reconnect delay in a specific queue, so that we can
19+
cancel the reconnect delay when a new request ask for an authentication and no free
20+
connection is available.
1721

1822
## How to install
1923

@@ -101,10 +105,10 @@ And add required servers in correct order into your location/server directive:
101105
### auth_ldap_cache_expiration_time
102106

103107
* Syntax: auth_ldap_cache_expiration_time time;
104-
* Default: auth_ldap_cache_expiration_time 10000;
108+
* Default: auth_ldap_cache_expiration_time 10s;
105109
* Context: http
106110

107-
Cache expiration time (in ms).
111+
Cache expiration time (see <https://nginx.org/en/docs/syntax.html> for time intervals syntax).
108112

109113
### auth_ldap_cache_size
110114

@@ -151,10 +155,10 @@ See the `resolver` directive of the **ngx_http_core_module**
151155
### auth_ldap_resolver_timeout
152156

153157
* Syntax: auth_ldap_resolver_timeout time;
154-
* Default: auth_ldap_resolver_timeout 10000;
158+
* Default: auth_ldap_resolver_timeout 10s;
155159
* Context: http
156160

157-
Resolver requests timeout (in ms).
161+
Resolver requests timeout (see <https://nginx.org/en/docs/syntax.html> for time intervals syntax).
158162

159163
### ldap_server
160164

@@ -208,7 +212,6 @@ Tell to search for full DN in member object.
208212
* Default: --;
209213
* Context: `ldap_server` block
210214

211-
212215
### satisfy
213216

214217
* Syntax: satisfy all | any;
@@ -231,7 +234,6 @@ This can usually help with the following error:
231234
http_auth_ldap: ldap_result() failed (-1: Can't contact LDAP server)
232235
```
233236

234-
235237
### ssl_check_cert
236238

237239
* Syntax: ssl_check_cert on | chain | off;
@@ -292,3 +294,18 @@ The prefix for the HEADER names used to carry the feteched attributes (default:
292294

293295
Space delimited list of LDAP attribute descriptions to include in the search (require valid-user or require user). Each attribute value will be return as a HTTP header (<attribute_header_prefix><search_attribute>) in the authentication response.
294296

297+
### reconnect_timeout
298+
299+
* Syntax: reconnect_timeout _timespec_;
300+
* Default: reconnect_timeout 10s;
301+
* Context: `ldap_server` block
302+
303+
The delay before reconnection attempts (see <https://nginx.org/en/docs/syntax.html> for _timespec_ syntax)
304+
305+
### connections
306+
307+
* Syntax: connections _count_;
308+
* Default: connections 1;
309+
* Context: `ldap_server` block
310+
311+
The number of connections to the server use in //

ngx_http_auth_ldap_module.c

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ typedef struct {
120120
ngx_queue_t free_connections;
121121
ngx_queue_t waiting_requests;
122122

123+
ngx_queue_t pending_connections;
123124
char **attrs; // Search attributes formated for ldap_search_ext()
124125
ngx_str_t attribute_header_prefix;
125126
} ngx_http_auth_ldap_server_t;
@@ -212,6 +213,7 @@ typedef struct ngx_http_auth_ldap_connection {
212213
#endif
213214

214215
ngx_queue_t queue;
216+
ngx_queue_t queue_pending; /* pendings connection (waiting re-connect) */
215217
ngx_http_auth_ldap_ctx_t *rctx;
216218

217219
LDAP* ld;
@@ -238,6 +240,7 @@ static ngx_int_t ngx_http_auth_ldap_init_worker(ngx_cycle_t *cycle);
238240
static ngx_int_t ngx_http_auth_ldap_init(ngx_conf_t *cf);
239241
static ngx_int_t ngx_http_auth_ldap_init_cache(ngx_cycle_t *cycle);
240242
static void ngx_http_auth_ldap_close_connection(ngx_http_auth_ldap_connection_t *c);
243+
static void ngx_http_auth_ldap_set_pending_connection(ngx_http_auth_ldap_connection_t *c);
241244
static void ngx_http_auth_ldap_read_handler(ngx_event_t *rev);
242245
static void ngx_http_auth_ldap_connect(ngx_http_auth_ldap_connection_t *c);
243246
static void ngx_http_auth_ldap_connect_continue(ngx_http_auth_ldap_connection_t *c);
@@ -1133,8 +1136,8 @@ ngx_http_auth_ldap_init_cache(ngx_cycle_t *cycle)
11331136
cache->num_buckets = count;
11341137
cache->elts_per_bucket = 8;
11351138

1136-
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cycle->log, 0, "http_auth_ldap: Allocating %ud bytes of LDAP cache.",
1137-
cache->num_buckets * cache->elts_per_bucket * sizeof(ngx_http_auth_ldap_cache_elt_t));
1139+
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cycle->log, 0, "http_auth_ldap: Allocating %ud bytes of LDAP cache (ttl=%dms).",
1140+
cache->num_buckets * cache->elts_per_bucket * sizeof(ngx_http_auth_ldap_cache_elt_t), cache->expiration_time);
11381141

11391142
cache->buckets = (ngx_http_auth_ldap_cache_elt_t *) ngx_calloc(count * 8 * sizeof(ngx_http_auth_ldap_cache_elt_t), cycle->log);
11401143
if (cache->buckets == NULL) {
@@ -1343,7 +1346,7 @@ ngx_http_auth_ldap_close_connection(ngx_http_auth_ldap_connection_t *c)
13431346
c->rctx = NULL;
13441347
if (c->state != STATE_DISCONNECTED) {
13451348
c->state = STATE_DISCONNECTED;
1346-
ngx_add_timer(&c->reconnect_event, c->server->reconnect_timeout);
1349+
ngx_http_auth_ldap_set_pending_connection(c);
13471350
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http_auth_ldap: Connection scheduled for reconnection in %d ms", c->server->reconnect_timeout);
13481351
}
13491352
}
@@ -1384,6 +1387,18 @@ ngx_http_auth_ldap_get_connection(ngx_http_auth_ldap_ctx_t *ctx)
13841387
return 1;
13851388
}
13861389

1390+
/* Check if we have pending (waiting reconnect) connection */
1391+
if (!ngx_queue_empty(&server->pending_connections)) {
1392+
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ctx->r->connection->log, 0,
1393+
"http_auth_ldap: ngx_http_auth_ldap_get_connection: Have pending connection");
1394+
q = ngx_queue_head(&server->pending_connections);
1395+
c = ngx_queue_data(q, ngx_http_auth_ldap_connection_t, queue_pending);
1396+
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ctx->r->connection->log, 0,
1397+
"http_auth_ldap: ngx_http_auth_ldap_get_connection: Shorten reconnect timer");
1398+
/* Shorten the reconnection timer */
1399+
ngx_add_timer(&c->reconnect_event, 0);
1400+
}
1401+
13871402
q = ngx_queue_next(&server->waiting_requests);
13881403
while (q != ngx_queue_sentinel(&server->waiting_requests)) {
13891404
if (q == &ctx->queue) {
@@ -1420,6 +1435,26 @@ ngx_http_auth_ldap_return_connection(ngx_http_auth_ldap_connection_t *c)
14201435
}
14211436
}
14221437

1438+
static void
1439+
ngx_http_auth_ldap_set_pending_connection(ngx_http_auth_ldap_connection_t *c)
1440+
{
1441+
ngx_queue_t *q;
1442+
1443+
ngx_add_timer(&c->reconnect_event, c->server->reconnect_timeout);
1444+
/* Check if connection is already in the pending queue */
1445+
for (q = ngx_queue_head(&c->server->pending_connections);
1446+
q != ngx_queue_sentinel(&c->server->pending_connections);
1447+
q = ngx_queue_next(q))
1448+
{
1449+
if (q == &c->queue_pending) {
1450+
ngx_log_error(NGX_LOG_WARN, c->log, 0,
1451+
"http_auth_ldap: ngx_http_auth_ldap_set_pending_connection: Connection already in pending queue");
1452+
return;
1453+
}
1454+
}
1455+
ngx_queue_insert_tail(&c->server->pending_connections, &c->queue_pending);
1456+
}
1457+
14231458
static void
14241459
ngx_http_auth_ldap_reply_connection(ngx_http_auth_ldap_connection_t *c, int error_code, char* error_msg)
14251460
{
@@ -1873,7 +1908,7 @@ ngx_http_auth_ldap_read_handler(ngx_event_t *rev)
18731908
santitize_str((u_char *)attr, SANITIZE_NO_CONV);
18741909
int attr_len = strlen(attr);
18751910
h->hash = 1;
1876-
#if (nginx_version >= 102300)
1911+
#if (nginx_version >= 1023000)
18771912
h->next = NULL;
18781913
#endif
18791914
h->key.len = c->server->attribute_header_prefix.len + attr_len;
@@ -2011,7 +2046,7 @@ ngx_http_auth_ldap_connect_continue(ngx_http_auth_ldap_connection_t *c)
20112046
if (rc == NGX_ERROR || rc == NGX_BUSY || rc == NGX_DECLINED) {
20122047
ngx_log_error(NGX_LOG_ERR, c->log, 0, "http_auth_ldap: Unable to connect to LDAP server \"%V\".",
20132048
&addr->name);
2014-
ngx_add_timer(&c->reconnect_event, c->server->reconnect_timeout);
2049+
ngx_http_auth_ldap_set_pending_connection(c);
20152050
return;
20162051
}
20172052

@@ -2040,6 +2075,20 @@ ngx_http_auth_ldap_reconnect_handler(ngx_event_t *ev)
20402075
{
20412076
ngx_connection_t *conn = ev->data;
20422077
ngx_http_auth_ldap_connection_t *c = conn->data;
2078+
ngx_queue_t *q;
2079+
2080+
/* Remove this connection from the pending queue */
2081+
for (q = ngx_queue_head(&c->server->pending_connections);
2082+
q != ngx_queue_sentinel(&c->server->pending_connections);
2083+
q = ngx_queue_next(q))
2084+
{
2085+
if (q == &c->queue_pending) {
2086+
ngx_queue_remove(q);
2087+
ngx_log_error(NGX_LOG_DEBUG, c->log, 0,
2088+
"http_auth_ldap: ngx_http_auth_ldap_reconnect_handler: Connection removed from pending queue");
2089+
break;
2090+
}
2091+
}
20432092
ngx_http_auth_ldap_connect(c);
20442093
}
20452094

@@ -2216,6 +2265,7 @@ ngx_http_auth_ldap_init_connections(ngx_cycle_t *cycle)
22162265
server = &((ngx_http_auth_ldap_server_t *) halmcf->servers->elts)[i];
22172266
ngx_queue_init(&server->free_connections);
22182267
ngx_queue_init(&server->waiting_requests);
2268+
ngx_queue_init(&server->pending_connections);
22192269
if (server->connections <= 1) {
22202270
server->connections = 1;
22212271
}
@@ -2272,7 +2322,7 @@ ngx_http_auth_ldap_set_realm(ngx_http_request_t *r, ngx_str_t *realm)
22722322
}
22732323

22742324
r->headers_out.www_authenticate->hash = 1;
2275-
#if (nginx_version >= 102300)
2325+
#if (nginx_version >= 1023000)
22762326
r->headers_out.www_authenticate->next = NULL;
22772327
#endif
22782328
r->headers_out.www_authenticate->key.len = sizeof("WWW-Authenticate") - 1;

0 commit comments

Comments
 (0)