Worker routing not behaving as expected, when the route route is a path below the root of the domain

Hi, I initially tried this in #🦀workers-rs but didn't get a response, so I'm trying again here. (Note: example.com is used instead of the domain). The tl;dr is my worker functions correctly if the trigger is at the domain root, i.e. .com/*. For triggers where the route is served from a path below the root, i.e. .com/v1/email/parse/*, I just get Not Found responses. More details below. As an experiment I have two triggers, as follows: https://api.example.com/* https://api.example.com/v1/email/parse/* And my worker has the following routes:
.post_async("/" [...]
.post_async("/text/" [...]
.get_async("/" [...]
.post_async("/" [...]
.post_async("/text/" [...]
.get_async("/" [...]
Curl has the following results:
# the following are all sent to https://api.example.com/*
curl https://api.example.com/ # OK
curl https://api.example.com # OK
curl --data-binary @email.txt https://api.example.com/ # JSON of a parsed email
curl --data-binary @email.txt https://api.example.com/text/ # JSON of a parsed email

# But when I try to use https://api.example.com/v1/email/parse/*
curl https://api.example.com/v1/email/parse/ # Not Found
curl https://api.example.com/v1/email/parse # Not Found
curl --data-binary @email.txt https://api.example.com/v1/email/parse # Not Found
curl --data-binary @email.txt https://api.example.com/v1/email/parse/text/ # Not Found
# the following are all sent to https://api.example.com/*
curl https://api.example.com/ # OK
curl https://api.example.com # OK
curl --data-binary @email.txt https://api.example.com/ # JSON of a parsed email
curl --data-binary @email.txt https://api.example.com/text/ # JSON of a parsed email

# But when I try to use https://api.example.com/v1/email/parse/*
curl https://api.example.com/v1/email/parse/ # Not Found
curl https://api.example.com/v1/email/parse # Not Found
curl --data-binary @email.txt https://api.example.com/v1/email/parse # Not Found
curl --data-binary @email.txt https://api.example.com/v1/email/parse/text/ # Not Found
Since I'm getting a Not Found response (instead of 522), I think that indicates that the requests are actually being routed to the correct place, and that the issue is not with the worker platform itself. Probably the underlying issue is either I'm not understanding something correctly or maybe a problem with the rust routing/pattern stuff? Does anyone have any suggestions? Thank you. P.S: maybe it has to do with the new custom domains for workers thing.
15 Replies
kian
kian•13mo ago
Your routers are for / and /text/ so that wouldn't cover /v1/email/parse/ Do you have other routes not included in the snippet?
spence
spence•13mo ago
@kiannh So, as I understand it, routes - in the cloudflare lingo - are configured in the worker.toml file, or in the dash. The actual paths that functions operate on are different.
Your routers are for / and /text/
"Routers" in this sense is a rust router, which receives a path as an argument, however the path is being accessed on the following routes (in the cloudflare lingo) https://api.example.com/* https://api.example.com/v1/email/parse/* Which, as I understand it, everything starting from the * and beyond is processed path, i.e. router as you said earlier. I should, I think, be able to send requests to https://api.example.com/text/ or to https://api.example.com/v1/email/parse/text/ and they should both work.
kian
kian•13mo ago
The Router has no knowledge of your Worker's routes - it just receives a path of /v1/email/parse/text/ which doesn't match any of your routes.
spence
spence•13mo ago
Ok let me just see if I understand what you're saying, because I'm not sure if it answers my question. If I have a worker, with its route, in the worker.toml file configured to be foo.com/bar/*, and this worker has the following "router" .get_async("/" [...], what is full URL it should be accessed at?
kian
kian•13mo ago
The Worker receives a URL of foo.com/bar/baz That’s what the router will run against, so / !== /bar/baz and you’ll get a 404
spence
spence•13mo ago
Where did baz come from?
kian
kian•13mo ago
Just a random URL that’d match your Worker route
spence
spence•13mo ago
Ok, well I built a sample rust worker exactly like that, and there's no baz. Try it yourself http://sh0w.org/bar/baz
spence
spence•13mo ago
Here's a picture of the route, set up via the dash
spence
spence•13mo ago
And the code left unchanged from the template repository
spence
spence•13mo ago
So, what URL is it supposed to be?
kian
kian•13mo ago
You have / in your Worker's router, but your Worker doesn't run on / so it will never receive a request for / Your Worker's code has no knowledge of the routes in your first screenshot, it simply receives the request's URL. If you wanted something to run on /bar/* then you'd do .get("/bar/*p", ...)
spence
spence•13mo ago
I see. It's strange that the rust router, wouldn't just begin the path from wherever the worker is configued?
kian
kian•13mo ago
Nope, because your Worker code has no idea what your Worker is configured to be running on. It might run on 10 different routes, or none at all. This is the same for any routing package you'd use in Workers.
spence
spence•13mo ago
I see, ok now it makes sense to me, thank you for your patience. For some reason I was convinced that the router would run relative to how it's configured, but I can see now how it would work the same as the js workers, which just have one fetch point. All the routing logic from there is done based on the full URL, so it makes sense how the rust would work now too.