fix parsing of url query with all methods

Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
This commit is contained in:
Василий Толстов 2021-09-01 02:06:01 +03:00
parent dd7e872858
commit a1f432fac9
2 changed files with 56 additions and 12 deletions

View File

@ -8,11 +8,27 @@ import (
type Request struct { type Request struct {
Name string `json:"name"` Name string `json:"name"`
Field1 string Field1 string `json:"field1"`
Field2 string Field2 string
Field3 int64 Field3 int64
} }
func TestPathValues(t *testing.T) {
req := &Request{Name: "vtolstov", Field1: "field1"}
p, m, err := newPathRequest("/api/v1/test?Name={name}&Field1={field1}", "POST", "*", req, nil)
if err != nil {
t.Fatal(err)
}
u, err := url.Parse(p)
if err != nil {
t.Fatal(err)
}
_ = m
if u.Query().Get("Name") != "vtolstov" || u.Query().Get("Field1") != "field1" {
t.Fatalf("invalid values %v", u.Query())
}
}
func TestValidPath(t *testing.T) { func TestValidPath(t *testing.T) {
req := &Request{Name: "vtolstov", Field1: "field1", Field2: "field2", Field3: 10} req := &Request{Name: "vtolstov", Field1: "field1", Field2: "field2", Field3: 10}
p, m, err := newPathRequest("/api/v1/{name}/list", "GET", "", req, nil) p, m, err := newPathRequest("/api/v1/{name}/list", "GET", "", req, nil)

50
util.go
View File

@ -52,10 +52,20 @@ func newPathRequest(path string, method string, body string, msg interface{}, ta
fieldsmapskip := make(map[string]struct{}) fieldsmapskip := make(map[string]struct{})
fieldsmap := make(map[string]string, len(tpl)) fieldsmap := make(map[string]string, len(tpl))
for _, v := range tpl { for _, v := range tpl {
if v[0] != '{' || v[len(v)-1] != '}' { var vs, ve int
continue for i := 0; i < len(v); i++ {
switch v[i] {
case '{':
vs = i + 1
case '}':
ve = i
}
if ve != 0 {
fieldsmap[v[vs:ve]] = ""
vs = 0
ve = 0
}
} }
fieldsmap[v[1:len(v)-1]] = ""
} }
nmsg, err := rutil.Zero(msg) nmsg, err := rutil.Zero(msg)
@ -151,18 +161,36 @@ func newPathRequest(path string, method string, body string, msg interface{}, ta
} }
var b strings.Builder var b strings.Builder
for _, fld := range tpl { for _, fld := range tpl {
_, _ = b.WriteRune('/') _, _ = b.WriteRune('/')
// nolint: nestif // nolint: nestif
if fld[0] == '{' && fld[len(fld)-1] == '}' { var vs, ve, vf int
if v, ok := fieldsmap[fld[1:len(fld)-1]]; ok { var pholder bool
if v != "" { for i := 0; i < len(fld); i++ {
_, _ = b.WriteString(v) switch fld[i] {
} case '{':
} else { vs = i + 1
_, _ = b.WriteString(fld) case '}':
ve = i
} }
} else { // nolint: nestif
if vs > 0 && ve != 0 {
if vm, ok := fieldsmap[fld[vs:ve]]; ok {
if vm != "" {
_, _ = b.WriteString(fld[vf : vs-1])
_, _ = b.WriteString(vm)
vf = ve + 1
}
} else {
_, _ = b.WriteString(fld)
}
vs = 0
ve = 0
pholder = true
}
}
if !pholder {
_, _ = b.WriteString(fld) _, _ = b.WriteString(fld)
} }
} }