Mercurial > gemma
diff pkg/controllers/json.go @ 414:c1047fd04a3a
Moved project specific Go packages to new pkg folder.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Wed, 15 Aug 2018 17:30:50 +0200 |
parents | controllers/json.go@889517f254f5 |
children | b2dc9c2f69e0 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pkg/controllers/json.go Wed Aug 15 17:30:50 2018 +0200 @@ -0,0 +1,111 @@ +package controllers + +import ( + "database/sql" + "encoding/json" + "fmt" + "log" + "net/http" + + "github.com/jackc/pgx" + + "gemma.intevation.de/gemma/pkg/auth" +) + +type JSONResult struct { + Code int + Result interface{} +} + +type JSONHandler struct { + Input func() interface{} + Handle func(interface{}, *http.Request, *sql.DB) (JSONResult, error) +} + +type JSONError struct { + Code int + Message string +} + +func (je JSONError) Error() string { + return fmt.Sprintf("%d: %s", je.Code, je.Message) +} + +func (j *JSONHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + + var input interface{} + if j.Input != nil { + input = j.Input() + defer req.Body.Close() + if err := json.NewDecoder(req.Body).Decode(input); err != nil { + http.Error(rw, "error: "+err.Error(), http.StatusBadRequest) + return + } + } + + var jr JSONResult + var err error + + if token, ok := auth.GetToken(req); ok { + err = auth.ConnPool.Do(token, func(db *sql.DB) (err error) { + jr, err = j.Handle(input, req, db) + return err + }) + } else { + jr, err = j.Handle(input, req, nil) + } + + if err != nil { + switch e := err.(type) { + case pgx.PgError: + var res = struct { + Result string `json:"result"` + Code string `json:"code"` + Message string `json:"message"` + }{ + Result: "failure", + Code: e.Code, + Message: e.Message, + } + rw.Header().Set("Content-Type", "application/json") + rw.WriteHeader(http.StatusInternalServerError) + if err := json.NewEncoder(rw).Encode(&res); err != nil { + log.Printf("error: %v\n", err) + } + case JSONError: + rw.Header().Set("Content-Type", "application/json") + if e.Code == 0 { + e.Code = http.StatusInternalServerError + } + rw.WriteHeader(e.Code) + var res = struct { + Message string `json:"message"` + }{ + Message: e.Message, + } + if err := json.NewEncoder(rw).Encode(&res); err != nil { + log.Printf("error: %v\n", err) + } + default: + log.Printf("err: %v\n", err) + http.Error(rw, + "error: "+err.Error(), + http.StatusInternalServerError) + } + return + } + + if jr.Code == 0 { + jr.Code = http.StatusOK + } + + if jr.Code != http.StatusNoContent { + rw.Header().Set("Content-Type", "application/json") + } + rw.WriteHeader(jr.Code) + if jr.Code != http.StatusNoContent { + if err := json.NewEncoder(rw).Encode(jr.Result); err != nil { + log.Printf("error: %v\n", err) + } + } +}