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 <[email protected]> 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:[email protected]] > Sent: Friday, July 29, 2016 8:14 AM > To: [email protected] > 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 <[email protected]> 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 <[email protected]> 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./modificati >>> 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 <[email protected]> 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-imag >>>> 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:[email protected]] >>>> Sent: Thursday, July 28, 2016 3:17 PM >>>> To: [email protected] >>>> 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 <[email protected]> wrote: >>>>> >>>>> I'm under the understanding that it is; >>>>> >>>>> request.getResource().getPath() >>>>> >>>>> -----Original Message----- >>>>> From: Roy Teeuwen [mailto:[email protected]] >>>>> Sent: Thursday, July 28, 2016 12:31 PM >>>>> To: [email protected] >>>>> 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 >>>> >>> >> >
