diff options
-rw-r--r-- | internal/domain/domain.go | 23 | ||||
-rw-r--r-- | internal/domain/domain_test.go | 4 |
2 files changed, 27 insertions, 0 deletions
diff --git a/internal/domain/domain.go b/internal/domain/domain.go index 31b30de0..1455d436 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -34,6 +34,10 @@ type locationDirectoryError struct { RelativePath string } +type locationFileNoExtensionError struct { + FullPath string +} + type project struct { NamespaceProject bool HTTPSOnly bool @@ -71,6 +75,10 @@ func (l *locationDirectoryError) Error() string { return "location error accessing directory where file expected" } +func (l *locationFileNoExtensionError) Error() string { + return "error accessing a path without an extension" +} + func acceptsGZip(r *http.Request) bool { if r.Header.Get("Range") != "" { return false @@ -325,6 +333,12 @@ func (d *D) resolvePath(projectName string, subPath ...string) (string, error) { testPath := publicPath + "/" + strings.Join(subPath, "/") fullPath, err := filepath.EvalSymlinks(testPath) if err != nil { + if endsWithoutHTMLExtension(testPath) { + return "", &locationFileNoExtensionError{ + FullPath: fullPath, + } + } + return "", err } @@ -370,6 +384,7 @@ func (d *D) tryNotFound(w http.ResponseWriter, r *http.Request, projectName stri func (d *D) tryFile(w http.ResponseWriter, r *http.Request, projectName string, subPath ...string) error { fullPath, err := d.resolvePath(projectName, subPath...) + if locationError, _ := err.(*locationDirectoryError); locationError != nil { if endsWithSlash(r.URL.Path) { fullPath, err = d.resolvePath(projectName, filepath.Join(subPath...), "index.html") @@ -385,6 +400,10 @@ func (d *D) tryFile(w http.ResponseWriter, r *http.Request, projectName string, } } + if locationError, _ := err.(*locationFileNoExtensionError); locationError != nil { + fullPath, err = d.resolvePath(projectName, strings.TrimSuffix(filepath.Join(subPath...), "/")+".html") + } + if err != nil { return err } @@ -490,6 +509,10 @@ func endsWithSlash(path string) bool { return strings.HasSuffix(path, "/") } +func endsWithoutHTMLExtension(path string) bool { + return !strings.HasSuffix(path, ".html") +} + func openNoFollow(path string) (*os.File, error) { return os.OpenFile(path, os.O_RDONLY|unix.O_NOFOLLOW, 0) } diff --git a/internal/domain/domain_test.go b/internal/domain/domain_test.go index b65396a7..72a9807a 100644 --- a/internal/domain/domain_test.go +++ b/internal/domain/domain_test.go @@ -43,17 +43,21 @@ func TestGroupServeHTTP(t *testing.T) { } assert.HTTPBodyContains(t, serveFileOrNotFound(testGroup), "GET", "http://group.test.io/", nil, "main-dir") + assert.HTTPBodyContains(t, serveFileOrNotFound(testGroup), "GET", "http://group.test.io/index", nil, "main-dir") assert.HTTPBodyContains(t, serveFileOrNotFound(testGroup), "GET", "http://group.test.io/index.html", nil, "main-dir") assert.HTTPRedirect(t, serveFileOrNotFound(testGroup), "GET", "http://group.test.io/project", nil) assert.HTTPBodyContains(t, serveFileOrNotFound(testGroup), "GET", "http://group.test.io/project", nil, `<a href="//group.test.io/project/">Found</a>`) assert.HTTPBodyContains(t, serveFileOrNotFound(testGroup), "GET", "http://group.test.io/project/", nil, "project-subdir") + assert.HTTPBodyContains(t, serveFileOrNotFound(testGroup), "GET", "http://group.test.io/project/index", nil, "project-subdir") + assert.HTTPBodyContains(t, serveFileOrNotFound(testGroup), "GET", "http://group.test.io/project/index/", nil, "project-subdir") assert.HTTPBodyContains(t, serveFileOrNotFound(testGroup), "GET", "http://group.test.io/project/index.html", nil, "project-subdir") assert.HTTPRedirect(t, serveFileOrNotFound(testGroup), "GET", "http://group.test.io/project/subdir", nil) assert.HTTPBodyContains(t, serveFileOrNotFound(testGroup), "GET", "http://group.test.io/project/subdir", nil, `<a href="//group.test.io/project/subdir/">Found</a>`) assert.HTTPBodyContains(t, serveFileOrNotFound(testGroup), "GET", "http://group.test.io/project/subdir/", nil, "project-subsubdir") assert.HTTPBodyContains(t, serveFileOrNotFound(testGroup), "GET", "http://group.test.io/project2/", nil, "project2-main") + assert.HTTPBodyContains(t, serveFileOrNotFound(testGroup), "GET", "http://group.test.io/project2/index", nil, "project2-main") assert.HTTPBodyContains(t, serveFileOrNotFound(testGroup), "GET", "http://group.test.io/project2/index.html", nil, "project2-main") assert.HTTPRedirect(t, serveFileOrNotFound(testGroup), "GET", "http://group.test.io/private.project/", nil) assert.HTTPError(t, serveFileOrNotFound(testGroup), "GET", "http://group.test.io//about.gitlab.com/%2e%2e", nil) |