[ 
https://issues.apache.org/jira/browse/CXF-8557?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17369244#comment-17369244
 ] 

Noah Rickles commented on CXF-8557:
-----------------------------------

[~reta], when I said that 

> A class-level {{@PathParam}} is created by the name of {{a}}. The following 
> annotations both correctly receive requests at {{/foo/bar}}:

I strictly meant on the server side. I can receive requests at that address and 
it correctly hits my service. The only issues are when a proxy implementation 
is created.

The scenario I outlined in the post is in the situation where the 
{{ClientProxyImpl}} is created with {{bean.create(..., "foo/bar")}}. The 
creation works fine (the varValues list is set up correctly due to the fix in 
the previous issue). It is on the invocation of that proxy that the flow begins 
that fragments the template in the path segmentation. 

>From what I understand, since the path segments are generated incorrectly like 
>so:
{code:java}
segments = JAXRSUtils.getPathSegments(path, false, false);

// segments = [ "{a : foo\", "bar}" ]{code}
So when the {{substituteVarargs}} method in {{UriBuilderImpl.java}} runs, there 
is nothing to substitute the {{"foo/bar"}} {{varValue}} into because the path 
segments do not contain a template. Please let me know if I need to clarify 
more.

> Incorrect Proxy Path Segmenting when @Path Annotation Regex Expression 
> Contains "/"
> -----------------------------------------------------------------------------------
>
>                 Key: CXF-8557
>                 URL: https://issues.apache.org/jira/browse/CXF-8557
>             Project: CXF
>          Issue Type: Bug
>          Components: JAX-RS
>    Affects Versions: 3.4.4
>            Reporter: Noah Rickles
>            Priority: Major
>              Labels: Bug
>
> Follow up to https://issues.apache.org/jira/browse/CXF-8556.
> A service in question needs to be reachable via multiple paths. The {{@Path}} 
> param allows for regex matching on a class-level like the following: 
> {{@Path("/\{a: regexExpression}")}}. A class-level {{@PathParam}} is created 
> by the name of {{a}}. The following annotations both correctly receive 
> requests at {{/foo/bar}}:
> {code:java}
> @Path("/{a : foo/bar}")
> @Path("/{a : foo\\/bar}")
> {code}
> When the proxy implementation is invoked, these paths are segmented as an 
> ArrayList with two entries: {{{a : foo}} and {{bar}}} and {a : foo\ and 
> {{bar}}} respectively. The expected behavior is for there to be one segment 
> corresponding to this path, \{a : foo/bar}, so that when variables are 
> replaced later ({{substituteVarargs}} method in {{UriBuilderImpl.java}}), the 
> path parameter {{a}} can be recognized as a vararg and replaced by a phrase 
> matching the regex expression.
> The flow that results in the fragmented segments begins here in the 
> {{invoke}} method of the {{ClientProxyImpl.java}} class:
> {code:java}
> if (this.isRoot) {
>     this.addNonEmptyPath(builder, 
> ori.getClassResourceInfo().getURITemplate().getValue());
> }
> this.addNonEmptyPath(builder, ori.getURITemplate().getValue());
> {code}
> This leads to the {{doPath}} method in the {{UriBuilderImpl.java}} class, 
> which calls the following with {{checkSegments}} equal to {{true}}:
> {code:java}
> List<PathSegment> segments;
> if (checkSegments) {
>     segments = JAXRSUtils.getPathSegments(path, false, false);
> } else {
>     segments = new ArrayList<>();
>     path = path.replaceAll("/", "%2F");
>     segments.add(new PathSegmentImpl(path, false));
> }
> {code}
> The {{getPathSegments}} method is as follows and is where the {{ArrayList}} 
> mentioned above gets populated:
> {code:java}
> public static List<PathSegment> getPathSegments(String thePath, boolean 
> decode,
>                                                 boolean ignoreLastSlash) {
>     List<PathSegment> theList =
>         Arrays.asList(thePath.split("/")).stream()
>         .filter(StringUtils.notEmpty())
>         .map(p -> new PathSegmentImpl(p, decode))
>         .collect(Collectors.toList());
>     int len = thePath.length();
>     if (len > 0 && thePath.charAt(len - 1) == '/') {
>         String value = ignoreLastSlash ? "" : "/";
>         theList.add(new PathSegmentImpl(value, false));
>     }
>     return theList;
> }
> {code}
> The path is split based on the presence of "/", without regard for if the 
> path segment is defined as a path parameter regex expression.
> The same behavior applies on paths not at a class-level also. For example, 
> the path denoted by a {{@Path("/\{a : foo/bar}/\{id}")}} on a lower level 
> resource segments the path into the following: {{{a : foo}}, {{bar}}}, and 
> \{id}, when it would be expected to segment into two segments, \{a : foo/bar} 
> and \{id}. The only difference here being when the path is segmented. Since 
> it is not a root path, it happens after the {{isRoot}} check, with the same 
> {{addNonEmptyPath}} method.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to