package webutility import ( "encoding/json" "fmt" "net/http" ) type StatusRecorder struct { writer http.ResponseWriter status int size int } func NewStatusRecorder(w http.ResponseWriter) *StatusRecorder { return &StatusRecorder{ writer: w, status: 0, size: 0, } } // http.ResponseWriter interface func (r *StatusRecorder) WriteHeader(code int) { r.status = code r.writer.WriteHeader(code) } // http.ResponseWriter interface func (r *StatusRecorder) Write(in []byte) (int, error) { r.size = len(in) return r.writer.Write(in) } // http.ResponseWriter interface func (r *StatusRecorder) Header() http.Header { return r.writer.Header() } func (r *StatusRecorder) Status() int { return r.status } func (r *StatusRecorder) Size() int { return r.size } // NotFoundHandlerFunc writes HTTP error 404 to w. func NotFoundHandlerFunc(w http.ResponseWriter, req *http.Request) { SetDefaultHeaders(w) if req.Method == "OPTIONS" { return } NotFound(w, req, fmt.Sprintf("Resource you requested was not found: %s", req.URL.String())) } // SetDefaultHeaders set's default headers for an HTTP response. func SetDefaultHeaders(w http.ResponseWriter) { w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS") w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization") w.Header().Set("Content-Type", "application/json; charset=utf-8") } func GetLocale(req *http.Request, dflt string) string { loc := req.FormValue("locale") if loc == "" { return dflt } return loc } // 2xx func Success(w http.ResponseWriter, payload interface{}, code int) { w.WriteHeader(code) if payload != nil { json.NewEncoder(w).Encode(payload) } } // 200 func OK(w http.ResponseWriter, payload interface{}) { Success(w, payload, http.StatusOK) } // 201 func Created(w http.ResponseWriter, payload interface{}) { Success(w, payload, http.StatusCreated) } type weberror struct { Request string `json:"request"` Error string `json:"error"` } // 4xx; 5xx func Error(w http.ResponseWriter, r *http.Request, code int, err string) { werr := weberror{Error: err, Request: r.Method + " " + r.RequestURI} w.WriteHeader(code) json.NewEncoder(w).Encode(werr) } // 400 func BadRequest(w http.ResponseWriter, r *http.Request, err string) { Error(w, r, http.StatusBadRequest, err) } // 401 func Unauthorized(w http.ResponseWriter, r *http.Request, err string) { Error(w, r, http.StatusUnauthorized, err) } // 403 func Forbidden(w http.ResponseWriter, r *http.Request, err string) { Error(w, r, http.StatusForbidden, err) } // 404 func NotFound(w http.ResponseWriter, r *http.Request, err string) { Error(w, r, http.StatusNotFound, err) } // 409 func Conflict(w http.ResponseWriter, r *http.Request, err string) { Error(w, r, http.StatusConflict, err) } // 500 func InternalServerError(w http.ResponseWriter, r *http.Request, err string) { Error(w, r, http.StatusInternalServerError, err) }