From 70f280f880dc300085e72988f01f94b4fd7f6eeb Mon Sep 17 00:00:00 2001 From: Ethan Kan Date: Mon, 9 Feb 2015 15:13:05 -0800 Subject: [PATCH] Added support for unsigned integers in binding parameters of form posts. Also changed parsing of integer fields to take into account the size of the fields. --- binding/binding.go | 56 +++++++++++++++++++++++++++++++++++++--------- context_test.go | 36 +++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 10 deletions(-) diff --git a/binding/binding.go b/binding/binding.go index 99f3d0e1..55f164f0 100644 --- a/binding/binding.go +++ b/binding/binding.go @@ -98,18 +98,54 @@ func mapForm(ptr interface{}, form map[string][]string) error { return nil } +func setIntField(val string, bitSize int, structField reflect.Value) error { + if val == "" { + val = "0" + } + + intVal, err := strconv.ParseInt(val, 10, bitSize) + if err == nil { + structField.SetInt(intVal) + } + + return err +} + +func setUintField(val string, bitSize int, structField reflect.Value) error { + if val == "" { + val = "0" + } + + uintVal, err := strconv.ParseUint(val, 10, bitSize) + if err == nil { + structField.SetUint(uintVal) + } + + return err +} + func setWithProperType(valueKind reflect.Kind, val string, structField reflect.Value) error { switch valueKind { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - if val == "" { - val = "0" - } - intVal, err := strconv.Atoi(val) - if err != nil { - return err - } else { - structField.SetInt(int64(intVal)) - } + case reflect.Int: + return setIntField(val, 0, structField) + case reflect.Int8: + return setIntField(val, 8, structField) + case reflect.Int16: + return setIntField(val, 16, structField) + case reflect.Int32: + return setIntField(val, 32, structField) + case reflect.Int64: + return setIntField(val, 64, structField) + case reflect.Uint: + return setUintField(val, 0, structField) + case reflect.Uint8: + return setUintField(val, 8, structField) + case reflect.Uint16: + return setUintField(val, 16, structField) + case reflect.Uint32: + return setUintField(val, 32, structField) + case reflect.Uint64: + return setUintField(val, 64, structField) case reflect.Bool: if val == "" { val = "false" diff --git a/context_test.go b/context_test.go index c77cd279..745e1cdc 100644 --- a/context_test.go +++ b/context_test.go @@ -441,6 +441,42 @@ func TestBindingJSONMalformed(t *testing.T) { } } +func TestBindingForm(t *testing.T) { + + body := bytes.NewBuffer([]byte("foo=bar&num=123&unum=1234567890")) + + r := New() + r.POST("/binding/form", func(c *Context) { + var body struct { + Foo string `form:"foo"` + Num int `form:"num"` + Unum uint `form:"unum"` + } + if c.Bind(&body) { + c.JSON(200, H{"foo": body.Foo, "num": body.Num, "unum": body.Unum}) + } + }) + + req, _ := http.NewRequest("POST", "/binding/form", body) + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + w := httptest.NewRecorder() + + r.ServeHTTP(w, req) + + if w.Code != 200 { + t.Errorf("Response code should be Ok, was: %d", w.Code) + } + + expected := "{\"foo\":\"bar\",\"num\":123,\"unum\":1234567890}\n" + if w.Body.String() != expected { + t.Errorf("Response should be %s, was %s", expected, w.Body.String()) + } + + if w.HeaderMap.Get("Content-Type") != "application/json; charset=utf-8" { + t.Errorf("Content-Type should be application/json, was %s", w.HeaderMap.Get("Content-Type")) + } +} + func TestClientIP(t *testing.T) { r := New()