* support bind http header param #1956
update #1956
```
package main
import (
"fmt"
"github.com/gin-gonic/gin"
)
type testHeader struct {
Rate int `header:"Rate"`
Domain string `header:"Domain"`
}
func main() {
r := gin.Default()
r.GET("/", func(c *gin.Context) {
h := testHeader{}
if err := c.ShouldBindHeader(&h); err != nil {
c.JSON(200, err)
}
fmt.Printf("%#v\n", h)
c.JSON(200, gin.H{"Rate": h.Rate, "Domain": h.Domain})
})
r.Run()
// client
// curl -H "rate:300" -H "domain:music" 127.0.0.1:8080/
// output
// {"Domain":"music","Rate":300}
}
```
* add unit test
* Modify the code to get the http header
When the http header is obtained in the standard library,
the key value will be modified by the CanonicalMIMEHeaderKey function,
and finally the value of the http header will be obtained from the map.
As follows.
```go
func (h MIMEHeader) Get(key string) string {
// ...
v := h[CanonicalMIMEHeaderKey(key)]
// ...
}
```
This pr also follows this modification
* Thanks to vkd for suggestions, modifying code
* Increase test coverage
env GOPATH=`pwd` go test github.com/gin-gonic/gin/binding -coverprofile=cover.prof
ok github.com/gin-gonic/gin/binding 0.015s coverage: 100.0% of statements
* Rollback check code
* add use case to README.md
* Fix context.Params race condition on Copy()
Using context.Param(key) on a context.Copy inside a goroutine
may lead to incorrect value on a high load, where another request
overwrite a Param
* Using waitgroup to wait asynchronous test case
* Add context.HandlerNames()
This change adds a HandlerNames method that will return all registered handles in the context, in descending order
This is useful for debugging and troubleshooting purposes, especially in large apps
* Tests
Add tests for HandlerNames
* Fix HandlerNames test
* Simplify test
* fix Context.Next() - recheck len of handlers every iteration
* add tests when Context.reset() can be called inside of handler
TestEngineHandleContext
TestContextResetInHandler
TestRouterStaticFSFileNotFound
* Context.Next() - format to while style
When `gin.Context.FormFile("...")` is called the `engine.MaxMultipartMemory` is never used. This PR makes sure that the `MaxMultipartMemory` is passed and removes 2 calls to `http.Request.ParseForm` since they are called from `http.Request.ParseMultipartForm`
`Gin` now have the `protobufBinding` function to check the request format, but didn't have a protobuf response function like `c.YAML()`.
In our company [ByteDance](http://bytedance.com/), the largest internet company using golang in China, we use `gin` to transfer __Protobuf__ instead of __Json__, we have to write some internal library to make some wrappers to achieve that, and the code is not elegant. So we really want such a feature.
* support query map
* add GetQueryMap and unittest
* support post-form map
* add readme for query map
* attempt to fix bug for post-form map when go version is 1.6
* remove duplicate code
* remove comment
* Add interface to read body bytes in binding
* Add BindingBody implementation for some binding
* Fix to use `BindBodyBytesKey` for key
* Revert "Fix to use `BindBodyBytesKey` for key"
This reverts commit 2c82901ceab6ae53730a3cfcd9839bee11a08f13.
* Use private-like key for body bytes
* Add tests for BindingBody & ShouldBindBodyWith
* Add note for README
* Remove redundant space between sentences
* feat(context): ShouldBind counterparts for Bind methods + tests
* docs(readme): Switch examples to use ShouldBind methods
Add section for bind methods types, explain difference in behavior.
Switch all `c.Bind` examples to use `c.ShouldBind`.
* update json-iterator revison to fix TestRenderIndentedJSON failed
* fix(test): add space between key and value as same as standard JSON.
* fix(test): add space between key and value as same as standard JSON.
* Add new function to Render interface for writing content type only
* Add support for the new function in Render interface for writing content-type only
* Fix unhandled merge conflict in context_test.go
* Update vendor.json
Otherwise, caller needs to invoke WriteHeaderNow himself after
AbortWithStatus(), which is error-prone.
Also modified ErrorLoggerT() such that it always writes log to response
body. Otherwise calling AbortWithStatus() will fail to write body because
c.Writer.Written() is set true by WriteHeaderNow().
benchmark old ns/op new ns/op delta
BenchmarkManyHandlers 4956 4463 -9.95%
benchmark old allocs new allocs delta
BenchmarkManyHandlers 16 13 -18.75%
benchmark old bytes new bytes delta
BenchmarkManyHandlers 256 216 -15.62%