Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

serveStatic doesn't work with extensionless files #2251

Closed
oscarotero opened this issue Feb 22, 2024 · 10 comments · Fixed by #2260, #2910, honojs/node-server#182 or honojs/node-server#183
Closed
Labels

Comments

@oscarotero
Copy link

What version of Hono are you using?

4.0.5

What runtime/platform is your app running on?

Deno

What steps can reproduce the bug?

I'm using Pagefind which generates the following file structure:
imaxe

What is the expected behavior?

When the browser request the file /pagefind/pagefind.unknown_278027f53872923.pf_meta it should be served correctly.

What do you see instead?

The browser gets a 404 error, and Hono logs

Error: Not a directory (os error 20): open './_site/pagefind/pagefind.unknown_278027f53872923.pf_meta/index.html'

Additional information

This is because Hono automatically add /index.html to any file without an extension (See the code here: https://github.com/honojs/hono/blob/main/src/utils/filepath.ts#L19-L21)

It should check first if the file exist before adding the defaultDocument sufix.

@thehipbit
Copy link

Is it expected that serveStatic should still log errors when serving extensionless files?

To be pedantic, these files do have extensions: .pf_index for example. Is there some way I can just register such extensions so they will be recognized as files before the OS fs gets involved with an erroneous index.html read?

Error: Not a directory (os error 20): open './server/www/pagefind/pagefind.en_d94842caac.pf_meta/index.html'
Error: Not a directory (os error 20): open './server/www/pagefind/index/en_ffaa787.pf_index/index.html'
Error: Not a directory (os error 20): open './server/www/pagefind/fragment/en_553fb48.pf_fragment/index.html'

@yusukebe
Copy link
Member

yusukebe commented Jun 5, 2024

@thehipbit

I can't fully understand that and cannot reproduce it. So, please create another issue and describe it. If possible, create a minimal project to reproduce it. Thanks.

@thehipbit
Copy link

I think the actual issue is the filename extension. The original comment in this issue concerns a file named pagefind.unknown_278027f53872923.pf_meta. The PageFind project generates many files with names like en_d94842caac.pf_meta and en_ffaa787.pf_index.

I was confused about why this issue is named "extensionless files" since PageFind creates files with extensions, albeit non-standard extensions, like .pf_meta and .pf_index.

Whenever the PageFind files are requested via serveStatic, I see an error in the terminal where it appears index.html was appended to the requested filename (making, for example, en_1dc9843.pf_index/index.html) and the OS apparently tried to access it and failed. The content is eventually returned in a valid response, but why did hono try to add index.html and check the filesystem first? Surely, this can't be the most efficient way to do it!

I believe the issue is the underscore in the filename extension. I tried experimenting with different name variations, and this is the result:

  • en_1dc9843.pf_index => Error: Not a directory (os error 20): open './server/www/t/en_1dc9843.pf_index/index.html'
  • en_1dc9843.pf-index => Error: Not a directory (os error 20): open './server/www/t/en_1dc9843.pf-index/index.html'
  • en_1dc9843.pfindex => (no error)

So I think the problem is the underscore (or any non-alphanumeric character) in the filename extension causes hono to try to append /index.html to the path.

I believe this is the line where that is happening:

} else if (!filename.match(/\.[a-zA-Z0-9]+$/)) {

If you wanted to support files with an underscore or dash in the filename extension, then the line should be

} else if (!filename.match(/\.[a-zA-Z0-9_-]+$/)) {

† I see this error Not a directory (os error 20) in the terminal with a minimal deno-based hono project using serveStatic on an Apple Mac M1, latest OS version.

@ersinakinci
Copy link

ersinakinci commented Jun 28, 2024

This is still a problem for me. I'm trying to use an actually extensionless file, ./public/.well-known/apple-developer-merchantid-domain-association, and serveStatic doesn't see it.

My workaround is to save my file with a .txt extension and use rewriteRequestPath:

app.use(
  "*",
  serveStatic({
    root: "./public",
    rewriteRequestPath: (path) =>
      path.replace(
        /^\/\.well-known\/apple-developer-merchantid-domain-association/,
        "/.well-known/apple-developer-merchantid-domain-association.txt"
      ),
  })
);

@yusukebe
Copy link
Member

yusukebe commented Jul 1, 2024

Hi @ersinakinci

Are you running it on Deno?

@ersinakinci
Copy link

Hi @yusukebe, nope running on Node.

@yusukebe
Copy link
Member

yusukebe commented Jul 2, 2024

@ersinakinci thanks.

This may be fixed with the latest version 1.11.5 of @hono/node-server.

@ersinakinci
Copy link

@yusukebe, just upgraded and unfortunately I'm still getting the same error.

@yusukebe
Copy link
Member

yusukebe commented Jul 3, 2024

@ersinakinci

Sorry! I've fixed it and released the new version 1.12.0. Try it.

@thehipbit
Copy link

I just wanted to point out how deeply impressive it is that this project responds to its users so quickly. I've used many other projects that take weeks or months to respond. The fact that @yusukebe can release fixes almost immediately is making me love this project. 👏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment