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
>>>> 
>>> 
>> 
> 

Reply via email to