Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 92 additions & 51 deletions internal/nginx/resolve_path.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package nginx

import (
"os"
"path/filepath"
"regexp"
"runtime"
Expand Down Expand Up @@ -57,64 +58,104 @@ func GetPrefix() string {
return nginxPrefix
}

// GetConfPath returns the path of the nginx configuration file
// GetConfPath returns the nginx configuration directory (e.g. "/etc/nginx").
// It tries to derive it from `nginx -V --conf-path=...`.
// If parsing fails, it falls back to a reasonable default instead of returning "".
func GetConfPath(dir ...string) (confPath string) {
if settings.NginxSettings.ConfigDir == "" {
out := getNginxV()
r, _ := regexp.Compile("--conf-path=(.*)/(.*.conf)")
match := r.FindStringSubmatch(out)
if len(match) < 1 {
logger.Error("nginx.GetConfPath len(match) < 1")
return ""
}
confPath = match[1]
} else {
confPath = settings.NginxSettings.ConfigDir
}

confPath = resolvePath(confPath)

joined := filepath.Clean(filepath.Join(confPath, filepath.Join(dir...)))
if !helper.IsUnderDirectory(joined, confPath) {
return confPath
}
return joined
if settings.NginxSettings.ConfigDir == "" {
out := getNginxV()
r, _ := regexp.Compile(`--conf-path=([^\s]+)`)
match := r.FindStringSubmatch(out)

Copy link

Copilot AI Oct 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mixed indentation detected: tabs and spaces are inconsistent. Line 69 uses tabs while the surrounding lines (65-68, 70-81) use spaces for indentation. This should be standardized to match the project's indentation style (appears to be tabs based on other parts of the file).

Suggested change

Copilot uses AI. Check for mistakes.
if len(match) > 1 {
fullConf := match[1]
confPath = filepath.Dir(fullConf)
} else {
if runtime.GOOS == "windows" {
confPath = GetPrefix()
} else {
confPath = "/etc/nginx"
}

Copy link

Copilot AI Oct 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mixed indentation detected: line 79 uses tabs while the surrounding lines use spaces. This should be standardized to match the project's indentation style.

Suggested change

Copilot uses AI. Check for mistakes.
logger.Debug("nginx.GetConfPath fallback used", "base", confPath)
}
} else {
confPath = settings.NginxSettings.ConfigDir
}

confPath = resolvePath(confPath)

joined := filepath.Clean(filepath.Join(confPath, filepath.Join(dir...)))
if !helper.IsUnderDirectory(joined, confPath) {
return confPath
}
return joined
}

// GetConfEntryPath returns the path of the nginx configuration file
// GetConfEntryPath returns the absolute path to the main nginx.conf.
// It prefers the value from `nginx -V --conf-path=...`.
// If that can't be parsed, it falls back to "<confDir>/nginx.conf".
func GetConfEntryPath() (path string) {
if settings.NginxSettings.ConfigPath == "" {
out := getNginxV()
r, _ := regexp.Compile("--conf-path=(.*.conf)")
match := r.FindStringSubmatch(out)
if len(match) < 1 {
logger.Error("nginx.GetConfEntryPath len(match) < 1")
return ""
}
path = match[1]
} else {
path = settings.NginxSettings.ConfigPath
}

return resolvePath(path)
if settings.NginxSettings.ConfigPath == "" {
out := getNginxV()
r, _ := regexp.Compile(`--conf-path=([^\s]+)`)
match := r.FindStringSubmatch(out)

if len(match) > 1 {
path = match[1]
} else {
baseDir := GetConfPath()

Copy link

Copilot AI Oct 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mixed indentation detected: line 108 uses tabs while the surrounding lines use spaces. This should be standardized to match the project's indentation style.

Suggested change

Copilot uses AI. Check for mistakes.
if baseDir != "" {
Comment on lines +107 to +109
Copy link

Copilot AI Oct 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential infinite recursion: GetConfEntryPath calls GetConfPath() as a fallback (line 107), which could lead to circular dependency issues if GetConfPath ever needs to call GetConfEntryPath. While this may not happen in the current code, consider passing a flag or using a different approach to avoid this pattern.

Copilot uses AI. Check for mistakes.
path = filepath.Join(baseDir, "nginx.conf")
} else {
logger.Error("nginx.GetConfEntryPath: cannot determine nginx.conf path")
path = ""
}
}
} else {
path = settings.NginxSettings.ConfigPath
}

return resolvePath(path)
}

// GetPIDPath returns the path of the nginx PID file
// GetPIDPath returns the nginx master process PID file path.
// We try to read it from `nginx -V --pid-path=...`.
// If that fails (which often happens in container images), we probe common
// locations like /run/nginx.pid and /var/run/nginx.pid instead of just failing.
func GetPIDPath() (path string) {
if settings.NginxSettings.PIDPath == "" {
out := getNginxV()
r, _ := regexp.Compile("--pid-path=(.*.pid)")
match := r.FindStringSubmatch(out)
if len(match) < 1 {
logger.Error("pid path not found in nginx -V output")
return ""
}
path = match[1]
} else {
path = settings.NginxSettings.PIDPath
}

return resolvePath(path)
if settings.NginxSettings.PIDPath == "" {
out := getNginxV()
r, _ := regexp.Compile(`--pid-path=([^\s]+)`)
match := r.FindStringSubmatch(out)

if len(match) > 1 {
path = match[1]
} else {
candidates := []string{
"/var/run/nginx.pid",
"/run/nginx.pid",
Comment on lines +136 to +138
Copy link

Copilot AI Oct 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hardcoded candidate paths for PID files don't include Windows-specific locations. Consider adding Windows-specific candidates (e.g., relative to GetPrefix() or GetNginxExeDir()) or conditionally defining candidates based on runtime.GOOS to ensure cross-platform compatibility.

Suggested change
candidates := []string{
"/var/run/nginx.pid",
"/run/nginx.pid",
var candidates []string
if runtime.GOOS == "windows" {
exeDir := GetNginxExeDir()
prefix := GetPrefix()
candidates = []string{
filepath.Join(exeDir, "nginx.pid"),
filepath.Join(exeDir, "logs", "nginx.pid"),
filepath.Join(prefix, "nginx.pid"),
filepath.Join(prefix, "logs", "nginx.pid"),
}
} else {
candidates = []string{
"/var/run/nginx.pid",
"/run/nginx.pid",
}

Copilot uses AI. Check for mistakes.
}

for _, c := range candidates {
if _, err := os.Stat(c); err == nil {
logger.Debug("GetPIDPath fallback hit", "path", c)
path = c
break
}
}

if path == "" {
logger.Error("GetPIDPath: could not determine PID path")
return ""
}
}
} else {
path = settings.NginxSettings.PIDPath
}

return resolvePath(path)
}

// GetSbinPath returns the path of the nginx executable
Expand Down
Loading