You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by Joerg Henne <jo...@cogito.de> on 2000/12/15 21:02:33 UTC

[C2] Handling Redirects

Hi all,

we have found using HTTP redirects from C2 to be a thorny issue. Using
HttpServletResponse.sendRedirect() the redirect can be initiated, just like,
for instance, the XSPResponseHelper does. However, sending a redirect is only
possible until some output has been generated and flushed down the HTTP
connection. 
Considering C2's pipelined architecture, I conclude that sending redirects is
only safe while, from the XSPGenerator's point of view, startDocument nas not
been called. Now here's the problem: there is no way to force code from a
logicsheet to be executed before contentHandler.startDocument() is called in
the generated XSP class. To fix this problem, I suggest modifications along
the lines of the patch you'll find below.
Another (minor) problem with redirects is the fact, that there is no (clean)
way for xsp code to stop the processing of the current document after a
redirect has been sent. This causes unnecessary resource use.

What the patch does:
- xsp-logicsheets may now include the new tag <xsp:init> within the context of
a logicsheet xsl:template-match. Code enclosed within these tags will be
placed at the very top of the xsp generator class's generate() method.

- it adds the exception type PageRedirectException which is a subclass of
ProcessingException. PageRedirectExceptions can carry redirect target
information.

- it allows the generated xsp generator's generate() method to throw
PageRedirectExceptions

- it adds the handling of PageRedirectExceptions to
ResourcePipeline.process(). A ProcessingException is thrown when a redirect is
tried from within an environement that is not an HttpEnvironement.

Joerg Henne

Re: [C2] Handling Redirects

Posted by Joerg Henne <jo...@cogito.de>.
Giacomo,

Giacomo Pati wrote,
> 
> IMO XSP pages should not use redirect. I think it's wrong by design. You
> should use a component that does not generate output at all (ie.
> Matcher, Selector, Action).

well, I agree that redirection is an out of band thing - something that does
not fit very well into XSP's concept. However, I think that it is a tool too
valuable for modeling applications to be ignored.

> We cannot introduce new XSP tags. The specification of the XSP language
> is not longer an authority of Cocoon because other projects implement
> XSP as well (ie. AxKit). New XSP elements must be discussed on the xsp
> mailing list.

I am aware of that. I really should have made it clearer in my earlier post
that my primary intention was to get a discussion going. Sorry for just
slamming a patch onto the list :-)

> What you'd like to introduce is exacly separating the code that you will
> put into the xsp:init section into an Action which signals the sitemap
> to do the rdirect or process further on.
> 
>   <map:match pattern="myuri/*>
>     <map:act type="should-we-redirect">
>       <map:redirect-to uri="http://somewhere/else/{to-go}"/>
>     </map:act>
>     <map:generate type="serverpage" src="pages/{1}"/>
>     ...
>   </map:match>

The actor concept is a really powerful one and I agree that handling redirects
by using actors is a much nicer design, but after some pondering I still think
that there are cases that cannot be solved without redirects from within the
XSP logic. 
Please consider, for instance, cases in which the descision for a redirect has
to be made based on which particular logic blocks have been incorporated into
a XSP page. Suppose we have a logicsheet which defines a set of functionality
which requires the user to be logged in and another one which can be used
without being logged in. To solve this problem using actors, I see three
possible options:
1. "marking" those XSP pages that require a login in some way, e.g. by putting
them below a certain directory
2. having the XML author provide the information about which pages require a
login to cocoon, e.g. by editing the sitemap
3. anticipating the XSP generation stage from within the actor and analysing
which logic blocks are used

All three solutions don't seem very satisfying or elegant to me. Naturally,
I'd be glad to hear about other solutions I haven't come up with.

> I don't see why the ResourcePipeline object should handle page redirects
> if the XSP page can't handle it. What is the benefit of that? Can you
> further explain that?

The assumption is: redirecting is a process that completely breaks the
pipeline concept of cocoon. So, if we can't do without it, then make it break
it drastically <g>. Furthermore, using exceptions for redirect handling is a
fairly common concept in servlet development, I think. For instance, Enhydra's
presentation objects do it that way. Based on this assumption, the
ResourcePipeline seemed to be the most natural place to handle the redirect.

Another reason for using an exception is the fact that after a redirect has
been sent, no other output should be created anymore. The
Response.sendRedirect() method will cause tomcat to come up with the
appropriate headers and a default HTML page explaining the redirect. Any other
output will potentially mess up this default page, confuse the browser and
scare somebody's cat. This can only be guaranteed, if we keep the
ServerPagesGenerator from cleaning up unclosed tags causing output to be
generated or if there is a way to intercept xsp production before the
startDocument() has been issued. I agree that the exception stuff is
redundant, if this interception is possible.

Joerg Henne

Re: [C2] Handling Redirects

Posted by Giacomo Pati <gi...@apache.org>.
Joerg Henne wrote:
> 
> Hi all,
> 
> we have found using HTTP redirects from C2 to be a thorny issue. Using
> HttpServletResponse.sendRedirect() the redirect can be initiated, just like,
> for instance, the XSPResponseHelper does. However, sending a redirect is only
> possible until some output has been generated and flushed down the HTTP
> connection.

IMO XSP pages should not use redirect. I think it's wrong by design. You
should use a component that does not generate output at all (ie.
Matcher, Selector, Action).

> Considering C2's pipelined architecture, I conclude that sending redirects is
> only safe while, from the XSPGenerator's point of view, startDocument nas not
> been called. Now here's the problem: there is no way to force code from a
> logicsheet to be executed before contentHandler.startDocument() is called in
> the generated XSP class. To fix this problem, I suggest modifications along
> the lines of the patch you'll find below.
> Another (minor) problem with redirects is the fact, that there is no (clean)
> way for xsp code to stop the processing of the current document after a
> redirect has been sent. This causes unnecessary resource use.

Simply use a return.

> What the patch does:
> - xsp-logicsheets may now include the new tag <xsp:init> within the context of
> a logicsheet xsl:template-match. Code enclosed within these tags will be
> placed at the very top of the xsp generator class's generate() method.

We cannot introduce new XSP tags. The specification of the XSP language
is not longer an authority of Cocoon because other projects implement
XSP as well (ie. AxKit). New XSP elements must be discussed on the xsp
mailing list.

What you'd like to introduce is exacly separating the code that you will
put into the xsp:init section into an Action which signals the sitemap
to do the rdirect or process further on.

  <map:match pattern="myuri/*>
    <map:act type="should-we-redirect">
      <map:redirect-to uri="http://somewhere/else/{to-go}"/>
    </map:act>
    <map:generate type="serverpage" src="pages/{1}"/>
    ...
  </map:match>

> - it adds the exception type PageRedirectException which is a subclass of
> ProcessingException. PageRedirectExceptions can carry redirect target
> information.
> 
> - it allows the generated xsp generator's generate() method to throw
> PageRedirectExceptions
> 
> - it adds the handling of PageRedirectExceptions to
> ResourcePipeline.process(). A ProcessingException is thrown when a redirect is
> tried from within an environement that is not an HttpEnvironement.

I don't see why the ResourcePipeline object should handle page redirects
if the XSP page can't handle it. What is the benefit of that? Can you
further explain that?

Giacomo