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

I have a working webapp based on CGI::Application which at the start of each request redirects the user to a login page if an appropriate cookie is not found.

This is achieved in cgiapp_init (simplified somewhat):

sub cgiapp_init { my $self = shift; my $user = $self->get_user_from_cookie(); unless ( defined $user ) { print $self->query->redirect('/login.pl'); exit; } $self->{user} = $user; return 1; }
I would much rather have some better way of exiting than just calling exit. It would be nice to have some form of variable/flag that could be set to stop the execution of the remaining functions but would let things like the teardown run.

How have others dealt with this?

--tidiness is the memory loss of environmental mnemonics

Replies are listed 'Best First'.
Re: Strategies for exiting early for CGI::Application based webapp.
by LTjake (Prior) on Oct 22, 2003 at 20:01 UTC

    The CGI::Application Wiki has an article called "Order of Operations" which also details a way to cleanly exit early.

    The beef of it is:

    sub mymode { ... $self->teardown(); print $self->_send_headers(); exit; }

    HTH

    --
    "To err is human, but to really foul things up you need a computer." --Paul Ehrlich

Re: Strategies for exiting early for CGI::Application based webapp.
by cees (Curate) on Oct 22, 2003 at 18:04 UTC

    If the 'login' page is also part of your CGI::Application module, then you can use the 'prerun_mode' method to change the current runmode to another. That is how I handle authentication is some of my apps.

    unless ( defined $user ) { $self->prerun_mode('login'); return; }

    If your login script is not part of the CGI::App, then you can do the redirect using CGI::Apps method for redirection, and then change the runmode to a null runmode.

    # If the user is not logged in, redirect to the login page unless ( defined $user ) { $self->prerun_mode('null_mode'); $self->header_props({-location => '/login.pl'}); $self->header_type('redirect'); return; } # A runmode that doesn't do anything sub null_mode { }

    One of the most important things to remember about CGI::Application is that you never ever use the print command to send output to the browser. If you ever catch yourself using print, then step back and figure out why you really need to use it. Chances are there is a better way to do it.

Re: Strategies for exiting early for CGI::Application based webapp.
by talexb (Chancellor) on Oct 22, 2003 at 14:40 UTC

    You could use a goto and make your way down to the bottom of the routine. I've done that in the past.

    --t. alex
    Life is short: get busy!
      All of CGI::Appliations juicy bits happen inside the routine run. Where would you have the goto point to - bearing in mind I don't want to modify CGI::Application?

      --tidiness is the memory loss of environmental mnemonics

      The code that I'm imagining would be something like

      { if cookie not found { redirect to login page; goto CLEAN_UP; } ... CLEAN_UP: do_some_clean_up(); }
      So this could be a sub-routine or a code reference.

      Does that answer your question?

      --t. alex
      Life is short: get busy!
Re: Strategies for exiting early for CGI::Application based webapp.
by Anonymous Monk on Oct 22, 2003 at 14:50 UTC
    Can you not just write a safe_exit() routine to call instead of exit?
      I suppose that I could but my intention is to not muck around too much with the internals of CGI::Application. Are you suggesting something like:
      sub safe_exit { my $self = shift; $self->teardown(); # Include other functions that should be run here. exit; }

      --tidiness is the memory loss of environmental mnemonics

        It is just another run mode, it issues only a redirect; teardown method will be called by CGI::Application itself. Also remember that you need to save any parameter that was passed along with the original request.

        Ciao, Valerio