| 
57 | 57 |   - [Bind form-data request with custom struct](#bind-form-data-request-with-custom-struct)  | 
58 | 58 |   - [Try to bind body into different structs](#try-to-bind-body-into-different-structs)  | 
59 | 59 |   - [Bind form-data request with custom struct and custom tag](#bind-form-data-request-with-custom-struct-and-custom-tag)  | 
 | 60 | +  - [Bind Query with custom unmarshalers](#bind-query-with-custom-unmarshalers)  | 
60 | 61 |   - [http2 server push](#http2-server-push)  | 
61 | 62 |   - [Define format for the log of routes](#define-format-for-the-log-of-routes)  | 
62 | 63 |   - [Set and get a cookie](#set-and-get-a-cookie)  | 
@@ -1155,7 +1156,7 @@ func main() {  | 
1155 | 1156 |   router.StaticFS("/more_static", http.Dir("my_file_system"))  | 
1156 | 1157 |   router.StaticFile("/favicon.ico", "./resources/favicon.ico")  | 
1157 | 1158 |   router.StaticFileFS("/more_favicon.ico", "more_favicon.ico", http.Dir("my_file_system"))  | 
1158 |  | -    | 
 | 1159 | + | 
1159 | 1160 |   // Listen and serve on 0.0.0.0:8080  | 
1160 | 1161 |   router.Run(":8080")  | 
1161 | 1162 | }  | 
@@ -2002,6 +2003,59 @@ func ListHandler(s *Service) func(ctx *gin.Context) {  | 
2002 | 2003 | }  | 
2003 | 2004 | ```  | 
2004 | 2005 | 
 
  | 
 | 2006 | +### Bind Query with custom unmarshalers  | 
 | 2007 | + | 
 | 2008 | +Any structure that has custom `UnmarshalJSON` or `UnmarshalText` or `UnmarshalBinary` can be used to parse input as necessary  | 
 | 2009 | + | 
 | 2010 | +```go  | 
 | 2011 | +package main  | 
 | 2012 | +import (  | 
 | 2013 | +  "fmt"  | 
 | 2014 | +  "net/http"  | 
 | 2015 | +  "strings"  | 
 | 2016 | +  "github.com/gin-gonic/gin"  | 
 | 2017 | +)  | 
 | 2018 | +// Booking contains data binded using custom unmarshaler.  | 
 | 2019 | +type Payload struct {  | 
 | 2020 | +  Email  EmailDetails `form:"email"`  | 
 | 2021 | +}  | 
 | 2022 | +// this structure has special json unmarshaller, in order to parse email (as an example) as specific structure  | 
 | 2023 | +type EmailDetails struct {  | 
 | 2024 | +  Name string  | 
 | 2025 | +  Host string  | 
 | 2026 | +}  | 
 | 2027 | +func (o *EmailDetails) UnmarshalJSON(data []byte) error {  | 
 | 2028 | +  elems := strings.Split(string(data), "@")  | 
 | 2029 | +  if len(elems) != 2 {  | 
 | 2030 | +    return fmt.Errorf("cannot parse %q as email", string(data))  | 
 | 2031 | +  }  | 
 | 2032 | +  o.Name = elems[0]  | 
 | 2033 | +  o.Host = elems[1]  | 
 | 2034 | +  return nil  | 
 | 2035 | +}  | 
 | 2036 | +func main() {  | 
 | 2037 | +  route := gin.Default()  | 
 | 2038 | +  route.GET("/email", getEmail)  | 
 | 2039 | +  route.Run(":8085")  | 
 | 2040 | +}  | 
 | 2041 | +func getEmail(c *gin.Context) {  | 
 | 2042 | +  var p Payload  | 
 | 2043 | +  if err := c.ShouldBindQuery(&p); err == nil {  | 
 | 2044 | +    c.JSON(http.StatusOK, gin.H{"message": "Email information is correct"})  | 
 | 2045 | +  } else {  | 
 | 2046 | +    c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})  | 
 | 2047 | +  }  | 
 | 2048 | +}  | 
 | 2049 | +```  | 
 | 2050 | + | 
 | 2051 | +```console  | 
 | 2052 | +$  curl "localhost:8085/[email protected]" | 
 | 2053 | +{"message":"Email information is correct"}  | 
 | 2054 | + | 
 | 2055 | +$ curl "localhost:8085/email?email=test-something-else"  | 
 | 2056 | +{"error":"cannot parse \"test-something-else\" as email"}  | 
 | 2057 | +```  | 
 | 2058 | + | 
2005 | 2059 | ### http2 server push  | 
2006 | 2060 | 
 
  | 
2007 | 2061 | http.Pusher is supported only **go1.8+**. See the [golang blog](https://go.dev/blog/h2push) for detail information.  | 
@@ -2134,7 +2188,7 @@ or network CIDRs from where clients which their request headers related to clien  | 
2134 | 2188 | IP can be trusted. They can be IPv4 addresses, IPv4 CIDRs, IPv6 addresses or  | 
2135 | 2189 | IPv6 CIDRs.  | 
2136 | 2190 | 
 
  | 
2137 |  | -**Attention:** Gin trust all proxies by default if you don't specify a trusted   | 
 | 2191 | +**Attention:** Gin trust all proxies by default if you don't specify a trusted  | 
2138 | 2192 | proxy using the function above, **this is NOT safe**. At the same time, if you don't  | 
2139 | 2193 | use any proxy, you can disable this feature by using `Engine.SetTrustedProxies(nil)`,  | 
2140 | 2194 | then `Context.ClientIP()` will return the remote address directly to avoid some  | 
@@ -2163,7 +2217,7 @@ func main() {  | 
2163 | 2217 | ```  | 
2164 | 2218 | 
 
  | 
2165 | 2219 | **Notice:** If you are using a CDN service, you can set the `Engine.TrustedPlatform`  | 
2166 |  | -to skip TrustedProxies check, it has a higher priority than TrustedProxies.   | 
 | 2220 | +to skip TrustedProxies check, it has a higher priority than TrustedProxies.  | 
2167 | 2221 | Look at the example below:  | 
2168 | 2222 | 
 
  | 
2169 | 2223 | ```go  | 
 | 
0 commit comments