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