11package nginx
22
33import (
4+ "os"
45 "path/filepath"
5- "regexp"
66 "runtime"
77 "strings"
88
@@ -34,16 +34,62 @@ func resolvePath(path string) string {
3434 return path
3535}
3636
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+
3784// GetPrefix returns the prefix of the nginx executable
3885func GetPrefix () string {
3986 if nginxPrefix != "" {
4087 return nginxPrefix
4188 }
4289
4390 out := getNginxV ()
44- r , _ := regexp .Compile (`--prefix=(\S+)` )
45- match := r .FindStringSubmatch (out )
46- if len (match ) < 1 {
91+ prefix := extractConfigureArg (out , "--prefix" )
92+ if prefix == "" {
4793 logger .Debug ("nginx.GetPrefix len(match) < 1" )
4894 if runtime .GOOS == "windows" {
4995 nginxPrefix = GetNginxExeDir ()
@@ -53,21 +99,29 @@ func GetPrefix() string {
5399 return nginxPrefix
54100 }
55101
56- nginxPrefix = resolvePath (match [ 1 ] )
102+ nginxPrefix = resolvePath (prefix )
57103 return nginxPrefix
58104}
59105
60- // GetConfPath returns the path of the nginx configuration file
106+ // GetConfPath returns the nginx configuration directory (e.g. "/etc/nginx").
107+ // It tries to derive it from `nginx -V --conf-path=...`.
108+ // If parsing fails, it falls back to a reasonable default instead of returning "".
61109func GetConfPath (dir ... string ) (confPath string ) {
62110 if settings .NginxSettings .ConfigDir == "" {
63111 out := getNginxV ()
64- r , _ := regexp .Compile ("--conf-path=(.*)/(.*.conf)" )
65- match := r .FindStringSubmatch (out )
66- if len (match ) < 1 {
67- logger .Error ("nginx.GetConfPath len(match) < 1" )
68- return ""
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 )
69124 }
70- confPath = match [1 ]
71125 } else {
72126 confPath = settings .NginxSettings .ConfigDir
73127 }
@@ -81,35 +135,59 @@ func GetConfPath(dir ...string) (confPath string) {
81135 return joined
82136}
83137
84- // GetConfEntryPath returns the path of the nginx configuration file
138+ // GetConfEntryPath returns the absolute path to the main nginx.conf.
139+ // It prefers the value from `nginx -V --conf-path=...`.
140+ // If that can't be parsed, it falls back to "<confDir>/nginx.conf".
85141func GetConfEntryPath () (path string ) {
86142 if settings .NginxSettings .ConfigPath == "" {
87143 out := getNginxV ()
88- r , _ := regexp .Compile ("--conf-path=(.*.conf)" )
89- match := r .FindStringSubmatch (out )
90- if len (match ) < 1 {
91- logger .Error ("nginx.GetConfEntryPath len(match) < 1" )
92- return ""
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+ }
93155 }
94- path = match [1 ]
95156 } else {
96157 path = settings .NginxSettings .ConfigPath
97158 }
98159
99160 return resolvePath (path )
100161}
101162
102- // GetPIDPath returns the path of the nginx PID file
163+ // GetPIDPath returns the nginx master process PID file path.
164+ // We try to read it from `nginx -V --pid-path=...`.
165+ // If that fails (which often happens in container images), we probe common
166+ // locations like /run/nginx.pid and /var/run/nginx.pid instead of just failing.
103167func GetPIDPath () (path string ) {
104168 if settings .NginxSettings .PIDPath == "" {
105169 out := getNginxV ()
106- r , _ := regexp .Compile ("--pid-path=(.*.pid)" )
107- match := r .FindStringSubmatch (out )
108- if len (match ) < 1 {
109- logger .Error ("pid path not found in nginx -V output" )
110- return ""
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+ }
111190 }
112- path = match [1 ]
113191 } else {
114192 path = settings .NginxSettings .PIDPath
115193 }
@@ -128,10 +206,8 @@ func GetAccessLogPath() (path string) {
128206
129207 if path == "" {
130208 out := getNginxV ()
131- r , _ := regexp .Compile (`--http-log-path=(\S+)` )
132- match := r .FindStringSubmatch (out )
133- if len (match ) > 1 {
134- path = match [1 ]
209+ path = extractConfigureArg (out , "--http-log-path" )
210+ if path != "" {
135211 resolvedPath := resolvePath (path )
136212
137213 // Check if the matched path exists but is not a regular file
@@ -159,10 +235,8 @@ func GetErrorLogPath() string {
159235
160236 if path == "" {
161237 out := getNginxV ()
162- r , _ := regexp .Compile (`--error-log-path=(\S+)` )
163- match := r .FindStringSubmatch (out )
164- if len (match ) > 1 {
165- path = match [1 ]
238+ path = extractConfigureArg (out , "--error-log-path" )
239+ if path != "" {
166240 resolvedPath := resolvePath (path )
167241
168242 // Check if the matched path exists but is not a regular file
@@ -189,16 +263,8 @@ func GetModulesPath() string {
189263 // First try to get from nginx -V output
190264 out := getNginxV ()
191265 if out != "" {
192- // Look for --modules-path in the output
193- if strings .Contains (out , "--modules-path=" ) {
194- parts := strings .Split (out , "--modules-path=" )
195- if len (parts ) > 1 {
196- // Extract the path
197- path := strings .Split (parts [1 ], " " )[0 ]
198- // Remove quotes if present
199- path = strings .Trim (path , "\" " )
200- return resolvePath (path )
201- }
266+ if path := extractConfigureArg (out , "--modules-path" ); path != "" {
267+ return resolvePath (path )
202268 }
203269 }
204270
0 commit comments