Best practices for returning 404/file-not-found pages inside and outside of mod_perl

View: New views
4 Messages — Rating Filter:   Alert me  

Best practices for returning 404/file-not-found pages inside and outside of mod_perl

by Mark Stosberg :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


In the past, the way I returned 404 page through CGI::App was something
like this:

  return $self->error(title => 'Page not found');

I learned that is too late to return a real 404 error running under CGI,
so the page comes back with a 200 status code, which isn't quite right.

More recently, I learned that with mod_perl, I learned that I can get
the system to return a true 404, so I updated the logic to do that when
possible:

  if (exists $ENV{MOD_PERL}) {
    $self->header_add( -status => 404 );
    return '';
  }
  else {
     return $self->error(title => 'Page not found')
  }

However, I don't think I'm doing the ideal think in mod_perl, because it
behaves strangely in some cases. Two specific cases:

If I use GET on the command line, instead of 404, I'll get back this:
"500 EOF when chunk header expected"

Unless I fallback to HTTP 1.0:

PERL_LWP_USE_HTTP_10=1 GET ...

But for some reason, setting this environment variable was not working
for with Test::WWW::Mechanize.

More troubling is the behavior I see in the browser: The first time I
access the script that would through this 404 in mod_perl, it works.
Then for attempts 2 through 6 return internal server errors complaining
about "can't locate modules". Starting on load 7, the pages are returned
   reliably with the 404 error. WTF?

The approach of CGI::Application::Dispatch is to also return the "404"
code, but also returns the body content along with it. In my case, I'm
hoping to trigger the internal ErrorDocument 404 page instead of
re-inventingt that wheel.

What am I missing?

Thanks!

    Mark






#####  CGI::Application community mailing list  ################
##                                                            ##
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp    ##
##                                                            ##
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:          http://cgiapp.erlbaum.net/                 ##
##                                                            ##
################################################################


Re: Best practices for returning 404/file-not-found pages inside and outside of mod_perl

by Rhesa Rozendaal-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Mark Stosberg wrote:

> In the past, the way I returned 404 page through CGI::App was something
> like this:
>
>   return $self->error(title => 'Page not found');
>
> I learned that is too late to return a real 404 error running under CGI,
> so the page comes back with a 200 status code, which isn't quite right.
>
> More recently, I learned that with mod_perl, I learned that I can get
> the system to return a true 404, so I updated the logic to do that when
> possible:
>
>   if (exists $ENV{MOD_PERL}) {
>     $self->header_add( -status => 404 );
>     return '';
>   }
>   else {
>      return $self->error(title => 'Page not found')
>   }


I recently ran into this myself, and discovered that setting the header_type
to 'redirect' fixed the issue:

    if (exists $ENV{MOD_PERL}) {
      $self->header_add( -status => 404 );
      return $self->redirect('/');
    }

Note I'm using the CAP::Redirect plugin, but the general principle holds. It
doesn't matter where you redirect to either, as it always trigggers the
ErrorDocument. Just don't return any content of your own.

At least, this works for me under Apache 2.2.2 / mod_perl 2.0.3

HTH,
Rhesa

#####  CGI::Application community mailing list  ################
##                                                            ##
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp    ##
##                                                            ##
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:          http://cgiapp.erlbaum.net/                 ##
##                                                            ##
################################################################


Re: Best practices for returning 404/file-not-found pages inside and outside of mod_perl

by Mark Stosberg :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> > In the past, the way I returned 404 page through CGI::App was something
> > like this:
> >
> >   return $self->error(title => 'Page not found');
> >
> > I learned that is too late to return a real 404 error running under CGI,
> > so the page comes back with a 200 status code, which isn't quite right.
> >
> > More recently, I learned that with mod_perl, I learned that I can get
> > the system to return a true 404, so I updated the logic to do that when
> > possible:
> >
> >   if (exists $ENV{MOD_PERL}) {
> >     $self->header_add( -status => 404 );
> >     return '';
> >   }
> >   else {
> >      return $self->error(title => 'Page not found')
> >   }
>
>
> I recently ran into this myself, and discovered that setting the header_type
> to 'redirect' fixed the issue:
>
>     if (exists $ENV{MOD_PERL}) {
>       $self->header_add( -status => 404 );
>       return $self->redirect('/');
>     }

Good to know! Had you run into the "500/eof/chunk" error as well, before you
added the redirect?

The approach I settled on was to patch LWP to quit throwing that error, as
"real" browsers seem to deal with it OK.

The other behavior I reported about "can't find modules" I think was a separate configuration issue in my case.

Thanks for the redirect tip, Rhesa!

    Mark
--
 . . . . . . . . . . . . . . . . . . . . . . . . . . .
   Mark Stosberg            Principal Developer  
   mark@...     Summersault, LLC    
   765-939-9301 ext 202     database driven websites
 . . . . . http://www.summersault.com/ . . . . . . . .



#####  CGI::Application community mailing list  ################
##                                                            ##
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp    ##
##                                                            ##
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:          http://cgiapp.erlbaum.net/                 ##
##                                                            ##
################################################################


Re: Best practices for returning 404/file-not-found pages inside and outside of mod_perl

by Mark Stosberg :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> > I learned that is too late to return a real 404 error running under CGI,
> > so the page comes back with a 200 status code, which isn't quite right.
> >
> > More recently, I learned that with mod_perl, I learned that I can get
> > the system to return a true 404, so I updated the logic to do that when
> > possible:
> >
> >   if (exists $ENV{MOD_PERL}) {
> >     $self->header_add( -status => 404 );
> >     return '';
> >   }
> >   else {
> >      return $self->error(title => 'Page not found')
> >   }
>
>
> I recently ran into this myself, and discovered that setting the header_type
> to 'redirect' fixed the issue:
>
>     if (exists $ENV{MOD_PERL}) {
>       $self->header_add( -status => 404 );
>       return $self->redirect('/');
>     }
>
> Note I'm using the CAP::Redirect plugin, but the general principle holds. It
> doesn't matter where you redirect to either, as it always trigggers the
> ErrorDocument. Just don't return any content of your own.
>
> At least, this works for me under Apache 2.2.2 / mod_perl 2.0.3

Rhesa,

With some testing, I found that this *doesn't* work for me with Apache 1.3.x and mod_perl. Instead,
I get a mismatch of a 404 and a generic "redirect" page sent as HTML but declared to be text/plain.
Example:

404 Not Found
Connection: close
Date: Wed, 07 May 2008 16:58:49 GMT
Location: /
Server: Apache/1.3.37 (Unix) mod_perl/1.29
Content-Type: text/plain
Client-Date: Wed, 07 May 2008 16:58:49 GMT
Client-Peer: 192.168.18.114:8202
Client-Response-Num: 1
Client-Transfer-Encoding: chunked

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<HTML><HEAD>
<TITLE>302 Found</TITLE>
</HEAD><BODY>
<H1>Found</H1>
The document has moved <A HREF="/">here</A>.<P>
[...snip...]

So I'm going to back to the hack I described recently, which seems to work for me.

    Mark



#####  CGI::Application community mailing list  ################
##                                                            ##
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp    ##
##                                                            ##
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:          http://cgiapp.erlbaum.net/                 ##
##                                                            ##
################################################################