github.com/waltonchain/waltonchain_gwtc_src@v1.1.4-0.20201225072101-8a298c95a819/swarm/api/http/error.go (about) 1 // Copyright 2017 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-wtc library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-wtc library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 /* 18 Show nicely (but simple) formatted HTML error pages (or respond with JSON 19 if the appropriate `Accept` header is set)) for the http package. 20 */ 21 package http 22 23 import ( 24 "encoding/json" 25 "fmt" 26 "html/template" 27 "net/http" 28 "time" 29 30 "github.com/wtc/go-wtc/log" 31 ) 32 33 //templateMap holds a mapping of an HTTP error code to a template 34 var templateMap map[int]*template.Template 35 36 //parameters needed for formatting the correct HTML page 37 type ErrorParams struct { 38 Msg string 39 Code int 40 Timestamp string 41 template *template.Template 42 Details template.HTML 43 } 44 45 //we init the error handling right on boot time, so lookup and http response is fast 46 func init() { 47 initErrHandling() 48 } 49 50 func initErrHandling() { 51 //pages are saved as strings - get these strings 52 genErrPage := GetGenericErrorPage() 53 notFoundPage := GetNotFoundErrorPage() 54 //map the codes to the available pages 55 tnames := map[int]string{ 56 0: genErrPage, //default 57 400: genErrPage, 58 404: notFoundPage, 59 500: genErrPage, 60 } 61 templateMap = make(map[int]*template.Template) 62 for code, tname := range tnames { 63 //assign formatted HTML to the code 64 templateMap[code] = template.Must(template.New(fmt.Sprintf("%d", code)).Parse(tname)) 65 } 66 } 67 68 //ShowError is used to show an HTML error page to a client. 69 //If there is an `Accept` header of `application/json`, JSON will be returned instead 70 //The function just takes a string message which will be displayed in the error page. 71 //The code is used to evaluate which template will be displayed 72 //(and return the correct HTTP status code) 73 func ShowError(w http.ResponseWriter, r *http.Request, msg string, code int) { 74 if code == http.StatusInternalServerError { 75 log.Error(msg) 76 } 77 respond(w, r, &ErrorParams{ 78 Code: code, 79 Msg: msg, 80 Timestamp: time.Now().Format(time.RFC1123), 81 template: getTemplate(code), 82 }) 83 } 84 85 //evaluate if client accepts html or json response 86 func respond(w http.ResponseWriter, r *http.Request, params *ErrorParams) { 87 w.WriteHeader(params.Code) 88 if r.Header.Get("Accept") == "application/json" { 89 respondJson(w, params) 90 } else { 91 respondHtml(w, params) 92 } 93 } 94 95 //return a HTML page 96 func respondHtml(w http.ResponseWriter, params *ErrorParams) { 97 err := params.template.Execute(w, params) 98 if err != nil { 99 log.Error(err.Error()) 100 } 101 } 102 103 //return JSON 104 func respondJson(w http.ResponseWriter, params *ErrorParams) { 105 w.Header().Set("Content-Type", "application/json") 106 json.NewEncoder(w).Encode(params) 107 } 108 109 //get the HTML template for a given code 110 func getTemplate(code int) *template.Template { 111 if val, tmpl := templateMap[code]; tmpl { 112 return val 113 } else { 114 return templateMap[0] 115 } 116 }