diff --git a/.gitignore b/.gitignore
index 0763d8492c..b8d2929016 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,6 +34,9 @@ profile.cov
# IdeaIDE
.idea
+# VS Code
+.vscode
+
# dashboard
/dashboard/assets/flow-typed
/dashboard/assets/node_modules
diff --git a/swarm/api/http/error.go b/swarm/api/http/error.go
index c932d0c784..7853a7f6e5 100644
--- a/swarm/api/http/error.go
+++ b/swarm/api/http/error.go
@@ -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 ResponseParams 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.
+ Please click here if your browser does not redirect you.`, "/"+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
@@ -111,7 +142,9 @@ func ShowMultipleChoices(w http.ResponseWriter, req *Request, list api.ManifestL
//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 Respond(w http.ResponseWriter, req *Request, msg string, code int) {
+ additionalMessage := ValidateCaseErrors(req)
switch code {
case http.StatusInternalServerError:
log.Output(msg, log.LvlError, 3, "ruid", req.ruid, "code", code)
@@ -122,6 +155,7 @@ func Respond(w http.ResponseWriter, req *Request, msg string, code int) {
respond(w, &req.Request, &ResponseParams{
Code: code,
Msg: msg,
+ Details: template.HTML(additionalMessage),
Timestamp: time.Now().Format(time.RFC1123),
template: getTemplate(code),
})
diff --git a/swarm/api/http/error_templates.go b/swarm/api/http/error_templates.go
index 0457cb8a70..cc9b996ba4 100644
--- a/swarm/api/http/error_templates.go
+++ b/swarm/api/http/error_templates.go
@@ -168,6 +168,11 @@ func GetGenericErrorPage() string {
{{.Msg}}
+
+ |
+ {{.Details}}
+ |
+
|
@@ -342,6 +347,12 @@ func GetNotFoundErrorPage() string {
{{.Msg}}
|
+
+ |
+ {{.Details}}
+ |
+
+
|
diff --git a/swarm/api/http/error_test.go b/swarm/api/http/error_test.go
index c2c8b908b8..dc545722e1 100644
--- a/swarm/api/http/error_test.go
+++ b/swarm/api/http/error_test.go
@@ -18,12 +18,13 @@ package http_test
import (
"encoding/json"
- "golang.org/x/net/html"
"io/ioutil"
"net/http"
"strings"
"testing"
+ "golang.org/x/net/html"
+
"github.com/ethereum/go-ethereum/swarm/testutil"
)
@@ -96,8 +97,37 @@ func Test500Page(t *testing.T) {
defer resp.Body.Close()
respbody, err = ioutil.ReadAll(resp.Body)
- if resp.StatusCode != 500 || !strings.Contains(string(respbody), "500") {
- t.Fatalf("Invalid Status Code received, expected 500, got %d", resp.StatusCode)
+ if resp.StatusCode != 404 {
+ t.Fatalf("Invalid Status Code received, expected 404, got %d", resp.StatusCode)
+ }
+
+ _, err = html.Parse(strings.NewReader(string(respbody)))
+ if err != nil {
+ t.Fatalf("HTML validation failed for error page returned!")
+ }
+}
+func Test500PageWith0xHashPrefix(t *testing.T) {
+ srv := testutil.NewTestSwarmServer(t)
+ defer srv.Close()
+
+ var resp *http.Response
+ var respbody []byte
+
+ url := srv.URL + "/bzz:/0xthisShouldFailWith500CodeAndAHelpfulMessage"
+ resp, err := http.Get(url)
+
+ if err != nil {
+ t.Fatalf("Request failed: %v", err)
+ }
+ defer resp.Body.Close()
+ respbody, err = ioutil.ReadAll(resp.Body)
+
+ if resp.StatusCode != 404 {
+ t.Fatalf("Invalid Status Code received, expected 404, got %d", resp.StatusCode)
+ }
+
+ if !strings.Contains(string(respbody), "The requested hash seems to be prefixed with") {
+ t.Fatalf("Did not receive the expected error message")
}
_, err = html.Parse(strings.NewReader(string(respbody)))
@@ -127,8 +157,8 @@ func TestJsonResponse(t *testing.T) {
defer resp.Body.Close()
respbody, err = ioutil.ReadAll(resp.Body)
- if resp.StatusCode != 500 {
- t.Fatalf("Invalid Status Code received, expected 500, got %d", resp.StatusCode)
+ if resp.StatusCode != 404 {
+ t.Fatalf("Invalid Status Code received, expected 404, got %d", resp.StatusCode)
}
if !isJSON(string(respbody)) {
diff --git a/swarm/api/http/server.go b/swarm/api/http/server.go
index 0acf86e40e..8bcda688dd 100644
--- a/swarm/api/http/server.go
+++ b/swarm/api/http/server.go
@@ -474,7 +474,7 @@ func (s *Server) HandleGet(w http.ResponseWriter, r *Request) {
key, err := s.api.Resolve(r.uri)
if err != nil {
getFail.Inc(1)
- Respond(w, r, fmt.Sprintf("cannot resolve %s: %s", r.uri.Addr, err), http.StatusInternalServerError)
+ Respond(w, r, fmt.Sprintf("cannot resolve %s: %s", r.uri.Addr, err), http.StatusNotFound)
return
}
@@ -558,7 +558,7 @@ func (s *Server) HandleGetFiles(w http.ResponseWriter, r *Request) {
key, err := s.api.Resolve(r.uri)
if err != nil {
getFilesFail.Inc(1)
- Respond(w, r, fmt.Sprintf("cannot resolve %s: %s", r.uri.Addr, err), http.StatusInternalServerError)
+ Respond(w, r, fmt.Sprintf("cannot resolve %s: %s", r.uri.Addr, err), http.StatusNotFound)
return
}
@@ -631,7 +631,7 @@ func (s *Server) HandleGetList(w http.ResponseWriter, r *Request) {
key, err := s.api.Resolve(r.uri)
if err != nil {
getListFail.Inc(1)
- Respond(w, r, fmt.Sprintf("cannot resolve %s: %s", r.uri.Addr, err), http.StatusInternalServerError)
+ Respond(w, r, fmt.Sprintf("cannot resolve %s: %s", r.uri.Addr, err), http.StatusNotFound)
return
}
@@ -735,7 +735,7 @@ func (s *Server) HandleGetFile(w http.ResponseWriter, r *Request) {
key, err := s.api.Resolve(r.uri)
if err != nil {
getFileFail.Inc(1)
- Respond(w, r, fmt.Sprintf("cannot resolve %s: %s", r.uri.Addr, err), http.StatusInternalServerError)
+ Respond(w, r, fmt.Sprintf("cannot resolve %s: %s", r.uri.Addr, err), http.StatusNotFound)
return
}
|