request/response: add implementations for response writer
This commit is contained in:
parent
8f4b378fdd
commit
cb1ea9f701
@ -2,9 +2,6 @@ package framework
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
@ -121,49 +118,3 @@ func (ctx *Context) SetHandlers(handlers []ControllerHandler) {
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ Implements request functions
|
||||
|
||||
// {{{ application/json
|
||||
|
||||
// ReadJSON binds the request JSON body to an object.
|
||||
//
|
||||
// A pointer of obj should be passed.
|
||||
func (ctx *Context) ReadJSON(obj any) error {
|
||||
if ctx.request == nil {
|
||||
return errors.New("missing request in the context")
|
||||
}
|
||||
dec := json.NewDecoder(ctx.request.Body)
|
||||
err := dec.Decode(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = dec.Decode(&struct{}{})
|
||||
if err != io.EOF {
|
||||
return errors.New("body must have only a single JSON value")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteJSON send back an object in JSON format with the status code
|
||||
func (ctx *Context) WriteJSON(status int, obj any) error {
|
||||
// There is a timeout, some error message data must have already been
|
||||
// written to the output. Stop writing anything into the responseWriter.
|
||||
if ctx.HasTimeout() {
|
||||
return nil
|
||||
}
|
||||
data, err := json.Marshal(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx.responseWriter.Header().Set("Content-type", "application/json")
|
||||
ctx.responseWriter.WriteHeader(status)
|
||||
_, err = ctx.responseWriter.Write(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// }}}
|
||||
// }}}
|
||||
|
@ -1,10 +1,18 @@
|
||||
package framework
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
type IResponse interface {
|
||||
WriteJSON(obj any) IResponse
|
||||
WriteJSONP(obj any) IResponse
|
||||
WriteXML(obj any) IResponse
|
||||
WriteHTML(template string, obj any) IResponse
|
||||
WriteJSON(status int, obj any) IResponse
|
||||
WriteXML(status int, obj any) IResponse
|
||||
WriteHTML(status int, filepath string, obj any) IResponse
|
||||
WriteText(format string, values ...any) IResponse
|
||||
|
||||
Redirect(path string) IResponse
|
||||
@ -21,3 +29,95 @@ type IResponse interface {
|
||||
// set 200
|
||||
SetOkStatus() IResponse
|
||||
}
|
||||
|
||||
func (ctx *Context) WriteJSON(status int, obj any) IResponse {
|
||||
// There is a timeout, some error message data must have already been
|
||||
// written to the output. Stop writing anything into the responseWriter.
|
||||
if ctx.HasTimeout() {
|
||||
return nil
|
||||
}
|
||||
data, err := json.Marshal(obj)
|
||||
if err != nil {
|
||||
return ctx.SetStatus(http.StatusInternalServerError)
|
||||
}
|
||||
ctx.responseWriter.Header().Set("Content-type", "application/json")
|
||||
ctx.responseWriter.WriteHeader(status)
|
||||
_, _ = ctx.responseWriter.Write(data)
|
||||
return ctx
|
||||
}
|
||||
|
||||
func (ctx *Context) WriteXML(status int, obj any) IResponse {
|
||||
// There is a timeout, some error message data must have already been
|
||||
// written to the output. Stop writing anything into the responseWriter.
|
||||
if ctx.HasTimeout() {
|
||||
return nil
|
||||
}
|
||||
data, err := xml.Marshal(obj)
|
||||
if err != nil {
|
||||
return ctx.SetStatus(http.StatusInternalServerError)
|
||||
}
|
||||
ctx.responseWriter.Header().Set("Content-type", "application/json")
|
||||
ctx.responseWriter.WriteHeader(status)
|
||||
_, _ = ctx.responseWriter.Write(data)
|
||||
return ctx
|
||||
}
|
||||
|
||||
func (ctx *Context) WriteHTML(status int, filepath string, obj any) IResponse {
|
||||
ctx.SetHeader("Content-Type", "application/html")
|
||||
t, _ := template.New("output").ParseFiles(filepath)
|
||||
t.Execute(ctx.responseWriter, obj)
|
||||
|
||||
return ctx
|
||||
}
|
||||
|
||||
func (ctx *Context) WriteText(format string, values ...any) IResponse {
|
||||
out := fmt.Sprintf(format, values...)
|
||||
ctx.SetHeader("Content-Type", "application/text")
|
||||
ctx.responseWriter.Write([]byte(out))
|
||||
return ctx
|
||||
}
|
||||
|
||||
func (ctx *Context) Redirect(path string) IResponse {
|
||||
http.Redirect(ctx.responseWriter, ctx.request, path, http.StatusTemporaryRedirect)
|
||||
return ctx
|
||||
}
|
||||
|
||||
func (ctx *Context) SetHeader(key string, val string) IResponse {
|
||||
ctx.responseWriter.Header().Add(key, val)
|
||||
return ctx
|
||||
}
|
||||
|
||||
func (ctx *Context) SetCookie(
|
||||
key string,
|
||||
val string,
|
||||
maxAge int,
|
||||
path, domain string,
|
||||
secure, httpOnly bool,
|
||||
) IResponse {
|
||||
if path == "" {
|
||||
path = "/"
|
||||
}
|
||||
|
||||
http.SetCookie(ctx.responseWriter, &http.Cookie{
|
||||
Name: key,
|
||||
Value: url.QueryEscape(val),
|
||||
MaxAge: maxAge,
|
||||
Path: path,
|
||||
Domain: domain,
|
||||
SameSite: http.SameSiteDefaultMode,
|
||||
Secure: secure,
|
||||
HttpOnly: httpOnly,
|
||||
})
|
||||
return ctx
|
||||
}
|
||||
|
||||
func (ctx *Context) SetStatus(code int) IResponse {
|
||||
ctx.responseWriter.WriteHeader(code)
|
||||
return ctx
|
||||
}
|
||||
|
||||
// set 200
|
||||
func (ctx *Context) SetOkStatus() IResponse {
|
||||
ctx.responseWriter.WriteHeader(http.StatusOK)
|
||||
return ctx
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user