-
Notifications
You must be signed in to change notification settings - Fork 919
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
Support colons in path for server-side #5676
Changes from all commits
9dccdc9
3bf47c5
7cf515f
18aa1f1
1404057
589a32f
09cfdeb
bbbc212
e1fad09
b2aa86b
e2d93c2
e1f4760
669a416
e6a1525
b74bff4
eb624c4
50d8dcc
4cfb0b6
0fce731
5013894
79fe6e6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,7 +30,6 @@ | |
import java.util.List; | ||
import java.util.Objects; | ||
import java.util.Set; | ||
import java.util.function.Function; | ||
import java.util.function.Predicate; | ||
import java.util.regex.Pattern; | ||
|
||
|
@@ -96,7 +95,7 @@ public final class RouteBuilder { | |
* @throws IllegalArgumentException if the specified path pattern is invalid | ||
*/ | ||
public RouteBuilder path(String pathPattern) { | ||
return pathMapping(getPathMapping(pathPattern, RouteBuilder::getPathMapping)); | ||
return pathMapping(getPathMapping(pathPattern)); | ||
} | ||
|
||
/** | ||
|
@@ -218,8 +217,7 @@ public RouteBuilder glob(String glob) { | |
|
||
private RouteBuilder glob(String glob, int numGroupsToSkip) { | ||
requireNonNull(glob, "glob"); | ||
return pathMapping( | ||
getPathMapping(glob, pathPattern -> globPathMapping(pathPattern, numGroupsToSkip))); | ||
return pathMapping(globPathMapping(glob, numGroupsToSkip)); | ||
} | ||
|
||
/** | ||
|
@@ -543,32 +541,12 @@ private static PathMapping getPathMapping(String pathPattern) { | |
"pathPattern: " + pathPattern + | ||
" (not an absolute path starting with '/' or a unknown pattern type)"); | ||
} | ||
if (!pathPattern.contains("{") && !pathPattern.contains(":")) { | ||
if (!pathPattern.contains("/{") && !pathPattern.contains("/:")) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Due to this change,
We may reject the pattern as before or treat this as a known problem if the percent-encoding issue is not relevant to this PR. I also don't see this mismatch as a critical problem. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I agree with this sentiment. However, I also thought that not only Because of this, I thought 1) this was easy enough for maintainers to reason about 2) users won't be using this pattern anyways 3) If we want to limit these type of characters, it shouldn't be limited to only I do think such strict validation will be nice to have for those who aren't familiar with percent-encoding rules though (I also have to refer to the rfc every time if I'm being honest). I think it might be nice to refer to other frameworks to see how strictly they are handling validation rules as well. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
return new ExactPathMapping(pathPattern); | ||
} | ||
return new ParameterizedPathMapping(pathPattern); | ||
} | ||
|
||
private static PathMapping getPathMapping(String pathPattern, | ||
Function<String, PathMapping> basePathMappingMapper) { | ||
requireNonNull(pathPattern, "pathPattern"); | ||
if (pathPattern.startsWith(EXACT) || | ||
pathPattern.startsWith(PREFIX) || | ||
pathPattern.startsWith(REGEX) || | ||
pathPattern.startsWith(GLOB)) { | ||
return basePathMappingMapper.apply(pathPattern); | ||
} | ||
|
||
// Parameterized, glob or no prefix. | ||
final String verb = VerbSuffixPathMapping.findVerb(pathPattern); | ||
if (verb == null) { | ||
return basePathMappingMapper.apply(pathPattern); | ||
} | ||
final String basePathPattern = pathPattern.substring(0, pathPattern.length() - verb.length() - 1); | ||
final PathMapping basePathMapping = basePathMappingMapper.apply(basePathPattern); | ||
return new VerbSuffixPathMapping(basePathMapping, verb); | ||
} | ||
|
||
static PathMapping prefixPathMapping(String prefix, boolean stripPrefix) { | ||
if ("/".equals(prefix)) { | ||
// Every path starts with '/'. | ||
|
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question)
/a/:b:c/:d
,b:c
is used as a path variable, e.g.ctx.pathParam("b:c")
. Is that an expected behavior?/brace/{b}:def
is an invalid pattern./colon/:a:verb
is an valid pattern and a path segment is captured witha:verb
at which I was a bit suprised.If we don't support
/:param:verb
style in theParameterizedPathMapping
, I prefer to raise an exception when a path variable includes:
. What do you think?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also found that the handling of
{}
and:
is different which confused me at first.Having said this, I decided to just follow the previous regex pattern since I didn't want to introduce inadvertent breaking changes.
Double checked that this behavior is consistent with the main branch.
I wanted to avoid introducing more breaking changes since this PR is already introducing certain breaking changes. I also agree that the assymmetry is confusing and it is easier to reason about if
:
and{}
have the same treatment.I guess this comes down to "does this issue annoy maintainers enough to make a breaking change (I'm not sure if users are actually using colon in names though)". I think we can discuss this further at the next stand up meeting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was confused.
/brace/{b}:def
only works on the main branch but didn't work with the previous release version, 1.28.4. As it is consistent with the previous version, it is okay.This PR is good as is. However, ultimately, it would be good to support a path pattern that allows the path variable can be located in a path segment. Some URL patterns seem useful:
/{project}/{repoName}.git
/download/{filename}.pdf
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree this could be useful. I think it's probably doable if we start using
{}
instead of\0
to internally representing the parameterized variables. Additionally, we probably need to modify the route parsing logic atRouters
as well.I don't have immediate plans to handle this since
RegexPathMapping
can kind of handle this case - I'd be happy to review if you would like to work on it though.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To support complex path patterns to build finer grain routes, I am considering dropping
:
from the path variable patterns in Armeria 2.0. We don't debate about that though.I don't see it was a good choice that we used
:
as a path variable.:
seems simple but it can be also used as a literal. If a path variable is mixed with a literal:
, it is ambiguous and difficult to know the exact name of the variable.I'll try it next time. 😃