Closed
Description
Issue Description
In v4.1.14 and v4.1.16, Bind is still broken (similar to issues #1448 and #1356) when the path has a :param
and the bind variable is not initialized. Without a path :param
, both work as expected.
Checklist
- [*] Dependencies installed
- [*] No typos
- [*] Searched existing issues and docs
Expected behaviour
Bind should work for both paths with params in the example code below, no panic or error.
Actual behaviour
Panic on bind to a single var.
False-positive error on bind to slice of vars.
Steps to reproduce
See working code below.
Working code to debug
package main
import (
"github.com/labstack/echo/v4"
"log"
)
type T map[string]interface{}
func main() {
s := echo.New()
s.PUT("/one/:foo", func(c echo.Context) error {
var t T
if err := c.Bind(&t); err != nil {
log.Fatal(err)
}
log.Printf("OK: %+v", t)
return nil
})
s.PUT("/many/:foo", func(c echo.Context) error {
var t []T
if err := c.Bind(&t); err != nil {
log.Fatal(err)
}
log.Printf("OK: %+v", t)
return nil
})
s.Start(":8811")
}
For single var (/one/:foo
):
$ curl -X PUT -H "Content-Type: application/json" -d '{"name":"John"}' localhost:8811/one/foo
____ __
/ __/___/ / ___
/ _// __/ _ \/ _ \
/___/\__/_//_/\___/ v4.1.14
High performance, minimalist Go web framework
https://echo.labstack.com
____________________________________O/_______
O\
⇨ http server started on [::]:8811
echo: http: panic serving 127.0.0.1:62092: assignment to entry in nil map
goroutine 21 [running]:
net/http.(*conn).serve.func1(0xc0000ccaa0)
/usr/local/Cellar/go/1.13.3/libexec/src/net/http/server.go:1767 +0x139
panic(0x1310540, 0x13df5b0)
/usr/local/Cellar/go/1.13.3/libexec/src/runtime/panic.go:679 +0x1b2
reflect.mapassign(0x1310240, 0x0, 0xc00009f0e0, 0xc00009f100)
/usr/local/Cellar/go/1.13.3/libexec/src/runtime/map.go:1329 +0x3f
reflect.Value.SetMapIndex(0x1310240, 0xc0000b8060, 0x195, 0x12f5e20, 0xc00009f0e0, 0x98, 0x1306240, 0xc00009f100, 0x94)
/usr/local/Cellar/go/1.13.3/libexec/src/reflect/value.go:1679 +0x268
github.com/labstack/echo/v4.(*DefaultBinder).bindData(0x1623b80, 0x12e7f80, 0xc0000b8060, 0xc000119918, 0x1374844, 0x5, 0x104b9a6, 0x105d1f0)
/Users/dn/Development/go/pkg/mod/github.com/labstack/echo/[email protected]/bind.go:96 +0x23b
github.com/labstack/echo/v4.(*DefaultBinder).Bind(0x1623b80, 0x12e7f80, 0xc0000b8060, 0x13f1520, 0xc0000ccb40, 0xc000119b01, 0xc0000b8060)
/Users/dn/Development/go/pkg/mod/github.com/labstack/echo/[email protected]/bind.go:43 +0x2a5
github.com/labstack/echo/v4.(*context).Bind(0xc0000ccb40, 0x12e7f80, 0xc0000b8060, 0xc000092540, 0xc000108070)
/Users/dn/Development/go/pkg/mod/github.com/labstack/echo/[email protected]/context.go:396 +0x63
main.main.func1(0x13f1520, 0xc0000ccb40, 0x0, 0x0)
/Users/dn/Development/go/src/github.com/daniel-nichter/lab/echov4/main.go:15 +0x60
github.com/labstack/echo/v4.(*Echo).add.func1(0x13f1520, 0xc0000ccb40, 0x0, 0x0)
/Users/dn/Development/go/pkg/mod/github.com/labstack/echo/[email protected]/echo.go:509 +0x8a
github.com/labstack/echo/v4.(*Echo).ServeHTTP(0xc000106000, 0x13ea420, 0xc0001041c0, 0xc00011c000)
/Users/dn/Development/go/pkg/mod/github.com/labstack/echo/[email protected]/echo.go:620 +0x16c
net/http.serverHandler.ServeHTTP(0xc000104000, 0x13ea420, 0xc0001041c0, 0xc00011c000)
/usr/local/Cellar/go/1.13.3/libexec/src/net/http/server.go:2802 +0xa4
net/http.(*conn).serve(0xc0000ccaa0, 0x13eab20, 0xc0000905c0)
/usr/local/Cellar/go/1.13.3/libexec/src/net/http/server.go:1890 +0x875
created by net/http.(*Server).Serve
/usr/local/Cellar/go/1.13.3/libexec/src/net/http/server.go:2927 +0x38e
For a slice of vars (/many/:foo
)
$ curl -X PUT -H "Content-Type: application/json" -d '[{"name":"John"}]' localhost:8811/many/foo
2020/02/01 15:05:57 code=400, message=binding element must be a struct, internal=binding element must be a struct
Remove :foo
param from both paths and both will work as expected.
Version/commit
v4.1.14 and v4.1.16