If we're talking dispatcher, then yes, this is the wrong list :) However if we focus on the general concern, which is that as a by-product of its design. There is an inherent exploit which can result in DOS attack when using a cache.
One solution might be a generic selector filter, one that can accept a list of patterns to whitelist or blacklist. -----Original Message----- From: Roy Teeuwen [mailto:r...@teeuwen.be] Sent: Saturday, July 30, 2016 6:58 AM To: users@sling.apache.org Subject: Re: Getting the actual resource from a request Hey Jason, Just come back to the dispatcher caching problem you saw. I think this is actually a global problem that happens anywhere, is there any rule in the dispatcher to be able stop this? Just to look at a fun real life example: http://wwwimages.adobe.com/content/dam/Adobe/images/shared/product_mnemonics/48x48/dreamweaver-no-shadow-48x48.png <http://wwwimages.adobe.com/content/dam/Adobe/images/shared/product_mnemonics/48x48/dreamweaver-no-shadow-48x48.png> http://wwwimages.adobe.com/content/dam/Adobe/images/shared/product_mnemonics/48x48/dreamweaver-no-shadow-48x48.png./test.jpg <http://wwwimages.adobe.com/content/dam/Adobe/images/shared/product_mnemonics/48x48/dreamweaver-no-shadow-48x48.png./test.jpg> http://wwwimages.adobe.com/content/dam/Adobe/images/shared/product_mnemonics/48x48/dreamweaver-no-shadow-48x48.png./test/another.jpg <http://wwwimages.adobe.com/content/dam/Adobe/images/shared/product_mnemonics/48x48/dreamweaver-no-shadow-48x48.png./test/another.jpg> It seems to make a new image in the dispatcher cache for every request. But I guess we would be on the wrong list to discuss something like this ;) Greets Roy > On 29 Jul 2016, at 15:04, Roy Teeuwen <r...@teeuwen.be> wrote: > > Hey Jason, > > You are absolutely right, damn :)! It’s because I didn’t realise that the > .jpg didn’t count as extension. I’m going to keep it with a suffix though: > /content/dam/nice-image.jpg.cdn./mod-date/20160815/nice-image.jpg just so > that in the browser it still looks like the image is called nice-image.jpg > ;). > > And you are also right about the second part, sadly enough :P. So maybe it > would be safe to make the servlet after all, so that I can check the mod-date > suffix part and see if that asset actually exists with that last modified > date and only return it then, and else return a 404. This would solve the > caching possibility of infinite image issue! > > Thanks > Roy > > >> On 29 Jul 2016, at 14:31, Jason Bailey <jason.bai...@sas.com> wrote: >> >> Roy, >> >> I think you may slap your forehead on this one :) You had to >> implement a service because when you added the cdn between the image >> name and the jpeg. It broke the resource resolution. That's why you >> had problems with the request.getResource() >> >> Once you fixed it by moving the selector, the resource is identified. That >> means, it's found the image. You don't need to have a service. The Sling >> application will take your URL, identify the resource and return that >> resource. >> >> So if all you did was just append .%timestamp$. to the end of your >> assets it will do what you want it do >> >> content/dam/nice-image.jpg.20160815. >> >> This is a nice idea for cdn's but you need to be aware of a potential issue. >> I know, from a dispatcher point of view that the ability to add selectors to >> any resource and return the original resource is a potential attack vector. >> An example would be if that url you gave was behind a dispatcher that does >> caching. I could sit there and call that asset with a millisecond time stamp >> and each time I did it, it would be cached, and the cache would get larger. >> Until some point I have consumed all of your disk space. >> >> I'm assuming a similar type issue with cdn's >> >> -Jason >> >> -----Original Message----- >> From: Roy Teeuwen [mailto:r...@teeuwen.be] >> Sent: Friday, July 29, 2016 8:14 AM >> To: users@sling.apache.org >> Subject: Re: Getting the actual resource from a request >> >> Hey all, >> >> Ok so I fixed it finally by doing the following: >> >> @SlingServlet( >> resourceTypes = "sling/servlet/default", >> selectors = "cdn" >> ) >> @Service({Servlet.class}) >> public class CDNAssetServlet extends SlingSafeMethodsServlet { >> >> private static final Logger LOG = >> LoggerFactory.getLogger(CDNAssetServlet.class); >> >> @Override >> protected void doGet(SlingHttpServletRequest request, >> SlingHttpServletResponse response) throws ServletException, IOException { >> Resource resource = request.getResource(); >> if (resource instanceof NonExistingResource) { >> LOG.info("Asset resource {} using the cdn selector does not >> exist", resource.getPath()); >> response.sendError(HttpServletResponse.SC_NOT_FOUND); >> } else { >> RequestDispatcherOptions opts = new RequestDispatcherOptions(); >> opts.setReplaceSelectors(""); >> RequestDispatcher dispatcher = >> request.getRequestDispatcher(resource, opts); >> if (dispatcher != null) { >> dispatcher.forward(request, response); >> } else { >> LOG.error("Could not get request dispatcher for asset resource >> {}", resource.getPath()); >> } >> } >> } >> } >> >> And then using the url provided by Jason :) thanks! >> @Olivier >> Still don’t know what you meant by just serving the resource instead of >> forwarding it, if you have an example you can still give it for when it >> would be more performant/better. >> Thanks all, >> Greets >> Roy >> >> >> >>> On 29 Jul 2016, at 00:01, Roy Teeuwen <r...@teeuwen.be> wrote: >>> >>> Also lastly to combine with my previous mail, it doesn’t have to be >>> only images. It could also be pdf’s, zips,… So the approach I am >>> using now won’t work in all the cases I want :) >>> >>> >>>> On 28 Jul 2016, at 23:44, Roy Teeuwen <r...@teeuwen.be> wrote: >>>> >>>> Hey Jason, Olivier, >>>> >>>> @Jason: >>>> Damn, I feel so stupid now :D indeed, using >>>> /content/dam/nice-image.jpg.cdn./modification-date/20160815/nice-image.jpg >>>> fixes everything. I don’t have to implement the nonexistingservlet anymore >>>> ;), I was indeed thinking that jpg was the extension and so that the cdn >>>> HAD to be before the jpg because else the cdn would be the extension, but >>>> your explanation makes sense! >>>> >>>> @Olivier: >>>> "What's the reason for forwarding instead of reading/serving the resource >>>> from the repository in your current servlet?” Currently I am doing it like >>>> that, but I find the implementation a bit nasty… See how I did it: >>>> >>>> @Override >>>> protected void doGet(SlingHttpServletRequest request, >>>> SlingHttpServletResponse response) throws ServletException, IOException { >>>> Resource resource = request.getResource(); >>>> final Image image = new Image(resource); >>>> image.set(Image.PN_REFERENCE, resource.getPath()); >>>> try { >>>> final String mimeType = image.getMimeType(); >>>> final Layer layer = image.getLayer(false, false, false); >>>> double quality = mimeType.equals(MIME_TYPE_GIF) ? 255 : 1.0; >>>> response.setContentType(mimeType); >>>> layer.write(mimeType, quality, response.getOutputStream()); >>>> response.getOutputStream().flush(); >>>> } catch (RepositoryException e) { >>>> LOG.error("could not get layer", e); >>>> } >>>> } >>>> >>>> Thats why I would think it would be easier / nicer to just forward it to >>>> the normal jpg handling servlet so that I don’t actually have to manually >>>> write it to the servlet response output. If there is a better way in >>>> serving the image resource from the repo, do tell :D. >>>> >>>> (For when you might be curious on why I am doing all of this, I am >>>> adding the latest modification date to all the image urls because >>>> the image urls actually get served by a cdn in front that proxies >>>> to the >>>> dam: >>>> https://some.azureedge.net/content/dam/nice-image.jpg.cdn./modifica >>>> ti on-date/20160815/nice-image.jpg , this way when the same image >>>> gets replaced in the dam by a new image with the same name on a >>>> page, I don’t have to invalidate the azure cdn cache because the >>>> modification date changing in the url takes care of that, and >>>> because I am not using a query string I also don’t have to care >>>> about nullifying the browser client-side caching) >>>> >>>> Thanks so far! >>>> Greets, >>>> Roy >>>> >>>> >>>>> On 28 Jul 2016, at 23:02, Jason Bailey <jason.bai...@sas.com> wrote: >>>>> >>>>> I was going to say that you shouldn't need to implement >>>>> NonExistingResource interface because a selector wouldn't impact >>>>> resolution then I had one of those blinding aha moments. >>>>> >>>>> In the case of the url you posted you aren't adding a selector, you are >>>>> modifying the resource name. '/content/dam/nice-image.jpg' does not have >>>>> an extension in the traditional sense, in the traditional sling sense the >>>>> resource would actually be '/content/dam/nice-image' and jpg would be a >>>>> handler that would return the asset as a jpeg. >>>>> >>>>> So when you are adding a selector to it it's not matching anything >>>>> because there is no '/content/dam/nice-image' resource to match against. >>>>> >>>>> So first make your request find the resource without the servlet in the >>>>> way. If you switch around the .cdn to the end and add a period at the end >>>>> of cdn like this... >>>>> >>>>> content/dam/nice-image.jpg.cdn./modification-date/20160815/nice-im >>>>> ag >>>>> e.jpg >>>>> >>>>> This should work to return the original nice-image.jpg at that point it >>>>> should be easier to create a servlet that will have the resource as part >>>>> of the request. >>>>> >>>>> Or optionally you could try adding a sling:resourceType to the image and >>>>> have a selector within that resource type that does what you need it do. >>>>> >>>>> -Jason >>>>> >>>>> >>>>> >>>>> -----Original Message----- >>>>> From: Roy Teeuwen [mailto:r...@teeuwen.be] >>>>> Sent: Thursday, July 28, 2016 3:17 PM >>>>> To: users@sling.apache.org >>>>> Subject: Re: Getting the actual resource from a request >>>>> >>>>> Hmm Sorry Jason, >>>>> >>>>> I might have had to notice that I am extending SlingSafeMethodServlet but >>>>> also implementing the following servlet: >>>>> https://docs.adobe.com/docs/en/cq/5-6-1/javadoc/com/day/cq/commons >>>>> /s ervlets/NonExistingResourceServlet.html >>>>> >>>>> And as it states in the docs itself, it also says: >>>>> public boolean accepts(SlingHttpServletRequest request) { >>>>> // get non-existing path (incl. selectors and extension!) >>>>> String path = request.getResource().getPath(); >>>>> // return true if this servlet can handle this path >>>>> return true; >>>>> } >>>>> >>>>> So probably it’s not possible to do it through this interface in without >>>>> manually parseing :) It also says in the docs: Please note: This is a >>>>> temporary solution until Sling provides a built-in mechanism for this use >>>>> case. Not to be used by client implementations! >>>>> >>>>> Any clue if it is possible yet to do it with standard sling, the thing I >>>>> try to achieve is a servlet that also catches resources with a selector >>>>> AND suffix (as stated in my example of course) ? >>>>> >>>>> Thanks! >>>>> Roy >>>>> >>>>> >>>>>> On 28 Jul 2016, at 18:35, Jason Bailey <jason.bai...@sas.com> wrote: >>>>>> >>>>>> I'm under the understanding that it is; >>>>>> >>>>>> request.getResource().getPath() >>>>>> >>>>>> -----Original Message----- >>>>>> From: Roy Teeuwen [mailto:r...@teeuwen.be] >>>>>> Sent: Thursday, July 28, 2016 12:31 PM >>>>>> To: users@sling.apache.org >>>>>> Subject: Getting the actual resource from a request >>>>>> >>>>>> Hey all, >>>>>> >>>>>> I am creating a SlingServlet that will work by both using a >>>>>> selector and a suffix. The resource is for example >>>>>> /content/dam/image.jpg and the actual url will be >>>>>> /content/dam/nice-image.cdn.jpg/modification-date/20160815/nice-image. >>>>>> jpg >>>>>> >>>>>> What is the most easy way to get the actual resource path again from the >>>>>> SlingHttpServletRequest? Currently I am doing the following but I find >>>>>> it a bit cumbersome: >>>>>> >>>>>> private String getResourcePath(SlingHttpServletRequest request) { >>>>>> String requestUrl = >>>>>> request.getRequestPathInfo().getResourcePath(); >>>>>> int endIndex = >>>>>> requestUrl.lastIndexOf(request.getRequestPathInfo().getSuffix()); >>>>>> String resourcePathWithSelector = requestUrl.substring(0, >>>>>> endIndex); endIndex = >>>>>> resourcePathWithSelector.lastIndexOf(request.getRequestPathInfo() >>>>>> .getSelectorString() + "." + >>>>>> request.getRequestPathInfo().getExtension()); >>>>>> return resourcePathWithSelector.substring(0, endIndex) + >>>>>> request.getRequestPathInfo().getExtension(); >>>>>> } >>>>>> >>>>>> Is there an easier way or is parsing it like this the only way? >>>>>> >>>>>> Also after I got the actual resourcePath, I tried doing the following, >>>>>> but this doesn’t seem to work, any clue on why? >>>>>> >>>>>> @Override >>>>>> protected void doGet(SlingHttpServletRequest request, >>>>>> SlingHttpServletResponse response) throws ServletException, IOException { >>>>>> RequestDispatcherOptions opts = new RequestDispatcherOptions(); >>>>>> opts.setReplaceSelectors(""); >>>>>> String resourcePath = getResourcePath(request); >>>>>> RequestDispatcher dispatcher = >>>>>> request.getRequestDispatcher(resourcePath, opts); >>>>>> if (dispatcher != null) { >>>>>> dispatcher.forward(request, response); >>>>>> } >>>>>> } >>>>>> >>>>>> I would expect that the previous would actually just forward it >>>>>> to the actual image being fetched from the getResourcePath but it >>>>>> just gives me a 404 not found (I checked the getResourcePath and >>>>>> it does return >>>>>> /content/dam/nice-image.jpg) >>>>>> >>>>>> Thanks! >>>>>> Roy >>>>> >>>> >>> >> >