123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- package nginx
- import (
- "bufio"
- "regexp"
- "strings"
- "unicode"
- )
- func (c *NgxConfig) parseServer(scanner *bufio.Scanner) {
- server := NewNgxServer()
- for scanner.Scan() {
- d := parseDirective(scanner)
- switch d.Directive {
- case Location:
- server.parseLocation(d.Params)
- case CommentStart:
- server.commentQueue.Enqueue(d.Params)
- default:
- server.parseDirective(d)
- }
- }
- // Attach the rest of the comments to the last location
- if len(server.Locations) > 0 {
- server.Locations[len(server.Locations)-1].Comments += server.commentQueue.DequeueAllComments()
- }
- // Attach comments which are over the current server
- server.Comments = c.commentQueue.DequeueAllComments()
- c.Servers = append(c.Servers, server)
- }
- func (c *NgxConfig) parseUpstream(scanner *bufio.Scanner) {
- upstream := &NgxUpstream{}
- for scanner.Scan() {
- d := NgxDirective{}
- text := strings.TrimSpace(scanner.Text())
- // escape empty line or comment line
- if len(text) < 1 || text[0] == '#' {
- return
- }
- sep := len(text) - 1
- for k, v := range text {
- if unicode.IsSpace(v) {
- sep = k
- break
- }
- }
- d.Directive = text[0:sep]
- d.Params = strings.Trim(text[sep:], ";")
- if d.Directive == Server {
- upstream.Directives = append(upstream.Directives, &d)
- } else if upstream.Name == "" {
- upstream.Name = d.Directive
- }
- }
- // attach comments which are over the current upstream
- upstream.Comments = c.commentQueue.DequeueAllComments()
- c.Upstreams = append(c.Upstreams, upstream)
- }
- func (s *NgxServer) parseDirective(d NgxDirective) {
- orig := d.Orig()
- // handle inline comments
- str, comments, _ := strings.Cut(orig, "#")
- if d.Directive == If {
- d.Params = "if " + d.Params
- d.Params = fmtCode(d.Params)
- s.Directives = append(s.Directives, &d)
- return
- }
- regExp := regexp.MustCompile("(\\S+?)\\s+?{?(.+)[;|}]")
- matchSlice := regExp.FindAllStringSubmatch(str, -1)
- for k, v := range matchSlice {
- // [[gzip_min_length 256; gzip_min_length 256] [gzip_proxied expired no-cache no-store private no_last_modified no_etag auth; gzip_proxied expired no-cache no-store private no_last_modified no_etag auth] [gzip on; gzip on] [gzip_vary on; gzip_vary on] [location /x/ {} location /x/ {] [gzip_comp_level 4; gzip_comp_level 4]]
- if len(v) > 0 {
- scanner := bufio.NewScanner(strings.NewReader(v[0]))
- if scanner.Scan() {
- d = parseDirective(scanner)
- // inline location
- if d.Directive == Location {
- s.parseLocation(d.Orig())
- } else {
- if k == 0 {
- d.Comments = s.commentQueue.DequeueAllComments()
- } else if k == len(matchSlice)-1 {
- d.Comments = comments
- }
- // trim right ';'
- d.TrimParams()
- // map[directive]=>[]Params
- s.Directives = append(s.Directives, &d)
- }
- }
- }
- }
- }
- func (s *NgxServer) parseLocation(str string) {
- path, content, _ := strings.Cut(str, "{")
- path = strings.TrimSpace(path)
- content = strings.TrimSpace(content)
- content = strings.Trim(content, "}")
- content = fmtCode(content)
- location := &NgxLocation{
- Path: path,
- Content: content,
- }
- location.Comments = s.commentQueue.DequeueAllComments()
- s.Locations = append(s.Locations, location)
- }
|