Skip to content

fix(backend): return 404 instead of panicking on unresolvable static paths - #858

Open
NopeCharon wants to merge 1 commit into
werf:mainfrom
NopeCharon:fix/backend/static-path-panic
Open

NopeCharon wants to merge 1 commit into
werf:mainfrom
NopeCharon:fix/backend/static-path-panic

Conversation

@NopeCharon

Copy link
Copy Markdown

Fixes #857

Problem

serveFilesHandler only handled os.IsNotExist errors from os.Stat. Any other error left fileInfo nil, and the following fileInfo.IsDir() call panicked. LoggingMiddleware recovered the panic, answered 500 and logged a stack trace.

Ordinary bad URLs trigger this:

  • /index.html/foo: ENOTDIR, because a path component is a regular file
  • a path segment longer than 255 bytes: ENAMETOOLONG

Changes

  • Treat ENOTDIR and ENAMETOOLONG like a missing file and render the 404 page.
  • Pass any other stat error (for example permission denied) to http.FileServer, which maps it to the right status code. This replaces the nil dereference.
  • Add TestServeFilesHandler, which covers existing and missing files, a path below a regular file, an overlong segment and a directory without index.html. Without the fix the test panics on the /page.html/foo case.

Validation

  • go test ./... passes in backend/ on Linux (arm64) and macOS.
  • gofumpt -extra, gci (Standard/Default/github.com/werf/) and golangci-lint v1.62.0 with the common-ci config report nothing new. The only remaining finding, the unused getRootRelease, was there before this change.
  • Manual check against a router with a stub root/en: /index.html/foo and a 300-character path now return 404 with 404.html. Before, they returned 500.

…paths

serveFilesHandler stats the requested file and only handled
os.IsNotExist errors. Every other error left fileInfo nil, so the
following fileInfo.IsDir() call panicked. LoggingMiddleware recovered
the panic and answered 500 while logging a full stack trace.

Ordinary bad URLs hit this path:

- /index.html/foo: a path component is a regular file, so stat fails
  with ENOTDIR, which os.IsNotExist does not cover;
- a path segment longer than NAME_MAX fails with ENAMETOOLONG.

Treat ENOTDIR and ENAMETOOLONG like a missing file and render the 404
page. Any other stat error (for example permission denied) is now
passed to http.FileServer, which maps it to the proper status code
instead of dereferencing a nil FileInfo.

Add a table test for serveFilesHandler covering existing and missing
files, a path below a regular file, an overlong segment and a
directory without index.html.

Fixes werf#857

Signed-off-by: NopeCharon <115794254+NopeCharon@users.noreply.github.com>
@NopeCharon
NopeCharon force-pushed the fix/backend/static-path-panic branch from 87b1341 to 20864ca Compare October 27, 2026 09:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Backend returns 500 with a panic for paths below a file or with an overlong segment

1 participant