swarm: give correct error on 0x hash prefix (#16195)
- added a case error struct that contains information about certain error cases in which we would like to output more information to the client - added a validation method that iterates and adds the information that is stored in the error cases
This commit is contained in:
committed by
Péter Szilágyi
parent
18bb3da55e
commit
b574b57766
@ -35,6 +35,7 @@ import (
|
||||
|
||||
//templateMap holds a mapping of an HTTP error code to a template
|
||||
var templateMap map[int]*template.Template
|
||||
var caseErrors []CaseError
|
||||
|
||||
//metrics variables
|
||||
var (
|
||||
@ -51,6 +52,13 @@ type ErrorParams struct {
|
||||
Details template.HTML
|
||||
}
|
||||
|
||||
//a custom error case struct that would be used to store validators and
|
||||
//additional error info to display with client responses.
|
||||
type CaseError struct {
|
||||
Validator func(*Request) bool
|
||||
Msg func(*Request) string
|
||||
}
|
||||
|
||||
//we init the error handling right on boot time, so lookup and http response is fast
|
||||
func init() {
|
||||
initErrHandling()
|
||||
@ -74,6 +82,29 @@ func initErrHandling() {
|
||||
//assign formatted HTML to the code
|
||||
templateMap[code] = template.Must(template.New(fmt.Sprintf("%d", code)).Parse(tname))
|
||||
}
|
||||
|
||||
caseErrors = []CaseError{
|
||||
{
|
||||
Validator: func(r *Request) bool { return r.uri != nil && r.uri.Addr != "" && strings.HasPrefix(r.uri.Addr, "0x") },
|
||||
Msg: func(r *Request) string {
|
||||
uriCopy := r.uri
|
||||
uriCopy.Addr = strings.TrimPrefix(uriCopy.Addr, "0x")
|
||||
return fmt.Sprintf(`The requested hash seems to be prefixed with '0x'. You will be redirected to the correct URL within 5 seconds.<br/>
|
||||
Please click <a href='%[1]s'>here</a> if your browser does not redirect you.<script>setTimeout("location.href='%[1]s';",5000);</script>`, "/"+uriCopy.String())
|
||||
},
|
||||
}}
|
||||
}
|
||||
|
||||
//ValidateCaseErrors is a method that process the request object through certain validators
|
||||
//that assert if certain conditions are met for further information to log as an error
|
||||
func ValidateCaseErrors(r *Request) string {
|
||||
for _, err := range caseErrors {
|
||||
if err.Validator(r) {
|
||||
return err.Msg(r)
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
//ShowMultipeChoices is used when a user requests a resource in a manifest which results
|
||||
@ -82,10 +113,10 @@ func initErrHandling() {
|
||||
//For example, if the user requests bzz:/<hash>/read and that manifest contains entries
|
||||
//"readme.md" and "readinglist.txt", a HTML page is returned with this two links.
|
||||
//This only applies if the manifest has no default entry
|
||||
func ShowMultipleChoices(w http.ResponseWriter, r *http.Request, list api.ManifestList) {
|
||||
func ShowMultipleChoices(w http.ResponseWriter, r *Request, list api.ManifestList) {
|
||||
msg := ""
|
||||
if list.Entries == nil {
|
||||
ShowError(w, r, "Internal Server Error", http.StatusInternalServerError)
|
||||
ShowError(w, r, "Could not resolve", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
//make links relative
|
||||
@ -102,7 +133,7 @@ func ShowMultipleChoices(w http.ResponseWriter, r *http.Request, list api.Manife
|
||||
//create clickable link for each entry
|
||||
msg += "<a href='" + base + e.Path + "'>" + e.Path + "</a><br/>"
|
||||
}
|
||||
respond(w, r, &ErrorParams{
|
||||
respond(w, &r.Request, &ErrorParams{
|
||||
Code: http.StatusMultipleChoices,
|
||||
Details: template.HTML(msg),
|
||||
Timestamp: time.Now().Format(time.RFC1123),
|
||||
@ -115,13 +146,15 @@ func ShowMultipleChoices(w http.ResponseWriter, r *http.Request, list api.Manife
|
||||
//The function just takes a string message which will be displayed in the error page.
|
||||
//The code is used to evaluate which template will be displayed
|
||||
//(and return the correct HTTP status code)
|
||||
func ShowError(w http.ResponseWriter, r *http.Request, msg string, code int) {
|
||||
func ShowError(w http.ResponseWriter, r *Request, msg string, code int) {
|
||||
additionalMessage := ValidateCaseErrors(r)
|
||||
if code == http.StatusInternalServerError {
|
||||
log.Error(msg)
|
||||
}
|
||||
respond(w, r, &ErrorParams{
|
||||
respond(w, &r.Request, &ErrorParams{
|
||||
Code: code,
|
||||
Msg: msg,
|
||||
Details: template.HTML(additionalMessage),
|
||||
Timestamp: time.Now().Format(time.RFC1123),
|
||||
template: getTemplate(code),
|
||||
})
|
||||
|
Reference in New Issue
Block a user