Henry Kuijpers created SLING-10466:
--------------------------------------
Summary: Ability of scoping sling:vanityPath per content path
Key: SLING-10466
URL: https://issues.apache.org/jira/browse/SLING-10466
Project: Sling
Issue Type: Improvement
Components: ResourceResolver
Affects Versions: Resource Resolver 1.7.8
Reporter: Henry Kuijpers
The sling mappings provide the possibility of creating a multi-tenant setup.
Multiple websites can be hosted, by providing Sling mappings that point to
their specific content paths. These mappings consist of domains. I.e.:
* https://my-website-a.com -> /content/my-website-a
* https://my-website-b.com -> /content/my-website-b
There is, however, an issue with this setup, when using sling:vanityPath.
Let’s say, we have the following structure:
/content/my-website-a/info/openinghours@sling:vanityPath=’/openinghours’
/content/my-website-b/test@sling:vanityPath=’/test’
Now:
When requesting https://my-website-a.com/openinghours , we see the content of
/content/my-website-a/info/openinghours (sling:vanityPath) – Correct
When requesting https://my-website-b.com/openinghours , we see the content of
/content/my-website-b/info/openinghours – Incorrect! This content does not
belong to this website!
The /test vanity is also available within both websites.
There seems to be support in Apache Sling for sling:vanityPath properties
containing a full URL:
https://github.com/apache/sling-org-apache-sling-resourceresolver/blob/4406b8fed0fedb48202fc6472fb552c36aa06e35/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java#L1285
This could be used to make the above work. However, that would require us to
store the protocol, domain & portnumber inside the sling:vanityPath property.
That does not feel right.
There is another option: We could try to use custom code to put the domains in
front of sling:vanityPath property values, by using a ResourceDecorator.
However, the ResourceDecorator in our custom bundle would not be started yet,
when Sling is starting up and doing the inventory, because our bundle is
dependent on the resourceresolver-bundle.
Also, another issue is that, when the mappings update, we would need to let
Sling re-scan everything (because our ResourceDecorator now has put the wrong
domain in front of all property values).
This basically leaves us without any good “hook” into this entire process.
If the sling:vanityPath property value contains a path (not a URL),
https://github.com/apache/sling-org-apache-sling-resourceresolver/blob/4406b8fed0fedb48202fc6472fb552c36aa06e35/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java#L1291
, the ANY_SCHEME_HOST constant is used, which has a value of “[^/]+/[^/]+”
which basically means that any scheme and any host matches. Given the usecase I
just described, it means that no matter where the sling:vanityPath properties
are stored, as long as they match the request *path* only, they match. Then,
the first one that is encountered (through the Iterator provided by
getResolveMapsIterator) – Potentially the wrong one!
When handling sling:vanityPath properties, there is not really any context of
domains, Sling mappings, … Purely a vanity path.
I think it could be possible to take the map entries into account, when
handling the vanity paths. This should mean that the ANY_SCHEME_HOST-constant
would not be used as part of the regex, but instead, we determine the host at a
later part, by taking into account the Sling mappings.
This would make the following cases possible:
1. Scope sling:vanityPath defined in a content path covered by a mapping, to
only that mapping, causing them to not be able to be requested by other domains;
2. When having found multiple content paths defining the same
sling:vanityPath, be able to actually select the right one (not tackling the
issue where 2 or more of the same vanity paths are defined under the same
content path);
3. Add a new Sling mapping (or remove / update an existing one) and the
sling:vanityPath scoping work right away.
So far, I’ve been experimenting a bit with the above and it seems most of it is
possible already, just that MapEntry (which is where the ANY_SCHEME_HOST +
vanity path value ends up as a regex) doesn’t have any knowledge of the Sling
mappings. I was thinking of making a wrapper class, to store the vanity path
without the scheme/host/port and allow it to dynamically select the right one
based on the request coming in.
I suppose it’s a good idea to be able to toggle this functionality, so that we
don’t interfere with existing setups. And also, if a content path defines a
sling:vanityPath that is not covered by a Sling Mapping – Should that
sling:vanityPath be global then? Or not work at all? (I think it should be
global, then.)
Does anyone have any thoughts about this? 😊
If we’re able to decide how we want to approach this, I can put in some effort
to make the changes.
--
This message was sent by Atlassian Jira
(v8.3.4#803005)