From fb06e29aa35f290de1d33bbd54a73a700577e477 Mon Sep 17 00:00:00 2001 From: zhengkunwang <31820853+zhengkunwang223@users.noreply.github.com> Date: Tue, 6 Feb 2024 14:02:12 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20Nginx=20=E9=85=8D=E7=BD=AE=E6=94=AF?= =?UTF-8?q?=E6=8C=81=20Lua=20=E6=A8=A1=E5=9D=97=20(#3844)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/service/nginx_utils.go | 25 +++- backend/app/service/website.go | 26 ++++- backend/app/service/website_utils.go | 15 ++- backend/utils/nginx/components/block.go | 12 +- backend/utils/nginx/components/http.go | 4 + backend/utils/nginx/components/location.go | 4 + backend/utils/nginx/components/lua_block.go | 120 ++++++++++++++++++++ backend/utils/nginx/components/server.go | 4 + backend/utils/nginx/components/statement.go | 1 + backend/utils/nginx/components/upstream.go | 4 + backend/utils/nginx/dumper.go | 15 +++ backend/utils/nginx/nginx.go | 2 +- backend/utils/nginx/parser/flag/flag.go | 1 + backend/utils/nginx/parser/lexer.go | 114 +++++++++++++------ backend/utils/nginx/parser/parser.go | 82 +++++++++---- 15 files changed, 353 insertions(+), 76 deletions(-) create mode 100644 backend/utils/nginx/components/lua_block.go diff --git a/backend/app/service/nginx_utils.go b/backend/app/service/nginx_utils.go index b2ff28c83..a032257a9 100644 --- a/backend/app/service/nginx_utils.go +++ b/backend/app/service/nginx_utils.go @@ -37,7 +37,10 @@ func getNginxFull(website *model.Website) (dto.NginxFull, error) { if err != nil { return nginxFull, err } - config := parser.NewStringParser(string(content)).Parse() + config, err := parser.NewStringParser(string(content)).Parse() + if err != nil { + return dto.NginxFull{}, err + } config.FilePath = nginxConfig.FilePath nginxConfig.OldContent = string(content) nginxConfig.Config = config @@ -54,7 +57,10 @@ func getNginxFull(website *model.Website) (dto.NginxFull, error) { if err != nil { return nginxFull, err } - siteConfig := parser.NewStringParser(string(siteNginxContent)).Parse() + siteConfig, err := parser.NewStringParser(string(siteNginxContent)).Parse() + if err != nil { + return dto.NginxFull{}, err + } siteConfig.FilePath = siteConfigPath siteNginxConfig.Config = siteConfig siteNginxConfig.OldContent = string(siteNginxContent) @@ -156,15 +162,22 @@ func deleteNginxConfig(scope string, params []dto.NginxParam, website *model.Web } func getNginxParamsFromStaticFile(scope dto.NginxKey, newParams []dto.NginxParam) []dto.NginxParam { - newConfig := &components.Config{} + var ( + newConfig = &components.Config{} + err error + ) + updateScope := "in" switch scope { case dto.SSL: - newConfig = parser.NewStringParser(string(nginx_conf.SSL)).Parse() + newConfig, err = parser.NewStringParser(string(nginx_conf.SSL)).Parse() case dto.CACHE: - newConfig = parser.NewStringParser(string(nginx_conf.Cache)).Parse() + newConfig, err = parser.NewStringParser(string(nginx_conf.Cache)).Parse() case dto.ProxyCache: - newConfig = parser.NewStringParser(string(nginx_conf.ProxyCache)).Parse() + newConfig, err = parser.NewStringParser(string(nginx_conf.ProxyCache)).Parse() + } + if err != nil { + return nil } for _, dir := range newConfig.GetDirectives() { addParam := dto.NginxParam{ diff --git a/backend/app/service/website.go b/backend/app/service/website.go index 2432f6834..92df5400b 100644 --- a/backend/app/service/website.go +++ b/backend/app/service/website.go @@ -1511,13 +1511,19 @@ func (w WebsiteService) OperateProxy(req request.WebsiteProxyConfig) (err error) switch req.Operate { case "create": - config = parser.NewStringParser(string(nginx_conf.Proxy)).Parse() + config, err = parser.NewStringParser(string(nginx_conf.Proxy)).Parse() + if err != nil { + return + } case "edit": par, err = parser.NewParser(includePath) if err != nil { return } - config = par.Parse() + config, err = par.Parse() + if err != nil { + return + } oldContent, err = fileOp.GetContent(includePath) if err != nil { return @@ -1533,6 +1539,7 @@ func (w WebsiteService) OperateProxy(req request.WebsiteProxyConfig) (err error) _ = fileOp.Rename(backPath, includePath) return updateNginxConfig(constant.NginxScopeServer, nil, &website) } + config.FilePath = includePath directives := config.Directives location, ok := directives[0].(*components.Location) @@ -1610,7 +1617,10 @@ func (w WebsiteService) GetProxies(id uint) (res []request.WebsiteProxyConfig, e return } proxyConfig.Content = string(content) - config = parser.NewStringParser(string(content)).Parse() + config, err = parser.NewStringParser(string(content)).Parse() + if err != nil { + return nil, err + } directives := config.GetDirectives() location, ok := directives[0].(*components.Location) @@ -2057,7 +2067,10 @@ func (w WebsiteService) OperateRedirect(req request.NginxRedirectReq) (err error if err != nil { return } - config = oldPar.Parse() + config, err = oldPar.Parse() + if err != nil { + return + } oldContent, err = fileOp.GetContent(includePath) if err != nil { return @@ -2198,7 +2211,10 @@ func (w WebsiteService) GetRedirect(id uint) (res []response.NginxRedirectConfig return } redirectConfig.Content = string(content) - config = parser.NewStringParser(string(content)).Parse() + config, err = parser.NewStringParser(string(content)).Parse() + if err != nil { + return + } dirs := config.GetDirectives() if len(dirs) > 0 { diff --git a/backend/app/service/website_utils.go b/backend/app/service/website_utils.go index cd1b87a2c..b7a988207 100644 --- a/backend/app/service/website_utils.go +++ b/backend/app/service/website_utils.go @@ -132,7 +132,10 @@ func createProxyFile(website *model.Website, runtime *model.Runtime) error { return err } } - config := parser.NewStringParser(string(nginx_conf.Proxy)).Parse() + config, err := parser.NewStringParser(string(nginx_conf.Proxy)).Parse() + if err != nil { + return err + } config.FilePath = filePath directives := config.Directives location, ok := directives[0].(*components.Location) @@ -208,7 +211,10 @@ func configDefaultNginx(website *model.Website, domains []model.WebsiteDomain, a nginxFileName := website.Alias + ".conf" configPath := path.Join(constant.AppInstallDir, constant.AppOpenresty, nginxInstall.Name, "conf", "conf.d", nginxFileName) nginxContent := string(nginx_conf.WebsiteDefault) - config := parser.NewStringParser(nginxContent).Parse() + config, err := parser.NewStringParser(nginxContent).Parse() + if err != nil { + return err + } servers := config.FindServers() if len(servers) == 0 { return errors.New("nginx config is not valid") @@ -872,7 +878,10 @@ func ChangeHSTSConfig(enable bool, nginxInstall model.AppInstall, website model. if err != nil { return err } - config := par.Parse() + config, err := par.Parse() + if err != nil { + return err + } config.FilePath = path directives := config.Directives location, ok := directives[0].(*components.Location) diff --git a/backend/utils/nginx/components/block.go b/backend/utils/nginx/components/block.go index 9342156ad..0e07e7793 100644 --- a/backend/utils/nginx/components/block.go +++ b/backend/utils/nginx/components/block.go @@ -1,9 +1,11 @@ package components type Block struct { - Line int - Comment string - Directives []IDirective + Line int + Comment string + Directives []IDirective + IsLuaBlock bool + LiteralCode string } func (b *Block) GetDirectives() []IDirective { @@ -18,6 +20,10 @@ func (b *Block) GetLine() int { return b.Line } +func (b *Block) GetCodeBlock() string { + return b.LiteralCode +} + func (b *Block) FindDirectives(directiveName string) []IDirective { directives := make([]IDirective, 0) for _, directive := range b.GetDirectives() { diff --git a/backend/utils/nginx/components/http.go b/backend/utils/nginx/components/http.go index 0fcb293bc..ff9d3028c 100644 --- a/backend/utils/nginx/components/http.go +++ b/backend/utils/nginx/components/http.go @@ -11,6 +11,10 @@ type Http struct { Line int } +func (h *Http) GetCodeBlock() string { + return "" +} + func (h *Http) GetComment() string { return h.Comment } diff --git a/backend/utils/nginx/components/location.go b/backend/utils/nginx/components/location.go index bf2775df4..c407c0ede 100644 --- a/backend/utils/nginx/components/location.go +++ b/backend/utils/nginx/components/location.go @@ -22,6 +22,10 @@ type Location struct { Replaces map[string]string } +func (l *Location) GetCodeBlock() string { + return "" +} + func NewLocation(directive IDirective) *Location { location := &Location{ Modifier: "", diff --git a/backend/utils/nginx/components/lua_block.go b/backend/utils/nginx/components/lua_block.go new file mode 100644 index 000000000..d9b4b3676 --- /dev/null +++ b/backend/utils/nginx/components/lua_block.go @@ -0,0 +1,120 @@ +package components + +import ( + "fmt" +) + +type LuaBlock struct { + Directives []IDirective + Name string + Comment string + LuaCode string + Line int +} + +func NewLuaBlock(directive IDirective) (*LuaBlock, error) { + if block := directive.GetBlock(); block != nil { + lb := &LuaBlock{ + Directives: []IDirective{}, + Name: directive.GetName(), + LuaCode: block.GetCodeBlock(), + } + + lb.Directives = append(lb.Directives, block.GetDirectives()...) + return lb, nil + } + return nil, fmt.Errorf("%s must have a block", directive.GetName()) +} + +func (lb *LuaBlock) GetName() string { + return lb.Name +} + +func (lb *LuaBlock) GetParameters() []string { + return []string{} +} + +func (lb *LuaBlock) GetDirectives() []IDirective { + directives := make([]IDirective, 0) + directives = append(directives, lb.Directives...) + return directives +} + +func (lb *LuaBlock) FindDirectives(directiveName string) []IDirective { + directives := make([]IDirective, 0) + for _, directive := range lb.GetDirectives() { + if directive.GetName() == directiveName { + directives = append(directives, directive) + } + if directive.GetBlock() != nil { + directives = append(directives, directive.GetBlock().FindDirectives(directiveName)...) + } + } + + return directives +} + +func (lb *LuaBlock) GetCodeBlock() string { + return lb.LuaCode +} + +func (lb *LuaBlock) GetBlock() IBlock { + return lb +} + +func (lb *LuaBlock) GetComment() string { + return lb.Comment +} + +func (lb *LuaBlock) RemoveDirective(key string, params []string) { + directives := lb.Directives + var newDirectives []IDirective + for _, dir := range directives { + if dir.GetName() == key { + if len(params) > 0 { + oldParams := dir.GetParameters() + if oldParams[0] == params[0] { + continue + } + } else { + continue + } + } + newDirectives = append(newDirectives, dir) + } + lb.Directives = newDirectives +} + +func (lb *LuaBlock) UpdateDirective(key string, params []string) { + if key == "" || len(params) == 0 { + return + } + directives := lb.Directives + index := -1 + for i, dir := range directives { + if dir.GetName() == key { + if IsRepeatKey(key) { + oldParams := dir.GetParameters() + if !(len(oldParams) > 0 && oldParams[0] == params[0]) { + continue + } + } + index = i + break + } + } + newDirective := &Directive{ + Name: key, + Parameters: params, + } + if index > -1 { + directives[index] = newDirective + } else { + directives = append(directives, newDirective) + } + lb.Directives = directives +} + +func (lb *LuaBlock) GetLine() int { + return lb.Line +} diff --git a/backend/utils/nginx/components/server.go b/backend/utils/nginx/components/server.go index cea31d2a1..c7138936f 100644 --- a/backend/utils/nginx/components/server.go +++ b/backend/utils/nginx/components/server.go @@ -11,6 +11,10 @@ type Server struct { Line int } +func (s *Server) GetCodeBlock() string { + return "" +} + func NewServer(directive IDirective) (*Server, error) { server := &Server{} if block := directive.GetBlock(); block != nil { diff --git a/backend/utils/nginx/components/statement.go b/backend/utils/nginx/components/statement.go index 04576e666..432a4c165 100644 --- a/backend/utils/nginx/components/statement.go +++ b/backend/utils/nginx/components/statement.go @@ -7,6 +7,7 @@ type IBlock interface { UpdateDirective(name string, params []string) GetComment() string GetLine() int + GetCodeBlock() string } type IDirective interface { diff --git a/backend/utils/nginx/components/upstream.go b/backend/utils/nginx/components/upstream.go index e73488204..68e26d42d 100644 --- a/backend/utils/nginx/components/upstream.go +++ b/backend/utils/nginx/components/upstream.go @@ -12,6 +12,10 @@ type Upstream struct { Line int } +func (us *Upstream) GetCodeBlock() string { + return "" +} + func (us *Upstream) GetName() string { return "upstream" } diff --git a/backend/utils/nginx/dumper.go b/backend/utils/nginx/dumper.go index f85a95e8a..06bc2bb15 100644 --- a/backend/utils/nginx/dumper.go +++ b/backend/utils/nginx/dumper.go @@ -65,6 +65,21 @@ func DumpDirective(d components.IDirective, style *Style) string { func DumpBlock(b components.IBlock, style *Style, startLine int) string { var buf bytes.Buffer + + if b.GetCodeBlock() != "" { + luaLines := strings.Split(b.GetCodeBlock(), "\n") + for i, line := range luaLines { + if strings.Replace(line, " ", "", -1) == "" { + continue + } + buf.WriteString(line) + if i != len(luaLines)-1 { + buf.WriteString("\n") + } + } + return buf.String() + } + line := startLine if b.GetLine() > startLine { for i := 0; i < b.GetLine()-startLine; i++ { diff --git a/backend/utils/nginx/nginx.go b/backend/utils/nginx/nginx.go index 0ba7706dd..9e7ffb792 100644 --- a/backend/utils/nginx/nginx.go +++ b/backend/utils/nginx/nginx.go @@ -10,5 +10,5 @@ func GetConfig(path string) (*components.Config, error) { if err != nil { return nil, err } - return p.Parse(), nil + return p.Parse() } diff --git a/backend/utils/nginx/parser/flag/flag.go b/backend/utils/nginx/parser/flag/flag.go index 4406bc674..88bf9d6e1 100644 --- a/backend/utils/nginx/parser/flag/flag.go +++ b/backend/utils/nginx/parser/flag/flag.go @@ -18,6 +18,7 @@ const ( Comment Illegal Regex + LuaCode ) var ( diff --git a/backend/utils/nginx/parser/lexer.go b/backend/utils/nginx/parser/lexer.go index d12b26317..fe64ee153 100644 --- a/backend/utils/nginx/parser/lexer.go +++ b/backend/utils/nginx/parser/lexer.go @@ -3,17 +3,18 @@ package parser import ( "bufio" "bytes" - "fmt" "github.com/1Panel-dev/1Panel/backend/utils/nginx/parser/flag" "io" + "strings" ) type lexer struct { - reader *bufio.Reader - file string - line int - column int - Latest flag.Flag + reader *bufio.Reader + file string + line int + column int + inLuaBlock bool + Latest flag.Flag } func lex(content string) *lexer { @@ -45,6 +46,11 @@ func (s *lexer) scan() flag.Flag { //} func (s *lexer) getNextFlag() flag.Flag { + if s.inLuaBlock { + s.inLuaBlock = false + flag := s.scanLuaCode() + return flag + } retoFlag: ch := s.peek() switch { @@ -56,6 +62,9 @@ retoFlag: case ch == ';': return s.NewToken(flag.Semicolon).Lit(string(s.read())) case ch == '{': + if isLuaBlock(s.Latest) { + s.inLuaBlock = true + } return s.NewToken(flag.BlockStart).Lit(string(s.read())) case ch == '}': return s.NewToken(flag.BlockEnd).Lit(string(s.read())) @@ -70,6 +79,35 @@ retoFlag: } } +func (s *lexer) scanLuaCode() flag.Flag { + ret := s.NewToken(flag.LuaCode) + stack := make([]rune, 0, 50) + code := strings.Builder{} + + for { + ch := s.read() + if ch == rune(flag.EOF) { + panic("unexpected end of file while scanning a string, maybe an unclosed lua code?") + } + if ch == '#' { + code.WriteRune(ch) + code.WriteString(s.readUntil(isEndOfLine)) + continue + } else if ch == '}' { + if len(stack) == 0 { + _ = s.reader.UnreadRune() + return ret.Lit(strings.TrimRight(strings.Trim(code.String(), "\n"), "\n ")) + } + if stack[len(stack)-1] == '{' { + stack = stack[0 : len(stack)-1] + } + } else if ch == '{' { + stack = append(stack, ch) + } + code.WriteRune(ch) + } +} + func (s *lexer) peek() rune { r, _, _ := s.reader.ReadRune() _ = s.reader.UnreadRune() @@ -128,7 +166,7 @@ func (s *lexer) scanComment() flag.Flag { func (s *lexer) scanQuotedString(delimiter rune) flag.Flag { var buf bytes.Buffer tok := s.NewToken(flag.QuotedString) - buf.WriteRune(s.read()) //consume delimiter + _, _ = buf.WriteRune(s.read()) for { ch := s.read() @@ -136,29 +174,13 @@ func (s *lexer) scanQuotedString(delimiter rune) flag.Flag { panic("unexpected end of file while scanning a string, maybe an unclosed quote?") } - if ch == '\\' { - if needsEscape(s.peek(), delimiter) { - nextch := s.read() - switch nextch { - case 'n': - fmt.Println("n") - buf.WriteRune('\n') - case 'r': - fmt.Println("r") - buf.WriteRune('\r') - case 't': - fmt.Println("t") - buf.WriteRune('\t') - case '\\': - buf.WriteRune('\\') - default: - buf.WriteRune('\\') - buf.WriteRune(nextch) - } - continue - } + if ch == '\\' && (s.peek() == delimiter) { + buf.WriteRune(ch) + buf.WriteRune(s.read()) + continue } - buf.WriteRune(ch) + + _, _ = buf.WriteRune(ch) if ch == delimiter { break } @@ -168,7 +190,31 @@ func (s *lexer) scanQuotedString(delimiter rune) flag.Flag { } func (s *lexer) scanKeyword() flag.Flag { - return s.NewToken(flag.Keyword).Lit(s.readUntil(isKeywordTerminator)) + var buf bytes.Buffer + tok := s.NewToken(flag.Keyword) + prev := s.read() + buf.WriteRune(prev) + for { + ch := s.peek() + + if isSpace(ch) || isEOF(ch) || ch == ';' { + break + } + + if ch == '{' { + if prev == '$' { + buf.WriteString(s.readUntil(func(r rune) bool { + return r == '}' + })) + buf.WriteRune(s.read()) //consume latest '}' + } else { + break + } + } + buf.WriteRune(s.read()) + } + + return tok.Lit(buf.String()) } func (s *lexer) scanVariable() flag.Flag { @@ -198,10 +244,6 @@ func isKeywordTerminator(ch rune) bool { return isSpace(ch) || isEndOfLine(ch) || ch == '{' || ch == ';' } -func needsEscape(ch, delimiter rune) bool { - return ch == delimiter || ch == 'n' || ch == 't' || ch == '\\' || ch == 'r' -} - func isSpace(ch rune) bool { return ch == ' ' || ch == '\t' || isEndOfLine(ch) } @@ -213,3 +255,7 @@ func isEOF(ch rune) bool { func isEndOfLine(ch rune) bool { return ch == '\r' || ch == '\n' } + +func isLuaBlock(t flag.Flag) bool { + return t.Type == flag.Keyword && strings.HasSuffix(t.Literal, "_by_lua_block") +} diff --git a/backend/utils/nginx/parser/parser.go b/backend/utils/nginx/parser/parser.go index 9f55d0b4d..7ebb756a5 100644 --- a/backend/utils/nginx/parser/parser.go +++ b/backend/utils/nginx/parser/parser.go @@ -2,17 +2,19 @@ package parser import ( "bufio" + "errors" "fmt" components "github.com/1Panel-dev/1Panel/backend/utils/nginx/components" "github.com/1Panel-dev/1Panel/backend/utils/nginx/parser/flag" "os" + "strings" ) type Parser struct { lexer *lexer currentToken flag.Flag followingToken flag.Flag - blockWrappers map[string]func(*components.Directive) components.IDirective + blockWrappers map[string]func(*components.Directive) (components.IDirective, error) directiveWrappers map[string]func(*components.Directive) components.IDirective } @@ -39,18 +41,21 @@ func NewParserFromLexer(lexer *lexer) *Parser { parser.nextToken() parser.nextToken() - parser.blockWrappers = map[string]func(*components.Directive) components.IDirective{ - "http": func(directive *components.Directive) components.IDirective { - return parser.wrapHttp(directive) + parser.blockWrappers = map[string]func(*components.Directive) (components.IDirective, error){ + "http": func(directive *components.Directive) (components.IDirective, error) { + return parser.wrapHttp(directive), nil }, - "server": func(directive *components.Directive) components.IDirective { - return parser.wrapServer(directive) + "server": func(directive *components.Directive) (components.IDirective, error) { + return parser.wrapServer(directive), nil }, - "location": func(directive *components.Directive) components.IDirective { - return parser.wrapLocation(directive) + "location": func(directive *components.Directive) (components.IDirective, error) { + return parser.wrapLocation(directive), nil }, - "upstream": func(directive *components.Directive) components.IDirective { - return parser.wrapUpstream(directive) + "upstream": func(directive *components.Directive) (components.IDirective, error) { + return parser.wrapUpstream(directive), nil + }, + "_by_lua_block": func(directive *components.Directive) (components.IDirective, error) { + return parser.wrapLuaBlock(directive) }, } @@ -76,14 +81,19 @@ func (p *Parser) followingTokenIs(t flag.Type) bool { return p.followingToken.Type == t } -func (p *Parser) Parse() *components.Config { - return &components.Config{ - FilePath: p.lexer.file, - Block: p.parseBlock(), +func (p *Parser) Parse() (*components.Config, error) { + parsedBlock, err := p.parseBlock(false) + if err != nil { + return nil, err } + c := &components.Config{ + FilePath: p.lexer.file, + Block: parsedBlock, + } + return c, err } -func (p *Parser) parseBlock() *components.Block { +func (p *Parser) parseBlock(inBlock bool) (*components.Block, error) { context := &components.Block{ Comment: "", Directives: make([]components.IDirective, 0), @@ -93,10 +103,22 @@ func (p *Parser) parseBlock() *components.Block { parsingloop: for { switch { - case p.curTokenIs(flag.EOF) || p.curTokenIs(flag.BlockEnd): + case p.curTokenIs(flag.EOF): + if inBlock { + return nil, errors.New("unexpected eof in block") + } break parsingloop + case p.curTokenIs(flag.BlockEnd): + break parsingloop + case p.curTokenIs(flag.LuaCode): + context.IsLuaBlock = true + context.LiteralCode = p.currentToken.Literal case p.curTokenIs(flag.Keyword): - context.Directives = append(context.Directives, p.parseStatement()) + s, err := p.parseStatement() + if err != nil { + return nil, err + } + context.Directives = append(context.Directives, s) case p.curTokenIs(flag.Comment): context.Directives = append(context.Directives, &components.Comment{ Detail: p.currentToken.Literal, @@ -106,10 +128,10 @@ parsingloop: p.nextToken() } - return context + return context, nil } -func (p *Parser) parseStatement() components.IDirective { +func (p *Parser) parseStatement() (components.IDirective, error) { d := &components.Directive{ Name: p.currentToken.Literal, Line: p.currentToken.Line, @@ -121,30 +143,38 @@ func (p *Parser) parseStatement() components.IDirective { if p.curTokenIs(flag.Semicolon) { if dw, ok := p.directiveWrappers[d.Name]; ok { - return dw(d) + return dw(d), nil } if p.followingTokenIs(flag.Comment) && p.currentToken.Line == p.followingToken.Line { d.Comment = p.followingToken.Literal p.nextToken() } - return d + return d, nil } if p.curTokenIs(flag.BlockStart) { - inLineComment := "" if p.followingTokenIs(flag.Comment) && p.currentToken.Line == p.followingToken.Line { inLineComment = p.followingToken.Literal p.nextToken() p.nextToken() } - block := p.parseBlock() + block, err := p.parseBlock(false) + if err != nil { + return nil, err + } + block.Comment = inLineComment d.Block = block + + if strings.HasSuffix(d.Name, "_by_lua_block") { + return p.blockWrappers["_by_lua_block"](d) + } + if bw, ok := p.blockWrappers[d.Name]; ok { return bw(d) } - return d + return d, nil } panic(fmt.Errorf("unexpected token %s (%s) on line %d, column %d", p.currentToken.Type.String(), p.currentToken.Literal, p.currentToken.Line, p.currentToken.Column)) @@ -169,6 +199,10 @@ func (p *Parser) wrapHttp(directive *components.Directive) *components.Http { return h } +func (p *Parser) wrapLuaBlock(directive *components.Directive) (*components.LuaBlock, error) { + return components.NewLuaBlock(directive) +} + func (p *Parser) parseUpstreamServer(directive *components.Directive) *components.UpstreamServer { return components.NewUpstreamServer(directive) }