Check extensions before performing directory redirects #274
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem
When using the
extensionsoption,sendinconsistently handles path resolution depending on whether a directory exists at the requested path.For example, given this file structure:
When requesting paths with
extensions: ['html']configured:/contact(no directory exists) → servescontact.html/about(directory exists) → redirects to/about/instead of servingabout.htmlThis inconsistency occurs because:
sendreceives an ENOENT error and tries extensions, successfully servingcontact.htmlsendimmediately callsredirect(path)without trying extensions firststat()returns ENOENTThis behavior is problematic for static site generators and frameworks that want to serve files like
about.htmlfrom the URL/about(no trailing slash) while also having subdirectories likeabout/team.html.Solution
Modified
sendFile()to attempt extension resolution before redirecting when:The
next()function now tracks whether the original path was a directory via anisDirparameter. If all configured extensions fail toresolve to a file and the original path was a directory, it falls back to the standard directory redirect behavior.
This ensures consistent behavior:
/contactwithcontact.htmlpresent → servescontact.html/aboutwithabout.htmlpresent → servesabout.html/aboutwith onlyabout/directory → redirects to/about//aboutwith both present → servesabout.html(prioritizes file over directory)References
Resolves #194
Related to expressjs/serve-static#138