X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=lib%2Fperl%2FCGI.pm;h=bb2b14b09a1e5373e5fdb9b64540fd2c4b61fccf;hb=5dea0be536bd0e658f231efd5631b331a8764e5a;hp=286bca52f7a4fa0c5636de9be6891b3b68e8fcd2;hpb=b0e111a2b5c5ebcb15e71359e4c5775d0d6a1fcc;p=libucw.git diff --git a/lib/perl/CGI.pm b/lib/perl/CGI.pm index 286bca52..bb2b14b0 100644 --- a/lib/perl/CGI.pm +++ b/lib/perl/CGI.pm @@ -1,11 +1,12 @@ # Poor Man's CGI Module for Perl # -# (c) 2002 Martin Mares +# (c) 2002--2007 Martin Mares +# Slightly modified by Tomas Valla # # This software may be freely distributed and used according to the terms # of the GNU Lesser General Public License. -package Sherlock::CGI; +package UCW::CGI; use strict; use warnings; @@ -23,8 +24,7 @@ BEGIN { sub url_escape($) { my $x = shift @_; - $x =~ s/([^-\$_.+!*'(),0-9A-Za-z\x80-\xff ])/"%".unpack('H2',$1)/ge; - $x =~ s/ /+/g; + $x =~ s/([^-\$_.!*'(),0-9A-Za-z\x80-\xff])/"%".unpack('H2',$1)/ge; return $x; } @@ -37,12 +37,47 @@ sub html_escape($) { return $x; } +### Analysing RFC 822 Style Headers ### + +sub rfc822_prepare($) { + my $x = shift @_; + # Convert all %'s and backslash escapes to %xx escapes + $x =~ s/%/%25/g; + $x =~ s/\\(.)/"%".unpack("H2",$1)/ge; + # Remove all comments, beware, they can be nested (unterminated comments are closed at EOL automatically) + while ($x =~ s/^(("[^"]*"|[^"(])*(\([^)]*)*)(\([^()]*(\)|$))/$1 /) { } + # Remove quotes and escape dangerous characters inside (again closing at the end automatically) + $x =~ s{"([^"]*)("|$)}{my $z=$1; $z =~ s/([^0-9a-zA-Z%_-])/"%".unpack("H2",$1)/ge; $z;}ge; + # All control characters are properly escaped, tokens are clearly visible. + # Finally remove all unnecessary spaces. + $x =~ s/\s+/ /g; + $x =~ s/(^ | $)//g; + $x =~ s{\s*([()<>@,;:\\"/\[\]?=])\s*}{$1}g; + return $x; +} + +sub rfc822_deescape($) { + my $x = shift @_; + $x =~ s/%(..)/pack("H2",$1)/ge; + return $x; +} + +### Reading of HTTP headers ### + +sub http_get($) { + my $h = shift @_; + $h =~ tr/a-z-/A-Z_/; + return $ENV{"HTTP_$h"} || $ENV{"$h"}; +} + +### Parsing of Arguments ### + our $arg_table; sub parse_arg_string($) { my ($s) = @_; $s =~ s/\s+//; - foreach $_ (split /&/,$s) { + foreach $_ (split /[&:]/,$s) { (/^([^=]+)=(.*)$/) or next; my $arg = $arg_table->{$1} or next; $_ = $2; @@ -54,15 +89,26 @@ sub parse_arg_string($) { if (my $rx = $arg->{'check'}) { if (!/^$rx$/) { $_ = $arg->{'default'}; } } - ${$arg->{'var'}} = $_; + + my $r = ref($arg->{'var'}); + if ($r eq 'SCALAR') { + ${$arg->{'var'}} = $_; + } elsif ($r eq 'ARRAY') { + push @{$arg->{'var'}}, $_; + } } } sub parse_args($) { $arg_table = shift @_; foreach my $a (values %$arg_table) { + my $r = ref($a->{'var'}); defined($a->{'default'}) or $a->{'default'}=""; - ${$a->{'var'}} = $a->{'default'}; + if ($r eq 'SCALAR') { + ${$a->{'var'}} = $a->{'default'}; + } elsif ($r eq 'ARRAY') { + @{$a->{'var'}} = (); + } } defined $ENV{"GATEWAY_INTERFACE"} or die "Not called as a CGI script"; my $method = $ENV{"REQUEST_METHOD"}; @@ -82,12 +128,15 @@ sub parse_args($) { } } +### Generating Self-ref URL's ### + sub make_out_args($) { my ($overrides) = @_; my $out = {}; foreach my $name (keys %$arg_table) { my $arg = $arg_table->{$name}; - defined $arg->{'pass'} && !$arg->{'pass'} && !exists $overrides->{$name} && next; + defined($arg->{'var'}) || next; + defined($arg->{'pass'}) && !$arg->{'pass'} && !exists $overrides->{$name} && next; my $value; if (!defined($value = $overrides->{$name})) { if (exists $overrides->{$name}) { @@ -106,7 +155,7 @@ sub make_out_args($) { sub self_ref(@) { my %h = @_; my $out = make_out_args(\%h); - return "?" . join('&', map { "$_=" . url_escape($out->{$_}) } sort keys %$out); + return "?" . join(':', map { "$_=" . url_escape($out->{$_}) } sort keys %$out); } sub self_form(@) { @@ -115,4 +164,42 @@ sub self_form(@) { return join('', map { "\n" } sort keys %$out); } +### Cookies + +sub cookie_esc($) { + my $x = shift @_; + if ($x !~ /^[a-zA-Z0-9%]+$/) { + $x =~ s/([\\\"])/\\$1/g; + $x = "\"$x\""; + } + return $x; +} + +sub set_cookie($$@) { + my $key = shift @_; + my $value = shift @_; + my %other = @_; + $other{'version'} = 1 unless defined $other{'version'}; + print "Set-Cookie: $key=", cookie_esc($value); + foreach my $k (keys %other) { + print ";$k=", cookie_esc($other{$k}); + } + print "\n"; +} + +sub parse_cookies() { + my $h = http_get("Cookie") or return (); + my @cook = (); + while (my ($padding,$name,$val,$xx,$rest) = ($h =~ /\s*([,;]\s*)*([^ =]+)=([^ =,;\"]*|\"([^\"\\]|\\.)*\")(\s.*|;.*|$)/)) { + if ($val =~ /^\"/) { + $val =~ s/^\"//; + $val =~ s/\"$//; + $val =~ s/\\(.)/$1/g; + } + push @cook, $name, $val; + $h = $rest; + } + return @cook; +} + 1; # OK