package CGIX; use strict; use warnings; use URI::Escape; sub new { my($class,@initializer) = @_; my $self = {}; $self->{header} = []; parse_QUERY_STRING(\$self); parse_HTTP_COOKIE(\$self); bless $self; return $self; } sub header { my $self = shift(); return join("\r\n", @{$self->{header}}), "\r\n\r\n"; } sub add_header{ my ($self, $new) = @_; push( @{$self->{header}}, $new ); } sub set_cookie { my ($self, $p) = @_; my $cs = ""; if( defined $p->{-name} && defined $p->{-value} ){ $cs .= "Set-Cookie: ".$p->{-name}."=".uri_escape($p->{-value}); if( defined $p->{-expires} ){ $cs .= "; Expires=".expires( $p->{-expires}, "cookie" ); } if( defined $p->{-path} ){ $cs .= "; Path=".$p->{-path}; } push( @{$self->{header}}, $cs ); } } sub param { my ($self, $param, $default) = @_; if( defined $self->{get}->{$param} ){ return $self->{get}->{$param}; } return $default; } sub cookie { my ($self, $param, $default) = @_; if( defined $self->{cookie}->{$param} ){ return $self->{cookie}->{$param}; } return $default; } sub parse_QUERY_STRING { my $self = shift; my @values = split(/\&/,$ENV{QUERY_STRING}); foreach (@values) { my ($paramname, $data) = split(/=/, $_); $$self->{get}->{$paramname} = $data; } } sub parse_HTTP_COOKIE { my $self = shift; my @values = split(/\;/,$ENV{HTTP_COOKIE}); foreach (@values) { my ($paramname, $data) = split(/=/, $_); $$self->{cookie}->{$paramname} = uri_unescape($data); } } sub expires { my($time,$format) = @_; $format ||= 'http'; my(@MON)=qw/Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec/; my(@WDAY) = qw/Sun Mon Tue Wed Thu Fri Sat/; # pass through preformatted dates for the sake of expire_calc() $time = expire_calc($time); return $time unless $time =~ /^\d+$/; # make HTTP/cookie date string from GMT'ed time # (cookies use '-' as date separator, HTTP uses ' ') my($sc) = ' '; $sc = '-' if $format eq "cookie"; my($sec,$min,$hour,$mday,$mon,$year,$wday) = gmtime($time); $year += 1900; return sprintf("%s, %02d$sc%s$sc%04d %02d:%02d:%02d GMT", $WDAY[$wday],$mday,$MON[$mon],$year,$hour,$min,$sec); } # This internal routine creates an expires time exactly some number of # hours from the current time. It incorporates modifications from # Mark Fisher. sub expire_calc { my($time) = @_; my(%mult) = ('s'=>1, 'm'=>60, 'h'=>60*60, 'd'=>60*60*24, 'M'=>60*60*24*30, 'y'=>60*60*24*365); # format for time can be in any of the forms... # "now" -- expire immediately # "+180s" -- in 180 seconds # "+2m" -- in 2 minutes # "+12h" -- in 12 hours # "+1d" -- in 1 day # "+3M" -- in 3 months # "+2y" -- in 2 years # "-3m" -- 3 minutes ago(!) # If you don't supply one of these forms, we assume you are # specifying the date yourself my($offset); if (!$time || (lc($time) eq 'now')) { $offset = 0; } elsif ($time=~/^\d+/) { return $time; } elsif ($time=~/^([+-]?(?:\d+|\d*\.\d*))([smhdMy])/) { $offset = ($mult{$2} || 1)*$1; } else { return $time; } my $cur_time = time; return ($cur_time+$offset); } 1;