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