diff --git a/backend/utils/nginx/components/block.go b/backend/utils/nginx/components/block.go index d1e7fb607..ad53d8a2e 100644 --- a/backend/utils/nginx/components/block.go +++ b/backend/utils/nginx/components/block.go @@ -1,6 +1,7 @@ package components type Block struct { + Line int Comment string Directives []IDirective } @@ -13,6 +14,10 @@ func (b *Block) GetComment() string { return b.Comment } +func (b *Block) GetLine() int { + return b.Line +} + func (b *Block) FindDirectives(directiveName string) []IDirective { directives := make([]IDirective, 0) for _, directive := range b.GetDirectives() { @@ -27,57 +32,101 @@ func (b *Block) FindDirectives(directiveName string) []IDirective { return directives } -func (b *Block) UpdateDirectives(directiveName string, directive Directive) { +//func (b *Block) UpdateDirectives(directiveName string, directive Directive) { +// directives := b.GetDirectives() +// index := -1 +// for i, dir := range directives { +// if dir.GetName() == directiveName { +// index = i +// break +// } +// } +// if index > -1 { +// directives[index] = &directive +// } else { +// directives = append(directives, &directive) +// } +// b.Directives = directives +//} + +func (b *Block) UpdateDirective(key string, params []string) { + if key == "" || len(params) == 0 { + return + } directives := b.GetDirectives() index := -1 for i, dir := range directives { - if dir.GetName() == directiveName { + if dir.GetName() == key { + if IsRepeatKey(key) { + oldParams := dir.GetParameters() + if !(len(oldParams) > 0 && oldParams[0] == params[0]) { + continue + } + } index = i break } } - if index > -1 { - directives[index] = &directive - } else { - directives = append(directives, &directive) - } - b.Directives = directives -} - -func (b *Block) UpdateDirectiveBySecondKey(name string, key string, directive Directive) { - - directives := b.GetDirectives() - - index := -1 - for i, dir := range directives { - if dir.GetName() == name && dir.GetParameters()[0] == key { - index = i - break - } + newDirective := &Directive{ + Name: key, + Parameters: params, } if index > -1 { - directives[index] = &directive + directives[index] = newDirective } else { - directives = append(directives, &directive) + directives = append(directives, newDirective) } b.Directives = directives } -func (b *Block) AddDirectives(directive Directive) { - directives := append(b.GetDirectives(), &directive) - b.Directives = directives -} +//func (b *Block) UpdateDirectiveBySecondKey(name string, key string, directive Directive) { +// +// directives := b.GetDirectives() +// +// index := -1 +// for i, dir := range directives { +// if dir.GetName() == name && dir.GetParameters()[0] == key { +// index = i +// break +// } +// } +// if index > -1 { +// directives[index] = &directive +// } else { +// directives = append(directives, &directive) +// } +// b.Directives = directives +//} -func (b *Block) RemoveDirectives(names []string) { - nameMaps := make(map[string]struct{}, len(names)) - for _, name := range names { - nameMaps[name] = struct{}{} - } +//func (b *Block) RemoveDirectives(names []string) { +// nameMaps := make(map[string]struct{}, len(names)) +// for _, name := range names { +// nameMaps[name] = struct{}{} +// } +// directives := b.GetDirectives() +// var newDirectives []IDirective +// for _, dir := range directives { +// if _, ok := nameMaps[dir.GetName()]; ok { +// continue +// } +// newDirectives = append(newDirectives, dir) +// } +// b.Directives = newDirectives +//} + +func (b *Block) RemoveDirective(key string, params []string) { directives := b.GetDirectives() var newDirectives []IDirective for _, dir := range directives { - if _, ok := nameMaps[dir.GetName()]; ok { - continue + if dir.GetName() == key { + if IsRepeatKey(key) { + oldParams := dir.GetParameters() + if len(oldParams) > 0 && oldParams[0] == params[0] { + continue + } + } else { + continue + } } newDirectives = append(newDirectives, dir) } diff --git a/backend/utils/nginx/components/comment.go b/backend/utils/nginx/components/comment.go index 014092aca..31459be09 100644 --- a/backend/utils/nginx/components/comment.go +++ b/backend/utils/nginx/components/comment.go @@ -2,6 +2,7 @@ package components type Comment struct { Detail string + Line int } func (c *Comment) GetName() string { @@ -19,3 +20,7 @@ func (c *Comment) GetBlock() IBlock { func (c *Comment) GetComment() string { return c.Detail } + +func (c *Comment) GetLine() int { + return c.Line +} diff --git a/backend/utils/nginx/components/config.go b/backend/utils/nginx/components/config.go index aab4d183e..35bb1369b 100644 --- a/backend/utils/nginx/components/config.go +++ b/backend/utils/nginx/components/config.go @@ -36,3 +36,17 @@ func (c *Config) FindHttp() *Http { return http } + +var repeatKeys = map[string]struct { +}{ + "limit_conn": {}, + "limit_conn_zone": {}, + "set": {}, +} + +func IsRepeatKey(key string) bool { + if _, ok := repeatKeys[key]; ok { + return true + } + return false +} diff --git a/backend/utils/nginx/components/directive.go b/backend/utils/nginx/components/directive.go index 04e63ea1e..dfdef75ef 100644 --- a/backend/utils/nginx/components/directive.go +++ b/backend/utils/nginx/components/directive.go @@ -1,6 +1,7 @@ package components type Directive struct { + Line int Block IBlock Name string Comment string @@ -22,3 +23,7 @@ func (d *Directive) GetParameters() []string { func (d *Directive) GetBlock() IBlock { return d.Block } + +func (d *Directive) GetLine() int { + return d.Line +} diff --git a/backend/utils/nginx/components/http.go b/backend/utils/nginx/components/http.go index 849054949..69bed41bd 100644 --- a/backend/utils/nginx/components/http.go +++ b/backend/utils/nginx/components/http.go @@ -8,6 +8,7 @@ type Http struct { Comment string Servers []*Server Directives []IDirective + Line int } func (h *Http) GetComment() string { @@ -17,11 +18,11 @@ func (h *Http) GetComment() string { func NewHttp(directive IDirective) (*Http, error) { if block := directive.GetBlock(); block != nil { http := &Http{ + Line: directive.GetBlock().GetLine(), Servers: []*Server{}, Directives: []IDirective{}, Comment: block.GetComment(), } - for _, directive := range block.GetDirectives() { if server, ok := directive.(*Server); ok { http.Servers = append(http.Servers, server) @@ -66,38 +67,49 @@ func (h *Http) FindDirectives(directiveName string) []IDirective { return directives } -func (h *Http) UpdateDirectives(directiveName string, directive Directive) { - directives := h.Directives +func (h *Http) UpdateDirective(key string, params []string) { + if key == "" || len(params) == 0 { + return + } + directives := h.GetDirectives() index := -1 for i, dir := range directives { - if dir.GetName() == directiveName { + 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] = &directive + directives[index] = newDirective } else { - directives = append(directives, &directive) + directives = append(directives, newDirective) } h.Directives = directives } -func (h *Http) AddDirectives(directive Directive) { - directives := append(h.GetDirectives(), &directive) - h.Directives = directives -} - -func (h *Http) RemoveDirectives(names []string) { - nameMaps := make(map[string]struct{}, len(names)) - for _, name := range names { - nameMaps[name] = struct{}{} - } +func (h *Http) RemoveDirective(key string, params []string) { directives := h.GetDirectives() var newDirectives []IDirective for _, dir := range directives { - if _, ok := nameMaps[dir.GetName()]; ok { - continue + if dir.GetName() == key { + if IsRepeatKey(key) { + oldParams := dir.GetParameters() + if len(oldParams) > 0 && oldParams[0] == params[0] { + continue + } + } else { + continue + } } newDirectives = append(newDirectives, dir) } @@ -108,19 +120,6 @@ func (h *Http) GetBlock() IBlock { return h } -func (h *Http) UpdateDirectiveBySecondKey(name string, key string, directive Directive) { - directives := h.Directives - index := -1 - for i, dir := range directives { - if dir.GetName() == name && dir.GetParameters()[0] == key { - index = i - break - } - } - if index > -1 { - directives[index] = &directive - } else { - directives = append(directives, &directive) - } - h.Directives = directives +func (h *Http) GetLine() int { + return h.Line } diff --git a/backend/utils/nginx/components/server.go b/backend/utils/nginx/components/server.go index ae7ef8a24..747e2b708 100644 --- a/backend/utils/nginx/components/server.go +++ b/backend/utils/nginx/components/server.go @@ -8,18 +8,19 @@ type Server struct { Comment string Listens []*ServerListen Directives []IDirective + Line int } func NewServer(directive IDirective) (*Server, error) { server := &Server{} if block := directive.GetBlock(); block != nil { + server.Line = directive.GetBlock().GetLine() server.Comment = block.GetComment() directives := block.GetDirectives() for _, dir := range directives { - switch dir.GetName() { case "listen": - server.Listens = append(server.Listens, NewServerListen(dir.GetParameters())) + server.Listens = append(server.Listens, NewServerListen(dir.GetParameters(), dir.GetLine())) default: server.Directives = append(server.Directives, dir) } @@ -54,6 +55,73 @@ func (s *Server) GetDirectives() []IDirective { return directives } +func (s *Server) FindDirectives(directiveName string) []IDirective { + directives := make([]IDirective, 0) + for _, directive := range s.Directives { + if directive.GetName() == directiveName { + directives = append(directives, directive) + } + if directive.GetBlock() != nil { + directives = append(directives, directive.GetBlock().FindDirectives(directiveName)...) + } + } + + return directives +} + +func (s *Server) UpdateDirective(key string, params []string) { + if key == "" || len(params) == 0 { + return + } + directives := s.GetDirectives() + 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) + } + s.Directives = directives +} + +func (s *Server) RemoveDirective(key string, params []string) { + directives := s.GetDirectives() + var newDirectives []IDirective + for _, dir := range directives { + if dir.GetName() == key { + if IsRepeatKey(key) { + oldParams := dir.GetParameters() + if len(oldParams) > 0 && oldParams[0] == params[0] { + continue + } + } else { + continue + } + } + newDirectives = append(newDirectives, dir) + } + s.Directives = newDirectives +} + +func (s *Server) GetLine() int { + return s.Line +} + func (s *Server) AddListen(bind string, defaultServer bool, params ...string) { listen := &ServerListen{ Bind: bind, @@ -120,19 +188,11 @@ func (s *Server) AddServerName(name string) { } func (s *Server) UpdateServerName(names []string) { - serverNameDirective := Directive{ - Name: "server_name", - Parameters: names, - } - s.UpdateDirectives("server_name", serverNameDirective) + s.UpdateDirective("server_name", names) } func (s *Server) UpdateRoot(path string) { - rootDir := Directive{ - Name: "root", - Parameters: []string{path}, - } - s.UpdateDirectives("root", rootDir) + s.UpdateDirective("root", []string{path}) } func (s *Server) UpdateRootLocation() { @@ -192,55 +252,3 @@ func (s *Server) RemoveListenByBind(bind string) { } s.Listens = listens } - -func (s *Server) FindDirectives(directiveName string) []IDirective { - directives := make([]IDirective, 0) - for _, directive := range s.Directives { - if directive.GetName() == directiveName { - directives = append(directives, directive) - } - if directive.GetBlock() != nil { - directives = append(directives, directive.GetBlock().FindDirectives(directiveName)...) - } - } - - return directives -} - -func (s *Server) UpdateDirectives(directiveName string, directive Directive) { - directives := s.Directives - index := -1 - for i, dir := range directives { - if dir.GetName() == directiveName { - index = i - break - } - } - if index > -1 { - directives[index] = &directive - } else { - directives = append(directives, &directive) - } - s.Directives = directives -} - -func (s *Server) AddDirectives(directive Directive) { - directives := append(s.Directives, &directive) - s.Directives = directives -} - -func (s *Server) RemoveDirectives(names []string) { - nameMaps := make(map[string]struct{}, len(names)) - for _, name := range names { - nameMaps[name] = struct{}{} - } - directives := s.Directives - var newDirectives []IDirective - for _, dir := range directives { - if _, ok := nameMaps[dir.GetName()]; ok { - continue - } - newDirectives = append(newDirectives, dir) - } - s.Directives = newDirectives -} diff --git a/backend/utils/nginx/components/server_listen.go b/backend/utils/nginx/components/server_listen.go index 472ed89ed..6807e6103 100644 --- a/backend/utils/nginx/components/server_listen.go +++ b/backend/utils/nginx/components/server_listen.go @@ -12,11 +12,13 @@ type ServerListen struct { DefaultServer string Parameters []string Comment string + Line int } -func NewServerListen(params []string) *ServerListen { +func NewServerListen(params []string, line int) *ServerListen { server := &ServerListen{ Parameters: []string{}, + Line: line, } for _, param := range params { if isBind(param) { @@ -66,3 +68,7 @@ func (sl *ServerListen) AddDefaultServer() { func (sl *ServerListen) RemoveDefaultServe() { sl.DefaultServer = "" } + +func (sl *ServerListen) GetLine() int { + return sl.Line +} diff --git a/backend/utils/nginx/components/statement.go b/backend/utils/nginx/components/statement.go index a096349eb..04576e666 100644 --- a/backend/utils/nginx/components/statement.go +++ b/backend/utils/nginx/components/statement.go @@ -3,10 +3,10 @@ package components type IBlock interface { GetDirectives() []IDirective FindDirectives(directiveName string) []IDirective - UpdateDirectives(directiveName string, directive Directive) - AddDirectives(directive Directive) - RemoveDirectives(names []string) + RemoveDirective(name string, params []string) + UpdateDirective(name string, params []string) GetComment() string + GetLine() int } type IDirective interface { @@ -14,12 +14,5 @@ type IDirective interface { GetParameters() []string GetBlock() IBlock GetComment() string -} - -type FileDirective interface { - isFileDirective() -} - -type IncludeDirective interface { - FileDirective + GetLine() int } diff --git a/backend/utils/nginx/components/upstream.go b/backend/utils/nginx/components/upstream.go index f6b197b75..83bd2c8b4 100644 --- a/backend/utils/nginx/components/upstream.go +++ b/backend/utils/nginx/components/upstream.go @@ -9,6 +9,7 @@ type Upstream struct { UpstreamServers []*UpstreamServer Directives []IDirective Comment string + Line int } func (us *Upstream) GetName() string { @@ -33,7 +34,6 @@ func (us *Upstream) GetDirectives() []IDirective { for _, uss := range us.UpstreamServers { directives = append(directives, uss) } - return directives } @@ -41,6 +41,7 @@ func NewUpstream(directive IDirective) (*Upstream, error) { parameters := directive.GetParameters() us := &Upstream{ UpstreamName: parameters[0], + Line: directive.GetLine(), } if block := directive.GetBlock(); block != nil { @@ -76,35 +77,55 @@ func (us *Upstream) FindDirectives(directiveName string) []IDirective { return directives } -func (us *Upstream) UpdateDirectives(directiveName string, directive Directive) { - directives := make([]IDirective, 0) - for _, dir := range us.GetDirectives() { - if dir.GetName() == directiveName { - directives = append(directives, &directive) - } else { - directives = append(directives, dir) +func (us *Upstream) UpdateDirective(key string, params []string) { + if key == "" || len(params) == 0 { + return + } + directives := us.GetDirectives() + 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 } } - us.Directives = directives -} - -func (us *Upstream) AddDirectives(directive Directive) { - directives := append(us.GetDirectives(), &directive) - us.Directives = directives -} - -func (us *Upstream) RemoveDirectives(names []string) { - nameMaps := make(map[string]struct{}, len(names)) - for _, name := range names { - nameMaps[name] = struct{}{} + newDirective := &Directive{ + Name: key, + Parameters: params, } + if index > -1 { + directives[index] = newDirective + } else { + directives = append(directives, newDirective) + } + us.Directives = directives +} + +func (us *Upstream) RemoveDirective(key string, params []string) { directives := us.GetDirectives() var newDirectives []IDirective for _, dir := range directives { - if _, ok := nameMaps[dir.GetName()]; ok { - continue + if dir.GetName() == key { + if IsRepeatKey(key) { + oldParams := dir.GetParameters() + if len(oldParams) > 0 && oldParams[0] == params[0] { + continue + } + } else { + continue + } } newDirectives = append(newDirectives, dir) } us.Directives = newDirectives } + +func (us *Upstream) GetLine() int { + return us.Line +} diff --git a/backend/utils/nginx/components/upstream_server.go b/backend/utils/nginx/components/upstream_server.go index 4d0959891..f5af46493 100644 --- a/backend/utils/nginx/components/upstream_server.go +++ b/backend/utils/nginx/components/upstream_server.go @@ -11,6 +11,7 @@ type UpstreamServer struct { Address string Flags []string Parameters map[string]string + Line int } func (uss *UpstreamServer) GetName() string { @@ -58,6 +59,7 @@ func NewUpstreamServer(directive IDirective) *UpstreamServer { Comment: directive.GetComment(), Flags: make([]string, 0), Parameters: make(map[string]string, 0), + Line: directive.GetLine(), } for i, parameter := range directive.GetParameters() { @@ -75,3 +77,7 @@ func NewUpstreamServer(directive IDirective) *UpstreamServer { return uss } + +func (uss *UpstreamServer) GetLine() int { + return uss.Line +} diff --git a/backend/utils/nginx/dumper.go b/backend/utils/nginx/dumper.go index 360341343..cce885e2f 100644 --- a/backend/utils/nginx/dumper.go +++ b/backend/utils/nginx/dumper.go @@ -3,62 +3,27 @@ package nginx import ( "bytes" "fmt" - components "github.com/1Panel-dev/1Panel/backend/utils/nginx/components" + "github.com/1Panel-dev/1Panel/backend/utils/nginx/components" "io/ioutil" - "sort" "strings" ) var ( - //NoIndentStyle default style - NoIndentStyle = &Style{ - SortDirectives: false, - StartIndent: 0, - Indent: 0, - } - - //IndentedStyle default style IndentedStyle = &Style{ - SortDirectives: false, - StartIndent: 0, - Indent: 4, - } - - //NoIndentSortedStyle default style - NoIndentSortedStyle = &Style{ - SortDirectives: true, - StartIndent: 0, - Indent: 0, - } - - //NoIndentSortedSpaceStyle default style - NoIndentSortedSpaceStyle = &Style{ - SortDirectives: true, SpaceBeforeBlocks: true, StartIndent: 0, - Indent: 0, + Indent: 4, } ) type Style struct { - SortDirectives bool SpaceBeforeBlocks bool StartIndent int Indent int } -func NewStyle() *Style { - style := &Style{ - SortDirectives: false, - StartIndent: 0, - Indent: 4, - } - return style -} - func (s *Style) Iterate() *Style { newStyle := &Style{ - SortDirectives: s.SortDirectives, SpaceBeforeBlocks: s.SpaceBeforeBlocks, StartIndent: s.StartIndent + s.Indent, Indent: s.Indent, @@ -91,23 +56,33 @@ func DumpDirective(d components.IDirective, style *Style) string { buf.WriteString(d.GetComment()) } buf.WriteString("\n") - buf.WriteString(DumpBlock(d.GetBlock(), style.Iterate())) + buf.WriteString(DumpBlock(d.GetBlock(), style.Iterate(), d.GetBlock().GetLine())) buf.WriteString(fmt.Sprintf("\n%s}", strings.Repeat(" ", style.StartIndent))) } return buf.String() } -func DumpBlock(b components.IBlock, style *Style) string { +func DumpBlock(b components.IBlock, style *Style, startLine int) string { var buf bytes.Buffer - - directives := b.GetDirectives() - if style.SortDirectives { - sort.SliceStable(directives, func(i, j int) bool { - return directives[i].GetName() < directives[j].GetName() - }) + line := startLine + if b.GetLine() > startLine { + for i := 0; i < b.GetLine()-startLine; i++ { + buf.WriteString("\n") + } + line = b.GetLine() } + directives := b.GetDirectives() + for i, directive := range directives { + + if directive.GetLine() > line { + for i := 0; i < b.GetLine()-line; i++ { + buf.WriteString("\n") + } + line = b.GetLine() + } + buf.WriteString(DumpDirective(directive, style)) if i != len(directives)-1 { buf.WriteString("\n") @@ -117,7 +92,7 @@ func DumpBlock(b components.IBlock, style *Style) string { } func DumpConfig(c *components.Config, style *Style) string { - return DumpBlock(c.Block, style) + return DumpBlock(c.Block, style, 1) } func WriteConfig(c *components.Config, style *Style) error { diff --git a/backend/utils/nginx/parser/parser.go b/backend/utils/nginx/parser/parser.go index e5b1bd7ed..1bc7541a4 100644 --- a/backend/utils/nginx/parser/parser.go +++ b/backend/utils/nginx/parser/parser.go @@ -88,6 +88,7 @@ func (p *Parser) parseBlock() *components.Block { context := &components.Block{ Comment: "", Directives: make([]components.IDirective, 0), + Line: p.currentToken.Line, } parsingloop: @@ -100,6 +101,7 @@ parsingloop: case p.curTokenIs(flag.Comment): context.Directives = append(context.Directives, &components.Comment{ Detail: p.currentToken.Literal, + Line: p.currentToken.Line, }) } p.nextToken() @@ -111,6 +113,7 @@ parsingloop: func (p *Parser) parseStatement() components.IDirective { d := &components.Directive{ Name: p.currentToken.Literal, + Line: p.currentToken.Line, } for p.nextToken(); p.currentToken.IsParameterEligible(); p.nextToken() {