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

inconsistent application of encodeUri #234

Closed
2 tasks done
moonmeister opened this issue Sep 21, 2021 · 17 comments · Fixed by #391
Closed
2 tasks done

inconsistent application of encodeUri #234

moonmeister opened this issue Sep 21, 2021 · 17 comments · Fixed by #391

Comments

@moonmeister
Copy link

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Fastify version

3.21.1

Plugin version

4.2.3

Node.js version

14.17.6

Operating system

macOS

Operating system version (i.e. 20.04, 11.3, 10)

11.6

Description

I needed to disable the wildcard setup in favor of explicit static routes so I could use the catch all route for handling non-static pages.

This broke some unrelated route handling later on and I've tracked it back to this change. I have files that need to be served from the /page-data/app/[...]/page-data.json route. This works fine when wildcard: true. However, when wildcard: false the code uses encodeUri on all the file names meaning the server is now listening for /page-data/app/%5B...%5D/page-data.json and breaks my app.

Steps to Reproduce

Try serving a file with fastify-static and wildcard: false. If the file has characters modified by encodeUri then the file will 404.

Expected Behavior

I'd expect that setting wildcard: false would still allow /page-data/app/[...]/page-data.json to be served at it's correct path.

@moonmeister
Copy link
Author

Is there some reason we're using 'encodeURI' for file names? or can this simply be removed? Happy to submit a PR.

@moonmeister
Copy link
Author

#166 suggest this feature is needed. What's the work around here?

@mcollina
Copy link
Member

I don't understand what is the ask or problem. Reserved characters in uri MUST be percent-encoded (it's the spec).

How does it break your app? Could you write a code example that would fail?

@moonmeister
Copy link
Author

Summary: I'm not arguing with the spec. What I'm saying is that when the wildcard is enabled all files are served successfully. Whether or not they contain escapable characters in the path. When you disable wildcard serving in fastify-static all the sudden files with escapable characters start to 404. see the example code/tests:

import Fastify from "fastify";
import fastifyStatic from "fastify-static"
import fastifyRoutes from "fastify-routes"
import path from "path"
import fetch from "node-fetch";

const fastify = new Fastify({ ignoreTrailingSlash: true });
fastify.register(fastifyRoutes, {});

fastify.register(fastifyStatic, {
  wildcard: false, //Change this to see tests pass or fail. 
  root: path.resolve("./test_public"),
})


fastify.listen(3000, async (err, address) => {
  if (err) throw err;
  console.log(`server listening on ${address}`);
  console.log("Listening on routes: ", fastify.routes.keys())


  for (let path of ["/afile.json", "/bfile[...].json", "/[...]/cfile.json"]) {
    console.log(`Testing GET ${path}`);

    const res = await fetch(`http://localhost:3000${path}`);

    if (res.status >= 200 && res.status < 300) {
      const body = await res.json();
      console.log(`${res.url} passed: ${res.status}`);
      console.log(`response body: ${JSON.stringify(body)}`);
    } else {
      console.log(`${res.url} not found: ${res.status}`);
      console.log(`This is expected to work`)
    }
  }

  fastify.close();
});

My guess the issues is that when the wild card is being used it doesn't encode the names of available files or the incoming request path. Thus all comparisons just work.

But, when the wild card serving is not being used, the list of available file names is being encoded. However, when a request comes in and that URL is compared agains available files it's not being encoded.

If encoding URIs is so important that's fine, the issue is we aren't consistently doing so and that's causing bugs in certain configurations.

@mcollina
Copy link
Member

It might be that a different/better fix for #143 is possible, something that does not break normal usage.

Would you like to give it a go and send a PR?

@moonmeister
Copy link
Author

I'll look into it as I can. Not sure if this is a find-my-way, fastify, or fastify-static, or expectations issue. Have to do some more in depth debugging.

@mcollina
Copy link
Member

Thanks!

@mav-rik
Copy link
Contributor

mav-rik commented Oct 3, 2021

@moonmeister according to rfc the [ and ] characters must always be encoded (stackoverflow). But it looks like browsers (like chrome) and node-fetch just ignore that rule and send [ and ] as is.
When you set wildcard: false the framework lists all the files in root directory and creates handlers for each file doing encodeURI for files paths which is the right thing to do. But node-fetch or chrome send un-escaped [ ] so the path does not match to any file.
When you set wildcard: true obviously the framework creates a single handler for root + '*' path. Then no matter if browser encodes the path or not it gets to the handler with asterisk.
In your case I would suggest to always encode path when requesting the file (which won't work in browser):

const res = await fetch(encodeURI(`http://localhost:3000${path}`));

Another solution would be to PR the code and add un-encoded (decoded) routes along with encoded ones. But I am not sure how bad this solution is.

@moonmeister
Copy link
Author

That's super helpful, and I was starting to suspect it with be a character specific issue. I'll think on the best course of action here.

@mav-rik
Copy link
Contributor

mav-rik commented Oct 4, 2021

@moonmeister actually it goes even deeper. The thing is that fastify itself handles it wrongly.
I created an issue for fastify and described the problem.
When the fastify issue is resolved the PR #166 must be undone and then this issue will be solved.

@stale
Copy link

stale bot commented Apr 16, 2022

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Apr 16, 2022
@moonmeister
Copy link
Author

Still needs work

@stale stale bot removed the stale label Apr 16, 2022
@stale
Copy link

stale bot commented May 2, 2022

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label May 2, 2022
@meskill
Copy link

meskill commented Jan 16, 2023

The issue on the fastify side is closed as completed.
Is there gonna be update on the current issue?

@stale stale bot removed the stale label Jan 16, 2023
@mcollina
Copy link
Member

Would you like to send a Pull Request to address this issue? Remember to add unit tests.

gurgunday added a commit to gurgunday/fastify-static that referenced this issue Jul 16, 2023
@gurgunday
Copy link
Member

gurgunday commented Jul 16, 2023

I think this issue can be closed.

Try serving a file with fastify-static and wildcard: false. If the file has characters modified by encodeUri then the file will 404.

Whatever the value of wildcard (true or false), the file is served correctly.

Edit: PR that adds tests.

@gurgunday gurgunday mentioned this issue Jul 16, 2023
3 tasks
mcollina pushed a commit that referenced this issue Jul 17, 2023
* add tests for #234

* change description

* use variable to store file contents
@mcollina
Copy link
Member

Thanks @gurgunday!

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 a pull request may close this issue.

5 participants