Fixing Mis-cased URIs Under Apache

Synopsis

This is rather old code, but saved my bacon more than once.Runs under Apache with Mod_Perl, and corrects the URI requested when it is giving lazily. Thus a request for “/INDEX.HTML” is rewritten to “/index.html” as appropriate.

Code

=head1 NAME

M::Apache::fixcase - Want to fix case, showing the user the error of their ways?

=head1 SYNOPSIS

PerlModule M::Apache::fixcase

<VirtualHost>

PerlTransHandler M::Apache::fixcase

</VirtualHost>

=cut

package M::Apache::fixcase;

use Apache2::Const qw(DECLINED);
use Apache2::RequestUtil ();

sub handler {
        my $r = shift;
        my $file=$r->document_root() . $r->uri();
        unless(-e $file) {
                # File doesn't exist, let's try to find it!
                my @uribits=split(/\//,$r->uri());
                shift @uribits; # shift off the beginning ''
                my $newuri=$r->document_root(); # $newuri is the uri we're building
                my $sofar=0;
                foreach my $bit (@uribits) {
                        $bit =~ s/\(|\)|\`//g; # stupid url tricks
                        $sofar=0; # reset sofar, so we know if we're still on track
                        opendir(FD,$newuri) or last;
                        foreach my $dthing (readdir(FD)) {
                                if($dthing =~ /^\./) { next; } # safety first;
                                if($dthing =~ /^$bit$/i) { # case-insenstive pattern match
                                        # We have a match!
                                        $sofar=1;
                                        $newuri .= "/" . $dthing;
                                        last;
                                }
                        }
                        closedir(FD);
                        unless($sofar) { last; } # we missed this bit, don't bother recursing further
                }
                if($sofar) {
                        # We made it!
                        my $dr=$r->document_root();
                        $newuri =~ s/^$dr//; # strip off the document_root from the new uri
                        $r->uri($newuri); # Set the uri to the new uri
                } # else we can't do anything...
        }
        return DECLINED; # Always pass it on
}

1;
This entry was posted in Coding, Linuxy and tagged , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *