Skip to main content

[jsr356-experts] Closing the gaps in the URI matching specification

  • From: Danny Coward < >
  • To:
  • Subject: [jsr356-experts] Closing the gaps in the URI matching specification
  • Date: Mon, 18 Mar 2013 17:12:35 -0700

Hi folks,

I wrote about this issue at some length last week about how the container matches an incoming URI to an endpoint path (URI or level 1 URI template) is underspecified. In sum there are two problems and here's what I propose the spec does to fix them. If you have serious objections, please speak up soon with alternative fixes to the problems !

1) The default container match scheme is not fully defined.

This shows up in cases where an incoming URI may potentially exact match one endpoint and also match another endpoint which uses a URI template. And potentially matches a third endpoint that uses another URI template. Which one gets the match ?

Here's what I propose:-

The container will attempt to match an incoming URI to an endpoint path (URI or level 1 URI-template) as follows:-
The container will recursively try to exact match the longest shared path prefix common to both incoming URI and endpoint path, done by stepping down the paths one segment at a time, using '/' as the separator.
If the shared path prefix is the same as the endpoint path and also the same as the incoming URI, then the paths match (end).
If the shared path prefix  is the same as the endpoint path, but shorter than the incoming URI, then the paths do not match (end).
If the shared path prefix is the same as the incoming URI, but shorter than the endpoint path then the paths do not match (end).
Otherwise, there are more segments of both paths to compare, so taking the next segment of both incoming URI and endpoint paths:-
If the next segment of the endpoint path is not a variable, it cannot match the next segment in the incoming URI, otherwise the shared path prefix would have included this path, so in this case, the paths do not match (end).
If the next endpoint directory is a variable, assign the value of the variable in the endpoint path to the value of the segment in the incoming URI, and append the segment to the shared path prefix and call it the new shared path prefix. Now repeat the steps above using the new shared path prefix.

So, here are some examples of that in practice:-

suppose an endpoint has path /a/b/
the only incoming URI that matches this is /a/b/

suppose an endpoint is mapped to /a/{var}
incoming URIs that do match: /a/b (with var=b), /a/apple (with var=apple)
URIs that do NOT match: /a, /a/b/c (because empty string and strings with reserved characters "/" are not valid URI-template level 1 expansions.)

suppose we have three endpoints and their paths:
endpoint A: /a/{var}/c
endpoint B: /a/b/c
endpoint C: /a/{var1}/{var2}
incoming URI: a/b/c matches B, not A or C, because an exact match is preferred.
incoming URI: a/d/c matches A with variable var=d, because like goldlocks, its just right :)
incoming URI: a/x/y/ matches C, with var1=x, var2=y

endpoint A: /{var1}/d
endpoint B: /b/{var2}
incoming URI: /b/d matches B with var2=d, not A with var1=b because the matching process works from left to right.

2) The ServerEndpointConfig.Configurator.matchesURI(URI incoming, String endpointPath) method cannot be supported without further specification changes.

There are two problems: one is, does a developer provided match overrule the default match algorithm ? And, second, if several *Configurator.matchesURI()'s report a match, which one wins ?

As I wrote last week, we could resolve this by saying configurator matchesURI wins over the default algorithm, and also imposing an order on the endpoints, though this latter part would be a bit tricky to specify properly. I suggested ordering what are currently Sets in the returns from the ServerApplicationConfig methods, define the precedence in relation to programmatically deployed endpoints. And use the order of all that to give an order of precendence of the configurators matchesURI results. But then we would still have the problem of how to order any annotated endpoints deployed as a result of a scan when there is no ServerApplicationConfig. Maybe we'd need some global priority ordering scheme...

The issue that's hard to get away from is that for a proper URI matching scheme, the scheme really needs to know ALL the endpoint paths in the application in order to determine a best match out of several candidates. Ordering the paths and picking off the first YES on a binary endpoint-level YES/NO match is a special case of that, and while we could define some kind of ordering, it neither feels especially useful nor simple to put into practice for developers.

So I hate to remove API at this point, but I am proposing removing the ServerEndpointConfig.Configurator.matchesURI() call and deferring the ability to override the matching scheme until the next version when we can define a proper application-level scheme for defining URI matching policies instead of trying to make it work at the endpoint level.

(For the brave at heart that really need the override, you still are able to override the handshake).

- Danny
Danny Coward
Java EE
Oracle Corporation

[jsr356-experts] Closing the gaps in the URI matching specification

Danny Coward 03/19/2013
Please Confirm