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 request.uri() Behaviour in Dynamic Catch-All Routes #126

Open
elcharitas opened this issue Oct 7, 2023 · 2 comments
Open

Comments

@elcharitas
Copy link

Problem Description:
I am currently implementing a catch-all route in my project using this runtime. Within the handler for this catch-all route, I need to access the request URI using request.uri().

Issue Details:

  • On the initial page load, everything appears to work as expected. The request.uri() correctly returns the expected path, such as "/hello."
  • However, upon refreshing the page or navigating to a different part of the application, I encounter unexpected behavior. The request.uri() function now returns "/api/[...all]" instead of the expected path as shown in the snippet below:
// api/[...all].rs
use vercel_runtime::{run, Body, Error, Request, Response};

#[tokio::main]
async fn main() -> Result<(), Error> {
    run(handler).await
}

pub async fn handler(req: Request) -> Result<Response<Body>, Error> {
    println!("request.uri, {}", request.uri()); // prints /hello then /api/[...all]
}

This behavior is unexpected and inconsistent, as I would expect request.uri() to consistently return the path of the current request. I have reviewed my vercel configuration and am confident that it's not causing this issue. Here's my vercel.json JIC.

{
  "functions": {
    "api/**/*.rs": {
      "runtime": "vercel-rust@4.0.6"
    }
  },
  "rewrites": [
    {
      "source": "/(.*)",
      "destination": "/api/$1"
    }
  ],
  "redirects": [
    {
      "source": "/",
      "destination": "/home",
      "statusCode": 301
    }
  ]
}

Steps to Reproduce:

  1. Create a catch-all route using the exact snippet above.
  2. Observe the value returned by request.uri().
  3. Refresh the page or navigate to a different route.
  4. Again, observe the value returned by request.uri(), which may now be unexpected.

Expected Behavior:
request.uri() should consistently return the correct path for the current request, regardless of how many times the page is refreshed or navigated.

Environment:

  • Rust version: 1.72
  • Vercel-Rust: 4.0.6

I appreciate any insights or suggestions on resolving this issue. Thank you!

@elcharitas
Copy link
Author

[UPDATE]

It seems the issue stems from lack of support for both rewrites and redirects with functions. Why? I have another sample where I used this simple vercel config and which works perfectly well:

{
  "functions": {
    "api/**/*.rs": {
      "runtime": "vercel-rust@4.0.6"
    }
  },
  "rewrites": [
    {
      "source": "/(.*)",
      "destination": "/api/$1"
    }
  ]
}

This means this issue relates to #121 except, I'm not making use of the bundling api

@elcharitas elcharitas changed the title Inconsistent request.uri() Behaviour in Catch-All Routes Inconsistent request.uri() Behaviour in Dynamic Catch-All Routes Nov 24, 2023
@elcharitas
Copy link
Author

elcharitas commented Nov 24, 2023

Further investigation shows that the issue described above has nothing to do with vercel.json or the rewrites config. It turns out the vercel rust runtime router is the best candidate to be held responsible for this bug as the issue totally disappears when an optional catch all route is created.

For anyone who may not be aware, there are two possible catch all routes file names which this runtime supports:

  • Dynamic catch all routes - [...all].rs
  • Optional catch all routes - [[...all]].rs

Until this issue is fixed (I may open a PR if I have the time), if you're experiencing this same issue, you can switch to making use of an optional catch all route which is more friendly IMO 😅

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

No branches or pull requests

1 participant