File Coverage

blib/lib/Apache/RedirectDBI.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             #$Id: RedirectDBI.pm,v 0.02 2001/10/05 18:59:00 perler@xorgate.com Exp $
2             package Apache::RedirectDBI;
3             $VERSION='0.02';
4 1     1   771 use strict;
  1         2  
  1         39  
5 1     1   1543 use Apache::Constants qw(:common OK DECLINED REDIRECT SERVER_ERROR);
  0            
  0            
6             my ($debug)=0;
7             my %Config = ('RedirectDBI_data_source'=>'',
8             'RedirectDBI_username'=>'',
9             'RedirectDBI_password'=>'',
10             'RedirectDBI_default'=>'',
11             'RedirectDBI_table2uri'=>'',
12             'RedirectDBI_location'=>'',
13             'RedirectDBI_url'=>'',
14             'RedirectDBI_field'=>'',
15             'RedirectDBI_external'=>'',
16             );
17              
18             sub handler {
19             my $r = shift; # Incoming request
20             my($key, $val); # Configuration key/value
21            
22             my $config = {}; # Configuration hash
23             my @tables; # Map table names to URIs
24             #
25             # Pull out the current URI
26             #
27             my $uri=$r->uri;
28             # If the requested URI did not end in a trailing '/' and the URI is
29             # a directory then print a location redirect to the right URL. The
30             # user will then repeat the request with the right location, and we
31             # do this again.
32             #
33             # If you don't do this, the user will see the URL change when they
34             # get redirected to wherever based on the table they use. This exposes
35             # the underlying directory names, which is a bad thing.
36             #
37             if(($uri !~ /\/$/) && (-d $r->document_root . $uri)) {
38             $uri.='/';
39             $r->header_out(Location=>$uri);
40             return REDIRECT;
41             }
42             # Pull out the configuration information
43             while(($key, $val) = each %Config) {
44             $val = $r->dir_config($key) || $val;
45             $key =~ s/^RedirectDBI_//; # Pull RedirectDBI_ off the start
46             $config->{$key} = $val;
47             }
48             #
49             # Connect to the database
50             #
51             my $dbh;
52             unless ($dbh = DBI->connect($config->{data_source}, $config->{username}, $config->{password})) {
53             $r->log_reason(__PACKAGE__." db connect error with $config->{data_source} $uri");
54             return SERVER_ERROR;
55             }
56             #
57             # Get the table/uri map apart
58             @tables = split /\s/, $config->{table2uri};
59             #
60             # Iterate over every other entry in @tables. Each entry will be the
61             # name of a table to check. For each table, count the number of users
62             # in the table who match the currently connected user. If there's
63             # at least one (there shouldn't be more than one, but you never know)
64             # then change the location of the current request, and fall out of the
65             # loop.
66             #
67             my $query;
68             my $mode=1;
69             $mode+=1 unless $config->{field};
70             for(my $i=0; $i<=$#tables; $i+=$mode) {
71             my $table = $tables[$i]; # Current table name
72             # SQL for search
73             $config->{field}||='name';
74             my $sql = "select ";
75             if($config->{url}) {
76             $sql.="$config->{url} ";
77             } else {
78             $sql.="$config->{field} ";
79             }
80             $sql.="from ".$table." where $config->{field}=" . $dbh->quote($r->connection->user);
81             print STDERR __PACKAGE__." sql=$sql\n" if $debug;
82             #
83             # Run search, get results
84             #
85             unless($query=$dbh->prepare($sql)) {
86             $r->log_reason(__PACKAGE__." ERROR: prepare: $DBI::errstr $uri");
87             $dbh->disconnect;
88             return SERVER_ERROR;
89             }
90             unless($query->execute) {
91             $r->log_reason(__PACKAGE__." ERROR: execute: $DBI::errstr $uri");
92             $dbh->disconnect;
93             return SERVER_ERROR;
94             }
95             my $matched_user = $query->fetchrow_array();
96             if($matched_user) { # User matched?
97             if($config->{url}) {
98             $uri=$matched_user;
99             } else {
100             my $touri = $tables[$i + 1];i # Get the location to send them to
101             $uri =~ s/^$config->{'location'}/$touri/; # and store this change
102             }
103             print STDERR __PACKAGE__." uri=$uri\n" if $debug;
104             last;
105             }
106             }
107             #
108             # If the URI wasn't changed then send the user to the default location
109             #
110             if ($uri eq $r->uri) {
111             $uri =~ s/^$config->{'location'}/$config->{'default'}/;
112             print STDERR __PACKAGE__." default_uri=$uri\n" if $debug;
113             }
114             #
115             # Redirect Apache to the right location, and continue.
116             #
117             my $retval;
118             if($config->{external}) {
119             print STDERR __PACKAGE__." external_REDIRECT\n" if $debug;
120             $r->header_out(Location=>$uri);
121             $retval=REDIRECT;
122             } else {
123             print STDERR __PACKAGE__." internal_redirect\n" if $debug;
124             $r->internal_redirect_handler($uri);
125             $retval=OK;
126             }
127             $query->finish;
128             $dbh->disconnect;
129             $retval;
130             }
131             1;
132              
133             __END__