parse.go 5.8 KB

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