github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/swarm/api/http/response.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:43</date> 10 //</624450111803494400> 11 12 13 package http 14 15 import ( 16 "encoding/json" 17 "fmt" 18 "html/template" 19 "net/http" 20 "strings" 21 "time" 22 23 "github.com/ethereum/go-ethereum/log" 24 "github.com/ethereum/go-ethereum/metrics" 25 "github.com/ethereum/go-ethereum/swarm/api" 26 ) 27 28 var ( 29 htmlCounter = metrics.NewRegisteredCounter("api.http.errorpage.html.count", nil) 30 jsonCounter = metrics.NewRegisteredCounter("api.http.errorpage.json.count", nil) 31 plaintextCounter = metrics.NewRegisteredCounter("api.http.errorpage.plaintext.count", nil) 32 ) 33 34 type ResponseParams struct { 35 Msg template.HTML 36 Code int 37 Timestamp string 38 template *template.Template 39 Details template.HTML 40 } 41 42 //当用户请求清单中的资源时,将使用showmultipleechoices,结果是 43 //结果模棱两可。它返回一个HTML页面,其中包含每个条目的可单击链接 44 //在符合请求URI模糊性的清单中。 45 //例如,如果用户请求bzz:/<hash>/read,并且该清单包含条目 46 //“readme.md”和“readinglist.txt”,将返回一个带有这两个链接的HTML页面。 47 //这仅在清单没有默认条目时适用 48 func ShowMultipleChoices(w http.ResponseWriter, r *http.Request, list api.ManifestList) { 49 log.Debug("ShowMultipleChoices", "ruid", GetRUID(r.Context()), "uri", GetURI(r.Context())) 50 msg := "" 51 if list.Entries == nil { 52 respondError(w, r, "Could not resolve", http.StatusInternalServerError) 53 return 54 } 55 requestUri := strings.TrimPrefix(r.RequestURI, "/") 56 57 uri, err := api.Parse(requestUri) 58 if err != nil { 59 respondError(w, r, "Bad Request", http.StatusBadRequest) 60 } 61 62 uri.Scheme = "bzz-list" 63 msg += fmt.Sprintf("Disambiguation:<br/>Your request may refer to multiple choices.<br/>Click <a class=\"orange\" href='"+"/"+uri.String()+"'>here</a> if your browser does not redirect you within 5 seconds.<script>setTimeout(\"location.href='%s';\",5000);</script><br/>", "/"+uri.String()) 64 respondTemplate(w, r, "error", msg, http.StatusMultipleChoices) 65 } 66 67 func respondTemplate(w http.ResponseWriter, r *http.Request, templateName, msg string, code int) { 68 log.Debug("respondTemplate", "ruid", GetRUID(r.Context()), "uri", GetURI(r.Context())) 69 respond(w, r, &ResponseParams{ 70 Code: code, 71 Msg: template.HTML(msg), 72 Timestamp: time.Now().Format(time.RFC1123), 73 template: TemplatesMap[templateName], 74 }) 75 } 76 77 func respondError(w http.ResponseWriter, r *http.Request, msg string, code int) { 78 log.Info("respondError", "ruid", GetRUID(r.Context()), "uri", GetURI(r.Context()), "code", code) 79 respondTemplate(w, r, "error", msg, code) 80 } 81 82 func respond(w http.ResponseWriter, r *http.Request, params *ResponseParams) { 83 w.WriteHeader(params.Code) 84 85 if params.Code >= 400 { 86 w.Header().Del("Cache-Control") 87 w.Header().Del("ETag") 88 } 89 90 acceptHeader := r.Header.Get("Accept") 91 /*这不能在开关中,因为接受头可以有多个值:“accept:*/*,text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8” 92 if strings.contains(acceptHeader,“application/json”) 93 如果错误:=respondjson(w,r,params);错误!= nIL{ 94 响应程序错误(w,r,“内部服务器错误”,http.statusInternalServerError) 95 } 96 else if strings.contains(acceptHeader,“text/html”) 97 响应HTML(w,r,params) 98 }否则{ 99 respondPlainText(w,r,params)//返回curl的良好错误 100 } 101 } 102 103 func respondhtml(w http.responsewriter,r*http.request,params*responseparams) 104 HTM计数器公司(1) 105 log.info(“respondhtml”,“ruid”,getruid(r.context()),“code”,params.code) 106 错误:=params.template.execute(w,params) 107 如果犯错!= nIL{ 108 日志错误(err.error()) 109 } 110 } 111 112 func respondjson(w http.responsewriter,r*http.request,params*responseparams)错误 113 jsoncounter.inc(1)公司 114 log.info(“respondjson”,“ruid”,getruid(r.context()),“code”,params.code) 115 w.header().set(“内容类型”,“应用程序/json”)。 116 返回json.newencoder(w).encode(params) 117 } 118 119 func respondplaintext(w http.responsewriter,r*http.request,params*responseparams)错误 120 明文计数器公司(1) 121 log.info(“respondPlainText”,“ruid”,getruid(r.context()),“code”,params.code) 122 w.header().set(“内容类型”,“文本/普通”)。 123 strToWrite:=“代码:”+fmt.sprintf(“%d”,params.code)+\n” 124 strToWrite+=“消息:”+string(params.msg)+\n“ 125 strToWrite+=“时间戳:”+params.timestamp+“”\n“ 126 _u,err:=w.write([]byte(strtowrite))。 127 返回错误 128 } 129