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

Handle trailing slashes for endpoints with regex path params #43016

Merged
merged 3 commits into from
Nov 12, 2024

Conversation

jonomorris
Copy link
Contributor

@jonomorris jonomorris commented Sep 4, 2024

For Reactive REST endpoints don't include the path end slash when performing regex path param matches.

This comment has been minimized.

@gsmet
Copy link
Member

gsmet commented Sep 5, 2024

@jonomorris Thanks for the PR! I think the test failures above look related ^

@jonomorris
Copy link
Contributor Author

gsmet yeah there are some problems, I'll look into it.

@jonomorris
Copy link
Contributor Author

@gsmet and @stuartwdouglas, I made a small update and the unit tests pass locally in independent-projects/resteasy-reactive and extensions/resteasy-reactive.

This comment has been minimized.

@geoand
Copy link
Contributor

geoand commented Sep 24, 2024

cc @FroMage

.statusCode(200)
.body(equalTo("Hello! 1"));

get("/hello/1/")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if you do get /hello/1////?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intermediate slashes are encoded, for instance the path becomes /1%2F%2F%2F%2F/, which doesn't match the regex path matcher \\d+.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, we only alow a single optional slash at the end, then?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's correct.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how I feel about this.
It feels special-casy.

Also, I looked for articles about tailing slashes, and I only find SEO articles that advise to only serve one variant (with, or without).

And last, I've come across this issue spring-projects/spring-framework#28552 where Sprint went the other way around and removed the default of allowing optional trailing slashes by default.

So, I'll ask for more comments from HTTP/REST colleagues who might have a relevant opinion: @cescoffier @vietj:

Do you think we should allow trailing slashes for routes defined without one?

Now, on the other hand, this issue is about fixing the particular difference of assuming a trailing slash for regex paths, so that it's coherent with normal paths, which already assume a trailing slash. And I agree both should be the same. I'm not entirely sure regex matches are right, though, I wonder if non-regex path matching might be in the wrong here and the one that needs fixing. WDYT @geoand ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/foo and /foo/ are not equivalent. They refer to different resources due to the trailing slash:

  • /foo refers to a resource.
  • /foo/ often suggests that it’s a collection or directory-like structure containing resources.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So @cescoffier you're saying we should change the current behaviour of Quarkus REST to not treat these as the same when routing?

I suppose making the change and running the TCK will tell us what JAX-RS thinks about that :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's the problem - many servers consider them equivalent, but the "theory" says they are not.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was a similar conversation here #26016 (comment)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, OK, so the TCK did not test this, and the spec says we have to treat them equivalent. Probably people rely on that now, so let's just harmonize and make sure regexes also behave in a similar way, and if we want to change the default later, we'll wait for users reporting an issue and revisit if required, for both regular and regex.

@@ -76,12 +76,18 @@ private RequestMatch<T> mapFromPathMatcher(String path, PathMatcher.PathMatch<Ar
for (int i = 1; i < potentialMatch.template.components.length; ++i) {
URITemplate.TemplateComponent segment = potentialMatch.template.components[i];
if (segment.type == URITemplate.Type.CUSTOM_REGEX) {
Matcher matcher = segment.pattern.matcher(path);
// exclude any path end slash when matching a subdir, but include it in the matched length
boolean endSlash = matchPos < path.length() && path.charAt(path.length() - 1) == '/';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we need to consider more than one slash at the end? See my next question for how this behaves for non-regexes.

@FroMage
Copy link
Member

FroMage commented Oct 2, 2024

Agreed @cescoffier @geoand ?

@jorsol
Copy link
Contributor

jorsol commented Nov 6, 2024

Will this fix match more complex regex like in #44242?

Edit: Just checked the patch and it works as expected. Thanks!

@jorsol
Copy link
Contributor

jorsol commented Nov 6, 2024

Can this be backported to 3.15 too? 🙏🏽

@geoand
Copy link
Contributor

geoand commented Nov 6, 2024

New features do not get backported to LTS releases Never mind, I thought this was something else. Let's first get it merged first, and then we'll see about backporting

@geoand
Copy link
Contributor

geoand commented Nov 6, 2024

Forgot about this one, sorry.

Can the PR be rebased on main so we can get a recent CI run?

@jonomorris jonomorris force-pushed the fix-42687_handle_trailing_slashes branch from c53f4f0 to 6687b4b Compare November 7, 2024 10:21
Copy link

quarkus-bot bot commented Nov 7, 2024

Status for workflow Quarkus CI

This is the status report for running Quarkus CI on commit 6687b4b.

✅ The latest workflow run for the pull request has completed successfully.

It should be safe to merge provided you have a look at the other checks in the summary.

You can consult the Develocity build scans.

@geoand
Copy link
Contributor

geoand commented Nov 7, 2024

@FroMage mind taking a last peak to make sure nothing changed?

Copy link
Member

@FroMage FroMage left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, let's see how this pans out

@FroMage FroMage merged commit be016b7 into quarkusio:main Nov 12, 2024
46 checks passed
@quarkus-bot quarkus-bot bot added this to the 3.17 - main milestone Nov 12, 2024
@jonomorris jonomorris deleted the fix-42687_handle_trailing_slashes branch November 12, 2024 20:25
@jorsol
Copy link
Contributor

jorsol commented Dec 5, 2024

Can this have label:triage/backport-3.15 ?

@geoand
Copy link
Contributor

geoand commented Dec 5, 2024

Perhaps down the line when this patch has been stress tested by later non LTS versions

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

Successfully merging this pull request may close these issues.

Reactive REST endpoints do not handle trailing slashes for paths w/ regex
6 participants