package kite import ( "context" "encoding/json" "encoding/xml" "mime/multipart" "net" "net/http" "net/url" "strings" "github.com/julienschmidt/httprouter" ) type contextKey string type Context struct { w *responseWriter r *http.Request p httprouter.Params } func (c *Context) GetRequest() *http.Request { return c.r } func (c *Context) GetResponse() http.ResponseWriter { return c.w } func (c *Context) GetStatusCode() int { return c.w.statusCode } func (c *Context) GetContext() context.Context { return c.r.Context() } func (c *Context) GetPathParam(key string) string { return c.p.ByName(key) } func (c *Context) GetQueryParam(key string) string { return c.r.URL.Query().Get(key) } func (c *Context) SetValue(key string, v any) { c.r = c.r.WithContext(context.WithValue(c.r.Context(), contextKey(key), v)) } func (c *Context) GetValue(key string) any { return c.r.Context().Value(contextKey(key)) } func (c *Context) AddHeader(key, v string) { c.w.Header().Add(key, v) } func (c *Context) SetHeader(key, v string) { c.w.Header().Set(key, v) } func (c *Context) GetHeader(key string) string { return c.r.Header.Get(key) } func (c *Context) SetCookie(cookie *http.Cookie) { http.SetCookie(c.w, cookie) } func (c *Context) GetCookie(key string) (*http.Cookie, error) { return c.r.Cookie(key) } func (c *Context) GetIP() string { if ip := c.r.Header.Get("X-Forwarded-For"); ip != "" { return strings.Split(ip, ",")[0] } if ip := c.r.Header.Get("X-Real-IP"); ip != "" { return ip } ip, _, _ := net.SplitHostPort(c.r.RemoteAddr) return ip } func (c *Context) GetMethod() string { return c.r.Method } func (c *Context) GetPath() string { return c.r.URL.Path } func (c *Context) GetForm() (url.Values, error) { if err := c.r.ParseForm(); err != nil { return nil, err } return c.r.Form, nil } func (c *Context) GetFormValue(key string) string { return c.r.FormValue(key) } func (c *Context) GetMultipartForm(maxMemory int64) (*multipart.Form, error) { if err := c.r.ParseMultipartForm(maxMemory); err != nil { return nil, err } return c.r.MultipartForm, nil } func (c *Context) GetMultipartFormFile(key string) (multipart.File, *multipart.FileHeader, error) { return c.r.FormFile(key) } func (c *Context) IsMethod(method string) bool { return c.r.Method == method } func (c *Context) WriteBytes(statusCode int, v []byte) error { c.w.WriteHeader(statusCode) _, err := c.w.Write(v) return err } func (c *Context) WriteString(statusCode int, v string) error { c.w.Header().Set("Content-Type", "text/plain; charset=utf-8") c.w.WriteHeader(statusCode) _, err := c.w.Write([]byte(v)) return err } func (c *Context) WriteJSON(statusCode int, v any) error { c.w.Header().Set("Content-Type", "application/json; charset=utf-8") c.w.WriteHeader(statusCode) return json.NewEncoder(c.w).Encode(v) } func (c *Context) WriteXML(statusCode int, v any) error { c.w.Header().Set("Content-Type", "application/xml; charset=utf-8") c.w.WriteHeader(statusCode) return xml.NewEncoder(c.w).Encode(v) } func (c *Context) WriteNoContent() error { c.w.WriteHeader(http.StatusNoContent) return nil } func (c *Context) Redirect(statusCode int, url string) error { http.Redirect(c.w, c.r, url, statusCode) return nil } func (c *Context) BindJSON(v any) error { defer c.r.Body.Close() return json.NewDecoder(c.r.Body).Decode(v) } func (c *Context) BindXML(v any) error { defer c.r.Body.Close() return xml.NewDecoder(c.r.Body).Decode(v) }