File Coverage

blib/lib/ReverseProxy/FormFiller.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             package ReverseProxy::FormFiller;
2              
3 1     1   62211 use strict;
  1         4  
  1         51  
4 1     1   531 use Apache2::Filter;
  0            
  0            
5             use Apache2::Const -compile => qw(:common);
6             use Apache2::RequestUtil;
7             use Apache2::RequestRec;
8             use Apache2::Log;
9             use URI::Escape;
10              
11             our $VERSION = '0.3';
12              
13             my $globalParams;
14              
15             sub logError {
16             my ($r, $error) = @_;
17             $r->log->error("ReverseProxy::FormFiller is not configured, since $error");
18             }
19              
20             sub getParams {
21             my $r = shift;
22             my $paramFile = $r->dir_config('FormFillerParamFile');
23             unless (defined $paramFile) {
24             &logError($r, "there is no perl var FormFillerParamFile defined in Apache config");
25             return 0;
26             }
27             unless (defined $globalParams->{$paramFile}) {
28             if (open F, $paramFile) {
29             local $/ = undef;
30             my $paramContent = ;
31             close F;
32             my $params;
33             eval "\$params = {$paramContent}";
34             if ($@) {
35             &logError($r, "$paramFile content doesn't seem to be a valid perl hash");
36             $globalParams->{$paramFile} = 0;
37             } else {
38             $params->{form} ||= 'form:first';
39             $params->{submit} ||= 'false';
40             $params->{javascript} ||= '';
41             $params->{publicFormData} ||= {};
42             $params->{publicFilledData} ||= {};
43             $params->{secretFormData} ||= {};
44             $params->{postDataSub} ||= [];
45             %{ $params->{secretFormData} } = (
46             %{ $params->{publicFormData} },
47             %{ $params->{secretFormData} }
48             );
49             $globalParams->{$paramFile} = $params;
50             }
51             } else {
52             &logError($r, "Apache can't read $paramFile");
53             $globalParams->{$paramFile} = 0;
54             }
55             }
56             return $globalParams->{$paramFile};
57             }
58              
59             ## forge javascript to fill and submit form
60             sub js {
61             my $params = shift;
62             my ($form, $submit) = ($params->{form}, $params->{submit});
63             eval "\$form = $form";
64             eval "\$submit = $submit";
65             my $js = " var form = jQuery('$form')\n"
66             . " form.attr('autocomplete', 'off')\n";
67             while ( my ($name, $value) = each %{ $params->{publicFormData} } ) {
68             eval "\$value = $value";
69             $js .= " form.find('input[name=$name], select[name=$name], textarea[name=$name]').val('$value')\n";
70             }
71             while ( my ($name, $value) = each %{ $params->{publicFilledData} } ) {
72             eval "\$value = $value";
73             $js .= " form.find('$name').val('$value')\n";
74             }
75             if ($params->{javascript}) {
76             my $javascript = $params->{javascript};
77             $javascript =~ s/"/\\"/g;
78             eval "\$javascript = \"$javascript\"";
79             $js .= "$javascript\n";
80             }
81             $js .= $submit eq "true" ? " form.submit()\n"
82             : $submit ne "false" ? " form.find('$submit').click()\n"
83             : "";
84             $js = "\n";
88             $js = "\n$js"
89             if ($params->{jQueryUrl});
90             return $js;
91             }
92              
93             ## filter applied to response body
94             sub output {
95             my $f = shift;
96             my $buffer;
97             my $params = &getParams($f->r);
98              
99             # Filter only html reponse body
100             unless (
101             (!defined $f->r->content_type or $f->r->content_type =~ /html/i)
102             && $params
103             ) {
104             $f->print($buffer) while ($f->read($buffer));
105             return Apache2::Const::OK;
106             }
107              
108             my $body = $f->ctx || "";
109             $body .= $buffer while ($f->read($buffer));
110             unless ($f->seen_eos) {
111             $f->ctx($body);
112             } else {
113             $f->r->subprocess_env;
114             my $js = &js($params);
115             $body =~ s/(<\/head>)/$js$1/i or $body =~ s/()/$1$js/i;
116             $f->print($body);
117             }
118             return Apache2::Const::OK;
119             }
120              
121             ## filter applied to request body
122             sub input {
123             my $f = shift;
124             my $buffer;
125             my $params = &getParams($f->r);
126              
127             # Filter only POST request body
128             unless ($f->r->method eq "POST" && $params) {
129             $f->print($buffer) while ($f->read($buffer));
130             return Apache2::Const::OK;
131             }
132              
133             my $body = $f->ctx || "";
134             $body .= $buffer while ($f->read($buffer));
135             unless ($f->seen_eos) {
136             $f->ctx($body);
137             } else {
138             $f->r->subprocess_env;
139             while ( my ($name, $value) = each %{ $params->{secretFormData} } ) {
140             eval "\$value = $value";
141             $name = uri_escape $name;
142             $value = uri_escape $value;
143             $body =~ s/$name=.*?((?:&|$))/$name=$value$1/;
144             }
145             foreach my $sub ( @{ $params->{postDataSub} } ) {
146             eval "\$body =~ $sub";
147             }
148             $f->print($body);
149             }
150             return Apache2::Const::OK;
151             }
152              
153             1;
154              
155             __END__