parse.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. package nginx
  2. import (
  3. "strings"
  4. "github.com/pkg/errors"
  5. "github.com/tufanbarisyildirim/gonginx/config"
  6. "github.com/tufanbarisyildirim/gonginx/dumper"
  7. "github.com/tufanbarisyildirim/gonginx/parser"
  8. )
  9. const (
  10. Server = "server"
  11. Location = "location"
  12. Upstream = "upstream"
  13. )
  14. func (s *NgxServer) ParseServer(directive config.IDirective) {
  15. s.parseServer(directive)
  16. }
  17. func (s *NgxServer) parseServer(directive config.IDirective) {
  18. if directive.GetBlock() == nil {
  19. return
  20. }
  21. for _, d := range directive.GetBlock().GetDirectives() {
  22. switch d.GetName() {
  23. case Location:
  24. var params []string
  25. for _, param := range d.GetParameters() {
  26. params = append(params, param.Value)
  27. }
  28. location := &NgxLocation{
  29. Path: strings.Join(params, " "),
  30. Comments: buildComment(d.GetComment()),
  31. }
  32. location.parseLocation(d, 0)
  33. s.Locations = append(s.Locations, location)
  34. default:
  35. dir := &NgxDirective{
  36. Directive: d.GetName(),
  37. Comments: buildComment(d.GetComment()),
  38. }
  39. dir.parseDirective(d, 0)
  40. s.Directives = append(s.Directives, dir)
  41. }
  42. }
  43. }
  44. func (l *NgxLocation) ParseLocation(directive config.IDirective, deep int) {
  45. l.parseLocation(directive, deep)
  46. }
  47. func (l *NgxLocation) parseLocation(directive config.IDirective, deep int) {
  48. if directive.GetBlock() == nil {
  49. return
  50. }
  51. if directive.GetBlock().GetCodeBlock() != "" {
  52. // deep copy
  53. style := *dumper.IndentedStyle
  54. style.StartIndent = deep * style.Indent
  55. l.Content += dumper.DumpLuaBlock(directive.GetBlock(), &style) + "\n"
  56. return
  57. }
  58. for _, location := range directive.GetBlock().GetDirectives() {
  59. if len(location.GetComment()) > 0 {
  60. for _, c := range location.GetComment() {
  61. l.Content += strings.Repeat("\t", deep) + c + "\n"
  62. }
  63. }
  64. var params []string
  65. for _, param := range location.GetParameters() {
  66. params = append(params, param.Value)
  67. }
  68. l.Content += strings.Repeat("\t", deep) + location.GetName() + " " + strings.Join(params, " ")
  69. if location.GetBlock() != nil && location.GetBlock().GetDirectives() != nil {
  70. l.Content += " { \n"
  71. l.parseLocation(location, deep+1)
  72. l.Content += strings.Repeat("\t", deep) + "} \n"
  73. } else {
  74. l.Content += ";\n"
  75. }
  76. }
  77. }
  78. func (d *NgxDirective) ParseDirective(directive config.IDirective, deep int) {
  79. d.parseDirective(directive, deep)
  80. }
  81. func (d *NgxDirective) parseDirective(directive config.IDirective, deep int) {
  82. if directive.GetBlock() != nil {
  83. d.Params += directive.GetName() + " "
  84. d.Directive = ""
  85. }
  86. var params []string
  87. for _, param := range directive.GetParameters() {
  88. params = append(params, param.Value)
  89. }
  90. d.Params += strings.Join(params, " ")
  91. if directive.GetBlock() != nil {
  92. d.Params += " {\n"
  93. for _, location := range directive.GetBlock().GetDirectives() {
  94. if len(location.GetComment()) > 0 {
  95. for _, c := range location.GetComment() {
  96. d.Params += strings.Repeat("\t", deep) + c + "\n"
  97. }
  98. }
  99. var params []string
  100. for _, param := range location.GetParameters() {
  101. params = append(params, param.Value)
  102. }
  103. d.Params += strings.Repeat("\t", deep+1) + location.GetName() + " " +
  104. strings.Join(params, " ") + ";\n"
  105. // d.parseDirective(location, deep+1)
  106. if location.GetBlock() == nil {
  107. continue
  108. }
  109. for _, v := range location.GetBlock().GetDirectives() {
  110. d.parseDirective(v, deep+1)
  111. }
  112. }
  113. d.Params += "}\n"
  114. return
  115. }
  116. }
  117. func (u *NgxUpstream) parseUpstream(directive config.IDirective) {
  118. if directive.GetBlock() == nil {
  119. return
  120. }
  121. for _, us := range directive.GetBlock().GetDirectives() {
  122. var params []string
  123. for _, param := range us.GetParameters() {
  124. params = append(params, param.Value)
  125. }
  126. d := &NgxDirective{
  127. Directive: us.GetName(),
  128. Params: strings.Join(params, " "),
  129. Comments: buildComment(us.GetComment()),
  130. }
  131. u.Directives = append(u.Directives, d)
  132. }
  133. }
  134. func (c *NgxConfig) parseCustom(directive config.IDirective) {
  135. if directive.GetBlock() == nil {
  136. // fix #699
  137. c.Custom += ";\n"
  138. return
  139. }
  140. c.Custom += "\n{\n"
  141. for _, v := range directive.GetBlock().GetDirectives() {
  142. var params []string
  143. for _, param := range v.GetParameters() {
  144. params = append(params, param.Value)
  145. }
  146. inlineComment := ""
  147. for _, inline := range v.GetInlineComment() {
  148. inlineComment += inline.Value + " "
  149. }
  150. c.Custom += strings.Join(v.GetComment(), "\n") + "\n" +
  151. v.GetName() + " " + strings.Join(params, " ") + ";" + inlineComment + "\n"
  152. }
  153. c.Custom += "}\n"
  154. }
  155. func buildComment(c []string) string {
  156. return strings.ReplaceAll(strings.Join(c, "\n"), "#", "")
  157. }
  158. func parse(block config.IBlock, ngxConfig *NgxConfig) (err error) {
  159. if block == nil {
  160. err = ErrBlockIsNil
  161. return
  162. }
  163. for _, v := range block.GetDirectives() {
  164. comments := buildComment(v.GetComment())
  165. switch v.GetName() {
  166. case Server:
  167. server := NewNgxServer()
  168. server.Comments = comments
  169. server.parseServer(v)
  170. ngxConfig.Servers = append(ngxConfig.Servers, server)
  171. case Upstream:
  172. var params []string
  173. for _, param := range v.GetParameters() {
  174. params = append(params, param.Value)
  175. }
  176. upstream := &NgxUpstream{
  177. Name: strings.Join(params, " "),
  178. }
  179. upstream.Comments = comments
  180. upstream.parseUpstream(v)
  181. ngxConfig.Upstreams = append(ngxConfig.Upstreams, upstream)
  182. default:
  183. var params []string
  184. for _, param := range v.GetParameters() {
  185. params = append(params, param.Value)
  186. }
  187. ngxConfig.Custom += strings.Join(v.GetComment(), "\n") + "\n" +
  188. v.GetName() + " " + strings.Join(params, " ")
  189. ngxConfig.parseCustom(v)
  190. }
  191. }
  192. if strings.TrimSpace(ngxConfig.Custom) == "" {
  193. return
  194. }
  195. custom, err := FmtCode(ngxConfig.Custom)
  196. if err != nil {
  197. return
  198. }
  199. ngxConfig.Custom = custom
  200. return
  201. }
  202. func ParseNgxConfigByContent(content string) (ngxConfig *NgxConfig, err error) {
  203. p := parser.NewStringParser(content, parser.WithSkipValidDirectivesErr())
  204. c, err := p.Parse()
  205. if err != nil {
  206. return
  207. }
  208. ngxConfig = NewNgxConfig("")
  209. ngxConfig.c = c
  210. err = parse(c.Block, ngxConfig)
  211. return
  212. }
  213. func ParseNgxConfig(filename string) (ngxConfig *NgxConfig, err error) {
  214. p, err := parser.NewParser(filename, parser.WithSkipValidDirectivesErr())
  215. if err != nil {
  216. return nil, errors.Wrap(err, "error ParseNgxConfig")
  217. }
  218. c, err := p.Parse()
  219. if err != nil {
  220. return
  221. }
  222. ngxConfig = NewNgxConfig(filename)
  223. ngxConfig.c = c
  224. err = parse(c.Block, ngxConfig)
  225. return
  226. }