]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/perlmods/lib/OpenILS/WWW/Redirect.pm
LP#1673857: teach catalog how to search and display copy tags
[working/Evergreen.git] / Open-ILS / src / perlmods / lib / OpenILS / WWW / Redirect.pm
1 package OpenILS::WWW::Redirect;
2 use strict; use warnings;
3
4 use Socket;
5 use Apache2::Log;
6 use Apache2::Const -compile => qw(OK REDIRECT :log);
7 use APR::Const    -compile => qw(:error SUCCESS);
8 use Apache2::RequestRec ();
9 use Apache2::RequestIO ();
10 use CGI ();
11
12 use OpenSRF::AppSession;
13 use OpenSRF::System;
14 use OpenSRF::Utils::Logger qw/$logger/;
15 use Net::IP;
16
17 use vars '$lib_ips_hash';
18 my $lib_ips_hash;
19
20 my $bootstrap_config_file;
21 sub import {
22     my( $self, $config ) = @_;
23     $bootstrap_config_file = $config;
24 }
25
26 sub init {
27     OpenSRF::System->bootstrap_client( config_file => $bootstrap_config_file );
28 }
29
30 sub parse_ips_file {
31     my $class = shift;
32     my $ips_file = shift;
33
34     if( open(F, $ips_file) ) {
35
36        while( my $data = <F> ) {
37          chomp($data);
38
39          my ($shortname, $ip1, $ip2, $skin, $domain) = split(/\s+/, $data);
40          next unless ($shortname and $ip1 and $ip2);
41
42          $lib_ips_hash->{$shortname} = [] unless $lib_ips_hash->{$shortname};
43          push( @{$lib_ips_hash->{$shortname}}, [ $ip1, $ip2, $skin, $domain ] );
44        }
45
46        close(F);
47
48     } else {
49         $logger->error("Unable to open lib IP redirector file $ips_file");
50     }
51 }
52
53
54 my %org_cache;
55 sub handler {
56     my $apache = shift;
57
58     my $cgi = CGI->new( $apache );
59     my $hostname = $cgi->server_name();
60     my $proto = ($cgi->https) ? 'https' : 'http';
61     my $user_ip = $ENV{REMOTE_ADDR};
62
63     # Extract the port number from the user requested URL.
64     my $port = '';
65     my $cgiurl = $cgi->url;
66     if ($cgiurl =~ m|https?://[^:]+:\d+/|) {
67         ($port = $cgiurl) =~ s|https?://[^:]+:(\d+).*|$1|;
68     }
69
70     # Apache config values
71     my $skin = $apache->dir_config('OILSRedirectSkin') || 'default';
72     my $depth = $apache->dir_config('OILSRedirectDepth');
73     my $locale = $apache->dir_config('OILSRedirectLocale') || 'en-US';
74     my $use_tt = ($apache->dir_config('OILSRedirectTpac') || '') =~ /true/i;
75     my $physical_loc;
76
77     $apache->log->debug("Redirector sees client frim $user_ip");
78
79     # parse the IP file
80     my ($shortname, $nskin, $nhostname) = redirect_libs($user_ip);
81
82     if ($shortname) { # we have a config
83
84         # Read any override vars from the ips txt file
85         if ($nskin =~ m/[^\s]/) { $skin = $nskin; }
86         if ($nhostname =~ m/[^\s]/) { $hostname = $nhostname; }
87
88         if($org_cache{$shortname}) {
89             $physical_loc = $org_cache{$shortname};
90
91         } else {
92
93             my $session = OpenSRF::AppSession->create("open-ils.actor");
94             my $org = $session->request(
95                 'open-ils.actor.org_unit.retrieve_by_shortname',
96                 $shortname)->gather(1);
97
98             $org_cache{$shortname} = $physical_loc = $org->id if $org;
99         }
100     }
101
102     # only encode the port if a nonstandard port was requested.
103     my $url = $port ? "$proto://$hostname:$port" : "$proto://$hostname";
104
105     if($use_tt) {
106
107         $url .= "/eg/opac/home";
108         $url .= "?physical_loc=$physical_loc" if $physical_loc;
109
110 =head1 potential locale/skin implementation
111
112         if($locale ne 'en-US') {
113             $apache->headers_out->add(
114                 "Set-Cookie" => $cgi->cookie(
115                     -name => "oils:locale", # see EGWeb.pm
116                     -path => "/eg",
117                     -value => $locale,
118                     -expires => undef
119                 )
120             );
121         }
122
123         if($skin ne 'default') {
124             $apache->headers_out->add(
125                 "Set-Cookie" => $cgi->cookie(
126                     -name => "oils:skin", # see EGWeb.pm
127                     -path => "/eg",
128                     -value => $skin,
129                     -expires => undef
130                 )
131             );
132         }
133 =cut
134
135     } else {
136         $url .= "/opac/$locale/skin/$skin/xml/index.xml";
137         if($physical_loc) {
138             $url .= "?ol=" . $physical_loc;
139             $url .= "&d=$depth" if defined $depth;
140         }
141     }
142
143     $logger->info("Apache redirecting $user_ip to $url");
144     $apache->headers_out->add('Location' => "$url");
145     return Apache2::Const::REDIRECT;
146 }
147
148 sub redirect_libs {
149     my $source_ip = new Net::IP (shift) or return 0;
150
151     # do this the linear way for now...
152     for my $shortname (keys %$lib_ips_hash) {
153
154         for my $block (@{$lib_ips_hash->{$shortname}}) {
155
156             $logger->debug("Checking whether " . $source_ip->ip() . " is in the range " . $block->[0] . " to " . $block->[1]);
157             if(defined($block->[0]) && defined($block->[1]) ) {
158                 my $range = new Net::IP( $block->[0] . ' - ' . $block->[1] );
159                 if( $source_ip->overlaps($range)==$IP_A_IN_B_OVERLAP ||
160                     $source_ip->overlaps($range)==$IP_IDENTICAL ) {
161                     return ($shortname, $block->[2] || '', $block->[3] || '');
162                 }
163             }
164         }
165     }
166     return 0;
167 }
168
169 1;