config.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. package config
  2. import (
  3. "errors"
  4. "github.com/cnlh/nps/lib/common"
  5. "github.com/cnlh/nps/lib/file"
  6. "regexp"
  7. "strings"
  8. )
  9. type CommonConfig struct {
  10. Server string
  11. VKey string
  12. Tp string //bridgeType kcp or tcp
  13. AutoReconnection bool
  14. Cnf *file.Config
  15. ProxyUrl string
  16. Client *file.Client
  17. }
  18. type LocalServer struct {
  19. Port int
  20. Password string
  21. }
  22. type Config struct {
  23. content string
  24. title []string
  25. CommonConfig *CommonConfig
  26. Hosts []*file.Host
  27. Tasks []*file.Tunnel
  28. LocalServer []*LocalServer
  29. }
  30. func NewConfig(path string) (c *Config, err error) {
  31. c = new(Config)
  32. var b []byte
  33. if b, err = common.ReadAllFromFile(path); err != nil {
  34. return
  35. } else {
  36. c.content = string(b)
  37. if c.title, err = getAllTitle(c.content); err != nil {
  38. return
  39. }
  40. var nowIndex int
  41. var nextIndex int
  42. var nowContent string
  43. for i := 0; i < len(c.title); i++ {
  44. nowIndex = strings.Index(c.content, c.title[i]) + len(c.title[i])
  45. if i < len(c.title)-1 {
  46. nextIndex = strings.Index(c.content, c.title[i+1])
  47. } else {
  48. nextIndex = len(c.content)
  49. }
  50. nowContent = c.content[nowIndex:nextIndex]
  51. if strings.Index(getTitleContent(c.title[i]), "secret") == 0 {
  52. c.LocalServer = append(c.LocalServer, delLocalService(nowContent))
  53. continue
  54. }
  55. switch c.title[i] {
  56. case "[common]":
  57. c.CommonConfig = dealCommon(nowContent)
  58. default:
  59. if strings.Index(nowContent, "host") > -1 {
  60. h := dealHost(nowContent)
  61. h.Remark = getTitleContent(c.title[i])
  62. c.Hosts = append(c.Hosts, h)
  63. } else {
  64. t := dealTunnel(nowContent)
  65. t.Remark = getTitleContent(c.title[i])
  66. c.Tasks = append(c.Tasks, t)
  67. }
  68. }
  69. }
  70. }
  71. return
  72. }
  73. func getTitleContent(s string) string {
  74. re, _ := regexp.Compile(`[\[\]]`)
  75. return re.ReplaceAllString(s, "")
  76. }
  77. func dealCommon(s string) *CommonConfig {
  78. c := &CommonConfig{}
  79. c.Cnf = new(file.Config)
  80. c.Client = file.NewClient("", true, true)
  81. for _, v := range strings.Split(s, "\n") {
  82. item := strings.Split(v, "=")
  83. if len(item) == 0 {
  84. continue
  85. } else if len(item) == 1 {
  86. item = append(item, "")
  87. }
  88. switch item[0] {
  89. case "server":
  90. c.Server = item[1]
  91. case "vkey":
  92. c.VKey = item[1]
  93. case "tp":
  94. c.Tp = item[1]
  95. case "auto_reconnection":
  96. c.AutoReconnection = common.GetBoolByStr(item[1])
  97. case "username":
  98. c.Cnf.U = item[1]
  99. case "password":
  100. c.Cnf.P = item[1]
  101. case "compress":
  102. c.Cnf.Compress = item[1]
  103. case "crypt":
  104. c.Cnf.Crypt = common.GetBoolByStr(item[1])
  105. case "proxy_socks5_url":
  106. c.ProxyUrl = item[1]
  107. case "rate_limit":
  108. c.Client.RateLimit = common.GetIntNoErrByStr(item[1])
  109. case "flow_limit":
  110. c.Client.Flow.FlowLimit = int64(common.GetIntNoErrByStr(item[1]))
  111. case "max_conn":
  112. c.Client.MaxConn = common.GetIntNoErrByStr(item[1])
  113. case "remark":
  114. c.Client.Remark = item[1]
  115. }
  116. }
  117. return c
  118. }
  119. func dealHost(s string) *file.Host {
  120. h := &file.Host{}
  121. var headerChange string
  122. for _, v := range strings.Split(s, "\n") {
  123. item := strings.Split(v, "=")
  124. if len(item) == 0 {
  125. continue
  126. } else if len(item) == 1 {
  127. item = append(item, "")
  128. }
  129. switch item[0] {
  130. case "host":
  131. h.Host = item[1]
  132. case "target":
  133. h.Target = strings.Replace(item[1], ",", "\n", -1)
  134. case "host_change":
  135. h.HostChange = item[1]
  136. case "location":
  137. h.Location = item[1]
  138. default:
  139. if strings.Contains(item[0], "header") {
  140. headerChange += strings.Replace(item[0], "header_", "", -1) + ":" + item[1] + "\n"
  141. }
  142. h.HeaderChange = headerChange
  143. }
  144. }
  145. return h
  146. }
  147. func dealTunnel(s string) *file.Tunnel {
  148. t := &file.Tunnel{}
  149. for _, v := range strings.Split(s, "\n") {
  150. item := strings.Split(v, "=")
  151. if len(item) == 0 {
  152. continue
  153. } else if len(item) == 1 {
  154. item = append(item, "")
  155. }
  156. switch item[0] {
  157. case "port":
  158. t.Ports = item[1]
  159. case "mode":
  160. t.Mode = item[1]
  161. case "target":
  162. t.Target = item[1]
  163. case "targetAddr":
  164. t.TargetAddr = item[1]
  165. case "password":
  166. t.Password = item[1]
  167. }
  168. }
  169. return t
  170. }
  171. func delLocalService(s string) *LocalServer {
  172. l := new(LocalServer)
  173. for _, v := range strings.Split(s, "\n") {
  174. item := strings.Split(v, "=")
  175. if len(item) == 0 {
  176. continue
  177. } else if len(item) == 1 {
  178. item = append(item, "")
  179. }
  180. switch item[0] {
  181. case "port":
  182. l.Port = common.GetIntNoErrByStr(item[1])
  183. case "password":
  184. l.Password = item[1]
  185. }
  186. }
  187. return l
  188. }
  189. func getAllTitle(content string) (arr []string, err error) {
  190. var re *regexp.Regexp
  191. re, err = regexp.Compile(`\[.+?\]`)
  192. if err != nil {
  193. return
  194. }
  195. arr = re.FindAllString(content, -1)
  196. m := make(map[string]bool)
  197. for _, v := range arr {
  198. if _, ok := m[v]; ok {
  199. err = errors.New("Item names are not allowed to be duplicated")
  200. return
  201. }
  202. m[v] = true
  203. }
  204. return
  205. }