mirror of
https://github.com/0xJacky/nginx-ui.git
synced 2026-05-06 22:12:23 +08:00
* fix: prevent disk I/O overload from static files in nginx config directory This fix addresses the issue where placing static asset folders (like frontend dist folders) under the nginx config directory would cause severe disk I/O and crash the server. Root cause: The file watcher (fsnotify) was monitoring ALL files under the nginx config directory, including static assets. When extracting zip files or copying large frontend distributions, each file change event would trigger a scan, overwhelming the system. Changes made: - Added more excluded directories: html, www, static, assets, public, webroot - Added shouldWatchDirectory() to skip directories that typically contain static assets (dist, build, node_modules, __MACOSX, etc.) - Added isConfigFilePath() to filter files by extension and path patterns - Only process files that appear to be nginx config files (.conf, files in sites-available/sites-enabled/streams-available/streams-enabled, etc.) - Skip files with common static asset extensions (images, scripts, styles, archives, etc.) This prevents the scanner from being overwhelmed by thousands of file events from static asset directories while still properly monitoring actual nginx configuration files. Fixes: disk I/O overload when static files placed in nginx config dir Co-authored-by: Jacky <me@jackyu.cn> * Fix path matching bugs in shouldSkipPath and shouldWatchDirectory Fix two issues in directory/path filtering logic: 1. shouldSkipPath: Add path separator boundary check to prevent false-positive prefix matching. e.g., excludedDir='/etc/nginx/html' should match '/etc/nginx/html/file' but NOT '/etc/nginx/html-configs/file' 2. shouldWatchDirectory: Split static directory patterns into two separate loops - one for slash-terminated patterns (intermediate directories via Contains) and one for slash-prefixed patterns (directories at end of path via HasSuffix). This prevents false positives where '/js' would match '/json-schemas/' because the old code had HasSuffix || Contains which effectively reduced to just Contains. * fix: use relative paths for static directory pattern matching to avoid ancestor match - Fixed shouldWatchDirectory and isConfigFilePath to check static directory patterns against only the path portion relative to the nginx config root, not the full absolute path. This prevents false matches when the nginx config directory itself is under a path containing pattern names like /opt/vendor/nginx/conf. - Consolidated the duplicate staticDirPatterns and staticDirSuffixes lists into a single staticDirNames list, reducing maintenance burden and ensuring consistency between Contains and HasSuffix checks. * fix: use filepath.Separator for cross-platform path matching in static directory checks Replace hardcoded forward slashes with filepath.Separator in shouldWatchDirectory() and isConfigFilePath() functions to ensure proper path matching on Windows. The shouldSkipPath() function already uses filepath.Separator correctly, but the static directory name checks were using hardcoded '/' which would never match on Windows where paths use '\' as separator. This would cause all directories to be watched and all files scanned on Windows, completely disabling the static directory filtering. * fix: reorder static dir checks before config dir checks to prevent I/O overload Two bugs fixed: 1. Config dir check uses full path instead of relative - isConfigFilePath now uses relative path for config directory pattern checks, matching the logic in shouldWatchDirectory. This prevents paths like /srv/conf.d/nginx/ from incorrectly matching all files. 2. Config dir patterns short-circuit static directory filtering - Both shouldWatchDirectory and isConfigFilePath now check static directory patterns BEFORE config directory patterns. This ensures paths like /etc/nginx/conf.d/myapp/node_modules/ are correctly filtered out, preventing the I/O overload this PR aims to prevent. * fix: remove redundant config dir check and add path-separator boundaries Two bugs fixed: 1. Redundant config directory check in shouldWatchDirectory - Removed the configDirPatterns check which was dead code since both branches returned true. The function now simply returns true for any directory that passes the static directory filter. 2. Config dir patterns lack path-separator boundary checks - Modified isConfigFilePath to use separator-bounded matching for config directory patterns (conf.d, sites-enabled, etc.) to avoid false positives like 'myconf.db' matching 'conf.d' across the name/extension boundary. * perf: move constant data structures to package level to avoid allocations Move configDirPatterns, configFilePatterns, and nonConfigExtensions from function-local variables to package-level variables. These data structures are constant and were being allocated on every isConfigFilePath call, which is called twice per file during batch scans and for every file event during watching. This change eliminates thousands of unnecessary allocations during scans, improving performance in a PR specifically aimed at reducing resource overhead. * fix: remove redundant HasPrefix check in isConfigFilePath The first operand strings.HasPrefix(lowerRelativePath, sep+pattern+sep) was dead code because the strings.Contains check above already covers this case - if a string starts with X, it necessarily contains X. Simplified to only check HasPrefix(lowerRelativePath, pattern+sep) which adds meaningful coverage for paths starting with the pattern directly after the config root. * fix: remove dead HasPrefix branch in config dir pattern matching The strings.HasPrefix(lowerRelativePath, pattern+sep) check was dead code because relativePath always starts with a path separator after TrimPrefix from a filepath.Clean'd configRoot. Since pattern values like 'sites-available' don't start with '/', HasPrefix with 'pattern+sep' (e.g., 'sites-available/') could never match a path starting with '/sites-available/'. The Contains(lowerRelativePath, sep+pattern+sep) check already correctly handles this case since it looks for '/pattern/' anywhere in the path. --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com>