File Coverage

blib/lib/Apache/Request/Redirect.pm
Criterion Covered Total %
statement 33 135 24.4
branch 0 36 0.0
condition 0 6 0.0
subroutine 11 22 50.0
pod 5 7 71.4
total 49 206 23.7


line stmt bran cond sub pod time code
1             package Apache::Request::Redirect;
2              
3 1     1   12939 use 5.006;
  1         4  
  1         76  
4 1     1   6 use strict;
  1         3  
  1         35  
5 1     1   5 use warnings;
  1         7  
  1         40  
6 1     1   6 use Carp;
  1         2  
  1         85  
7 1     1   6 use Exporter;
  1         2  
  1         46  
8              
9 1     1   5 use vars qw(@ISA @EXPORT $LOG_REQUEST $LOG_QUERYSTRING $LOG_RESPONSE);
  1         1  
  1         124  
10              
11             @ISA = qw(Exporter);
12             @EXPORT = qw($LOG_REQUEST $LOG_QUERYSTRING $LOG_RESPONSE);
13              
14 1     1   1638 use HTTP::Response;
  1         84330  
  1         40  
15 1     1   1084 use HTTP::Request;
  1         977  
  1         33  
16 1     1   7 use HTTP::Headers;
  1         2  
  1         31  
17 1     1   1314 use LWP::UserAgent;
  1         32656  
  1         44  
18 1     1   14 use URI;
  1         2  
  1         1713  
19              
20             $Apache::Request::Redirect::VERSION = '0.05';
21              
22             $Apache::Request::Redirect::LOG = 0;
23              
24             $LOG_REQUEST = 0b0001;
25             $LOG_QUERYSTRING = 0b0010;
26             $LOG_RESPONSE = 0b0100;
27              
28              
29             my $MOD_PERL = 0;
30             # Turn on special checking for Doug MacEachern's modperl
31             if (exists $ENV{MOD_PERL}) {
32             eval "require mod_perl";
33             # mod_perl handlers may run system() on scripts using CGI.pm;
34             # Make sure so we don't get fooled by inherited $ENV{MOD_PERL}
35             if (defined $mod_perl::VERSION) {
36             if ($mod_perl::VERSION >= 1.99) {
37             $MOD_PERL = 2;
38             require Apache::RequestRec;
39             require Apache::RequestUtil;
40             require APR::Pool;
41             } else {
42             $MOD_PERL = 1;
43             require Apache;
44             }
45             }
46             }
47              
48              
49             my %fields = (
50             apachereq => '',
51             host => 'localhost',
52             url => '/',
53             args => {},
54             use_http10 => 0,
55             );
56              
57             sub new {
58 0     0 0   my ($proto,%options) = @_;
59 0   0       my $class = ref($proto) || $proto;
60 0           my $self = { };
61 0           while (my ($key,$value) = each(%options)) {
62 0 0         if (exists($fields{$key})) {
63 0           $self->{$key} = $value;
64             } else {
65 0           die $class . "::new: invalid option '$key'\n";
66             }
67             }
68             #foreach (keys %fields) {
69             # die $class . "::new: omitted required option '$_'\n"
70             # if (!defined $self->{$_});
71             #}
72            
73 0           bless $self, $class;
74            
75             # attivo apachereq direttamente da Apache
76 0 0         if ($MOD_PERL) {
77 0 0         $self->apachereq(Apache->request) unless $self->apachereq;
78 0           my $apachereq = $self->apachereq;
79 0 0         if ($MOD_PERL == 1) {
80             #$apacheref->register_cleanup(\&CGI::_reset_globals);
81             } else {
82             # XXX: once we have the new API
83             # will do a real PerlOptions -SetupEnv check
84             #$apacheref->subprocess_env unless exists $ENV{REQUEST_METHOD};
85             #$apacheref->pool->cleanup_register(\&CGI::_reset_globals);
86             }
87             }
88              
89 0 0         if ($Apache::Request::Redirect::LOG != 0) {
90 0           eval {
91 0           require "Log/FileSimple.pm";
92             };
93 0 0         if ($@) {
94 0           warn "Warning: Logging disabled...cannot find Log::FileSimple module";
95 0           $Apache::Request::Redirect::LOG = 0;
96             } else {
97 0           $self->{log} = new Log::FileSimple(
98             name=> "Apache::Request::Redirect",
99             file=> '/tmp/Apache-Request-Redirect.log',
100             mask=> $Apache::Request::Redirect::LOG,
101             );
102             }
103             }
104 0           return $self;
105             }
106              
107             sub redirect() {
108             # passare un riferimento ad hash con
109             # i parametri della query in quanto la query string (GET)
110             # o il content (POST) deve essere ricostruito
111             # (Mason si mangia il content)
112 0     0 1   my $self = shift;
113 0           my $request = $self->_prepare_request();
114 0           $self->_log(message => "Request:\n" . $request->as_string , id => $LOG_REQUEST);
115 0           my $response = $self->_send_request($request);
116 0           my $response_text = $response->as_string;
117 0           $self->_log(id => $LOG_RESPONSE, message => "Response:\n" .
118             $response_text);
119 0           return $response;
120             }
121              
122             sub _prepare_request() {
123 0     0     my $self = shift;
124 0           my $request_args = $self->{args};
125              
126             # Costruisco l'header della richiesta da quello originale
127 0           my $headers = new HTTP::Headers(%{$self->{apachereq}->headers_in});
  0            
128             # modifico l'host per impostarlo a quello che andro' realmente a
129             # chiamare
130 0           $headers->header('Host',$self->{host});
131             # dato che questo modulo e' fatto per post processare
132             # l'html ottenuto...non posso permettere che mi ritorni
133             # html compresso
134 0           $headers->remove_header('Accept-Encoding');
135             #$self->_log(id => $LOG_REQUEST, message => 'HTTP::Headers',objects=>[$headers]);
136             # costruisco l'url ed il content
137 0           my $uri = URI->new();
138 0           $uri->scheme('http');
139 0           $uri->host($self->{host});
140 0           $uri->path($self->{url});
141 0           $uri->query_form(%$request_args);
142 0           my $content;
143 0 0         if ($self->{apachereq}->method eq 'POST') {
144             # costruisco il content
145 0           $content = $self->_built_content();
146             # nel post la query string totale la metto nel
147             # content e non nell'url
148 0           $content .= $uri->query;
149             # nell'url ci lasciamo la sola query_string originale (00.04)
150 0           $uri->query(scalar($self->{apachereq}->args));
151             # imposto la lunghezza del content nell'header
152 0           $headers->header('Content-Length' => length($content));
153             } else {
154             # nel get il content non c'e' (sara' vero ? :-)
155 0           $headers->remove_header('Content-Length');
156             }
157             # costruisco la nuova richiesta per il recupero dell'url
158 0           my $request = new HTTP::Request($self->{apachereq}->method,
159             $uri,
160             $headers,
161             $content
162             );
163 0           return $request;
164             }
165              
166             sub _send_request() {
167 0     0     my $self = shift;
168 0           my $request = shift;
169              
170 0 0         if ($self->{use_http10}) {
171 0           require LWP::Protocol::http10;
172 0           LWP::Protocol::implementor('http', 'LWP::Protocol::http10');
173             }
174 0           my $ua = new LWP::UserAgent;
175 0           my $response = $ua->send_request($request);
176 0           return $response;
177             }
178              
179             sub _log() {
180 0     0     my $self = shift;
181 0 0         $self->{log} && $self->{log}->log(@_);
182             }
183              
184             sub _built_content() {
185 0     0     my $self = shift;
186 0           my $request_args = $self->{args};
187              
188 0           my $request = $self->{apachereq};
189 0           my $content;
190             my $boundary;
191 0 0         if ($request->header_in("Content-type") =~
192             qr|^multipart/form-data; boundary=(.+?)$|i) {
193 0           $boundary = "--$1";
194 0           for my $upload ($self->{apachereq}->upload) {
195 0           $self->_log(message => 'Upload object',
196             objects=>[$upload], id => $LOG_REQUEST);
197 0           $content .= "$boundary\r\n";
198 0           my $info = $upload->info;
199 0           while (my($key, $val) = each %$info) {
200 0 0         if ($key ne 'Content-Type') {
201 0           $content .= "$key: $val; ";
202             }
203             # rimuovo l'ultimo ;
204 0           chop($content);
205             }
206 0           $content .= "\r\nContent-Type: " .
207             $upload->info("Content-Type") . "\r\n\r\n";
208 0           my $fh = $upload->fh;
209 0           while (<$fh>) {
210 0           $content .= $_;
211             }
212             # lo rimuovo da args
213 0           delete $request_args->{$upload->name};
214             }
215             # aggiungo gli args
216 0           while (my ($key,$val) = each(%$request_args)) {
217 0           $content .= qq|\r\n$boundary\r\nContent-Disposition: | .
218             qq|form-data; name="$key"\r\n\r\n$val|;
219             }
220 0           $content .= "\r\n$boundary--\r\n";
221             }
222            
223 0           return $content;
224             }
225              
226             # read-write property
227              
228             sub apachereq {
229 0     0 1   my $s = shift;
230 0 0         if (@_) {
231 0 0 0       die "apachereq must be a reference to Apache or Apache::Request object"
232             if (ref($_[0]) ne "Apache" && ref($_[0]) ne "Apache::Request");
233 0           $s->{apachereq} = shift;
234             }
235 0           return $s->{apachereq};
236             }
237              
238 0 0   0 1   sub host { my $s = shift; if (@_) { $s->{host} = shift; } return $s->{host}; }
  0            
  0            
  0            
239 0 0   0 1   sub url { my $s = shift; if (@_) { $s->{url} = shift; } return $s->{url}; }
  0            
  0            
  0            
240 0 0   0 0   sub use_http10 { my $s = shift; if (@_) { $s->{use_http10} = shift; } return $s->{use_http10}; }
  0            
  0            
  0            
241              
242             sub args {
243 0     0 1   my $s = shift;
244 0 0         if (@_) {
245 0 0         die "args must be a reference to a hash insteed of " . ref($_[0])
246             if (ref($_[0]) ne "HASH");
247 0           $s->{args} = shift;
248             }
249 0           return $s->{args};
250             }
251              
252             1;
253             __END__