@@ -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);
238240static ngx_int_t ngx_http_auth_ldap_init (ngx_conf_t * cf );
239241static ngx_int_t ngx_http_auth_ldap_init_cache (ngx_cycle_t * cycle );
240242static 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 );
241244static void ngx_http_auth_ldap_read_handler (ngx_event_t * rev );
242245static void ngx_http_auth_ldap_connect (ngx_http_auth_ldap_connection_t * c );
243246static 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+
14231458static void
14241459ngx_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