diff --git a/lib/gat/gatcaddyfile/gattype.go b/lib/gat/gatcaddyfile/gattype.go index 3b96dc9362e13baf888968a69beb34f65710671a..14186ad48db68aa8b19ddd587a42d3ccf82270b7 100644 --- a/lib/gat/gatcaddyfile/gattype.go +++ b/lib/gat/gatcaddyfile/gattype.go @@ -1,6 +1,8 @@ package gatcaddyfile import ( + "fmt" + "github.com/caddyserver/caddy/v2" "github.com/caddyserver/caddy/v2/caddyconfig" "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" @@ -25,6 +27,27 @@ func (ServerType) Setup(blocks []caddyfile.ServerBlock, m map[string]any) (*cadd server.Match = MatcherFromConnectionStrings(block.Keys, &warnings) + for _, segment := range block.Segments { + d := caddyfile.NewDispenser(segment) + if !d.Next() { + continue + } + switch d.Val() { + case "pgbouncer": + var route gat.RouteConfig + if d.CountRemainingArgs() == 2 { + d.Next() + route.Match = MatcherFromConnectionString(d.Val(), &warnings) + } + // TODO(garet) read actual value + server.Routes = append(server.Routes, route) + case "discovery": + // TODO(garet) + default: + return nil, nil, fmt.Errorf("unknown directive: %s", d.Val()) + } + } + app.Servers = append(app.Servers, server) } diff --git a/lib/gat/gatcaddyfile/matchers.go b/lib/gat/gatcaddyfile/matchers.go index a85e141e4e1e9ff489e192582ae4f61dfb0ac1c4..a6c33a0a691e325f9d47ba32982730d44fa9d229 100644 --- a/lib/gat/gatcaddyfile/matchers.go +++ b/lib/gat/gatcaddyfile/matchers.go @@ -7,6 +7,7 @@ import ( "github.com/caddyserver/caddy/v2/caddyconfig" "gfx.cafe/gfx/pggat/lib/gat/matchers" + "gfx.cafe/gfx/pggat/lib/util/strutil" ) func MatcherFromConnectionStrings(strs []string, warnings *[]caddyconfig.Warning) json.RawMessage { @@ -47,9 +48,9 @@ func MatcherFromConnectionString(str string, warnings *[]caddyconfig.Warning) js var and matchers.And var parametersString string - str, parametersString, _ = strings.Cut(str, "?") + str, parametersString, _ = strutil.CutRight(str, "?") - if parametersString != "" { + if parametersString != "" && parametersString != "*" { var parameters matchers.StartupParameters parameters.Parameters = make(map[string]string) kvs := strings.Split(parametersString, "&") @@ -69,8 +70,8 @@ func MatcherFromConnectionString(str string, warnings *[]caddyconfig.Warning) js } var database matchers.Database - str, database.Database, _ = strings.Cut(str, "/") - if database.Database != "" { + str, database.Database, _ = strutil.CutRight(str, "/") + if database.Database != "" && database.Database != "*" { and.And = append( and.And, caddyconfig.JSONModuleObject( @@ -82,16 +83,10 @@ func MatcherFromConnectionString(str string, warnings *[]caddyconfig.Warning) js ) } - var address = matchers.LocalAddress{ - Network: "tcp", - } + var address matchers.LocalAddress var user matchers.User - var ok bool - user.User, address.Address, ok = strings.Cut(str, "@") - if !ok { - address.Address = user.User - user.User = "" - } else if user.User != "" { + user.User, address.Address, _ = strutil.CutLeft(str, "@") + if user.User != "" && user.User != "*" { and.And = append( and.And, caddyconfig.JSONModuleObject( @@ -102,7 +97,12 @@ func MatcherFromConnectionString(str string, warnings *[]caddyconfig.Warning) js ), ) } - if address.Address != "" { + if address.Address != "" && address.Address != "*" { + if strings.HasPrefix(address.Address, "/") { + address.Network = "unix" + } else { + address.Network = "tcp" + } and.And = append( and.And, caddyconfig.JSONModuleObject( diff --git a/lib/gat/handlers/allowed_startup_parameters/module.go b/lib/gat/handlers/allowed_startup_parameters/module.go index 5eeadc4ec642a0421f92f33e01e7fdd11c331d03..f23ab20e767f24769ecd06b515263126b18c929b 100644 --- a/lib/gat/handlers/allowed_startup_parameters/module.go +++ b/lib/gat/handlers/allowed_startup_parameters/module.go @@ -1,4 +1,4 @@ -package module +package allowed_startup_parameters import ( "fmt" diff --git a/lib/util/strutil/cut.go b/lib/util/strutil/cut.go new file mode 100644 index 0000000000000000000000000000000000000000..d8798b33d244a0368bd6acd7b3557f2aa5dc3c57 --- /dev/null +++ b/lib/util/strutil/cut.go @@ -0,0 +1,21 @@ +package strutil + +import "strings" + +// CutLeft is similar to strings.Cut but it returns "", s, false if not found +func CutLeft(s string, sep string) (before, after string, found bool) { + before, after, found = strings.Cut(s, sep) + if !found { + after = before + before = "" + } + return +} + +// CutRight is similar to strings.Cut but it searches from the end first +func CutRight(s string, sep string) (before, after string, found bool) { + if i := strings.LastIndex(s, sep); i >= 0 { + return s[:i], s[i+len(sep):], true + } + return s, "", false +}