-
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
Better Servlet PathMappings for Regex #7891
Comments
We could allow users to label their groups for what they want those sections to be when using more complex regex patterns. Eg: Pattern pat = Pattern.compile("^(?<servlet>/([A-Za-z0-9]{3,})/([0-9]{3}))(?<pathInfo>/.*)?$");
Matcher mat = pat.matcher("/mango/001/sku-888");
if (mat.matches())
{
System.out.printf("Groups = %d%n", mat.groupCount());
for (int i = 0; i < mat.groupCount(); i++)
{
System.out.printf("Group[%d] = '%s'%n", i, mat.group(i));
}
System.out.printf("Servlet - %s%n", mat.group("servlet"));
System.out.printf("PathInfo - %s%n", mat.group("pathInfo"));
}
else
{
System.out.println("Not a match");
} Output:
|
@gregw @joakime, this looks a little verbose to me. How about adopting a convention where there can be at most two groups per matched regex pattern, where the first group denotes the I've rewritten all our regex patterns for servlet mappings accordingly, and applied the following "hack" to
Please let me know what you think. Thanks! |
The first group is rarely the servletName Some examples.
|
The other thing to consider with using group names is that it could be possible to use them to break the invariant that @jluehe is the linked PR workable? (other than it still does the match multiple times) |
Fixed test Signed-off-by: Greg Wilkins <[email protected]>
@gregw, I've tried out the linked PR and ran into an issue: URI=https://localhost:6101/services/data/v56.0/connect/knowledge-migrations Pattern: ^(./services/data[/|.]?)(.)$ Expected assignments: _servletPath: /services/data/ Assignments with linked PR: _servletPath: /services/data/v56.0/connect/knowledge-migrations |
That pattern is odd and would not match the provided URI path. Try it yourself on regex101.com... https://regex101.com/r/XfSIo7/1 The dot at the beginning would mean a match of any single character before the Here's an slightly adjusted regex, with similar results. https://regex101.com/r/O4dEsL/1 Check the "Match Information" panel on the right, the "Group 1" results would be your Servlet Name, and the "Group 2" results would be your Path Info. |
Sorry, @joakime, the pattern I quoted was supposed to read: I agree the leading |
I'm beginning to feel that the invariant you mention is irrelevant when using UriTemplatePathSpec or RegexPathSpec. Or we should just take a page from Servlet url-pattern suffixes and just treat the whole input request (post context) to be the Servlet Path, and have no Path Info? Example:
Results in :
|
A regex pattern starting with If we support the named groups, then you can override this behavior, by specifying the groups you want to be Servlet Path vs PathInfo. |
We could also put the |
Here's the example of your pattern but with named groups. https://regex101.com/r/7O6M7Q/1 These named groups would allow you to specify where the important details separation should be. |
Thx, @joakime! I've compared with our original pattern and ran related functional tests, and as it turns out, the Still not sure what extra benefit the named groups would give us ... Re: Btw, you don't need the escape on the . in the character list definition, the dot character is always a literal within the character list. +1 |
Including the slash on the request.getServletPath() is an odd choice. If we look at the normal url-pattern for prefix based matches on the Servlet spec, the separation works like this. package jetty.pathspec;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.component.LifeCycle;
public class PrefixBehaviorDemo
{
public static void main(String[] args) throws Exception
{
Server server = new Server(9999);
ServletContextHandler contextHandler = new ServletContextHandler();
contextHandler.setContextPath("/ctx");
ServletHolder dumpHolder = new ServletHolder("dump", new HttpServlet()
{
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException
{
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/plain");
PrintWriter out = resp.getWriter();
out.printf("Request URI: %s%n", req.getRequestURI());
out.printf("Request Context Path: %s%n", req.getContextPath());
out.printf("Request Servlet Path: %s%n", req.getServletPath());
out.printf("Request Servlet PathInfo: %s%n", req.getPathInfo());
}
});
contextHandler.addServlet(dumpHolder, "/dump/*");
server.setHandler(contextHandler);
try
{
server.start();
HttpClient httpClient = HttpClient.newHttpClient();
demoRequest(httpClient, server.getURI().resolve("/ctx/dump/this"));
demoRequest(httpClient, server.getURI().resolve("/ctx/dump/deep/in/the/heart/of/texas"));
}
finally
{
LifeCycle.stop(server);
}
}
private static void demoRequest(HttpClient httpClient, URI path)
{
try
{
HttpRequest httpRequest = HttpRequest.newBuilder(path).GET().build();
HttpResponse<String> httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
System.out.printf("HTTP %s %s Response Status: %d%n", httpRequest.method(), httpRequest.uri(), httpResponse.statusCode());
System.out.println(httpResponse.body());
}
catch (IOException | InterruptedException e)
{
e.printStackTrace();
}
}
} A setup of ...
Request URI:
Request URI:
I think it would make more sense for that slash (or dot) to belong to the pathInfo portion. |
@joakime, I agree that would make more sense, and we can revisit later - for now, I just want to get the existing patterns working with Jetty 10 ... |
Fix 7891 regex pathInfo + Use the pathSpec methods to set servletPath and pathInfo when possible Signed-off-by: Greg Wilkins <[email protected]>
Fix 7891 regex pathInfo + Use the pathSpec methods to set servletPath and pathInfo when possible Signed-off-by: Greg Wilkins <[email protected]>
merged to 11, cherry-picked to 12 |
@gregw @joakime, I've tried out your patch efd9f26, and it does not seem to work for our use cases. Example: Expectation: Actual result with patch: This goes back to my earlier comment when I first tried out the patch ... |
The current |
The regex pattern This categorization is important when resolving across all of the PathSpec's you have registered.
The current implementation treats only PREFIX_GLOB as having the potential for pathInfo. |
Thx, @joakime! Can the current implementation be enhanced to support our use case? I've enabled Jetty 10.0.9 in our dev branch, with my patch (hack) as mentioned above applied to it, and things are looking very promising so far! Alternatively, could the current implementation be changed to support custom pattern matching as shown in my hack? |
I'm making some improvements to RegexPathSpec in regards to how often it does matching. (going from 3 per hit to 1 per hit) |
Awesome, @joakime! |
Re: #7891 (comment), turns out the leading |
Signed-off-by: Joakim Erdfelt <[email protected]>
Signed-off-by: Joakim Erdfelt <[email protected]>
Signed-off-by: Joakim Erdfelt <[email protected]>
Signed-off-by: Joakim Erdfelt <[email protected]>
Signed-off-by: Joakim Erdfelt <[email protected]>
Signed-off-by: Joakim Erdfelt <[email protected]>
Signed-off-by: Joakim Erdfelt <[email protected]>
Signed-off-by: Joakim Erdfelt <[email protected]>
Signed-off-by: Joakim Erdfelt <[email protected]>
Signed-off-by: Joakim Erdfelt <[email protected]>
Signed-off-by: Joakim Erdfelt <[email protected]>
Signed-off-by: Joakim Erdfelt <[email protected]>
+ Implemented recalculations + Added more comments Signed-off-by: Joakim Erdfelt <[email protected]>
Fix 7891 regex pathInfo + Use the pathSpec methods to set servletPath and pathInfo when possible Signed-off-by: Greg Wilkins <[email protected]>
This issue has been automatically marked as stale because it has been a |
Closing, merged in PR #7947 |
Jetty version(s)
Description
The path mappings for RegexPathSpec does not use groups for prefix matches to set
servletPath
andpathInfo
.The text was updated successfully, but these errors were encountered: