request/response: add more implementations
This commit is contained in:
		@ -1,6 +1,11 @@
 | 
			
		||||
package framework
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"encoding/xml"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"io"
 | 
			
		||||
	"mime/multipart"
 | 
			
		||||
	"net/url"
 | 
			
		||||
 | 
			
		||||
@ -281,3 +286,126 @@ func (ctx *Context) FormStringSlice(key string, defval []string) ([]string, bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// }}}
 | 
			
		||||
// {{{ type binder
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	ErrNoRequest    = errors.New("missing request in the context")
 | 
			
		||||
	ErrNotSingleObj = errors.New("body must have only a single value")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// JSON body
 | 
			
		||||
func (ctx *Context) BindJSON(obj any) error {
 | 
			
		||||
	if ctx.request == nil {
 | 
			
		||||
		return ErrNoRequest
 | 
			
		||||
	}
 | 
			
		||||
	dec := json.NewDecoder(ctx.request.Body)
 | 
			
		||||
	err := dec.Decode(obj)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	err = dec.Decode(&struct{}{})
 | 
			
		||||
	if err != io.EOF {
 | 
			
		||||
		return ErrNotSingleObj
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// XML body
 | 
			
		||||
func (ctx *Context) BindXML(obj any) error {
 | 
			
		||||
	if ctx.request == nil {
 | 
			
		||||
		return ErrNoRequest
 | 
			
		||||
	}
 | 
			
		||||
	dec := xml.NewDecoder(ctx.request.Body)
 | 
			
		||||
	err := dec.Decode(obj)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	err = dec.Decode(&struct{}{})
 | 
			
		||||
	if err != io.EOF {
 | 
			
		||||
		return ErrNotSingleObj
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RAW body
 | 
			
		||||
func (ctx *Context) GetRawData() ([]byte, error) {
 | 
			
		||||
	if ctx.request == nil {
 | 
			
		||||
		return []byte{}, ErrNoRequest
 | 
			
		||||
	}
 | 
			
		||||
	body, err := io.ReadAll(ctx.request.Body)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return []byte{}, err
 | 
			
		||||
	}
 | 
			
		||||
	/* Restore the body (io.ReadCloser) to it's original state */
 | 
			
		||||
	ctx.request.Body = io.NopCloser(bytes.NewBuffer(body))
 | 
			
		||||
 | 
			
		||||
	return body, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// }}}
 | 
			
		||||
// {{{ Basic informations
 | 
			
		||||
 | 
			
		||||
func (ctx *Context) Uri() string {
 | 
			
		||||
	return ctx.request.RequestURI
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ctx *Context) Method() string {
 | 
			
		||||
	return ctx.request.Method
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ctx *Context) Host() string {
 | 
			
		||||
	return ctx.request.Host
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ctx *Context) ClientIP() string {
 | 
			
		||||
	r := ctx.request
 | 
			
		||||
	ipAddress := r.Header.Get("X-Real-Ip")
 | 
			
		||||
	if ipAddress == "" {
 | 
			
		||||
		ipAddress = r.Header.Get("X-Forwarded-For")
 | 
			
		||||
	}
 | 
			
		||||
	if ipAddress == "" {
 | 
			
		||||
		ipAddress = r.RemoteAddr
 | 
			
		||||
	}
 | 
			
		||||
	return ipAddress
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// }}}
 | 
			
		||||
// {{{ Headers
 | 
			
		||||
 | 
			
		||||
// Header
 | 
			
		||||
func (ctx *Context) Headers() map[string][]string {
 | 
			
		||||
	return ctx.request.Header
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ctx *Context) Header(key string) (string, bool) {
 | 
			
		||||
	vals := ctx.request.Header.Values(key)
 | 
			
		||||
	if vals == nil || len(vals) <= 0 {
 | 
			
		||||
		return "", false
 | 
			
		||||
	}
 | 
			
		||||
	return vals[0], true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// }}}
 | 
			
		||||
// {{{ Cookies
 | 
			
		||||
 | 
			
		||||
// Cookies gets cookie key-value pairs
 | 
			
		||||
func (ctx *Context) Cookies() map[string]string {
 | 
			
		||||
	cookies := ctx.request.Cookies()
 | 
			
		||||
	ret := map[string]string{}
 | 
			
		||||
	for _, c := range cookies {
 | 
			
		||||
		ret[c.Name] = c.Value
 | 
			
		||||
	}
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ctx *Context) Cookie(key string) (string, bool) {
 | 
			
		||||
	cookies := ctx.Cookies()
 | 
			
		||||
	if val, ok := cookies[key]; ok {
 | 
			
		||||
		return val, true
 | 
			
		||||
	}
 | 
			
		||||
	return "", false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// }}}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user