github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/gin/context.go (about)

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