]> mj.ucw.cz Git - libucw.git/blob - lib/perl/CGI.pm
Better explanation.
[libucw.git] / lib / perl / CGI.pm
1 #       Poor Man's CGI Module for Perl
2 #
3 #       (c) 2002 Martin Mares <mj@ucw.cz>
4 #       Slightly modified by Tomas Valla <tom@ucw.cz>
5 #
6 #       This software may be freely distributed and used according to the terms
7 #       of the GNU Lesser General Public License.
8
9 package Sherlock::CGI;
10
11 use strict;
12 use warnings;
13
14 BEGIN {
15         # The somewhat hairy Perl export mechanism
16         use Exporter();
17         our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
18         $VERSION = 1.0;
19         @ISA = qw(Exporter);
20         @EXPORT = qw(&html_escape &url_escape &self_ref &self_form);
21         @EXPORT_OK = qw();
22         %EXPORT_TAGS = ();
23 }
24
25 sub url_escape($) {
26         my $x = shift @_;
27         $x =~ s/([^-\$_.!*'(),0-9A-Za-z\x80-\xff])/"%".unpack('H2',$1)/ge;
28         return $x;
29 }
30
31 sub html_escape($) {
32         my $x = shift @_;
33         $x =~ s/&/&amp;/g;
34         $x =~ s/</&lt;/g;
35         $x =~ s/>/&gt;/g;
36         $x =~ s/"/&quot;/g;
37         return $x;
38 }
39
40 our $arg_table;
41
42 sub parse_arg_string($) {
43         my ($s) = @_;
44         $s =~ s/\s+//;
45         foreach $_ (split /[&:]/,$s) {
46                 (/^([^=]+)=(.*)$/) or next;
47                 my $arg = $arg_table->{$1} or next;
48                 $_ = $2;
49                 s/\+/ /g;
50                 s/%(..)/pack("c",hex $1)/eg;
51                 s/(\r|\n|\t)/ /g;
52                 s/^\s+//;
53                 s/\s+$//;
54                 if (my $rx = $arg->{'check'}) {
55                         if (!/^$rx$/) { $_ = $arg->{'default'}; }
56                 }
57                 
58                 my $r = ref($arg->{'var'});
59                 if ($r eq 'SCALAR') {
60                         ${$arg->{'var'}} = $_;
61                 } elsif ($r eq 'ARRAY') {
62                         push @{$arg->{'var'}}, $_;
63                 }
64         }
65 }
66
67 sub parse_args($) {
68         $arg_table = shift @_;
69         foreach my $a (values %$arg_table) {
70                 my $r = ref($a->{'var'});
71                 defined($a->{'default'}) or $a->{'default'}="";
72                 if ($r eq 'SCALAR') {
73                         ${$a->{'var'}} = $a->{'default'};
74                 } elsif ($r eq 'ARRAY') {
75                         @{$a->{'var'}} = ();
76                 }
77         }
78         defined $ENV{"GATEWAY_INTERFACE"} or die "Not called as a CGI script";
79         my $method = $ENV{"REQUEST_METHOD"};
80         if ($method eq "GET") {
81                 parse_arg_string($ENV{"QUERY_STRING"});
82         } elsif ($method eq "POST") {
83                 if ($ENV{"CONTENT_TYPE"} =~ /^application\/x-www-form-urlencoded\b/i) {
84                         while (<STDIN>) {
85                                 chomp;
86                                 parse_arg_string($_);
87                         }
88                 } else {
89                         return "Unknown content type for POST data";
90                 }
91         } else {
92                 return "Unknown request method";
93         }
94 }
95
96 sub make_out_args($) {
97         my ($overrides) = @_;
98         my $out = {};
99         foreach my $name (keys %$arg_table) {
100                 my $arg = $arg_table->{$name};
101                 defined $arg->{'pass'} && !$arg->{'pass'} && !exists $overrides->{$name} && next;
102                 my $value;
103                 if (!defined($value = $overrides->{$name})) {
104                         if (exists $overrides->{$name}) {
105                                 $value = $arg->{'default'};
106                         } else {
107                                 $value = ${$arg->{'var'}};
108                         }
109                 }
110                 if ($value ne $arg->{'default'}) {
111                         $out->{$name} = $value;
112                 }
113         }
114         return $out;
115 }
116
117 sub self_ref(@) {
118         my %h = @_;
119         my $out = make_out_args(\%h);
120         return "?" . join(':', map { "$_=" . url_escape($out->{$_}) } sort keys %$out);
121 }
122
123 sub self_form(@) {
124         my %h = @_;
125         my $out = make_out_args(\%h);
126         return join('', map { "<input type=hidden name=$_ value='" . html_escape($out->{$_}) . "'>\n" } sort keys %$out);
127 }
128
129 1;  # OK