Skip to content

Commit f5df9be

Browse files
committed
enhance: nginx path parsing and add tests #1412, #1414
1 parent 8b565a4 commit f5df9be

File tree

3 files changed

+231
-112
lines changed

3 files changed

+231
-112
lines changed

api/cluster/node.go

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,7 @@ func GetNodeList(c *gin.Context) {
4545
return analytic.GetNode(m)
4646
})
4747

48-
data, ok := core.ListAllData()
49-
if !ok {
50-
return
51-
}
52-
53-
c.JSON(http.StatusOK, model.DataList{
54-
Data: data,
55-
})
48+
core.List()
5649
}
5750

5851
func AddNode(c *gin.Context) {

internal/nginx/resolve_path.go

Lines changed: 129 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package nginx
33
import (
44
"os"
55
"path/filepath"
6-
"regexp"
76
"runtime"
87
"strings"
98

@@ -35,16 +34,62 @@ func resolvePath(path string) string {
3534
return path
3635
}
3736

37+
func extractConfigureArg(out, flag string) string {
38+
if out == "" || flag == "" {
39+
return ""
40+
}
41+
42+
if !strings.HasPrefix(flag, "--") {
43+
flag = "--" + flag
44+
}
45+
46+
needle := flag + "="
47+
idx := strings.Index(out, needle)
48+
if idx == -1 {
49+
return ""
50+
}
51+
52+
start := idx + len(needle)
53+
if start >= len(out) {
54+
return ""
55+
}
56+
57+
value := out[start:]
58+
value = strings.TrimLeft(value, " \t")
59+
if value == "" {
60+
return ""
61+
}
62+
63+
if value[0] == '"' || value[0] == '\'' {
64+
quoteChar := value[0]
65+
rest := value[1:]
66+
closingIdx := strings.IndexByte(rest, quoteChar)
67+
if closingIdx == -1 {
68+
return strings.TrimSpace(rest)
69+
}
70+
return strings.TrimSpace(rest[:closingIdx])
71+
}
72+
73+
cut := len(value)
74+
if idx := strings.Index(value, " --"); idx != -1 && idx < cut {
75+
cut = idx
76+
}
77+
if idx := strings.IndexAny(value, "\r\n"); idx != -1 && idx < cut {
78+
cut = idx
79+
}
80+
81+
return strings.TrimSpace(value[:cut])
82+
}
83+
3884
// GetPrefix returns the prefix of the nginx executable
3985
func GetPrefix() string {
4086
if nginxPrefix != "" {
4187
return nginxPrefix
4288
}
4389

4490
out := getNginxV()
45-
r, _ := regexp.Compile(`--prefix=(\S+)`)
46-
match := r.FindStringSubmatch(out)
47-
if len(match) < 1 {
91+
prefix := extractConfigureArg(out, "--prefix")
92+
if prefix == "" {
4893
logger.Debug("nginx.GetPrefix len(match) < 1")
4994
if runtime.GOOS == "windows" {
5095
nginxPrefix = GetNginxExeDir()
@@ -54,108 +99,100 @@ func GetPrefix() string {
5499
return nginxPrefix
55100
}
56101

57-
nginxPrefix = resolvePath(match[1])
102+
nginxPrefix = resolvePath(prefix)
58103
return nginxPrefix
59104
}
60105

61106
// GetConfPath returns the nginx configuration directory (e.g. "/etc/nginx").
62107
// It tries to derive it from `nginx -V --conf-path=...`.
63108
// If parsing fails, it falls back to a reasonable default instead of returning "".
64109
func GetConfPath(dir ...string) (confPath string) {
65-
if settings.NginxSettings.ConfigDir == "" {
66-
out := getNginxV()
67-
r, _ := regexp.Compile(`--conf-path=([^\s]+)`)
68-
match := r.FindStringSubmatch(out)
69-
70-
if len(match) > 1 {
71-
fullConf := match[1]
72-
confPath = filepath.Dir(fullConf)
73-
} else {
74-
if runtime.GOOS == "windows" {
75-
confPath = GetPrefix()
76-
} else {
77-
confPath = "/etc/nginx"
78-
}
79-
80-
logger.Debug("nginx.GetConfPath fallback used", "base", confPath)
81-
}
82-
} else {
83-
confPath = settings.NginxSettings.ConfigDir
84-
}
85-
86-
confPath = resolvePath(confPath)
87-
88-
joined := filepath.Clean(filepath.Join(confPath, filepath.Join(dir...)))
89-
if !helper.IsUnderDirectory(joined, confPath) {
90-
return confPath
91-
}
92-
return joined
110+
if settings.NginxSettings.ConfigDir == "" {
111+
out := getNginxV()
112+
fullConf := extractConfigureArg(out, "--conf-path")
113+
114+
if fullConf != "" {
115+
confPath = filepath.Dir(fullConf)
116+
} else {
117+
if runtime.GOOS == "windows" {
118+
confPath = GetPrefix()
119+
} else {
120+
confPath = "/etc/nginx"
121+
}
122+
123+
logger.Debug("nginx.GetConfPath fallback used", "base", confPath)
124+
}
125+
} else {
126+
confPath = settings.NginxSettings.ConfigDir
127+
}
128+
129+
confPath = resolvePath(confPath)
130+
131+
joined := filepath.Clean(filepath.Join(confPath, filepath.Join(dir...)))
132+
if !helper.IsUnderDirectory(joined, confPath) {
133+
return confPath
134+
}
135+
return joined
93136
}
94137

95138
// GetConfEntryPath returns the absolute path to the main nginx.conf.
96139
// It prefers the value from `nginx -V --conf-path=...`.
97140
// If that can't be parsed, it falls back to "<confDir>/nginx.conf".
98141
func GetConfEntryPath() (path string) {
99-
if settings.NginxSettings.ConfigPath == "" {
100-
out := getNginxV()
101-
r, _ := regexp.Compile(`--conf-path=([^\s]+)`)
102-
match := r.FindStringSubmatch(out)
103-
104-
if len(match) > 1 {
105-
path = match[1]
106-
} else {
107-
baseDir := GetConfPath()
108-
109-
if baseDir != "" {
110-
path = filepath.Join(baseDir, "nginx.conf")
111-
} else {
112-
logger.Error("nginx.GetConfEntryPath: cannot determine nginx.conf path")
113-
path = ""
114-
}
115-
}
116-
} else {
117-
path = settings.NginxSettings.ConfigPath
118-
}
119-
120-
return resolvePath(path)
142+
if settings.NginxSettings.ConfigPath == "" {
143+
out := getNginxV()
144+
path = extractConfigureArg(out, "--conf-path")
145+
146+
if path == "" {
147+
baseDir := GetConfPath()
148+
149+
if baseDir != "" {
150+
path = filepath.Join(baseDir, "nginx.conf")
151+
} else {
152+
logger.Error("nginx.GetConfEntryPath: cannot determine nginx.conf path")
153+
path = ""
154+
}
155+
}
156+
} else {
157+
path = settings.NginxSettings.ConfigPath
158+
}
159+
160+
return resolvePath(path)
121161
}
122162

123163
// GetPIDPath returns the nginx master process PID file path.
124164
// We try to read it from `nginx -V --pid-path=...`.
125165
// If that fails (which often happens in container images), we probe common
126166
// locations like /run/nginx.pid and /var/run/nginx.pid instead of just failing.
127167
func GetPIDPath() (path string) {
128-
if settings.NginxSettings.PIDPath == "" {
129-
out := getNginxV()
130-
r, _ := regexp.Compile(`--pid-path=([^\s]+)`)
131-
match := r.FindStringSubmatch(out)
132-
133-
if len(match) > 1 {
134-
path = match[1]
135-
} else {
136-
candidates := []string{
137-
"/var/run/nginx.pid",
138-
"/run/nginx.pid",
139-
}
140-
141-
for _, c := range candidates {
142-
if _, err := os.Stat(c); err == nil {
143-
logger.Debug("GetPIDPath fallback hit", "path", c)
144-
path = c
145-
break
146-
}
147-
}
148-
149-
if path == "" {
150-
logger.Error("GetPIDPath: could not determine PID path")
151-
return ""
152-
}
153-
}
154-
} else {
155-
path = settings.NginxSettings.PIDPath
156-
}
157-
158-
return resolvePath(path)
168+
if settings.NginxSettings.PIDPath == "" {
169+
out := getNginxV()
170+
path = extractConfigureArg(out, "--pid-path")
171+
172+
if path == "" {
173+
candidates := []string{
174+
"/var/run/nginx.pid",
175+
"/run/nginx.pid",
176+
}
177+
178+
for _, c := range candidates {
179+
if _, err := os.Stat(c); err == nil {
180+
logger.Debug("GetPIDPath fallback hit", "path", c)
181+
path = c
182+
break
183+
}
184+
}
185+
186+
if path == "" {
187+
logger.Error("GetPIDPath: could not determine PID path")
188+
return ""
189+
}
190+
}
191+
} else {
192+
path = settings.NginxSettings.PIDPath
193+
}
194+
195+
return resolvePath(path)
159196
}
160197

161198
// GetSbinPath returns the path of the nginx executable
@@ -169,10 +206,8 @@ func GetAccessLogPath() (path string) {
169206

170207
if path == "" {
171208
out := getNginxV()
172-
r, _ := regexp.Compile(`--http-log-path=(\S+)`)
173-
match := r.FindStringSubmatch(out)
174-
if len(match) > 1 {
175-
path = match[1]
209+
path = extractConfigureArg(out, "--http-log-path")
210+
if path != "" {
176211
resolvedPath := resolvePath(path)
177212

178213
// Check if the matched path exists but is not a regular file
@@ -200,10 +235,8 @@ func GetErrorLogPath() string {
200235

201236
if path == "" {
202237
out := getNginxV()
203-
r, _ := regexp.Compile(`--error-log-path=(\S+)`)
204-
match := r.FindStringSubmatch(out)
205-
if len(match) > 1 {
206-
path = match[1]
238+
path = extractConfigureArg(out, "--error-log-path")
239+
if path != "" {
207240
resolvedPath := resolvePath(path)
208241

209242
// Check if the matched path exists but is not a regular file
@@ -230,16 +263,8 @@ func GetModulesPath() string {
230263
// First try to get from nginx -V output
231264
out := getNginxV()
232265
if out != "" {
233-
// Look for --modules-path in the output
234-
if strings.Contains(out, "--modules-path=") {
235-
parts := strings.Split(out, "--modules-path=")
236-
if len(parts) > 1 {
237-
// Extract the path
238-
path := strings.Split(parts[1], " ")[0]
239-
// Remove quotes if present
240-
path = strings.Trim(path, "\"")
241-
return resolvePath(path)
242-
}
266+
if path := extractConfigureArg(out, "--modules-path"); path != "" {
267+
return resolvePath(path)
243268
}
244269
}
245270

0 commit comments

Comments
 (0)