Hey Jason,

That would solve the selector problem, but it wouldn't really solve the suffix 
problem though. But that one can be fixed in the same way although I would 
expect the whitelisting to be a bit tougher in that one ;), seeing as suffix is 
used as a dynamic variable most of the times. For my specific needs I did solve 
it now by actually looking at the request and seeing if the modification date 
equals the actual asset modification date. Thanks for all the help!

Resource resource = request.getResource();
if(resource instanceof NonExistingResource) {
    LOG.info("Asset resource {} using the cdn selector does not exist", 
resource.getPath());
    response.sendError(404);
} else if(!"last-modified".equals(getSuffixSegment(request, 0))) {
    LOG.info("Asset resource {} is not using the last modified suffix", 
resource.getPath());
    response.sendError(404);
} else if(resource.adaptTo(Asset.class) == null) {
    LOG.info("Resource {} is not an asset", resource.getPath());
    response.sendError(404);
} else 
if(!String.valueOf(((Asset)resource.adaptTo(Asset.class)).getLastModified()).equals(getSuffixSegment(request,
 1))) {
    LOG.info("Asset resource {} does not have the same last modified date as 
request: {}", resource.getPath(), getSuffixSegment(request, 1));
    response.sendError(404);
} 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());
    }
}

Greets
Roy

> On 1 Aug 2016, at 16:26, Jason Bailey <jason.bai...@sas.com> wrote:
> 
> 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
>>>>>> 
>>>>> 
>>>> 
>>> 
>> 
> 

Reply via email to