-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Improved PathSpec handling for servletName & pathInfo #7947
Conversation
Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/MatchedPath.java
Show resolved
Hide resolved
jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/ServletPathSpec.java
Outdated
Show resolved
Hide resolved
jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/ServletPathSpec.java
Outdated
Show resolved
Hide resolved
jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/ServletPathSpec.java
Outdated
Show resolved
Hide resolved
jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/ServletPathSpec.java
Outdated
Show resolved
Hide resolved
jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathMappings.java
Show resolved
Hide resolved
Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
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.
A few things from a quick look through.
I don't love that we are not optimizing if there are Regex patterns, but I think that can be a TODO for later.
{ | ||
_exactMap = new ArrayTernaryTrie<>((ArrayTernaryTrie<MappedResource<E>>)_exactMap, 1.5); | ||
// This is not a Servlet mapping, turn off optimization on Exact | ||
_optimizedExact = false; |
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 feel that we probably can do optimized exact matches, even for regex etc. The Trie maps to a MappedResource that includes the PathSpec, so if match produces a non ServletPathSpec match, then we know we have to run it again to ensure we match any groups etc.
But maybe this is OK for now. Perhaps add a TODO to investigate if an exact map can be done.
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.
Lets punt on optimized regex for now.
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.
Added some comments about the concerns on exact/prefix/suffix and non-servlet path specs
jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathMappings.java
Outdated
Show resolved
Hide resolved
{ | ||
_prefixMap = new ArrayTernaryTrie<>((ArrayTernaryTrie<MappedResource<E>>)_prefixMap, 1.5); | ||
// This is not a Servlet mapping, turn off optimization on Prefix | ||
_optimizedPrefix = false; |
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.
Again, we should be able to extract the prefix from any PREFIX_GLOB and put that in the Trie.
So again, for now add a TODO to optimize later.
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.
It's not quite as easy as you think.
The comments added show what needs to be resolved.
TODO added as well.
else | ||
{ | ||
// This is not a Servlet mapping, turn off optimization on Suffix | ||
_optimizedSuffix = false; |
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.
Hmmm I really don't like all these optimized booleans. Might just be better to null out the map/trie and have a null mean don't look up. That is a single test rather than always testing boolean then looking at the map/trie
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.
That means creating the Trie anew with every .add() or .put()
jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathMappings.java
Outdated
Show resolved
Hide resolved
jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathMappings.java
Outdated
Show resolved
Hide resolved
{ | ||
case EXACT: | ||
if (_declaration.equals(path)) | ||
return MatchedPath.from(path, null); |
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.
This should be a final field as it will always be the immutable MatchedPath.from(_declaration, null)
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.
final where? if you have multiple PathSpecs, you have multiple final fields, which means a lookup/map again.
if (isWildcardMatch(path)) | ||
{ | ||
String pathMatch = path; | ||
String pathInfo = null; | ||
if (path.length() != (_specLength - 2)) | ||
{ | ||
pathMatch = path.substring(0, _specLength - 2); | ||
pathInfo = path.substring(_specLength - 2); | ||
} | ||
return MatchedPath.from(pathMatch, pathInfo); |
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.
This also needs to avoid allocation in the common case of "/foo" matching "/foo/*"
if (isWildcardMatch(path)) | |
{ | |
String pathMatch = path; | |
String pathInfo = null; | |
if (path.length() != (_specLength - 2)) | |
{ | |
pathMatch = path.substring(0, _specLength - 2); | |
pathInfo = path.substring(_specLength - 2); | |
} | |
return MatchedPath.from(pathMatch, pathInfo); | |
if (isWildcardMatch(path)) | |
{ | |
if (path.length() == (_specLength - 2)) | |
return finalFieldAllocatedInConstructor; | |
String pathMatch = anotherFinalFiledAllocatedInConstructor ; | |
String pathInfo = path.substring(_specLength - 2); | |
return MatchedPath.from(pathMatch, pathInfo); |
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.
You'll have a map of values, mapping each PathSpec and potential path.
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.
The pathSpec itself should know it's prefix, so that is what is returned. No map needed.
@joakime do you want me to have a go at fixing some of these issues? |
+ Implemented recalculations + Added more comments Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
I addressed most of the review comments. The comments about final fields for various things don't make much sense to me, as we are dealing with multiple PathSpec objects in the collection, so having a final field make sense will result in another Map lookup, which kinda defeats the whole final field benefit. If you can make it work without a new collection/trie/etc, give it a whirl. |
I'll do a PR against this PR addressing some of my performance concerns.... good task for on the train/plane tomorrow. |
@gregw 🚩 bump 🚩 : this need attention for the next release. |
Ack |
@joakime I pushed a change to this branch that should improve performance. |
+1 from me. |
jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/AbstractPathSpec.java
Outdated
Show resolved
Hide resolved
jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/MatchedPath.java
Outdated
Show resolved
Hide resolved
jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/MatchedPath.java
Outdated
Show resolved
Hide resolved
jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/MatchedResource.java
Show resolved
Hide resolved
jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/MatchedPath.java
Show resolved
Hide resolved
jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/ServletPathSpec.java
Outdated
Show resolved
Hide resolved
jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/UriTemplatePathSpec.java
Outdated
Show resolved
Hide resolved
jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/UriTemplatePathSpec.java
Outdated
Show resolved
Hide resolved
jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/RegexPathSpec.java
Show resolved
Hide resolved
jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/RegexPathSpecTest.java
Show resolved
Hide resolved
Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
Introduction of MatchedResource and MatchedPath to capture the results of a PathSpec match.