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