request/response: add implementations for response writer
This commit is contained in:
parent
8f4b378fdd
commit
cb1ea9f701
@ -2,9 +2,6 @@ package framework
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"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
|
package framework
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"encoding/xml"
|
||||||
|
"fmt"
|
||||||
|
"html/template"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
type IResponse interface {
|
type IResponse interface {
|
||||||
WriteJSON(obj any) IResponse
|
WriteJSON(status int, obj any) IResponse
|
||||||
WriteJSONP(obj any) IResponse
|
WriteXML(status int, obj any) IResponse
|
||||||
WriteXML(obj any) IResponse
|
WriteHTML(status int, filepath string, obj any) IResponse
|
||||||
WriteHTML(template string, obj any) IResponse
|
|
||||||
WriteText(format string, values ...any) IResponse
|
WriteText(format string, values ...any) IResponse
|
||||||
|
|
||||||
Redirect(path string) IResponse
|
Redirect(path string) IResponse
|
||||||
@ -21,3 +29,95 @@ type IResponse interface {
|
|||||||
// set 200
|
// set 200
|
||||||
SetOkStatus() IResponse
|
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