You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
DirectoryHTTPHandler cannot serve a directory URL as its index.html
Version: FlyingFox 0.27.1 Type: feature request
Summary
DirectoryHTTPHandler maps a request path onto a file under root and serves that file. It has no
notion of a directory index, so a request for /docs/ — a directory URL — resolves to the directory
itself, HTTPBodySequence(file:) fails, and the handler returns 404. Serving /docs/index.html
requires the client to spell out the filename.
index.html does not currently appear anywhere in FlyingFox/Sources.
Relevance
Serving a directory of static files is one of the things FlyingFox is most obviously good for, and
any site produced by a static-site generator (Ignite, Publish, Jekyll, Hugo, Eleventy) is laid out as section/index.html and links to it as /section/. Those links are not something the site author
can avoid: they are how generators emit clean URLs, and they are what <a href="/en/clubs/"> in the
generated HTML says.
The result is that DirectoryHTTPHandler handles almost the whole job for the static-site case and
then has to be replaced wholesale, because the one missing piece is in the path resolution rather
than in the response. Everything after resolution — content type, Content-Length, ETag and Last-Modified with 304 handling, range requests — is already there and is the part that would be
tedious to reimplement.
An opt-in parameter, so current behaviour is untouched for anyone who does not ask for it:
publicinit(root:URL,
serverPath:String="/",
directoryIndex:String?=nil, // e.g. "index.html"
cacheControl:[HTTPCacheControl.ResponseDirective]=[.private])
In makeFileURL(for:), when directoryIndex is set and the resolved URL is a directory, append the
index filename; if that file does not exist, return nil as today (404) rather than inventing a
directory listing. A listing is a separate feature with its own security and formatting questions,
and it is not what the static-site case needs.
Two details worth settling in the design:
Redirect or serve? Most servers 301 /docs to /docs/ so that relative links inside the
document resolve correctly. Serving the index directly at /docs breaks relative hrefs. Doing
what nginx does (redirect when the path lacks the trailing slash, serve when it has one) is the
least surprising, but simply serving the index for both is defensible for a development server and
a lot simpler.
Nothing else changes. Dot segments are already handled: HTTPDecoder.standardizePath removes
them before any handler runs, which was the fix for Security vulnerability: Path traversal in DirectoryHTTPHandler #24. So this request is only about the index filename, not about traversal.
Context
From vdhamer/Photo-Club-Hub-HTML#249, a macOS app that generates a static site and previews it over
HTTP. The app currently ships its own handler that resolves the path and then delegates to FileHTTPHandler for everything else. Two things keep it from being DirectoryHTTPHandler: the
directory index above, and a containment check that resolves symlinks — the latter genuinely belongs
in the app, since only the app knows which root a symlink has to stay under, so it is not part of
this request.
Note: this suggestion came out of adopting FlyingFox in vdhamer/Photo-Club-Hub-HTML. I explicitly asked
Claude Code (Opus 5) for changes that would reduce the glue code on our side and would plausibly
benefit other FlyingFox users as well — the analysis above is its work against the 0.27.1
sources (yes, I did review it before filing). Offered as one user's suggestion; feel free to reject it if it does
not fit where you want the library to go.
DirectoryHTTPHandlercannot serve a directory URL as itsindex.htmlVersion: FlyingFox 0.27.1
Type: feature request
Summary
DirectoryHTTPHandlermaps a request path onto a file underrootand serves that file. It has nonotion of a directory index, so a request for
/docs/— a directory URL — resolves to the directoryitself,
HTTPBodySequence(file:)fails, and the handler returns 404. Serving/docs/index.htmlrequires the client to spell out the filename.
index.htmldoes not currently appear anywhere inFlyingFox/Sources.Relevance
Serving a directory of static files is one of the things FlyingFox is most obviously good for, and
any site produced by a static-site generator (Ignite, Publish, Jekyll, Hugo, Eleventy) is laid out as
section/index.htmland links to it as/section/. Those links are not something the site authorcan avoid: they are how generators emit clean URLs, and they are what
<a href="/en/clubs/">in thegenerated HTML says.
The result is that
DirectoryHTTPHandlerhandles almost the whole job for the static-site case andthen has to be replaced wholesale, because the one missing piece is in the path resolution rather
than in the response. Everything after resolution — content type,
Content-Length,ETagandLast-Modifiedwith 304 handling, range requests — is already there and is the part that would betedious to reimplement.
Reproducing
GET /en/clubs/index.htmlGET /en/clubs/en/clubs/index.htmlGET /index.htmlSuggested API
An opt-in parameter, so current behaviour is untouched for anyone who does not ask for it:
In
makeFileURL(for:), whendirectoryIndexis set and the resolved URL is a directory, append theindex filename; if that file does not exist, return
nilas today (404) rather than inventing adirectory listing. A listing is a separate feature with its own security and formatting questions,
and it is not what the static-site case needs.
Two details worth settling in the design:
/docsto/docs/so that relative links inside thedocument resolve correctly. Serving the index directly at
/docsbreaks relativehrefs. Doingwhat nginx does (redirect when the path lacks the trailing slash, serve when it has one) is the
least surprising, but simply serving the index for both is defensible for a development server and
a lot simpler.
HTTPDecoder.standardizePathremovesthem before any handler runs, which was the fix for Security vulnerability: Path traversal in
DirectoryHTTPHandler#24. So this request is only about the index filename, not about traversal.Context
From vdhamer/Photo-Club-Hub-HTML#249, a macOS app that generates a static site and previews it over
HTTP. The app currently ships its own handler that resolves the path and then delegates to
FileHTTPHandlerfor everything else. Two things keep it from beingDirectoryHTTPHandler: thedirectory index above, and a containment check that resolves symlinks — the latter genuinely belongs
in the app, since only the app knows which root a symlink has to stay under, so it is not part of
this request.
Note: this suggestion came out of adopting FlyingFox in
vdhamer/Photo-Club-Hub-HTML. I explicitly asked
Claude Code (Opus 5) for changes that would reduce the glue code on our side and would plausibly
benefit other FlyingFox users as well — the analysis above is its work against the 0.27.1
sources (yes, I did review it before filing). Offered as one user's suggestion; feel free to reject it if it does
not fit where you want the library to go.