diff --git a/context.go b/context.go index 12920fd8..6c528eb7 100644 --- a/context.go +++ b/context.go @@ -72,6 +72,8 @@ func (c *Context) Copy() *Context { return &cp } +// Returns the main handle's name. For example if the handler is "handleGetUsers()", this +// function will return "main.handleGetUsers" func (c *Context) HandlerName() string { return nameOfFunction(c.handlers.Last()) } @@ -125,7 +127,8 @@ func (c *Context) AbortWithError(code int, err error) *Error { // Attaches an error to the current context. The error is pushed to a list of errors. // It's a good idea to call Error for each error that occurred during the resolution of a request. -// A middleware can be used to collect all the errors and push them to a database together, print a log, or append it in the HTTP response. +// A middleware can be used to collect all the errors +// and push them to a database together, print a log, or append it in the HTTP response. func (c *Context) Error(err error) *Error { var parsedError *Error switch err.(type) { @@ -145,8 +148,8 @@ func (c *Context) Error(err error) *Error { /******** METADATA MANAGEMENT********/ /************************************/ -// Sets a new pair key/value just for this context. -// It also lazy initializes the hashmap if it was not used previously. +// Set is used to store a new key/value pair exclusivelly for this context. +// It also lazy initializes c.Keys if it was not used previously. func (c *Context) Set(key string, value interface{}) { if c.Keys == nil { c.Keys = make(map[string]interface{}) @@ -154,7 +157,7 @@ func (c *Context) Set(key string, value interface{}) { c.Keys[key] = value } -// Returns the value for the given key, ie: (value, true). +// Get returns the value for the given key, ie: (value, true). // If the value does not exists it returns (nil, false) func (c *Context) Get(key string) (value interface{}, exists bool) { if c.Keys != nil { @@ -175,19 +178,19 @@ func (c *Context) MustGet(key string) interface{} { /************ INPUT DATA ************/ /************************************/ -// Shortcut for c.Request.URL.Query().Get(key) +// Query is a shortcut for c.Request.URL.Query().Get(key) func (c *Context) Query(key string) (va string) { va, _ = c.query(key) return } -// Shortcut for c.Request.PostFormValue(key) +// PostForm is a shortcut for c.Request.PostFormValue(key) func (c *Context) PostForm(key string) (va string) { va, _ = c.postForm(key) return } -// Shortcut for c.Params.ByName(key) +// Param is a shortcut for c.Params.ByName(key) func (c *Context) Param(key string) string { return c.Params.ByName(key) } @@ -199,6 +202,13 @@ func (c *Context) DefaultPostForm(key, defaultValue string) string { return defaultValue } +// DefaultQuery returns the keyed url query value if it exists, othewise it returns the +// specified defaultValue. +// ``` +// /?name=Manu +// c.DefaultQuery("name", "unknown") == "Manu" +// c.DefaultQuery("id", "none") == "none" +// ``` func (c *Context) DefaultQuery(key, defaultValue string) string { if va, ok := c.query(key); ok { return va @@ -228,22 +238,26 @@ func (c *Context) postForm(key string) (string, bool) { return "", false } -// This function checks the Content-Type to select a binding engine automatically, +// Bind checks the Content-Type to select a binding engine automatically, // Depending the "Content-Type" header different bindings are used: // "application/json" --> JSON binding // "application/xml" --> XML binding -// else --> returns an error -// if Parses the request's body as JSON if Content-Type == "application/json" using JSON or XML as a JSON input. It decodes the json payload into the struct specified as a pointer.Like ParseBody() but this method also writes a 400 error if the json is not valid. +// otherwise --> returns an error +// If Parses the request's body as JSON if Content-Type == "application/json" using JSON or XML as a JSON input. +// It decodes the json payload into the struct specified as a pointer. +// Like ParseBody() but this method also writes a 400 error if the json is not valid. func (c *Context) Bind(obj interface{}) error { b := binding.Default(c.Request.Method, c.ContentType()) return c.BindWith(obj, b) } -// Shortcut for c.BindWith(obj, binding.JSON) +// BindJSON is a shortcut for c.BindWith(obj, binding.JSON) func (c *Context) BindJSON(obj interface{}) error { return c.BindWith(obj, binding.JSON) } +// BindWith binds the passed struct pointer using the specified binding engine. +// See the binding package. func (c *Context) BindWith(obj interface{}, b binding.Binding) error { if err := b.Bind(c.Request, obj); err != nil { c.AbortWithError(400, err).SetType(ErrorTypeBind) @@ -252,7 +266,7 @@ func (c *Context) BindWith(obj interface{}, b binding.Binding) error { return nil } -// Best effort algoritm to return the real client IP, it parses +// ClientIP implements a best effort algorithm to return the real client IP, it parses // X-Real-IP and X-Forwarded-For in order to work properly with reverse-proxies such us: nginx or haproxy. func (c *Context) ClientIP() string { if c.engine.ForwardedByClientIP { @@ -272,6 +286,7 @@ func (c *Context) ClientIP() string { return strings.TrimSpace(c.Request.RemoteAddr) } +// ContentType returns the Content-Type header of the request. func (c *Context) ContentType() string { return filterFlags(c.requestHeader("Content-Type")) } @@ -287,8 +302,8 @@ func (c *Context) requestHeader(key string) string { /******** RESPONSE RENDERING ********/ /************************************/ -// Intelligent shortcut for c.Writer.Header().Set(key, value) -// it writes a header in the response. +// Header is a intelligent shortcut for c.Writer.Header().Set(key, value) +// It writes a header in the response. // If value == "", this method removes the header `c.Writer.Header().Del(key)` func (c *Context) Header(key, value string) { if len(value) == 0 { @@ -310,7 +325,7 @@ func (c *Context) renderError(err error) { c.AbortWithError(500, err).SetType(ErrorTypeRender) } -// Renders the HTTP template specified by its file name. +// HTML renders the HTTP template specified by its file name. // It also updates the HTTP code and sets the Content-Type as "text/html". // See http://golang.org/doc/articles/wiki/ func (c *Context) HTML(code int, name string, obj interface{}) { @@ -318,7 +333,7 @@ func (c *Context) HTML(code int, name string, obj interface{}) { c.Render(code, instance) } -// Serializes the given struct as pretty JSON (indented + endlines) into the response body. +// IndentedJSON serializes the given struct as pretty JSON (indented + endlines) into the response body. // It also sets the Content-Type as "application/json". // WARNING: we recommend to use this only for development propuses since printing pretty JSON is // more CPU and bandwidth consuming. Use Context.JSON() instead. @@ -326,7 +341,7 @@ func (c *Context) IndentedJSON(code int, obj interface{}) { c.Render(code, render.IndentedJSON{Data: obj}) } -// Serializes the given struct as JSON into the response body. +// JSON serializes the given struct as JSON into the response body. // It also sets the Content-Type as "application/json". func (c *Context) JSON(code int, obj interface{}) { c.writermem.WriteHeader(code) @@ -335,19 +350,19 @@ func (c *Context) JSON(code int, obj interface{}) { } } -// Serializes the given struct as XML into the response body. +// XML serializes the given struct as XML into the response body. // It also sets the Content-Type as "application/xml". func (c *Context) XML(code int, obj interface{}) { c.Render(code, render.XML{Data: obj}) } -// Writes the given string into the response body. +// String writes the given string into the response body. func (c *Context) String(code int, format string, values ...interface{}) { c.writermem.WriteHeader(code) render.WriteString(c.Writer, format, values) } -// Returns a HTTP redirect to the specific location. +// Redirect returns a HTTP redirect to the specific location. func (c *Context) Redirect(code int, location string) { c.Render(-1, render.Redirect{ Code: code, diff --git a/errors.go b/errors.go index 982c0267..e829c886 100644 --- a/errors.go +++ b/errors.go @@ -102,10 +102,10 @@ func (a errorMsgs) ByType(typ ErrorType) errorMsgs { // Shortcut for errors[len(errors)-1] func (a errorMsgs) Last() *Error { length := len(a) - if length == 0 { - return nil + if length > 0 { + return a[length-1] } - return a[length-1] + return nil } // Returns an array will all the error messages. diff --git a/gin.go b/gin.go index 7b0ede17..e06792b9 100644 --- a/gin.go +++ b/gin.go @@ -209,8 +209,8 @@ func iterate(path, method string, routes RoutesInfo, root *node) RoutesInfo { Handler: nameOfFunction(root.handlers.Last()), }) } - for _, node := range root.children { - routes = iterate(path, method, routes, node) + for _, child := range root.children { + routes = iterate(path, method, routes, child) } return routes }