You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Michael Greenish <gr...@yahoo.com> on 2006/03/21 20:56:51 UTC

external redirect after internal redirect not working

Hello,

I am attempting an external redirect after an internal
redirect and it isn't working. 

Below are code excerpts:

use strict;
use DBI;
use Apache2::RequestRec();
use APR::Table();
use CGI;
$CGI::POST_MAX=1024 * 1024;  # max 1M posts
$CGI::DISABLE_UPLOADS = 0;  # change to 1 to disable
uploads
use CGI::Cookie();
use Apache2::Const  qw( OK FORBIDDEN REDIRECT :log );
use Apache2::Log;

# Get request object
$r = shift;

# Check if coming in from internal redirect
if( defined $r->prev ) {
    $r = $r->prev;
}

# Do some stuff...

# redirect
$r->headers_out->set( Location => $redirectURL );
$r->status( REDIRECT );
return REDIRECT;

The external redirect works as long as I am not coming
from an internal redirect.  Any ideas?

thanks,

greanie

__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 

Re: external redirect after internal redirect not working

Posted by Geoffrey Young <ge...@modperlcookbook.org>.

Tom Schindl wrote:
> Hi Geoff,
> 
> Geoffrey Young wrote:
> 
>>Tom Schindl wrote:
>>
>>
>>>This means the when the documentation holds information about situation
>>>where one has to use $r->status(), I would propose that in should add
>>>the use case of filters.
>>>
>>>This has nothing TODO with your problem I only wanted to point out that
>>>not all cases where setting $r->status manually are documented there.
>>
>>
>>you really should never alter $r->status, as apache uses it for internal
>>bookeeping...
>>
> 
> 
> Although that's not on this special topic your do you also think that
> setting $r->status() in an output filter is a wrong or is this desired
> behaviour?

well, I'm not sure that filters differ from any other handler in this
regard, since it all happens before httpd sends the response to the client
and before it can enter the error document cycle, which is where this stuff
matters.

it actually doesn't matter a whole lot, but the last time I checked it fell
out like this - if you set $r->status manually and the request fails your
error document cycle could get mucked up, resulting in default "a blah error
was also encountered" if you use the default error pages.

not that it's all that big a deal, but prevailing wisdom through the ages
(here and on the httpd lists) has been "don't do that."  people question it
from time to time and IIRC someone even started to code httpd so that you
_could_ do it with impunity.  but I'm not sure if that made it in or not.

anyway, I'm probably making a bigger deal of this than it really is :)

> 
> See my question a few days ago. Is this a bug?

it's a feature :) until someone reworks our filter mechansim to make it
right.  my pointer was only to the comments in modperl_filter.c, comments I
logged maybe 2 years ago when I tried to do the exact same thing :)

--Geoff

Re: external redirect after internal redirect not working

Posted by Tom Schindl <to...@gmx.at>.
Hi Geoff,

Geoffrey Young wrote:
> 
> Tom Schindl wrote:
> 
>>This means the when the documentation holds information about situation
>>where one has to use $r->status(), I would propose that in should add
>>the use case of filters.
>>
>>This has nothing TODO with your problem I only wanted to point out that
>>not all cases where setting $r->status manually are documented there.
> 
> 
> you really should never alter $r->status, as apache uses it for internal
> bookeeping...
> 

Although that's not on this special topic your do you also think that
setting $r->status() in an output filter is a wrong or is this desired
behaviour?

See my question a few days ago. Is this a bug?

Tom

Re: external redirect after internal redirect not working

Posted by Geoffrey Young <ge...@modperlcookbook.org>.

Tom Schindl wrote:
> This means the when the documentation holds information about situation
> where one has to use $r->status(), I would propose that in should add
> the use case of filters.
> 
> This has nothing TODO with your problem I only wanted to point out that
> not all cases where setting $r->status manually are documented there.

you really should never alter $r->status, as apache uses it for internal
bookeeping...

except for registry scripts :)  for registry scripts $r->status is a hack
way of telling registry to 'return REDIRECT' since registry itself can't
trust the value of the cgi script's return code (since it's an emulation
layer).  beneath the hood, however, registry discards the $r->status setting
and sets it back to whatever it was before registry ran:

    # handlers shouldn't set $r->status but return it, so we reset the
    # status after running it
    my $old_status = $self->{REQ}->status;
    my $rc = $self->run;
    my $new_status = $self->{REQ}->status($old_status);
    return ($rc == Apache2::Const::OK && $old_status != $new_status)
        ? $new_status
        : $rc;

Re: external redirect after internal redirect not working

Posted by Tom Schindl <to...@gmx.at>.
> 
> It's been a while since I set up the server but I
> think I did it because setting up the apache config
> file was easier.  And the redirect works under normal

What's the big deal, in my idea Registry is only helpful if you want to
speed up your CGI-Scripts not for new development and many times
registry creates problems because of accidentally created closures.

<Location /rocks>
    SetHandler perl-script
    PerlResponseHandler  MyApache2::Rocks
</Location>


> circumstances, but not when coming from an internal
> redirect.  What is the difference?  Is there another
> way to perform the redirect in registry mode?
> 
> 
> 

Where form do you retrieve your $r?

[....]

>>
> http://perl.apache.org/docs/2.0/user/coding/cooking.html#Sending_Cookies_in_REDIRECT_Response__ModPerl__Registry_
> 

Take a look at the paragraph below this link and you'll see a redirect
issued from a normal handler. It looks like there's a difference between
registry and normal handlers.

Re: external redirect after internal redirect not working

Posted by Jonathan Vanasco <jo...@2xlp.com>.
On Mar 22, 2006, at 2:49 PM, Michael Greenish wrote:
> It's been a while since I set up the server but I
> think I did it because setting up the apache config
> file was easier.  And the redirect works under normal
> circumstances, but not when coming from an internal
> redirect.  What is the difference?  Is there another
> way to perform the redirect in registry mode?

I'd guess one of two things (but i'm usually wrong about this stuff.)
	a_ there might be some sort of redirect limiter config option.  i  
know a few MTAs have something like that when redirecting an email  
address to avoid endless loops.
	b_ maybe it has something to do with the footnote at that registry  
recipe:

			http://perl.apache.org/docs/2.0/user/coding/ 
cooking.html#Sending_Cookies_in_REDIRECT_Response__ModPerl__Registry_
			note that this example differs from the Registry example only in  
that it does not attempt to fiddle with $r->status() -  
ModPerl::Registry uses $r->status() as a hack, but handlers should  
never manipulate the status field in the request record.

		that sounds to me like it has to do with the nature of the redirect  
as an internal subrequest and not an external one.   i'm only  
speculating, but i think the subrequest is a nested request like this:
				possible implemetation
				 	request 		{
								subrequest
								{
									redirect
								}
							}
				and that anything not fatal is essentially ok
				
				that would be dissimilar to it being a 'startover' with a new url  
like this:

				possible implemetation
					 request 		{
									redirect
								}
					subrequest
								{
									redirect
								}

in either case, if someone who works on the internals could clarify  
that, i've been wondering this for a while.

the naming of the api and placement of methods, to me, is really  
awkward - subrequest suggests that its an entirely new request nested  
in $r (which, judging by the rest of the class methods, it seems to  
be )  but having internal_redirect in there suggests that its a  
redirect and startover for the parent request.   in sure there is a  
very good reason why redirect is in subrequest and not request -  
could someone point me to a url where i can read up?

in any event, i'd look into $r->is_initial_req
	http://perl.apache.org/docs/2.0/api/Apache2/ 
RequestUtil.html#C_is_initial_req_

and try something like  that recipe to subrequests only.


Re: external redirect after internal redirect not working

Posted by Michael Greenish <gr...@yahoo.com>.

> Why are you running this as a registry script? You
> are referencing so
> many things only available in mod_perl that you
> could simply wrap
> your whole code inside "sub handler {  }" and you
> don't have to set
> $r->status() manually which may be the problem.
> 
> Tom
> 

It's been a while since I set up the server but I
think I did it because setting up the apache config
file was easier.  And the redirect works under normal
circumstances, but not when coming from an internal
redirect.  What is the difference?  Is there another
way to perform the redirect in registry mode?


> Michael Greenish wrote:
> > I am working in modperl::registry (not writing my
> own
> > handlers) and I found this recipe on the modperl
> > website:
> > 
> >
>
http://perl.apache.org/docs/2.0/user/coding/cooking.html#Sending_Cookies_in_REDIRECT_Response__ModPerl__Registry_
> > 
> > And, sorry Tom, but I don't understand your
> response. 
> > 
> > 
> > thanks,
> > 
> > greanie
> > 
> > --- Tom Schindl <to...@gmx.at> wrote:
> > 
> > 
> >>Fred Moyer wrote:
> >>
> >>>Michael Greenish wrote:
> >>>
> >>>>use strict;
> >>>
> >>>[..]
> >>>
> >>>
> >>>># redirect
> >>>>$r->headers_out->set( Location => $redirectURL
> );
> >>>>$r->status( REDIRECT );
> >>>
> >>>>return REDIRECT;
> >>>
> >>>I see a few things here that catch my eye but
> what
> >>
> >>stands out the most
> >>
> >>>is the use of the same return code for the
> browser
> >>
> >>and apache.  why are
> >>
> >>>you using $r->status?  Is it one of the reasons
> >>
> >>listed here?
> >>
> >>This doesn't help but:
> >>
> >>To the list you definately have to add Filters
> where
> >>one mp2 or Apache i
> >>don't know doesn't care about the resturn value of
> >>the filter-handler.
> >>
> >>Tom
> >>
> >>
> >>
> >
>
http://perl.apache.org/docs/2.0/api/Apache2/RequestRec.html#C_status_
> > 
> >>>
> >>Tom
> >>
> > 
> > 
> > 
> > __________________________________________________
> > Do You Yahoo!?
> > Tired of spam?  Yahoo! Mail has the best spam
> protection around 
> > http://mail.yahoo.com 
> > 
> > 
> 
> 


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 

Re: external redirect after internal redirect not working

Posted by Tom Schindl <to...@gmx.at>.
This means the when the documentation holds information about situation
where one has to use $r->status(), I would propose that in should add
the use case of filters.

This has nothing TODO with your problem I only wanted to point out that
not all cases where setting $r->status manually are documented there.

Why are you running this as a registry script? You are referencing so
many things only available in mod_perl that you could simply wrap
your whole code inside "sub handler {  }" and you don't have to set
$r->status() manually which may be the problem.

Tom

Michael Greenish wrote:
> I am working in modperl::registry (not writing my own
> handlers) and I found this recipe on the modperl
> website:
> 
> http://perl.apache.org/docs/2.0/user/coding/cooking.html#Sending_Cookies_in_REDIRECT_Response__ModPerl__Registry_
> 
> And, sorry Tom, but I don't understand your response. 
> 
> 
> thanks,
> 
> greanie
> 
> --- Tom Schindl <to...@gmx.at> wrote:
> 
> 
>>Fred Moyer wrote:
>>
>>>Michael Greenish wrote:
>>>
>>>>use strict;
>>>
>>>[..]
>>>
>>>
>>>># redirect
>>>>$r->headers_out->set( Location => $redirectURL );
>>>>$r->status( REDIRECT );
>>>
>>>>return REDIRECT;
>>>
>>>I see a few things here that catch my eye but what
>>
>>stands out the most
>>
>>>is the use of the same return code for the browser
>>
>>and apache.  why are
>>
>>>you using $r->status?  Is it one of the reasons
>>
>>listed here?
>>
>>This doesn't help but:
>>
>>To the list you definately have to add Filters where
>>one mp2 or Apache i
>>don't know doesn't care about the resturn value of
>>the filter-handler.
>>
>>Tom
>>
>>
>>
> http://perl.apache.org/docs/2.0/api/Apache2/RequestRec.html#C_status_
> 
>>>
>>Tom
>>
> 
> 
> 
> __________________________________________________
> Do You Yahoo!?
> Tired of spam?  Yahoo! Mail has the best spam protection around 
> http://mail.yahoo.com 
> 
> 


Re: external redirect after internal redirect not working

Posted by Michael Greenish <gr...@yahoo.com>.
I am working in modperl::registry (not writing my own
handlers) and I found this recipe on the modperl
website:

http://perl.apache.org/docs/2.0/user/coding/cooking.html#Sending_Cookies_in_REDIRECT_Response__ModPerl__Registry_

And, sorry Tom, but I don't understand your response. 


thanks,

greanie

--- Tom Schindl <to...@gmx.at> wrote:

> Fred Moyer wrote:
> > Michael Greenish wrote:
> >> use strict;
> > [..]
> > 
> >> # redirect
> >> $r->headers_out->set( Location => $redirectURL );
> >> $r->status( REDIRECT );
> > 
> >> return REDIRECT;
> > 
> > I see a few things here that catch my eye but what
> stands out the most
> > is the use of the same return code for the browser
> and apache.  why are
> > you using $r->status?  Is it one of the reasons
> listed here?
> > 
> 
> This doesn't help but:
> 
> To the list you definately have to add Filters where
> one mp2 or Apache i
> don't know doesn't care about the resturn value of
> the filter-handler.
> 
> Tom
> 
> 
> >
>
http://perl.apache.org/docs/2.0/api/Apache2/RequestRec.html#C_status_
> > 
> > 
> 
> Tom
> 


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 

Re: external redirect after internal redirect not working

Posted by Tom Schindl <to...@gmx.at>.
Fred Moyer wrote:
> Michael Greenish wrote:
>> use strict;
> [..]
> 
>> # redirect
>> $r->headers_out->set( Location => $redirectURL );
>> $r->status( REDIRECT );
> 
>> return REDIRECT;
> 
> I see a few things here that catch my eye but what stands out the most
> is the use of the same return code for the browser and apache.  why are
> you using $r->status?  Is it one of the reasons listed here?
> 

This doesn't help but:

To the list you definately have to add Filters where one mp2 or Apache i
don't know doesn't care about the resturn value of the filter-handler.

Tom


> http://perl.apache.org/docs/2.0/api/Apache2/RequestRec.html#C_status_
> 
> 

Tom

Re: external redirect after internal redirect not working

Posted by Fred Moyer <fr...@redhotpenguin.com>.
Michael Greenish wrote:
 > use strict;
[..]
> # redirect
> $r->headers_out->set( Location => $redirectURL );
> $r->status( REDIRECT );
 > return REDIRECT;

I see a few things here that catch my eye but what stands out the most 
is the use of the same return code for the browser and apache.  why are 
you using $r->status?  Is it one of the reasons listed here?

http://perl.apache.org/docs/2.0/api/Apache2/RequestRec.html#C_status_