resolve_path.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. package nginx
  2. import (
  3. "path/filepath"
  4. "regexp"
  5. "runtime"
  6. "strings"
  7. "github.com/0xJacky/Nginx-UI/internal/helper"
  8. "github.com/0xJacky/Nginx-UI/settings"
  9. "github.com/uozi-tech/cosy/logger"
  10. )
  11. var (
  12. nginxPrefix string
  13. )
  14. // Returns the directory containing the nginx executable
  15. func GetNginxExeDir() string {
  16. return filepath.Dir(getNginxSbinPath())
  17. }
  18. // Resolves relative paths by joining them with the nginx executable directory on Windows
  19. func resolvePath(path string) string {
  20. if path == "" {
  21. return ""
  22. }
  23. // Handle relative paths on Windows
  24. if runtime.GOOS == "windows" && !filepath.IsAbs(path) {
  25. return filepath.Join(GetNginxExeDir(), path)
  26. }
  27. return path
  28. }
  29. // GetPrefix returns the prefix of the nginx executable
  30. func GetPrefix() string {
  31. if nginxPrefix != "" {
  32. return nginxPrefix
  33. }
  34. out := getNginxV()
  35. r, _ := regexp.Compile(`--prefix=(\S+)`)
  36. match := r.FindStringSubmatch(out)
  37. if len(match) < 1 {
  38. logger.Error("nginx.GetPrefix len(match) < 1")
  39. nginxPrefix = "/usr/local/nginx"
  40. return nginxPrefix
  41. }
  42. nginxPrefix = resolvePath(match[1])
  43. return nginxPrefix
  44. }
  45. // GetConfPath returns the path of the nginx configuration file
  46. func GetConfPath(dir ...string) (confPath string) {
  47. if settings.NginxSettings.ConfigDir == "" {
  48. out := getNginxV()
  49. r, _ := regexp.Compile("--conf-path=(.*)/(.*.conf)")
  50. match := r.FindStringSubmatch(out)
  51. if len(match) < 1 {
  52. logger.Error("nginx.GetConfPath len(match) < 1")
  53. return ""
  54. }
  55. confPath = match[1]
  56. } else {
  57. confPath = settings.NginxSettings.ConfigDir
  58. }
  59. confPath = resolvePath(confPath)
  60. joined := filepath.Clean(filepath.Join(confPath, filepath.Join(dir...)))
  61. if !helper.IsUnderDirectory(joined, confPath) {
  62. return confPath
  63. }
  64. return joined
  65. }
  66. // GetConfEntryPath returns the path of the nginx configuration file
  67. func GetConfEntryPath() (path string) {
  68. if settings.NginxSettings.ConfigPath == "" {
  69. out := getNginxV()
  70. r, _ := regexp.Compile("--conf-path=(.*.conf)")
  71. match := r.FindStringSubmatch(out)
  72. if len(match) < 1 {
  73. logger.Error("nginx.GetConfEntryPath len(match) < 1")
  74. return ""
  75. }
  76. path = match[1]
  77. } else {
  78. path = settings.NginxSettings.ConfigPath
  79. }
  80. return resolvePath(path)
  81. }
  82. // GetPIDPath returns the path of the nginx PID file
  83. func GetPIDPath() (path string) {
  84. if settings.NginxSettings.PIDPath == "" {
  85. out := getNginxV()
  86. r, _ := regexp.Compile("--pid-path=(.*.pid)")
  87. match := r.FindStringSubmatch(out)
  88. if len(match) < 1 {
  89. logger.Error("pid path not found in nginx -V output")
  90. return ""
  91. }
  92. path = match[1]
  93. } else {
  94. path = settings.NginxSettings.PIDPath
  95. }
  96. return resolvePath(path)
  97. }
  98. // GetSbinPath returns the path of the nginx executable
  99. func GetSbinPath() (path string) {
  100. return getNginxSbinPath()
  101. }
  102. // GetAccessLogPath returns the path of the nginx access log file
  103. func GetAccessLogPath() (path string) {
  104. path = settings.NginxSettings.AccessLogPath
  105. if path == "" {
  106. out := getNginxV()
  107. r, _ := regexp.Compile(`--http-log-path=(\S+)`)
  108. match := r.FindStringSubmatch(out)
  109. if len(match) > 1 {
  110. path = match[1]
  111. resolvedPath := resolvePath(path)
  112. // Check if the matched path exists but is not a regular file
  113. if !isValidRegularFile(resolvedPath) {
  114. logger.Debug("access log path from nginx -V exists but is not a regular file, try to get from nginx -T output", "path", resolvedPath)
  115. fallbackPath := getAccessLogPathFromNginxT()
  116. if fallbackPath != "" {
  117. path = fallbackPath
  118. return path // Already resolved in getAccessLogPathFromNginxT
  119. }
  120. }
  121. }
  122. if path == "" {
  123. logger.Debug("access log path not found in nginx -V output, try to get from nginx -T output")
  124. path = getAccessLogPathFromNginxT()
  125. }
  126. }
  127. return resolvePath(path)
  128. }
  129. // GetErrorLogPath returns the path of the nginx error log file
  130. func GetErrorLogPath() string {
  131. path := settings.NginxSettings.ErrorLogPath
  132. if path == "" {
  133. out := getNginxV()
  134. r, _ := regexp.Compile(`--error-log-path=(\S+)`)
  135. match := r.FindStringSubmatch(out)
  136. if len(match) > 1 {
  137. path = match[1]
  138. resolvedPath := resolvePath(path)
  139. // Check if the matched path exists but is not a regular file
  140. if !isValidRegularFile(resolvedPath) {
  141. logger.Debug("error log path from nginx -V exists but is not a regular file, try to get from nginx -T output", "path", resolvedPath)
  142. fallbackPath := getErrorLogPathFromNginxT()
  143. if fallbackPath != "" {
  144. path = fallbackPath
  145. return path // Already resolved in getErrorLogPathFromNginxT
  146. }
  147. }
  148. }
  149. if path == "" {
  150. logger.Debug("error log path not found in nginx -V output, try to get from nginx -T output")
  151. path = getErrorLogPathFromNginxT()
  152. }
  153. }
  154. return resolvePath(path)
  155. }
  156. // GetModulesPath returns the path of the nginx modules
  157. func GetModulesPath() string {
  158. // First try to get from nginx -V output
  159. out := getNginxV()
  160. if out != "" {
  161. // Look for --modules-path in the output
  162. if strings.Contains(out, "--modules-path=") {
  163. parts := strings.Split(out, "--modules-path=")
  164. if len(parts) > 1 {
  165. // Extract the path
  166. path := strings.Split(parts[1], " ")[0]
  167. // Remove quotes if present
  168. path = strings.Trim(path, "\"")
  169. return resolvePath(path)
  170. }
  171. }
  172. }
  173. // Default path if not found
  174. if runtime.GOOS == "windows" {
  175. return resolvePath("modules")
  176. }
  177. return resolvePath("/usr/lib/nginx/modules")
  178. }