123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- package wisp
- import (
- "context"
- "encoding/json"
- "encoding/xml"
- "errors"
- "io"
- "net/http"
- "net/url"
- "strconv"
- "strings"
- "github.com/julienschmidt/httprouter"
- )
- type Context struct {
- response http.ResponseWriter
- request *http.Request
- params httprouter.Params
- ctx context.Context
- }
- // Basic getters
- func (c *Context) Response() http.ResponseWriter {
- return c.response
- }
- func (c *Context) Request() *http.Request {
- return c.request
- }
- func (c *Context) Params() httprouter.Params {
- return c.params
- }
- func (c *Context) Context() context.Context {
- return c.ctx
- }
- // URL Param retrieval (from path)
- func (c *Context) Param(name string) string {
- return c.params.ByName(name)
- }
- // Query param retrieval
- func (c *Context) Query(name string) string {
- return c.request.URL.Query().Get(name)
- }
- func (c *Context) QueryDefault(name, defaultValue string) string {
- if v := c.Query(name); v != "" {
- return v
- }
- return defaultValue
- }
- // Form param retrieval (POST, PUT with form data)
- func (c *Context) FormValue(name string) string {
- return c.request.FormValue(name)
- }
- func (c *Context) FormValueDefault(name, defaultValue string) string {
- if v := c.FormValue(name); v != "" {
- return v
- }
- return defaultValue
- }
- // Body binding helpers
- func (c *Context) BindJSON(dest interface{}) error {
- defer c.request.Body.Close()
- dec := json.NewDecoder(c.request.Body)
- dec.DisallowUnknownFields()
- return dec.Decode(dest)
- }
- func (c *Context) BindXML(dest interface{}) error {
- defer c.request.Body.Close()
- dec := xml.NewDecoder(c.request.Body)
- return dec.Decode(dest)
- }
- func (c *Context) BindForm() (url.Values, error) {
- defer c.request.Body.Close()
- contentType := c.request.Header.Get("Content-Type")
- if !strings.Contains(contentType, "application/x-www-form-urlencoded") {
- return nil, errors.New("content-type is not application/x-www-form-urlencoded")
- }
- return url.ParseQuery(c.request.PostForm.Encode())
- }
- func (c *Context) BindMultipartForm(maxMemory int64) error {
- return c.request.ParseMultipartForm(maxMemory)
- }
- // Cookie helpers
- func (c *Context) Cookie(name string) (*http.Cookie, error) {
- return c.request.Cookie(name)
- }
- func (c *Context) SetCookie(cookie *http.Cookie) {
- http.SetCookie(c.response, cookie)
- }
- // Response helpers
- func (c *Context) Write(data []byte) (int, error) {
- return c.response.Write(data)
- }
- func (c *Context) String(status int, s string) error {
- _, err := io.WriteString(c.response, s)
- return err
- }
- func (c *Context) JSON(status int, data any) error {
- c.response.Header().Set("Content-Type", "application/json")
- c.response.WriteHeader(status)
- return json.NewEncoder(c.response).Encode(data)
- }
- func (c *Context) XML(status int, data any) error {
- c.response.Header().Set("Content-Type", "application/xml")
- c.response.WriteHeader(status)
- return xml.NewEncoder(c.response).Encode(data)
- }
- func (c *Context) Redirect(status int, urlStr string) {
- http.Redirect(c.response, c.request, urlStr, status)
- }
- func (c *Context) Status(code int) {
- c.response.WriteHeader(code)
- }
- // Helpers for common status responses
- func (c *Context) NoContent() {
- c.Status(http.StatusNoContent)
- }
- func (c *Context) NotFound() {
- c.Status(http.StatusNotFound)
- }
- func (c *Context) BadRequest(e error) error {
- c.response.WriteHeader(http.StatusBadRequest)
- _, err := c.response.Write([]byte(e.Error()))
- return err
- }
- func (c *Context) InternalServerError(e error) error {
- c.response.WriteHeader(http.StatusInternalServerError)
- _, err := c.response.Write([]byte(e.Error()))
- return err
- }
- // Context cancellation / deadline
- func (c *Context) Done() <-chan struct{} {
- return c.ctx.Done()
- }
- func (c *Context) Err() error {
- return c.ctx.Err()
- }
- // Request parsing helpers for common data types
- func (c *Context) ParamInt(name string) (int, error) {
- v := c.Param(name)
- return strconv.Atoi(v)
- }
- func (c *Context) ParamIntDefault(name string, defaultValue int) int {
- v := c.Param(name)
- if v == "" {
- return defaultValue
- }
- i, err := strconv.Atoi(v)
- if err != nil {
- return defaultValue
- }
- return i
- }
- func (c *Context) QueryInt(name string) (int, error) {
- v := c.Query(name)
- return strconv.Atoi(v)
- }
- func (c *Context) QueryIntDefault(name string, defaultValue int) int {
- v := c.Query(name)
- if v == "" {
- return defaultValue
- }
- i, err := strconv.Atoi(v)
- if err != nil {
- return defaultValue
- }
- return i
- }
- func (c *Context) FormInt(name string) (int, error) {
- v := c.FormValue(name)
- return strconv.Atoi(v)
- }
- func (c *Context) FormIntDefault(name string, defaultValue int) int {
- v := c.FormValue(name)
- if v == "" {
- return defaultValue
- }
- i, err := strconv.Atoi(v)
- if err != nil {
- return defaultValue
- }
- return i
- }
- // Context management helpers
- func (c *Context) SetValue(key, val any) {
- c.ctx = context.WithValue(c.ctx, key, val)
- }
- func (c *Context) Value(key any) any {
- return c.ctx.Value(key)
- }
|