From 38f7fea738224eaa144f5f8e98a6e4213e39fd02 Mon Sep 17 00:00:00 2001 From: Lee ByeongJun Date: Wed, 3 Apr 2024 10:52:04 +0900 Subject: [PATCH 1/2] Handle unicode characters in 404 page URL --- gno.land/pkg/gnoweb/gnoweb.go | 23 +++++++++++++++-------- gno.land/pkg/gnoweb/gnoweb_test.go | 4 +++- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/gno.land/pkg/gnoweb/gnoweb.go b/gno.land/pkg/gnoweb/gnoweb.go index 4854ed4791e..b4f18486578 100644 --- a/gno.land/pkg/gnoweb/gnoweb.go +++ b/gno.land/pkg/gnoweb/gnoweb.go @@ -9,6 +9,7 @@ import ( "io/fs" "log/slog" "net/http" + "net/url" "os" "path/filepath" "runtime" @@ -122,7 +123,7 @@ func MakeApp(logger *slog.Logger, cfg Config) gotuna.App { app.Router.NotFoundHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { path := r.RequestURI - handleNotFound(app, &cfg, path, w, r) + handleNotFound(logger, app, &cfg, path, w, r) }) return app } @@ -444,12 +445,12 @@ func handlerStaticFile(logger *slog.Logger, app gotuna.App, cfg *Config) http.Ha fpath := filepath.Clean(vars["path"]) f, err := fs.Open(fpath) if os.IsNotExist(err) { - handleNotFound(app, cfg, fpath, w, r) + handleNotFound(logger, app, cfg, fpath, w, r) return } stat, err := f.Stat() if err != nil || stat.IsDir() { - handleNotFound(app, cfg, fpath, w, r) + handleNotFound(logger, app, cfg, fpath, w, r) return } @@ -467,7 +468,7 @@ func handlerFavicon(logger *slog.Logger, app gotuna.App, cfg *Config) http.Handl fpath := "img/favicon.ico" f, err := fs.Open(fpath) if os.IsNotExist(err) { - handleNotFound(app, cfg, fpath, w, r) + handleNotFound(logger, app, cfg, fpath, w, r) return } w.Header().Set("Content-Type", "image/x-icon") @@ -476,11 +477,17 @@ func handlerFavicon(logger *slog.Logger, app gotuna.App, cfg *Config) http.Handl }) } -func handleNotFound(app gotuna.App, cfg *Config, path string, w http.ResponseWriter, r *http.Request) { +func handleNotFound(logger *slog.Logger, app gotuna.App, cfg *Config, path string, w http.ResponseWriter, r *http.Request) { + // decode path for non-ascii characters + decodedPath, err := url.PathUnescape(path) + if err != nil { + logger.Error("failed to decode path", err) + decodedPath = path + } w.WriteHeader(http.StatusNotFound) app.NewTemplatingEngine(). Set("title", "Not found"). - Set("path", path). + Set("path", decodedPath). Set("Config", cfg). Render(w, r, "404.html", "funcs.html") } @@ -501,7 +508,7 @@ func pathOf(diruri string) string { parts := strings.Split(diruri, "/") if parts[0] == "gno.land" { return "/" + strings.Join(parts[1:], "/") - } else { - panic(fmt.Sprintf("invalid dir-URI %q", diruri)) } + + panic(fmt.Sprintf("invalid dir-URI %q", diruri)) } diff --git a/gno.land/pkg/gnoweb/gnoweb_test.go b/gno.land/pkg/gnoweb/gnoweb_test.go index 86a739b4a36..42bf612097d 100644 --- a/gno.land/pkg/gnoweb/gnoweb_test.go +++ b/gno.land/pkg/gnoweb/gnoweb_test.go @@ -42,6 +42,9 @@ func TestRoutes(t *testing.T) { {"/gor", found, "/game-of-realms"}, {"/blog", found, "/r/gnoland/blog"}, {"/404-not-found", notFound, "/404-not-found"}, + {"/아스키문자가아닌경로", notFound, "/아스키문자가아닌경로"}, + {"/%ED%85%8C%EC%8A%A4%ED%8A%B8", notFound, "테스트"}, + {"/グノー", notFound, "グノー"}, } config, _ := integration.TestingNodeConfig(t, gnoenv.RootDir()) @@ -65,7 +68,6 @@ func TestRoutes(t *testing.T) { assert.Equal(t, r.status, response.Code) assert.Contains(t, response.Body.String(), r.substring) - // println(response.Body.String()) }) } } From 302e362ddbf91112246f93ab696fb6033d2bab5e Mon Sep 17 00:00:00 2001 From: Lee ByeongJun Date: Wed, 3 Apr 2024 11:57:46 +0900 Subject: [PATCH 2/2] update test case --- gno.land/pkg/gnoweb/gnoweb_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gno.land/pkg/gnoweb/gnoweb_test.go b/gno.land/pkg/gnoweb/gnoweb_test.go index 42bf612097d..55434e3b9fc 100644 --- a/gno.land/pkg/gnoweb/gnoweb_test.go +++ b/gno.land/pkg/gnoweb/gnoweb_test.go @@ -43,8 +43,9 @@ func TestRoutes(t *testing.T) { {"/blog", found, "/r/gnoland/blog"}, {"/404-not-found", notFound, "/404-not-found"}, {"/아스키문자가아닌경로", notFound, "/아스키문자가아닌경로"}, - {"/%ED%85%8C%EC%8A%A4%ED%8A%B8", notFound, "테스트"}, - {"/グノー", notFound, "グノー"}, + {"/%ED%85%8C%EC%8A%A4%ED%8A%B8", notFound, "/테스트"}, + {"/グノー", notFound, "/グノー"}, + {"/⚛️", notFound, "/⚛️"}, } config, _ := integration.TestingNodeConfig(t, gnoenv.RootDir())