elixir-plug / plug

Compose web applications with functions
https://hex.pm/packages/plug
Other
2.84k stars 582 forks source link

Suffix matching behavior breaks Bypass tests for paths containing * #1127

Closed thecristen closed 1 year ago

thecristen commented 1 year ago

Is there a way to opt out of the suffix matching behavior? I believe that change in v1.13 is what broke my test. I'm using Bypass to mock responses for a few of my unit tests. After upgrading Bypass (and in turn being forced to upgrade Plug from 1.12 to 1.14), my tests that hit a URL containing * now fail with the following

(Plug.Router.InvalidSpecError) invalid dynamic path. The characters : and * must be immediately followed by lowercase letters or underscore, got: :

The URL in question has the path /1/indexes/*/queries, it gets sent to a 3rd party API (so I'm not going to change it).

I'm struggling to figure out a workaround for my test. I am wondering if there is a way for me to tell Plug somehow that I'm not trying to build a dynamic path.

whatyouhide commented 1 year ago

Heyo, thanks for the issue.

I think the issue might be that you need to follow * with a variable name, not a suffix:

CleanShot 2023-01-18 at 08 31 18@2x

If this is the case, we need to improve the error message.

Also, I'm confused on a thing: do you want to send /1/indexes/*/queries as is to the 3rd party, or the * is still meant to be a match, and you want to send URLs such as /1/indexes/foo/queries?

thecristen commented 1 year ago

Thanks for the response; to clarify, I want to (need to) send /1/indexes/*/queries as is to the 3rd party. It's not so much a route that's part of my own application, but my application happens to be making a HTTPoison.post to the third-party URL that happens to have the "/1/indexes/*/queries" path. Hope this helps!

josevalim commented 1 year ago

@thecristen you should be able to write: /1/indexes/*_unused/queries or even /1/indexes/*_unused. Whatever follows * is going to be the name of the variables where the remaining paths will be assigned to. Then you can still access the whole path in the connection and send it to the 3rd party.

thecristen commented 1 year ago

Thanks @josevalim I will give it a try. 😄 Also my bad for pointing to Plug 1.14, as I just found I can reproduce with 1.12.1.

thecristen commented 1 year ago

Well, that works as a workaround for the sake of my tests, but I'd have to adjust it in prod since the API I'm POSTing to doesn't support a "/1/indexes/*_whatever/queries" path.

josevalim commented 1 year ago

@thecristen when plug matches on *_whatever, the actual path is on _whatever. You should be able to change it afterwards in any way you want so you don't submit exactly _whatever to the API.