"Fossies" - the Fresh Open Source Software Archive

Member "gin-1.7.7/context.go" (24 Nov 2021, 37175 Bytes) of package /linux/www/gin-1.7.7.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Go source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "context.go": 1.7.6_vs_1.7.7.

    1 // Copyright 2014 Manu Martinez-Almeida.  All rights reserved.
    2 // Use of this source code is governed by a MIT style
    3 // license that can be found in the LICENSE file.
    4 
    5 package gin
    6 
    7 import (
    8     "errors"
    9     "fmt"
   10     "io"
   11     "io/ioutil"
   12     "log"
   13     "math"
   14     "mime/multipart"
   15     "net"
   16     "net/http"
   17     "net/url"
   18     "os"
   19     "strings"
   20     "sync"
   21     "time"
   22 
   23     "github.com/gin-contrib/sse"
   24     "github.com/gin-gonic/gin/binding"
   25     "github.com/gin-gonic/gin/render"
   26 )
   27 
   28 // Content-Type MIME of the most common data formats.
   29 const (
   30     MIMEJSON              = binding.MIMEJSON
   31     MIMEHTML              = binding.MIMEHTML
   32     MIMEXML               = binding.MIMEXML
   33     MIMEXML2              = binding.MIMEXML2
   34     MIMEPlain             = binding.MIMEPlain
   35     MIMEPOSTForm          = binding.MIMEPOSTForm
   36     MIMEMultipartPOSTForm = binding.MIMEMultipartPOSTForm
   37     MIMEYAML              = binding.MIMEYAML
   38 )
   39 
   40 // BodyBytesKey indicates a default body bytes key.
   41 const BodyBytesKey = "_gin-gonic/gin/bodybyteskey"
   42 
   43 const abortIndex int8 = math.MaxInt8 / 2
   44 
   45 // Context is the most important part of gin. It allows us to pass variables between middleware,
   46 // manage the flow, validate the JSON of a request and render a JSON response for example.
   47 type Context struct {
   48     writermem responseWriter
   49     Request   *http.Request
   50     Writer    ResponseWriter
   51 
   52     Params   Params
   53     handlers HandlersChain
   54     index    int8
   55     fullPath string
   56 
   57     engine       *Engine
   58     params       *Params
   59     skippedNodes *[]skippedNode
   60 
   61     // This mutex protect Keys map
   62     mu sync.RWMutex
   63 
   64     // Keys is a key/value pair exclusively for the context of each request.
   65     Keys map[string]interface{}
   66 
   67     // Errors is a list of errors attached to all the handlers/middlewares who used this context.
   68     Errors errorMsgs
   69 
   70     // Accepted defines a list of manually accepted formats for content negotiation.
   71     Accepted []string
   72 
   73     // queryCache use url.ParseQuery cached the param query result from c.Request.URL.Query()
   74     queryCache url.Values
   75 
   76     // formCache use url.ParseQuery cached PostForm contains the parsed form data from POST, PATCH,
   77     // or PUT body parameters.
   78     formCache url.Values
   79 
   80     // SameSite allows a server to define a cookie attribute making it impossible for
   81     // the browser to send this cookie along with cross-site requests.
   82     sameSite http.SameSite
   83 }
   84 
   85 /************************************/
   86 /********** CONTEXT CREATION ********/
   87 /************************************/
   88 
   89 func (c *Context) reset() {
   90     c.Writer = &c.writermem
   91     c.Params = c.Params[0:0]
   92     c.handlers = nil
   93     c.index = -1
   94 
   95     c.fullPath = ""
   96     c.Keys = nil
   97     c.Errors = c.Errors[0:0]
   98     c.Accepted = nil
   99     c.queryCache = nil
  100     c.formCache = nil
  101     *c.params = (*c.params)[:0]
  102     *c.skippedNodes = (*c.skippedNodes)[:0]
  103 }
  104 
  105 // Copy returns a copy of the current context that can be safely used outside the request's scope.
  106 // This has to be used when the context has to be passed to a goroutine.
  107 func (c *Context) Copy() *Context {
  108     cp := Context{
  109         writermem: c.writermem,
  110         Request:   c.Request,
  111         Params:    c.Params,
  112         engine:    c.engine,
  113     }
  114     cp.writermem.ResponseWriter = nil
  115     cp.Writer = &cp.writermem
  116     cp.index = abortIndex
  117     cp.handlers = nil
  118     cp.Keys = map[string]interface{}{}
  119     for k, v := range c.Keys {
  120         cp.Keys[k] = v
  121     }
  122     paramCopy := make([]Param, len(cp.Params))
  123     copy(paramCopy, cp.Params)
  124     cp.Params = paramCopy
  125     return &cp
  126 }
  127 
  128 // HandlerName returns the main handler's name. For example if the handler is "handleGetUsers()",
  129 // this function will return "main.handleGetUsers".
  130 func (c *Context) HandlerName() string {
  131     return nameOfFunction(c.handlers.Last())
  132 }
  133 
  134 // HandlerNames returns a list of all registered handlers for this context in descending order,
  135 // following the semantics of HandlerName()
  136 func (c *Context) HandlerNames() []string {
  137     hn := make([]string, 0, len(c.handlers))
  138     for _, val := range c.handlers {
  139         hn = append(hn, nameOfFunction(val))
  140     }
  141     return hn
  142 }
  143 
  144 // Handler returns the main handler.
  145 func (c *Context) Handler() HandlerFunc {
  146     return c.handlers.Last()
  147 }
  148 
  149 // FullPath returns a matched route full path. For not found routes
  150 // returns an empty string.
  151 //     router.GET("/user/:id", func(c *gin.Context) {
  152 //         c.FullPath() == "/user/:id" // true
  153 //     })
  154 func (c *Context) FullPath() string {
  155     return c.fullPath
  156 }
  157 
  158 /************************************/
  159 /*********** FLOW CONTROL ***********/
  160 /************************************/
  161 
  162 // Next should be used only inside middleware.
  163 // It executes the pending handlers in the chain inside the calling handler.
  164 // See example in GitHub.
  165 func (c *Context) Next() {
  166     c.index++
  167     for c.index < int8(len(c.handlers)) {
  168         c.handlers[c.index](c)
  169         c.index++
  170     }
  171 }
  172 
  173 // IsAborted returns true if the current context was aborted.
  174 func (c *Context) IsAborted() bool {
  175     return c.index >= abortIndex
  176 }
  177 
  178 // Abort prevents pending handlers from being called. Note that this will not stop the current handler.
  179 // Let's say you have an authorization middleware that validates that the current request is authorized.
  180 // If the authorization fails (ex: the password does not match), call Abort to ensure the remaining handlers
  181 // for this request are not called.
  182 func (c *Context) Abort() {
  183     c.index = abortIndex
  184 }
  185 
  186 // AbortWithStatus calls `Abort()` and writes the headers with the specified status code.
  187 // For example, a failed attempt to authenticate a request could use: context.AbortWithStatus(401).
  188 func (c *Context) AbortWithStatus(code int) {
  189     c.Status(code)
  190     c.Writer.WriteHeaderNow()
  191     c.Abort()
  192 }
  193 
  194 // AbortWithStatusJSON calls `Abort()` and then `JSON` internally.
  195 // This method stops the chain, writes the status code and return a JSON body.
  196 // It also sets the Content-Type as "application/json".
  197 func (c *Context) AbortWithStatusJSON(code int, jsonObj interface{}) {
  198     c.Abort()
  199     c.JSON(code, jsonObj)
  200 }
  201 
  202 // AbortWithError calls `AbortWithStatus()` and `Error()` internally.
  203 // This method stops the chain, writes the status code and pushes the specified error to `c.Errors`.
  204 // See Context.Error() for more details.
  205 func (c *Context) AbortWithError(code int, err error) *Error {
  206     c.AbortWithStatus(code)
  207     return c.Error(err)
  208 }
  209 
  210 /************************************/
  211 /********* ERROR MANAGEMENT *********/
  212 /************************************/
  213 
  214 // Error attaches an error to the current context. The error is pushed to a list of errors.
  215 // It's a good idea to call Error for each error that occurred during the resolution of a request.
  216 // A middleware can be used to collect all the errors and push them to a database together,
  217 // print a log, or append it in the HTTP response.
  218 // Error will panic if err is nil.
  219 func (c *Context) Error(err error) *Error {
  220     if err == nil {
  221         panic("err is nil")
  222     }
  223 
  224     parsedError, ok := err.(*Error)
  225     if !ok {
  226         parsedError = &Error{
  227             Err:  err,
  228             Type: ErrorTypePrivate,
  229         }
  230     }
  231 
  232     c.Errors = append(c.Errors, parsedError)
  233     return parsedError
  234 }
  235 
  236 /************************************/
  237 /******** METADATA MANAGEMENT********/
  238 /************************************/
  239 
  240 // Set is used to store a new key/value pair exclusively for this context.
  241 // It also lazy initializes  c.Keys if it was not used previously.
  242 func (c *Context) Set(key string, value interface{}) {
  243     c.mu.Lock()
  244     if c.Keys == nil {
  245         c.Keys = make(map[string]interface{})
  246     }
  247 
  248     c.Keys[key] = value
  249     c.mu.Unlock()
  250 }
  251 
  252 // Get returns the value for the given key, ie: (value, true).
  253 // If the value does not exists it returns (nil, false)
  254 func (c *Context) Get(key string) (value interface{}, exists bool) {
  255     c.mu.RLock()
  256     value, exists = c.Keys[key]
  257     c.mu.RUnlock()
  258     return
  259 }
  260 
  261 // MustGet returns the value for the given key if it exists, otherwise it panics.
  262 func (c *Context) MustGet(key string) interface{} {
  263     if value, exists := c.Get(key); exists {
  264         return value
  265     }
  266     panic("Key \"" + key + "\" does not exist")
  267 }
  268 
  269 // GetString returns the value associated with the key as a string.
  270 func (c *Context) GetString(key string) (s string) {
  271     if val, ok := c.Get(key); ok && val != nil {
  272         s, _ = val.(string)
  273     }
  274     return
  275 }
  276 
  277 // GetBool returns the value associated with the key as a boolean.
  278 func (c *Context) GetBool(key string) (b bool) {
  279     if val, ok := c.Get(key); ok && val != nil {
  280         b, _ = val.(bool)
  281     }
  282     return
  283 }
  284 
  285 // GetInt returns the value associated with the key as an integer.
  286 func (c *Context) GetInt(key string) (i int) {
  287     if val, ok := c.Get(key); ok && val != nil {
  288         i, _ = val.(int)
  289     }
  290     return
  291 }
  292 
  293 // GetInt64 returns the value associated with the key as an integer.
  294 func (c *Context) GetInt64(key string) (i64 int64) {
  295     if val, ok := c.Get(key); ok && val != nil {
  296         i64, _ = val.(int64)
  297     }
  298     return
  299 }
  300 
  301 // GetUint returns the value associated with the key as an unsigned integer.
  302 func (c *Context) GetUint(key string) (ui uint) {
  303     if val, ok := c.Get(key); ok && val != nil {
  304         ui, _ = val.(uint)
  305     }
  306     return
  307 }
  308 
  309 // GetUint64 returns the value associated with the key as an unsigned integer.
  310 func (c *Context) GetUint64(key string) (ui64 uint64) {
  311     if val, ok := c.Get(key); ok && val != nil {
  312         ui64, _ = val.(uint64)
  313     }
  314     return
  315 }
  316 
  317 // GetFloat64 returns the value associated with the key as a float64.
  318 func (c *Context) GetFloat64(key string) (f64 float64) {
  319     if val, ok := c.Get(key); ok && val != nil {
  320         f64, _ = val.(float64)
  321     }
  322     return
  323 }
  324 
  325 // GetTime returns the value associated with the key as time.
  326 func (c *Context) GetTime(key string) (t time.Time) {
  327     if val, ok := c.Get(key); ok && val != nil {
  328         t, _ = val.(time.Time)
  329     }
  330     return
  331 }
  332 
  333 // GetDuration returns the value associated with the key as a duration.
  334 func (c *Context) GetDuration(key string) (d time.Duration) {
  335     if val, ok := c.Get(key); ok && val != nil {
  336         d, _ = val.(time.Duration)
  337     }
  338     return
  339 }
  340 
  341 // GetStringSlice returns the value associated with the key as a slice of strings.
  342 func (c *Context) GetStringSlice(key string) (ss []string) {
  343     if val, ok := c.Get(key); ok && val != nil {
  344         ss, _ = val.([]string)
  345     }
  346     return
  347 }
  348 
  349 // GetStringMap returns the value associated with the key as a map of interfaces.
  350 func (c *Context) GetStringMap(key string) (sm map[string]interface{}) {
  351     if val, ok := c.Get(key); ok && val != nil {
  352         sm, _ = val.(map[string]interface{})
  353     }
  354     return
  355 }
  356 
  357 // GetStringMapString returns the value associated with the key as a map of strings.
  358 func (c *Context) GetStringMapString(key string) (sms map[string]string) {
  359     if val, ok := c.Get(key); ok && val != nil {
  360         sms, _ = val.(map[string]string)
  361     }
  362     return
  363 }
  364 
  365 // GetStringMapStringSlice returns the value associated with the key as a map to a slice of strings.
  366 func (c *Context) GetStringMapStringSlice(key string) (smss map[string][]string) {
  367     if val, ok := c.Get(key); ok && val != nil {
  368         smss, _ = val.(map[string][]string)
  369     }
  370     return
  371 }
  372 
  373 /************************************/
  374 /************ INPUT DATA ************/
  375 /************************************/
  376 
  377 // Param returns the value of the URL param.
  378 // It is a shortcut for c.Params.ByName(key)
  379 //     router.GET("/user/:id", func(c *gin.Context) {
  380 //         // a GET request to /user/john
  381 //         id := c.Param("id") // id == "john"
  382 //     })
  383 func (c *Context) Param(key string) string {
  384     return c.Params.ByName(key)
  385 }
  386 
  387 // Query returns the keyed url query value if it exists,
  388 // otherwise it returns an empty string `("")`.
  389 // It is shortcut for `c.Request.URL.Query().Get(key)`
  390 //     GET /path?id=1234&name=Manu&value=
  391 //     c.Query("id") == "1234"
  392 //     c.Query("name") == "Manu"
  393 //     c.Query("value") == ""
  394 //     c.Query("wtf") == ""
  395 func (c *Context) Query(key string) string {
  396     value, _ := c.GetQuery(key)
  397     return value
  398 }
  399 
  400 // DefaultQuery returns the keyed url query value if it exists,
  401 // otherwise it returns the specified defaultValue string.
  402 // See: Query() and GetQuery() for further information.
  403 //     GET /?name=Manu&lastname=
  404 //     c.DefaultQuery("name", "unknown") == "Manu"
  405 //     c.DefaultQuery("id", "none") == "none"
  406 //     c.DefaultQuery("lastname", "none") == ""
  407 func (c *Context) DefaultQuery(key, defaultValue string) string {
  408     if value, ok := c.GetQuery(key); ok {
  409         return value
  410     }
  411     return defaultValue
  412 }
  413 
  414 // GetQuery is like Query(), it returns the keyed url query value
  415 // if it exists `(value, true)` (even when the value is an empty string),
  416 // otherwise it returns `("", false)`.
  417 // It is shortcut for `c.Request.URL.Query().Get(key)`
  418 //     GET /?name=Manu&lastname=
  419 //     ("Manu", true) == c.GetQuery("name")
  420 //     ("", false) == c.GetQuery("id")
  421 //     ("", true) == c.GetQuery("lastname")
  422 func (c *Context) GetQuery(key string) (string, bool) {
  423     if values, ok := c.GetQueryArray(key); ok {
  424         return values[0], ok
  425     }
  426     return "", false
  427 }
  428 
  429 // QueryArray returns a slice of strings for a given query key.
  430 // The length of the slice depends on the number of params with the given key.
  431 func (c *Context) QueryArray(key string) []string {
  432     values, _ := c.GetQueryArray(key)
  433     return values
  434 }
  435 
  436 func (c *Context) initQueryCache() {
  437     if c.queryCache == nil {
  438         if c.Request != nil {
  439             c.queryCache = c.Request.URL.Query()
  440         } else {
  441             c.queryCache = url.Values{}
  442         }
  443     }
  444 }
  445 
  446 // GetQueryArray returns a slice of strings for a given query key, plus
  447 // a boolean value whether at least one value exists for the given key.
  448 func (c *Context) GetQueryArray(key string) ([]string, bool) {
  449     c.initQueryCache()
  450     if values, ok := c.queryCache[key]; ok && len(values) > 0 {
  451         return values, true
  452     }
  453     return []string{}, false
  454 }
  455 
  456 // QueryMap returns a map for a given query key.
  457 func (c *Context) QueryMap(key string) map[string]string {
  458     dicts, _ := c.GetQueryMap(key)
  459     return dicts
  460 }
  461 
  462 // GetQueryMap returns a map for a given query key, plus a boolean value
  463 // whether at least one value exists for the given key.
  464 func (c *Context) GetQueryMap(key string) (map[string]string, bool) {
  465     c.initQueryCache()
  466     return c.get(c.queryCache, key)
  467 }
  468 
  469 // PostForm returns the specified key from a POST urlencoded form or multipart form
  470 // when it exists, otherwise it returns an empty string `("")`.
  471 func (c *Context) PostForm(key string) string {
  472     value, _ := c.GetPostForm(key)
  473     return value
  474 }
  475 
  476 // DefaultPostForm returns the specified key from a POST urlencoded form or multipart form
  477 // when it exists, otherwise it returns the specified defaultValue string.
  478 // See: PostForm() and GetPostForm() for further information.
  479 func (c *Context) DefaultPostForm(key, defaultValue string) string {
  480     if value, ok := c.GetPostForm(key); ok {
  481         return value
  482     }
  483     return defaultValue
  484 }
  485 
  486 // GetPostForm is like PostForm(key). It returns the specified key from a POST urlencoded
  487 // form or multipart form when it exists `(value, true)` (even when the value is an empty string),
  488 // otherwise it returns ("", false).
  489 // For example, during a PATCH request to update the user's email:
  490 //     email=mail@example.com  -->  ("mail@example.com", true) := GetPostForm("email") // set email to "mail@example.com"
  491 //     email=                  -->  ("", true) := GetPostForm("email") // set email to ""
  492 //                             -->  ("", false) := GetPostForm("email") // do nothing with email
  493 func (c *Context) GetPostForm(key string) (string, bool) {
  494     if values, ok := c.GetPostFormArray(key); ok {
  495         return values[0], ok
  496     }
  497     return "", false
  498 }
  499 
  500 // PostFormArray returns a slice of strings for a given form key.
  501 // The length of the slice depends on the number of params with the given key.
  502 func (c *Context) PostFormArray(key string) []string {
  503     values, _ := c.GetPostFormArray(key)
  504     return values
  505 }
  506 
  507 func (c *Context) initFormCache() {
  508     if c.formCache == nil {
  509         c.formCache = make(url.Values)
  510         req := c.Request
  511         if err := req.ParseMultipartForm(c.engine.MaxMultipartMemory); err != nil {
  512             if err != http.ErrNotMultipart {
  513                 debugPrint("error on parse multipart form array: %v", err)
  514             }
  515         }
  516         c.formCache = req.PostForm
  517     }
  518 }
  519 
  520 // GetPostFormArray returns a slice of strings for a given form key, plus
  521 // a boolean value whether at least one value exists for the given key.
  522 func (c *Context) GetPostFormArray(key string) ([]string, bool) {
  523     c.initFormCache()
  524     if values := c.formCache[key]; len(values) > 0 {
  525         return values, true
  526     }
  527     return []string{}, false
  528 }
  529 
  530 // PostFormMap returns a map for a given form key.
  531 func (c *Context) PostFormMap(key string) map[string]string {
  532     dicts, _ := c.GetPostFormMap(key)
  533     return dicts
  534 }
  535 
  536 // GetPostFormMap returns a map for a given form key, plus a boolean value
  537 // whether at least one value exists for the given key.
  538 func (c *Context) GetPostFormMap(key string) (map[string]string, bool) {
  539     c.initFormCache()
  540     return c.get(c.formCache, key)
  541 }
  542 
  543 // get is an internal method and returns a map which satisfy conditions.
  544 func (c *Context) get(m map[string][]string, key string) (map[string]string, bool) {
  545     dicts := make(map[string]string)
  546     exist := false
  547     for k, v := range m {
  548         if i := strings.IndexByte(k, '['); i >= 1 && k[0:i] == key {
  549             if j := strings.IndexByte(k[i+1:], ']'); j >= 1 {
  550                 exist = true
  551                 dicts[k[i+1:][:j]] = v[0]
  552             }
  553         }
  554     }
  555     return dicts, exist
  556 }
  557 
  558 // FormFile returns the first file for the provided form key.
  559 func (c *Context) FormFile(name string) (*multipart.FileHeader, error) {
  560     if c.Request.MultipartForm == nil {
  561         if err := c.Request.ParseMultipartForm(c.engine.MaxMultipartMemory); err != nil {
  562             return nil, err
  563         }
  564     }
  565     f, fh, err := c.Request.FormFile(name)
  566     if err != nil {
  567         return nil, err
  568     }
  569     f.Close()
  570     return fh, err
  571 }
  572 
  573 // MultipartForm is the parsed multipart form, including file uploads.
  574 func (c *Context) MultipartForm() (*multipart.Form, error) {
  575     err := c.Request.ParseMultipartForm(c.engine.MaxMultipartMemory)
  576     return c.Request.MultipartForm, err
  577 }
  578 
  579 // SaveUploadedFile uploads the form file to specific dst.
  580 func (c *Context) SaveUploadedFile(file *multipart.FileHeader, dst string) error {
  581     src, err := file.Open()
  582     if err != nil {
  583         return err
  584     }
  585     defer src.Close()
  586 
  587     out, err := os.Create(dst)
  588     if err != nil {
  589         return err
  590     }
  591     defer out.Close()
  592 
  593     _, err = io.Copy(out, src)
  594     return err
  595 }
  596 
  597 // Bind checks the Content-Type to select a binding engine automatically,
  598 // Depending the "Content-Type" header different bindings are used:
  599 //     "application/json" --> JSON binding
  600 //     "application/xml"  --> XML binding
  601 // otherwise --> returns an error.
  602 // It parses the request's body as JSON if Content-Type == "application/json" using JSON or XML as a JSON input.
  603 // It decodes the json payload into the struct specified as a pointer.
  604 // It writes a 400 error and sets Content-Type header "text/plain" in the response if input is not valid.
  605 func (c *Context) Bind(obj interface{}) error {
  606     b := binding.Default(c.Request.Method, c.ContentType())
  607     return c.MustBindWith(obj, b)
  608 }
  609 
  610 // BindJSON is a shortcut for c.MustBindWith(obj, binding.JSON).
  611 func (c *Context) BindJSON(obj interface{}) error {
  612     return c.MustBindWith(obj, binding.JSON)
  613 }
  614 
  615 // BindXML is a shortcut for c.MustBindWith(obj, binding.BindXML).
  616 func (c *Context) BindXML(obj interface{}) error {
  617     return c.MustBindWith(obj, binding.XML)
  618 }
  619 
  620 // BindQuery is a shortcut for c.MustBindWith(obj, binding.Query).
  621 func (c *Context) BindQuery(obj interface{}) error {
  622     return c.MustBindWith(obj, binding.Query)
  623 }
  624 
  625 // BindYAML is a shortcut for c.MustBindWith(obj, binding.YAML).
  626 func (c *Context) BindYAML(obj interface{}) error {
  627     return c.MustBindWith(obj, binding.YAML)
  628 }
  629 
  630 // BindHeader is a shortcut for c.MustBindWith(obj, binding.Header).
  631 func (c *Context) BindHeader(obj interface{}) error {
  632     return c.MustBindWith(obj, binding.Header)
  633 }
  634 
  635 // BindUri binds the passed struct pointer using binding.Uri.
  636 // It will abort the request with HTTP 400 if any error occurs.
  637 func (c *Context) BindUri(obj interface{}) error {
  638     if err := c.ShouldBindUri(obj); err != nil {
  639         c.AbortWithError(http.StatusBadRequest, err).SetType(ErrorTypeBind) // nolint: errcheck
  640         return err
  641     }
  642     return nil
  643 }
  644 
  645 // MustBindWith binds the passed struct pointer using the specified binding engine.
  646 // It will abort the request with HTTP 400 if any error occurs.
  647 // See the binding package.
  648 func (c *Context) MustBindWith(obj interface{}, b binding.Binding) error {
  649     if err := c.ShouldBindWith(obj, b); err != nil {
  650         c.AbortWithError(http.StatusBadRequest, err).SetType(ErrorTypeBind) // nolint: errcheck
  651         return err
  652     }
  653     return nil
  654 }
  655 
  656 // ShouldBind checks the Content-Type to select a binding engine automatically,
  657 // Depending the "Content-Type" header different bindings are used:
  658 //     "application/json" --> JSON binding
  659 //     "application/xml"  --> XML binding
  660 // otherwise --> returns an error
  661 // It parses the request's body as JSON if Content-Type == "application/json" using JSON or XML as a JSON input.
  662 // It decodes the json payload into the struct specified as a pointer.
  663 // Like c.Bind() but this method does not set the response status code to 400 and abort if the json is not valid.
  664 func (c *Context) ShouldBind(obj interface{}) error {
  665     b := binding.Default(c.Request.Method, c.ContentType())
  666     return c.ShouldBindWith(obj, b)
  667 }
  668 
  669 // ShouldBindJSON is a shortcut for c.ShouldBindWith(obj, binding.JSON).
  670 func (c *Context) ShouldBindJSON(obj interface{}) error {
  671     return c.ShouldBindWith(obj, binding.JSON)
  672 }
  673 
  674 // ShouldBindXML is a shortcut for c.ShouldBindWith(obj, binding.XML).
  675 func (c *Context) ShouldBindXML(obj interface{}) error {
  676     return c.ShouldBindWith(obj, binding.XML)
  677 }
  678 
  679 // ShouldBindQuery is a shortcut for c.ShouldBindWith(obj, binding.Query).
  680 func (c *Context) ShouldBindQuery(obj interface{}) error {
  681     return c.ShouldBindWith(obj, binding.Query)
  682 }
  683 
  684 // ShouldBindYAML is a shortcut for c.ShouldBindWith(obj, binding.YAML).
  685 func (c *Context) ShouldBindYAML(obj interface{}) error {
  686     return c.ShouldBindWith(obj, binding.YAML)
  687 }
  688 
  689 // ShouldBindHeader is a shortcut for c.ShouldBindWith(obj, binding.Header).
  690 func (c *Context) ShouldBindHeader(obj interface{}) error {
  691     return c.ShouldBindWith(obj, binding.Header)
  692 }
  693 
  694 // ShouldBindUri binds the passed struct pointer using the specified binding engine.
  695 func (c *Context) ShouldBindUri(obj interface{}) error {
  696     m := make(map[string][]string)
  697     for _, v := range c.Params {
  698         m[v.Key] = []string{v.Value}
  699     }
  700     return binding.Uri.BindUri(m, obj)
  701 }
  702 
  703 // ShouldBindWith binds the passed struct pointer using the specified binding engine.
  704 // See the binding package.
  705 func (c *Context) ShouldBindWith(obj interface{}, b binding.Binding) error {
  706     return b.Bind(c.Request, obj)
  707 }
  708 
  709 // ShouldBindBodyWith is similar with ShouldBindWith, but it stores the request
  710 // body into the context, and reuse when it is called again.
  711 //
  712 // NOTE: This method reads the body before binding. So you should use
  713 // ShouldBindWith for better performance if you need to call only once.
  714 func (c *Context) ShouldBindBodyWith(obj interface{}, bb binding.BindingBody) (err error) {
  715     var body []byte
  716     if cb, ok := c.Get(BodyBytesKey); ok {
  717         if cbb, ok := cb.([]byte); ok {
  718             body = cbb
  719         }
  720     }
  721     if body == nil {
  722         body, err = ioutil.ReadAll(c.Request.Body)
  723         if err != nil {
  724             return err
  725         }
  726         c.Set(BodyBytesKey, body)
  727     }
  728     return bb.BindBody(body, obj)
  729 }
  730 
  731 // ClientIP implements one best effort algorithm to return the real client IP.
  732 // It called c.RemoteIP() under the hood, to check if the remote IP is a trusted proxy or not.
  733 // If it is it will then try to parse the headers defined in Engine.RemoteIPHeaders (defaulting to [X-Forwarded-For, X-Real-Ip]).
  734 // If the headers are not syntactically valid OR the remote IP does not correspond to a trusted proxy,
  735 // the remote IP (coming form Request.RemoteAddr) is returned.
  736 func (c *Context) ClientIP() string {
  737     // Check if we're running on a trusted platform, continue running backwards if error
  738     if c.engine.TrustedPlatform != "" {
  739         // Developers can define their own header of Trusted Platform or use predefined constants
  740         if addr := c.requestHeader(c.engine.TrustedPlatform); addr != "" {
  741             return addr
  742         }
  743     }
  744 
  745     // Legacy "AppEngine" flag
  746     if c.engine.AppEngine {
  747         log.Println(`The AppEngine flag is going to be deprecated. Please check issues #2723 and #2739 and use 'TrustedPlatform: gin.PlatformGoogleAppEngine' instead.`)
  748         if addr := c.requestHeader("X-Appengine-Remote-Addr"); addr != "" {
  749             return addr
  750         }
  751     }
  752 
  753     remoteIP, trusted := c.RemoteIP()
  754     if remoteIP == nil {
  755         return ""
  756     }
  757 
  758     if trusted && c.engine.ForwardedByClientIP && c.engine.RemoteIPHeaders != nil {
  759         for _, headerName := range c.engine.RemoteIPHeaders {
  760             ip, valid := c.engine.validateHeader(c.requestHeader(headerName))
  761             if valid {
  762                 return ip
  763             }
  764         }
  765     }
  766     return remoteIP.String()
  767 }
  768 
  769 func (e *Engine) isTrustedProxy(ip net.IP) bool {
  770     if e.trustedCIDRs != nil {
  771         for _, cidr := range e.trustedCIDRs {
  772             if cidr.Contains(ip) {
  773                 return true
  774             }
  775         }
  776     }
  777     return false
  778 }
  779 
  780 // RemoteIP parses the IP from Request.RemoteAddr, normalizes and returns the IP (without the port).
  781 // It also checks if the remoteIP is a trusted proxy or not.
  782 // In order to perform this validation, it will see if the IP is contained within at least one of the CIDR blocks
  783 // defined by Engine.SetTrustedProxies()
  784 func (c *Context) RemoteIP() (net.IP, bool) {
  785     ip, _, err := net.SplitHostPort(strings.TrimSpace(c.Request.RemoteAddr))
  786     if err != nil {
  787         return nil, false
  788     }
  789     remoteIP := net.ParseIP(ip)
  790     if remoteIP == nil {
  791         return nil, false
  792     }
  793 
  794     return remoteIP, c.engine.isTrustedProxy(remoteIP)
  795 }
  796 
  797 func (e *Engine) validateHeader(header string) (clientIP string, valid bool) {
  798     if header == "" {
  799         return "", false
  800     }
  801     items := strings.Split(header, ",")
  802     for i := len(items) - 1; i >= 0; i-- {
  803         ipStr := strings.TrimSpace(items[i])
  804         ip := net.ParseIP(ipStr)
  805         if ip == nil {
  806             return "", false
  807         }
  808 
  809         // X-Forwarded-For is appended by proxy
  810         // Check IPs in reverse order and stop when find untrusted proxy
  811         if (i == 0) || (!e.isTrustedProxy(ip)) {
  812             return ipStr, true
  813         }
  814     }
  815     return
  816 }
  817 
  818 // ContentType returns the Content-Type header of the request.
  819 func (c *Context) ContentType() string {
  820     return filterFlags(c.requestHeader("Content-Type"))
  821 }
  822 
  823 // IsWebsocket returns true if the request headers indicate that a websocket
  824 // handshake is being initiated by the client.
  825 func (c *Context) IsWebsocket() bool {
  826     if strings.Contains(strings.ToLower(c.requestHeader("Connection")), "upgrade") &&
  827         strings.EqualFold(c.requestHeader("Upgrade"), "websocket") {
  828         return true
  829     }
  830     return false
  831 }
  832 
  833 func (c *Context) requestHeader(key string) string {
  834     return c.Request.Header.Get(key)
  835 }
  836 
  837 /************************************/
  838 /******** RESPONSE RENDERING ********/
  839 /************************************/
  840 
  841 // bodyAllowedForStatus is a copy of http.bodyAllowedForStatus non-exported function.
  842 func bodyAllowedForStatus(status int) bool {
  843     switch {
  844     case status >= 100 && status <= 199:
  845         return false
  846     case status == http.StatusNoContent:
  847         return false
  848     case status == http.StatusNotModified:
  849         return false
  850     }
  851     return true
  852 }
  853 
  854 // Status sets the HTTP response code.
  855 func (c *Context) Status(code int) {
  856     c.Writer.WriteHeader(code)
  857 }
  858 
  859 // Header is a intelligent shortcut for c.Writer.Header().Set(key, value).
  860 // It writes a header in the response.
  861 // If value == "", this method removes the header `c.Writer.Header().Del(key)`
  862 func (c *Context) Header(key, value string) {
  863     if value == "" {
  864         c.Writer.Header().Del(key)
  865         return
  866     }
  867     c.Writer.Header().Set(key, value)
  868 }
  869 
  870 // GetHeader returns value from request headers.
  871 func (c *Context) GetHeader(key string) string {
  872     return c.requestHeader(key)
  873 }
  874 
  875 // GetRawData return stream data.
  876 func (c *Context) GetRawData() ([]byte, error) {
  877     return ioutil.ReadAll(c.Request.Body)
  878 }
  879 
  880 // SetSameSite with cookie
  881 func (c *Context) SetSameSite(samesite http.SameSite) {
  882     c.sameSite = samesite
  883 }
  884 
  885 // SetCookie adds a Set-Cookie header to the ResponseWriter's headers.
  886 // The provided cookie must have a valid Name. Invalid cookies may be
  887 // silently dropped.
  888 func (c *Context) SetCookie(name, value string, maxAge int, path, domain string, secure, httpOnly bool) {
  889     if path == "" {
  890         path = "/"
  891     }
  892     http.SetCookie(c.Writer, &http.Cookie{
  893         Name:     name,
  894         Value:    url.QueryEscape(value),
  895         MaxAge:   maxAge,
  896         Path:     path,
  897         Domain:   domain,
  898         SameSite: c.sameSite,
  899         Secure:   secure,
  900         HttpOnly: httpOnly,
  901     })
  902 }
  903 
  904 // Cookie returns the named cookie provided in the request or
  905 // ErrNoCookie if not found. And return the named cookie is unescaped.
  906 // If multiple cookies match the given name, only one cookie will
  907 // be returned.
  908 func (c *Context) Cookie(name string) (string, error) {
  909     cookie, err := c.Request.Cookie(name)
  910     if err != nil {
  911         return "", err
  912     }
  913     val, _ := url.QueryUnescape(cookie.Value)
  914     return val, nil
  915 }
  916 
  917 // Render writes the response headers and calls render.Render to render data.
  918 func (c *Context) Render(code int, r render.Render) {
  919     c.Status(code)
  920 
  921     if !bodyAllowedForStatus(code) {
  922         r.WriteContentType(c.Writer)
  923         c.Writer.WriteHeaderNow()
  924         return
  925     }
  926 
  927     if err := r.Render(c.Writer); err != nil {
  928         panic(err)
  929     }
  930 }
  931 
  932 // HTML renders the HTTP template specified by its file name.
  933 // It also updates the HTTP code and sets the Content-Type as "text/html".
  934 // See http://golang.org/doc/articles/wiki/
  935 func (c *Context) HTML(code int, name string, obj interface{}) {
  936     instance := c.engine.HTMLRender.Instance(name, obj)
  937     c.Render(code, instance)
  938 }
  939 
  940 // IndentedJSON serializes the given struct as pretty JSON (indented + endlines) into the response body.
  941 // It also sets the Content-Type as "application/json".
  942 // WARNING: we recommend to use this only for development purposes since printing pretty JSON is
  943 // more CPU and bandwidth consuming. Use Context.JSON() instead.
  944 func (c *Context) IndentedJSON(code int, obj interface{}) {
  945     c.Render(code, render.IndentedJSON{Data: obj})
  946 }
  947 
  948 // SecureJSON serializes the given struct as Secure JSON into the response body.
  949 // Default prepends "while(1)," to response body if the given struct is array values.
  950 // It also sets the Content-Type as "application/json".
  951 func (c *Context) SecureJSON(code int, obj interface{}) {
  952     c.Render(code, render.SecureJSON{Prefix: c.engine.secureJSONPrefix, Data: obj})
  953 }
  954 
  955 // JSONP serializes the given struct as JSON into the response body.
  956 // It adds padding to response body to request data from a server residing in a different domain than the client.
  957 // It also sets the Content-Type as "application/javascript".
  958 func (c *Context) JSONP(code int, obj interface{}) {
  959     callback := c.DefaultQuery("callback", "")
  960     if callback == "" {
  961         c.Render(code, render.JSON{Data: obj})
  962         return
  963     }
  964     c.Render(code, render.JsonpJSON{Callback: callback, Data: obj})
  965 }
  966 
  967 // JSON serializes the given struct as JSON into the response body.
  968 // It also sets the Content-Type as "application/json".
  969 func (c *Context) JSON(code int, obj interface{}) {
  970     c.Render(code, render.JSON{Data: obj})
  971 }
  972 
  973 // AsciiJSON serializes the given struct as JSON into the response body with unicode to ASCII string.
  974 // It also sets the Content-Type as "application/json".
  975 func (c *Context) AsciiJSON(code int, obj interface{}) {
  976     c.Render(code, render.AsciiJSON{Data: obj})
  977 }
  978 
  979 // PureJSON serializes the given struct as JSON into the response body.
  980 // PureJSON, unlike JSON, does not replace special html characters with their unicode entities.
  981 func (c *Context) PureJSON(code int, obj interface{}) {
  982     c.Render(code, render.PureJSON{Data: obj})
  983 }
  984 
  985 // XML serializes the given struct as XML into the response body.
  986 // It also sets the Content-Type as "application/xml".
  987 func (c *Context) XML(code int, obj interface{}) {
  988     c.Render(code, render.XML{Data: obj})
  989 }
  990 
  991 // YAML serializes the given struct as YAML into the response body.
  992 func (c *Context) YAML(code int, obj interface{}) {
  993     c.Render(code, render.YAML{Data: obj})
  994 }
  995 
  996 // ProtoBuf serializes the given struct as ProtoBuf into the response body.
  997 func (c *Context) ProtoBuf(code int, obj interface{}) {
  998     c.Render(code, render.ProtoBuf{Data: obj})
  999 }
 1000 
 1001 // String writes the given string into the response body.
 1002 func (c *Context) String(code int, format string, values ...interface{}) {
 1003     c.Render(code, render.String{Format: format, Data: values})
 1004 }
 1005 
 1006 // Redirect returns a HTTP redirect to the specific location.
 1007 func (c *Context) Redirect(code int, location string) {
 1008     c.Render(-1, render.Redirect{
 1009         Code:     code,
 1010         Location: location,
 1011         Request:  c.Request,
 1012     })
 1013 }
 1014 
 1015 // Data writes some data into the body stream and updates the HTTP code.
 1016 func (c *Context) Data(code int, contentType string, data []byte) {
 1017     c.Render(code, render.Data{
 1018         ContentType: contentType,
 1019         Data:        data,
 1020     })
 1021 }
 1022 
 1023 // DataFromReader writes the specified reader into the body stream and updates the HTTP code.
 1024 func (c *Context) DataFromReader(code int, contentLength int64, contentType string, reader io.Reader, extraHeaders map[string]string) {
 1025     c.Render(code, render.Reader{
 1026         Headers:       extraHeaders,
 1027         ContentType:   contentType,
 1028         ContentLength: contentLength,
 1029         Reader:        reader,
 1030     })
 1031 }
 1032 
 1033 // File writes the specified file into the body stream in an efficient way.
 1034 func (c *Context) File(filepath string) {
 1035     http.ServeFile(c.Writer, c.Request, filepath)
 1036 }
 1037 
 1038 // FileFromFS writes the specified file from http.FileSystem into the body stream in an efficient way.
 1039 func (c *Context) FileFromFS(filepath string, fs http.FileSystem) {
 1040     defer func(old string) {
 1041         c.Request.URL.Path = old
 1042     }(c.Request.URL.Path)
 1043 
 1044     c.Request.URL.Path = filepath
 1045 
 1046     http.FileServer(fs).ServeHTTP(c.Writer, c.Request)
 1047 }
 1048 
 1049 // FileAttachment writes the specified file into the body stream in an efficient way
 1050 // On the client side, the file will typically be downloaded with the given filename
 1051 func (c *Context) FileAttachment(filepath, filename string) {
 1052     c.Writer.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", filename))
 1053     http.ServeFile(c.Writer, c.Request, filepath)
 1054 }
 1055 
 1056 // SSEvent writes a Server-Sent Event into the body stream.
 1057 func (c *Context) SSEvent(name string, message interface{}) {
 1058     c.Render(-1, sse.Event{
 1059         Event: name,
 1060         Data:  message,
 1061     })
 1062 }
 1063 
 1064 // Stream sends a streaming response and returns a boolean
 1065 // indicates "Is client disconnected in middle of stream"
 1066 func (c *Context) Stream(step func(w io.Writer) bool) bool {
 1067     w := c.Writer
 1068     clientGone := w.CloseNotify()
 1069     for {
 1070         select {
 1071         case <-clientGone:
 1072             return true
 1073         default:
 1074             keepOpen := step(w)
 1075             w.Flush()
 1076             if !keepOpen {
 1077                 return false
 1078             }
 1079         }
 1080     }
 1081 }
 1082 
 1083 /************************************/
 1084 /******** CONTENT NEGOTIATION *******/
 1085 /************************************/
 1086 
 1087 // Negotiate contains all negotiations data.
 1088 type Negotiate struct {
 1089     Offered  []string
 1090     HTMLName string
 1091     HTMLData interface{}
 1092     JSONData interface{}
 1093     XMLData  interface{}
 1094     YAMLData interface{}
 1095     Data     interface{}
 1096 }
 1097 
 1098 // Negotiate calls different Render according acceptable Accept format.
 1099 func (c *Context) Negotiate(code int, config Negotiate) {
 1100     switch c.NegotiateFormat(config.Offered...) {
 1101     case binding.MIMEJSON:
 1102         data := chooseData(config.JSONData, config.Data)
 1103         c.JSON(code, data)
 1104 
 1105     case binding.MIMEHTML:
 1106         data := chooseData(config.HTMLData, config.Data)
 1107         c.HTML(code, config.HTMLName, data)
 1108 
 1109     case binding.MIMEXML:
 1110         data := chooseData(config.XMLData, config.Data)
 1111         c.XML(code, data)
 1112 
 1113     case binding.MIMEYAML:
 1114         data := chooseData(config.YAMLData, config.Data)
 1115         c.YAML(code, data)
 1116 
 1117     default:
 1118         c.AbortWithError(http.StatusNotAcceptable, errors.New("the accepted formats are not offered by the server")) // nolint: errcheck
 1119     }
 1120 }
 1121 
 1122 // NegotiateFormat returns an acceptable Accept format.
 1123 func (c *Context) NegotiateFormat(offered ...string) string {
 1124     assert1(len(offered) > 0, "you must provide at least one offer")
 1125 
 1126     if c.Accepted == nil {
 1127         c.Accepted = parseAccept(c.requestHeader("Accept"))
 1128     }
 1129     if len(c.Accepted) == 0 {
 1130         return offered[0]
 1131     }
 1132     for _, accepted := range c.Accepted {
 1133         for _, offer := range offered {
 1134             // According to RFC 2616 and RFC 2396, non-ASCII characters are not allowed in headers,
 1135             // therefore we can just iterate over the string without casting it into []rune
 1136             i := 0
 1137             for ; i < len(accepted); i++ {
 1138                 if accepted[i] == '*' || offer[i] == '*' {
 1139                     return offer
 1140                 }
 1141                 if accepted[i] != offer[i] {
 1142                     break
 1143                 }
 1144             }
 1145             if i == len(accepted) {
 1146                 return offer
 1147             }
 1148         }
 1149     }
 1150     return ""
 1151 }
 1152 
 1153 // SetAccepted sets Accept header data.
 1154 func (c *Context) SetAccepted(formats ...string) {
 1155     c.Accepted = formats
 1156 }
 1157 
 1158 /************************************/
 1159 /***** GOLANG.ORG/X/NET/CONTEXT *****/
 1160 /************************************/
 1161 
 1162 // Deadline always returns that there is no deadline (ok==false),
 1163 // maybe you want to use Request.Context().Deadline() instead.
 1164 func (c *Context) Deadline() (deadline time.Time, ok bool) {
 1165     return
 1166 }
 1167 
 1168 // Done always returns nil (chan which will wait forever),
 1169 // if you want to abort your work when the connection was closed
 1170 // you should use Request.Context().Done() instead.
 1171 func (c *Context) Done() <-chan struct{} {
 1172     return nil
 1173 }
 1174 
 1175 // Err always returns nil, maybe you want to use Request.Context().Err() instead.
 1176 func (c *Context) Err() error {
 1177     return nil
 1178 }
 1179 
 1180 // Value returns the value associated with this context for key, or nil
 1181 // if no value is associated with key. Successive calls to Value with
 1182 // the same key returns the same result.
 1183 func (c *Context) Value(key interface{}) interface{} {
 1184     if key == 0 {
 1185         return c.Request
 1186     }
 1187     if keyAsString, ok := key.(string); ok {
 1188         val, _ := c.Get(keyAsString)
 1189         return val
 1190     }
 1191     return nil
 1192 }