@@ -59,7 +59,7 @@ type Context struct {
5959	params        * Params 
6060	skippedNodes  * []skippedNode 
6161
62- 	// This mutex protect  Keys map 
62+ 	// This mutex protects  Keys map.  
6363	mu  sync.RWMutex 
6464
6565	// Keys is a key/value pair exclusively for the context of each request. 
@@ -71,10 +71,10 @@ type Context struct {
7171	// Accepted defines a list of manually accepted formats for content negotiation. 
7272	Accepted  []string 
7373
74- 	// queryCache use url.ParseQuery cached  the param  query result from c.Request.URL.Query() 
74+ 	// queryCache caches  the query result from c.Request.URL.Query().  
7575	queryCache  url.Values 
7676
77- 	// formCache use url.ParseQuery cached  PostForm contains the parsed form data from POST, PATCH, 
77+ 	// formCache caches c.Request. PostForm, which  contains the parsed form data from POST, PATCH, 
7878	// or PUT body parameters. 
7979	formCache  url.Values 
8080
@@ -252,7 +252,7 @@ func (c *Context) Set(key string, value interface{}) {
252252}
253253
254254// Get returns the value for the given key, ie: (value, true). 
255- // If the value does not exists  it returns (nil, false) 
255+ // If the value does not exist  it returns (nil, false) 
256256func  (c  * Context ) Get (key  string ) (value  interface {}, exists  bool ) {
257257	c .mu .RLock ()
258258	value , exists  =  c .Keys [key ]
@@ -602,7 +602,7 @@ func (c *Context) SaveUploadedFile(file *multipart.FileHeader, dst string) error
602602}
603603
604604// Bind checks the Content-Type to select a binding engine automatically, 
605- // Depending the "Content-Type" header different bindings are used: 
605+ // Depending on  the "Content-Type" header different bindings are used: 
606606//     "application/json" --> JSON binding 
607607//     "application/xml"  --> XML binding 
608608// otherwise --> returns an error. 
@@ -661,7 +661,7 @@ func (c *Context) MustBindWith(obj interface{}, b binding.Binding) error {
661661}
662662
663663// ShouldBind checks the Content-Type to select a binding engine automatically, 
664- // Depending the "Content-Type" header different bindings are used: 
664+ // Depending on  the "Content-Type" header different bindings are used: 
665665//     "application/json" --> JSON binding 
666666//     "application/xml"  --> XML binding 
667667// otherwise --> returns an error 
@@ -739,7 +739,7 @@ func (c *Context) ShouldBindBodyWith(obj interface{}, bb binding.BindingBody) (e
739739// It called c.RemoteIP() under the hood, to check if the remote IP is a trusted proxy or not. 
740740// If it is it will then try to parse the headers defined in Engine.RemoteIPHeaders (defaulting to [X-Forwarded-For, X-Real-Ip]). 
741741// If the headers are not syntactically valid OR the remote IP does not correspond to a trusted proxy, 
742- // the remote IP (coming form  Request.RemoteAddr) is returned. 
742+ // the remote IP (coming from  Request.RemoteAddr) is returned. 
743743func  (c  * Context ) ClientIP () string  {
744744	// Check if we're running on a trusted platform, continue running backwards if error 
745745	if  c .engine .TrustedPlatform  !=  ""  {
@@ -757,10 +757,14 @@ func (c *Context) ClientIP() string {
757757		}
758758	}
759759
760- 	remoteIP , trusted  :=  c .RemoteIP ()
760+ 	// It also checks if the remoteIP is a trusted proxy or not. 
761+ 	// In order to perform this validation, it will see if the IP is contained within at least one of the CIDR blocks 
762+ 	// defined by Engine.SetTrustedProxies() 
763+ 	remoteIP  :=  net .ParseIP (c .RemoteIP ())
761764	if  remoteIP  ==  nil  {
762765		return  "" 
763766	}
767+ 	trusted  :=  c .engine .isTrustedProxy (remoteIP )
764768
765769	if  trusted  &&  c .engine .ForwardedByClientIP  &&  c .engine .RemoteIPHeaders  !=  nil  {
766770		for  _ , headerName  :=  range  c .engine .RemoteIPHeaders  {
@@ -773,53 +777,13 @@ func (c *Context) ClientIP() string {
773777	return  remoteIP .String ()
774778}
775779
776- func  (e  * Engine ) isTrustedProxy (ip  net.IP ) bool  {
777- 	if  e .trustedCIDRs  !=  nil  {
778- 		for  _ , cidr  :=  range  e .trustedCIDRs  {
779- 			if  cidr .Contains (ip ) {
780- 				return  true 
781- 			}
782- 		}
783- 	}
784- 	return  false 
785- }
786- 
787780// RemoteIP parses the IP from Request.RemoteAddr, normalizes and returns the IP (without the port). 
788- // It also checks if the remoteIP is a trusted proxy or not. 
789- // In order to perform this validation, it will see if the IP is contained within at least one of the CIDR blocks 
790- // defined by Engine.SetTrustedProxies() 
791- func  (c  * Context ) RemoteIP () (net.IP , bool ) {
781+ func  (c  * Context ) RemoteIP () string  {
792782	ip , _ , err  :=  net .SplitHostPort (strings .TrimSpace (c .Request .RemoteAddr ))
793783	if  err  !=  nil  {
794- 		return  nil , false 
795- 	}
796- 	remoteIP  :=  net .ParseIP (ip )
797- 	if  remoteIP  ==  nil  {
798- 		return  nil , false 
799- 	}
800- 
801- 	return  remoteIP , c .engine .isTrustedProxy (remoteIP )
802- }
803- 
804- func  (e  * Engine ) validateHeader (header  string ) (clientIP  string , valid  bool ) {
805- 	if  header  ==  ""  {
806- 		return  "" , false 
807- 	}
808- 	items  :=  strings .Split (header , "," )
809- 	for  i  :=  len (items ) -  1 ; i  >=  0 ; i --  {
810- 		ipStr  :=  strings .TrimSpace (items [i ])
811- 		ip  :=  net .ParseIP (ipStr )
812- 		if  ip  ==  nil  {
813- 			return  "" , false 
814- 		}
815- 
816- 		// X-Forwarded-For is appended by proxy 
817- 		// Check IPs in reverse order and stop when find untrusted proxy 
818- 		if  (i  ==  0 ) ||  (! e .isTrustedProxy (ip )) {
819- 			return  ipStr , true 
820- 		}
784+ 		return  "" 
821785	}
822- 	return 
786+ 	return   ip 
823787}
824788
825789// ContentType returns the Content-Type header of the request. 
@@ -863,7 +827,7 @@ func (c *Context) Status(code int) {
863827	c .Writer .WriteHeader (code )
864828}
865829
866- // Header is a  intelligent shortcut for c.Writer.Header().Set(key, value). 
830+ // Header is an  intelligent shortcut for c.Writer.Header().Set(key, value). 
867831// It writes a header in the response. 
868832// If value == "", this method removes the header `c.Writer.Header().Del(key)` 
869833func  (c  * Context ) Header (key , value  string ) {
@@ -946,7 +910,7 @@ func (c *Context) HTML(code int, name string, obj interface{}) {
946910
947911// IndentedJSON serializes the given struct as pretty JSON (indented + endlines) into the response body. 
948912// It also sets the Content-Type as "application/json". 
949- // WARNING: we recommend to use  this only for development purposes since printing pretty JSON is 
913+ // WARNING: we recommend using  this only for development purposes since printing pretty JSON is 
950914// more CPU and bandwidth consuming. Use Context.JSON() instead. 
951915func  (c  * Context ) IndentedJSON (code  int , obj  interface {}) {
952916	c .Render (code , render.IndentedJSON {Data : obj })
@@ -1010,7 +974,7 @@ func (c *Context) String(code int, format string, values ...interface{}) {
1010974	c .Render (code , render.String {Format : format , Data : values })
1011975}
1012976
1013- // Redirect returns a  HTTP redirect to the specific location. 
977+ // Redirect returns an  HTTP redirect to the specific location. 
1014978func  (c  * Context ) Redirect (code  int , location  string ) {
1015979	c .Render (- 1 , render.Redirect {
1016980		Code :     code ,
@@ -1102,7 +1066,7 @@ type Negotiate struct {
11021066	Data      interface {}
11031067}
11041068
1105- // Negotiate calls different Render according acceptable Accept format. 
1069+ // Negotiate calls different Render according to  acceptable Accept format. 
11061070func  (c  * Context ) Negotiate (code  int , config  Negotiate ) {
11071071	switch  c .NegotiateFormat (config .Offered ... ) {
11081072	case  binding .MIMEJSON :
0 commit comments