diff --git a/Makefile b/Makefile index 7211144a..7ab57e27 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,10 @@ test: exit 1; \ elif grep -q "build failed" tmp.out; then \ rm tmp.out; \ - exit; \ + exit 1; \ + elif grep -q "setup failed" tmp.out; then \ + rm tmp.out; \ + exit 1; \ fi; \ if [ -f profile.out ]; then \ cat profile.out | grep -v "mode:" >> coverage.out; \ diff --git a/binding/binding_test.go b/binding/binding_test.go index 1044e6c2..c9dea347 100644 --- a/binding/binding_test.go +++ b/binding/binding_test.go @@ -61,6 +61,10 @@ type FooStructForMapType struct { MapFoo map[string]interface{} `form:"map_foo"` } +type FooStructForIgnoreFormTag struct { + Foo *string `form:"-"` +} + type InvalidNameType struct { TestName string `invalid_name:"test_name"` } @@ -278,6 +282,12 @@ func TestBindingFormForTime2(t *testing.T) { "", "") } +func TestFormBindingIgnoreField(t *testing.T) { + testFormBindingIgnoreField(t, "POST", + "/", "/", + "-=bar", "") +} + func TestBindingFormInvalidName(t *testing.T) { testFormBindingInvalidName(t, "POST", "/", "/", @@ -860,6 +870,21 @@ func testFormBindingForTimeFailLocation(t *testing.T, method, path, badPath, bod assert.Error(t, err) } +func testFormBindingIgnoreField(t *testing.T, method, path, badPath, body, badBody string) { + b := Form + assert.Equal(t, "form", b.Name()) + + obj := FooStructForIgnoreFormTag{} + req := requestWithBody(method, path, body) + if method == "POST" { + req.Header.Add("Content-Type", MIMEPOSTForm) + } + err := b.Bind(req, &obj) + assert.NoError(t, err) + + assert.Nil(t, obj.Foo) +} + func testFormBindingInvalidName(t *testing.T, method, path, badPath, body, badBody string) { b := Form assert.Equal(t, "form", b.Name()) diff --git a/binding/form_mapping.go b/binding/form_mapping.go index 8900ab70..8eb5c0d1 100644 --- a/binding/form_mapping.go +++ b/binding/form_mapping.go @@ -41,6 +41,9 @@ func mapFormByTag(ptr interface{}, form map[string][]string, tag string) error { defaultValue = defaultList[1] } } + if inputFieldName == "-" { + continue + } if inputFieldName == "" { inputFieldName = typeField.Name diff --git a/gin.go b/gin.go index 6e5ea6d7..ad64c35f 100644 --- a/gin.go +++ b/gin.go @@ -318,6 +318,7 @@ func (engine *Engine) RunUnix(file string) (err error) { return } defer listener.Close() + os.Chmod(file, 0777) err = http.Serve(listener, engine) return } diff --git a/logger.go b/logger.go index 6d8f838e..bd28a11c 100644 --- a/logger.go +++ b/logger.go @@ -64,6 +64,8 @@ type LogFormatterParams struct { ErrorMessage string // IsTerm shows whether does gin's output descriptor refers to a terminal. IsTerm bool + // BodySize is the size of the Response Body + BodySize int } // defaultLogFormatter is the default log format function Logger middleware uses. @@ -191,6 +193,8 @@ func LoggerWithConfig(conf LoggerConfig) HandlerFunc { param.StatusCode = c.Writer.Status() param.ErrorMessage = c.Errors.ByType(ErrorTypePrivate).String() + param.BodySize = c.Writer.Size() + if raw != "" { path = path + "?" + raw } diff --git a/mode.go b/mode.go index f787b5ca..8aa84aa8 100644 --- a/mode.go +++ b/mode.go @@ -11,8 +11,8 @@ import ( "github.com/gin-gonic/gin/binding" ) -// ENV_GIN_MODE indicates environment name for gin mode. -const ENV_GIN_MODE = "GIN_MODE" +// EnvGinMode indicates environment name for gin mode. +const EnvGinMode = "GIN_MODE" const ( // DebugMode indicates gin mode is debug. @@ -44,7 +44,7 @@ var ginMode = debugCode var modeName = DebugMode func init() { - mode := os.Getenv(ENV_GIN_MODE) + mode := os.Getenv(EnvGinMode) SetMode(mode) } diff --git a/mode_test.go b/mode_test.go index cf27acd8..3dba5150 100644 --- a/mode_test.go +++ b/mode_test.go @@ -13,13 +13,13 @@ import ( ) func init() { - os.Setenv(ENV_GIN_MODE, TestMode) + os.Setenv(EnvGinMode, TestMode) } func TestSetMode(t *testing.T) { assert.Equal(t, testCode, ginMode) assert.Equal(t, TestMode, Mode()) - os.Unsetenv(ENV_GIN_MODE) + os.Unsetenv(EnvGinMode) SetMode("") assert.Equal(t, debugCode, ginMode)