http://www.perlmonks.org?node_id=704425

skx has asked for the wisdom of the Perl Monks concerning the following question:

I've got an issue with redirection failing from my CGI::Application when running under mod_perl.

I'm very new to mod_perl so I could well believe that I've done something wrong. My configuration for Apache2 + mod_perl is very minimal:

ServerName ... Alias /cgi-bin/ /mf/cgi-bin/ <Location /cgi-bin> SetHandler perl-script PerlHandler ModPerl::Registry PerlSendHeader On Options +ExecCGI </Location>

This works for most of my application, and appears to improve response time significantly - however there is one problem. My redirections, as coded in the CGI::Application do not work.

I've pared this down to a minimal clone of my code - I have a base class implementing a redirect method, and I have a subclass which uses that to redirect a few times.

In plain CGI-mode this works. In mod_perl it gives me the following output direct to my browser:

redirect<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>200 OK</title>
</head><body>
<h1>OK</h1>
<p>The document has moved 
<a href="http://example.com/">here</a>.</p>
<hr>
<address>Apache/2.2.9 (Debian) PHP/5.2.6-2+b1 with
 Suhosin-Patch mod_ssl/2.2.9
 OpenSSL/0.9.8g mod_musicindex/1.2.2
 mod_perl/2.0.4 Perl/v5.10.0
 Server at mail-scanning.com Port 80</address>
</body></html>

Now here is my example code which exhibits the same problem:

#!/usr/bin/perl -w use strict; use warnings; use CGI::Application; # # Base package # package Base; use base 'CGI::Application'; sub redirectPage { my ( $self, $url ) = (@_); $self->header_add( -location => $url ); $self->header_type('redirect'); } # # Derived package # package Derived; use base 'Base'; sub setup { my( $self ) = ( @_ ); $self->run_modes( homepage => 'homepage' ); $self->start_mode('homepage'); $self->mode_param('mode'); } # # Dummy method to redirect to an external site. # sub homepage { my( $self ) = ( @_ ); return ( $self->redirectPage("http://example.com/") ); } # # Instance script # package main; my $derived = new Derived(); $derived->run();

Any clues, or tips are most welcome. Any more details I can provide just ask - this is all running upon libapache2-mod-perl2, as included in Debian.

Update: - Strangly using CGI::Application::Plugin::Redirect works correctly if I change my code:

package Base; use base 'CGI::Application'; use CGI::Application::Plugin::Redirect; sub redirectPage { my ( $self, $url ) = (@_); return( $self->redirect( $url ) ); }
Steve
--

Replies are listed 'Best First'.
Re: Failure to redirect when my CGI::Application powered site is used under mod_perl2
by Anonymous Monk on Aug 14, 2008 at 21:13 UTC
    In plain CGI-mode this works. In mod_perl it gives me the following output direct to my browser:

    Try

    lwp-request -m get -USsexd http://whatever/cgi/ lwp-request -m get -USsex http://whatever/cgi/

      I'm not familiar with those commands, but here is what they produce:

      (Please excuse the formatting.)

      lwp-request -m get -USsexd http://mail-scanning/cgi-bin/temp.cgi
      skx@gold:~$ lwp-request -m get -USsexd http://mail-scanning/cgi-bin/te +mp.cgi LWP::UserAgent::new: () LWP::UserAgent::request: () LWP::UserAgent::send_request: GET http://mail-scanning/cgi-bin/temp.cg +i LWP::UserAgent::_need_proxy: Not proxied LWP::Protocol::http::request: () LWP::Protocol::collect: read 8 bytes LWP::Protocol::collect: read 387 bytes LWP::UserAgent::request: Simple response: OK GET http://mail-scanning/cgi-bin/temp.cgi User-Agent: lwp-request/5.810 GET http://mail-scanning/cgi-bin/temp.cgi --> 200 OK Connection: close Date: Thu, 14 Aug 2008 21:15:16 GMT Location: http://example.com/ Server: Apache/2.2.9 (Debian) PHP/5.2.6-2+b1 with Suhosin-Patch mod_ss +l/2.2.9 OpenSSL/0.9.8g mod_musicindex/1.2.2 mod_perl/2.0.4 Perl/v5.10 +.0 Content-Type: text/plain Client-Date: Thu, 14 Aug 2008 21:15:16 GMT Client-Peer: 192.168.1.10:80 Client-Response-Num: 1 Client-Transfer-Encoding: chunked

      The second  lwp-request -m get -USsex http://mail-scanning/cgi-bin/temp.cgi

      LWP::UserAgent::new: () LWP::UserAgent::request: () LWP::UserAgent::send_request: GET http://mail-scanning/cgi-bin/temp.cg +i LWP::UserAgent::_need_proxy: Not proxied LWP::Protocol::http::request: () LWP::Protocol::collect: read 8 bytes LWP::Protocol::collect: read 387 bytes LWP::UserAgent::request: Simple response: OK GET http://mail-scanning/cgi-bin/temp.cgi User-Agent: lwp-request/5.810 GET http://mail-scanning/cgi-bin/temp.cgi --> 200 OK Connection: close Date: Thu, 14 Aug 2008 21:16:29 GMT Location: http://example.com/ Server: Apache/2.2.9 (Debian) PHP/5.2.6-2+b1 with Suhosin-Patch mod_ss +l/2.2.9 OpenSSL/0.9.8g mod_musicindex/1.2.2 mod_perl/2.0.4 Perl/v5.10 +.0 Content-Type: text/plain Client-Date: Thu, 14 Aug 2008 21:16:29 GMT Client-Peer: 192.168.1.10:80 Client-Response-Num: 1 Client-Transfer-Encoding: chunked redirect<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>200 OK</title> </head><body> <h1>OK</h1> <p>The document has moved <a href="http://example.com/">here</a>.</p> <hr> <address>Apache/2.2.9 (Debian) PHP/5.2.6-2+b1 with Suhosin-Patch mod_s +sl/2.2.9 OpenSSL/0.9.8g mod_musicindex/1.2.2 mod_perl/2.0.4 Perl/v5.1 +0.0 Server at mail-scanning Port 80</address> </body></html>
      Steve
      --

        To reply to myself it seems that I have two solutions:

        • Use CGI::Application::Plugin::Redirect
        • Update my code:
        sub redirectURL { my ( $self, $url ) = (@_); $self->header_type('redirect'); $self->header_add( -url => $url , -status => 301 ); return; }

        That redundent "return" seems to make things work properly in my demo and real application.

        I guess the return value of "header_add" is causing problems ..

        Steve
        --