request/response: add more implementations
This commit is contained in:
		| @ -1,6 +1,11 @@ | |||||||
| package framework | package framework | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"bytes" | ||||||
|  | 	"encoding/json" | ||||||
|  | 	"encoding/xml" | ||||||
|  | 	"errors" | ||||||
|  | 	"io" | ||||||
| 	"mime/multipart" | 	"mime/multipart" | ||||||
| 	"net/url" | 	"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