On 11 Jan 2010, at 20:59, Felix Meschberger wrote:

> Hi,
> 
> On 11.01.2010 21:36, Ian Boston wrote:
>> 
>> On 11 Jan 2010, at 19:43, Felix Meschberger wrote:
>> 
>>> 
>>> 
>>> On 08.01.2010 16:31, Ian Boston wrote:
>>>> We have been trying to implement a Batch method processor (ie a servlet 
>>>> that performs multiple requests batching the responses up into a single 
>>>> request/response) in Sling.
>>>> 
>>>> Normally with servlets this would require 
>>>> requestDispacher.forward(wrappedRequest, wrappedResponse) but this doent 
>>>> work since Sling unwrapps all request back to a internal 
>>>> SlingHttpServletRequestImpl object so although you can get hold of the 
>>>> requestDispatcher, and call the forward method, its almost pointless.
>>> 
>>> I fear, I do not completely understand the problem.
>>> 
>>> You can provide any SlingHttpServletRequest|Response to the forward
>>> method and this instance will be presented to the included servlet.
>>> 
>>> If not the provided instances are given to the included servlet, I would
>>> consider this a major issue....
>>> 
>>>> 
>>>> Whats the right way of doing this sort of thing in Sling ?
>>> 
>>> I would say that it should be possible to forward multiple times
>>> collecting the output -- you would just have to make sure, no output and
>>> headers are really written back by the servlets/scripts forwarded to.
>>> Thus the wrappedResponse would have to make sure not to set responses
>>> headers (by default in Sling included servlets *can* set response
>>> headers unlike in the Servlet API, where this is not possible).
>> 
>> Wrapping the response works perfectly,
>> 
>> Wrapping the request does not.
>> 
>> The SlingRequestDispatcher uses the RequestData.unwrap(...) to unwrap any 
>> request back to the first SlingHttpServletRequestImpl (private to the engine 
>> bundle) effectively negating any attempt to wrap the request object.
> 
> I am not sure, whether we are referring to the same code ...
> 
> The SlingRequestDispatcher.dispatch method does:
> 
>   SlingHttpServletRequest cRequest = RequestData.unwrap(request);
> 
> which returns a SlingHttpServletRequest from the request, which is a
> ServletRequest.
> 
> Now the RequestData.unwrap(ServletRequest method) does :
> 
>        // this should be triggered and immediately return if the
>        // request is a SlingHttpServletRequestWrapper or
>        // a SlingHttpServletRequestImpl object
>        if (request instanceof SlingHttpServletRequest) {
>            return (SlingHttpServletRequest) request;
>        }
> 
>        // unwrap wrappers
>        while (request instanceof ServletRequestWrapper) {
>            request = ((ServletRequestWrapper) request).getRequest();
> 
>            // immediate termination if we found one
>            if (request instanceof SlingHttpServletRequest) {
>                return (SlingHttpServletRequest) request;
>            }
>        }
> 
> according to my reading, this should returns topmost
> SlingHttpServletRequest object, in general is the request object itself.
> 
> If there is a misconception on my part, I would be happy to be standing
> corrected !
> 
> The intent is to *not* unwrap down to the innermost
> SlingHttpServletRequestImpl and use that.


I might have got the start of the call stack wrong but
its the other unwrap method that causes the problem. 
I stepped through it in a debugger a few days ago and I think the important 
call stack started when the request was converted into RequestData from which 
the request parameters are taken.

I think 
SlingMainServlet.processRequest() 
RequestData.service( ) line 493 
RequestData.getRequestData() line 400
RequestData.unwrap() line 314

That goes back to the impl,
The servlet is than taken from that request data, so any attempt to re-dispatch 
to a new path will bind to the old RequestData.


to exactly what happens when a 

request.getRequestDispatcher(path).forward(wrappedRequest, wrappedResponse) 

is invoked I will need to re-run a debug session, probably best to hold on.
Ian






> 
> Regards
> Felix
> 
>> 
>> Perhaps there should be a marker interface to identify when its safe to use 
>> a request object and when it needs to be unwrapped further.
>> 
>> Ian
>> 
>> 
>>> 
>>> Regards
>>> Felix
>>> 
>>>> 
>>>> Ian
>>>> 
>>>> BTW, we have also tried Filters registered against the SlingMainSevlet 
>>>> (via OSGI), adding another top level servlet directly to the httpservice 
>>>> and adding filters at the http service level before the SlingMainServlet. 
>>>> None appear to work for all sorts of reason, sadly perfectly valid and to 
>>>> spec.
>> 
>> 

Reply via email to