tsviewer/response/response.go
2019-01-17 01:35:51 +01:00

87 lines
1.5 KiB
Go

package response
import (
"encoding/json"
"log"
"net/http"
"git.cliffbreak.de/Cliffbreak/tsviewer/request/meta"
)
type HandlerFunc func() (int, error)
// Responder is a service for responses
type Responder interface {
Send(http.ResponseWriter, int)
}
// Response data type
type Response struct {
Content interface{}
Pretty bool
}
type Envelope struct {
Data interface{} `json:"data,omitempty"`
}
// New creates a new Response
func New(content interface{}, r *http.Request) *Response {
var resp Response
meta := meta.NewFromRequest(r)
if meta.Envelope {
resp = Response{
Content: Envelope{
Data: content,
},
}
} else {
resp = Response{
Content: content,
}
}
resp.Pretty = meta.Pretty
return &resp
}
// Send sends the response
func (resp Response) Send(w http.ResponseWriter, status int) (int, error) {
var (
rawJSON []byte
err error
)
if resp.Pretty {
rawJSON, err = json.MarshalIndent(resp.Content, "", " ")
} else {
rawJSON, err = json.Marshal(resp.Content)
}
if err != nil {
return http.StatusInternalServerError, err
} else if string(rawJSON) == "null" {
rawJSON = make([]byte, 0)
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(status)
w.Write(rawJSON)
return status, nil
}
func Handler(w http.ResponseWriter, r *http.Request, hf HandlerFunc) {
status, err := hf()
if err == nil {
return
}
log.Printf("HTTP %d: %q", status, err)
if status, err = New(NewError(status, err), r).Send(w, status); err != nil {
http.Error(w, http.StatusText(status), status)
}
}