Skip to content

Commit 48ae7af

Browse files
committed
ngx_cache_purge: fix correctness, safety, and build issues
Fix C89/gnu89 compliance by hoisting all mid-scope variable declarations to the top of their enclosing function scope in the fastcgi, proxy, scgi, and uwsgi purge handlers. Affected variables: deleted (all four handlers), cv_val, i, name, caches (proxy), wctx (two walk callbacks). Fix cache_purge_batch_size being accepted and stored but never consulted. Rewrite process_queue() to loop over queue->batch_size items per call. Returns NGX_AGAIN after a full batch, NGX_OK when the queue empties early. Fix live reload silently discarding changes to batch_size, throttle_ms, and queue_size. On reload init_shm_zone() now acquires queue->mutex and writes the new values into the running queue. max_size is floor-bounded by the current queue depth to prevent the queue appearing full mid-reload. Fix vary_aware variant deletion leaving stale shared-memory metadata. Previously delete_exact_file() called ngx_delete_file() directly, leaving each variant's rbtree node with exists=1 and a non-zero fs_size, causing stale HIT responses and inflated cache->sh->size accounting until restart. Add ngx_cache_purge_invalidate_node() which decodes the 16-byte MD5 cache key from the last 32 hex characters of the file path, performs an O(log n) rbtree lookup, and clears fcn->exists, fcn->fs_size, and sh->size under shpool->mutex before the file is removed. Add a cache pointer to the walk context so the callback can reach the cache object. Lock ordering is preserved throughout: queue_mutex before shpool_mutex. Fix integer overflow in shm_size arithmetic on 32-bit builds. Add NGX_CACHE_PURGE_QUEUE_SIZE_MAX (65535) and reject queue_size=0 and batch_size=0 in init_main_conf; both values make the queue unusable in different ways. Fix data race on queue->size in the enqueue debug log path. The field was read after ngx_shmtx_unlock(). Capture the value into a local variable while the mutex is held and use that snapshot in the log call. Fix queue->size declared as ngx_atomic_t despite always being accessed under queue->mutex. Change to ngx_uint_t and remove the resulting (ngx_uint_t) casts at all usage sites. Fix send_response() body length formula. Remove two redundant aliases (resp_tmpl_len, len) that were always equal to body_len. Replace the opaque "- 2 - 2 - 1" expression with (resp_body_size - 1 - 4) and add a comment explaining each term. Replace the magic constant 6 used as the KEY: header offset in two places with NGX_CACHE_PURGE_KEY_HDR_OFFSET and a comment explaining the layout. Mark all eight response content-type size globals const. Add a NULL guard for cplcf->conf at the top of the access handler before its first dereference. Fix the config script shebang from bash to sh. The file is dot-sourced by nginx's auto/configure; on Debian and Ubuntu /bin/sh is dash. Remove the heredoc that wrote to $NGX_AUTOCONF_ERR; that file is reserved for the nginx build system. Write the status message to stdout instead. Fix non-existent GitHub Actions version pins. All four references were one or two major versions ahead of any released tag and the pipeline failed to resolve them: actions/checkout v5->v4, setup-buildx-action v4->v3, build-push-action v7->v6, upload-artifact v7->v4. Fix cppcheck --std=c89 to --std=c11; nginx's build system uses -std=gnu89 and cppcheck has no gnu89 mode. Add basic.t TEST 15 covering the vary_aware directory walk. The test pre-seeds two fake variant files with the same KEY: line at different shard paths and verifies that a single PURGE request removes both. This code path had no test coverage. Rewrite the background_handler and process_queue block comments which described processing one item per invocation after the batch loop was introduced.
1 parent 4e012c1 commit 48ae7af

3 files changed

Lines changed: 552 additions & 181 deletions

File tree

config

Lines changed: 31 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,22 @@
1-
#!/bin/bash
1+
#!/bin/sh
2+
#
3+
# nginx module build configuration script.
4+
#
5+
# This file is dot-sourced by nginx's auto/configure using POSIX sh. It must
6+
# be written in strict POSIX sh — no bash-specific syntax (arrays, [[ … ]],
7+
# process substitution, etc.). The shebang documents the intended interpreter
8+
# but has no effect on how configure invokes the script.
9+
#
10+
# Convention:
11+
# $NGX_AUTOCONF_ERR is nginx's internal build diagnostic log (objs/autoconf.err).
12+
# Third-party modules must NOT write to it; that file is reserved for the
13+
# nginx build system. User-facing messages go to stdout.
14+
#
215

3-
# nginx module build configuration
4-
# This file tells nginx how to compile the ngx_cache_purge module
5-
6-
# Check which HTTP modules are enabled and set appropriate defines
16+
# ------------------------------------------------------------------
17+
# Propagate upstream protocol availability into the module's #define
18+
# guards so that the C source can use #if (NGX_HTTP_PROXY) etc.
19+
# ------------------------------------------------------------------
720
if [ "$HTTP_PROXY" = "YES" ]; then
821
have=NGX_HTTP_PROXY . auto/have
922
fi
@@ -20,53 +33,33 @@ if [ "$HTTP_UWSGI" = "YES" ]; then
2033
have=NGX_HTTP_UWSGI . auto/have
2134
fi
2235

23-
# Module name and source files
36+
# ------------------------------------------------------------------
37+
# Module identity and sources
38+
# ------------------------------------------------------------------
2439
ngx_addon_name=ngx_http_cache_purge_module
2540
CACHE_PURGE_SRCS="$ngx_addon_dir/ngx_cache_purge_module.c"
2641

27-
# Build configuration for different nginx versions
42+
# ------------------------------------------------------------------
43+
# Register the module with nginx's build system.
44+
#
45+
# nginx >= 1.9.11 exports $ngx_module_link and uses auto/module for
46+
# both static (LINK=ADDON) and dynamic (LINK=DYNAMIC) builds.
47+
# Older versions require manual population of HTTP_MODULES and
48+
# NGX_ADDON_SRCS.
49+
# ------------------------------------------------------------------
2850
if [ -n "$ngx_module_link" ]; then
29-
# Modern nginx (1.9.11+) with dynamic module support
3051
ngx_module_type=HTTP
3152
ngx_module_name="$ngx_addon_name"
3253
ngx_module_srcs="$CACHE_PURGE_SRCS"
33-
34-
# Dependencies - this module requires HTTP cache support
3554
ngx_module_deps=""
36-
37-
# Module libraries (none needed for this module)
3855
ngx_module_libs=""
39-
40-
# Add module to build
4156
. auto/module
4257
else
43-
# Older nginx versions (< 1.9.11) - static linking only
4458
HTTP_MODULES="$HTTP_MODULES $ngx_addon_name"
4559
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $CACHE_PURGE_SRCS"
4660
fi
4761

48-
# Define that this module is available
62+
# Mark the module as present (used by other modules that may depend on it).
4963
have=NGX_CACHE_PURGE_MODULE . auto/have
5064

51-
# Module version information
52-
cat << END >> $NGX_AUTOCONF_ERR
53-
54-
ngx_cache_purge module configured.
55-
56-
Features:
57-
+ Background queue system for async purge processing
58-
+ Memory leak fixes for partial purge operations
59-
+ Configurable throttling and batch processing
60-
+ Enhanced security and error handling
61-
+ Full backwards compatibility
62-
63-
Configuration directives:
64-
+ cache_purge_background_queue on|off
65-
+ cache_purge_queue_size <number>
66-
+ cache_purge_batch_size <number>
67-
+ cache_purge_throttle_ms <milliseconds>
68-
69-
Build with: --add-module=path/to/ngx_cache_purge
70-
or: --add-dynamic-module=path/to/ngx_cache_purge
71-
72-
END
65+
echo " + ngx_cache_purge module added"

0 commit comments

Comments
 (0)