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

I am whacked on this bad Mason issue. My apache passes .html files through mason.

My dhandler catches unknown requests. So /this-isnt-a-page.html ends up in the dhandler. The dhandler redirects to page-not-found-error.html

The redirect sends the bad page name as a parameter.

if (! ($r->uri =~ / special patterns go here /)) { $m->redirect('/page-not-found-error.html?p=' .uri_escape($r->u +ri)); }
For a bad directory, /this-directory-does-not-exist Apache itself redirects:
ErrorDocument 404 /page-not-found-error.html
And page-not-found-error.html ends in .html so it is also handled by mason, and it works in both cases (mason dhandler redirect or apache 404 redirect):
% my $page = uri_unescape($p) || $ENV{REDIRECT_URL}; You were looking for <% $page %> and the server can't find it.

All this works.

In page-not-found-error.html there is a hash that remaps old paths to new paths -- that is, doing aliasing via Mason rather than in apache.conf:

if ($new) { # from http://www.masonhq.com/?FAQ:HTTPAndHTML $m->clear_buffer; $r->method('GET'); $r->headers_in->unset('Content-length'); $r->content_type('text/html'); $r->header_out('Location' => $new); $m->abort(301); }
This works.

I can set up a hash entry saying /login/advanced/game.html redirects to /login/agame.html and it works.

What doesn't work is when there's no file name: /this-directory-does-not-exist

While I can determine where to send it correctly, /the-right-place/index.html Apache throws an error like this

Not Found The requested URL /login/advanced was not found on this server. Additionally, a 301 Moved Permanently error was encountered while tryi +ng to use an ErrorDocument to handle the request.
Complicated question, but why won't apache take a request for /login/advanced which then remaps to /login/advanced/index.html and is dispatchd using
$m->clear_buffer; $r->method('GET'); $r->headers_in->unset('Content-length'); $r->content_type('text/html'); $r->header_out('Location' => $new); $m->abort(301);
and do it? Why is apache bitching about
The requested URL /login/advanced was not found on this server. Additionally, a 301 Moved Permanently error was encountered while tryi +ng to use an ErrorDocument to handle the request.
Help!

Replies are listed 'Best First'.
Re: mason, dhandlers, page not found, and redirects
by Fletch (Bishop) on Sep 18, 2005 at 13:18 UTC

    I don't recall exactly off hand (not to mention I haven't touched HTML::Mason in a while), but I'm fairly sure the ORA Mason book discuses this in the coverage of dhandlers. Basically the problem is that since the directory doesn't exist in the filesystem Apache never triggers anything in your Mason code; the work around is to use a <Location /foo> direct anything under that part of your URI space to Mason.

Re: mason, dhandlers, page not found, and redirects
by EvanCarroll (Chaplain) on Sep 18, 2005 at 16:27 UTC
    I'm not sure I understand your question, but as to why this doesn't work, If I understand the question, the answer would be because of the nature of apache. If the directory structure isn't in place for the file requested then the request will never make it to the dhandler. In your httpd conf you have a FileMatch directive, you mght want to add a location match to force apache to dish out to the dhandlers those requests unconditionally

    You have:
    <LocationMatch "\.html$">

    So you make a request to /nonexistantdir/foo.html; Apache shouts, no /nonexistantdir/ and dishes you a 404, this is faster than yeilding control to mason.

    However, replace with:
    <Location /nonexistantdir>
    And suddently mason gets everything indiscriminately, if it is in that dir.


    Evan Carroll
    www.EvanCarroll.com
Re: mason, dhandlers, page not found, and redirects
by Anonymous Monk on Sep 19, 2005 at 00:05 UTC
    Let me clarify my bad post some.

    Can't easily use the apache location approach to give Mason dibs on a while directory, as lotza different file types in there don't want Mason to mangle.

    Yes, apache generates the 404. And apache flips to a custom page-not-found page. But -- here's the whack part -- the custom 404 page is a .html file in the mason tree, so it gets masonified. And it does indeed get masonified: the custom not-found file is indeed working under mason -- header, nav, etc.

    Can do all the mason things on this page, run code, etc -- except cannot seem to redirect away from this custom page, using either the mason redirect method or the 'flush' 'header_out' 'abort' approach.

    my question again then: if the not-found page will 'do' mason, why won't apache accept a redirect away from it??

    befuddled...

      Any reason you can't just turn off decline_dirs? I think that'll let you do what you want in a much cleaner way.