DTA-CAB

 view release on metacpan or  search on metacpan

CAB/Server/HTTP/Handler/CGI.pm  view on Meta::CPAN


##--------------------------------------------------------------
## Methods

## $h = $class_or_obj->new(%options)
## + %options:
##     #encoding => $defaultEncoding,  ##-- default encoding (UTF-8)
##     allowGet => $bool,             ##-- allow GET requests? (default=1)
##     allowPost => $bool,            ##-- allow POST requests? (default=1)
##     pushMode => $mode,             ##-- push mode for addVars (dfefault='push')
##     prepare  => \&prepare,         ##-- CODE-ref for prepare()
##     run      => \&run,             ##-- CODE-ref for run()
##     finish   => \&finish,          ##-- CODE-ref for finish()
##
## + runtime %$h data:
##     #cgi => $cgiobj,               ##-- CGI object (after cgiParse())
##     #vars => \%vars,               ##-- CGI variables (after cgiParse())
##     #cgisrc => $cgisrc,            ##-- CGI source (after cgiParse())
sub new {
  my $that = shift;
  my $h =  bless {
		  #encoding=>'UTF-8', ##-- default CGI parameter encoding
		  allowGet=>1,
		  allowPost=>1,
		  pushMode => 'push',
		  @_
		 }, ref($that)||$that;
  return $h;
}

## $bool = $h->prepare($server)
##  + calls $h->{prepare}->($h,$server) if defined
sub prepare {
  return $_[0]{prepare}->(@_) if ($_[0]{prepare});
  return 1;
}

## \%vars = $h->decodeVars(\%vars,%opts)
##  + decodes cgi-style variables using $h->decodeString($str,%opts)
##  + %opts:
##     vars    => \@vars,      ##-- list of vars to decode (default=keys(%vars))
##     someKey => $someVal,    ##-- passed to $h->decodeString()
sub decodeVars {
  my ($h,$vars,%opts) = @_;
  return undef if (!defined($vars));
  my $keys = $opts{vars} || [keys %$vars];
  my ($vref);
  foreach (grep {exists $vars->{$_}} @$keys) {
    $vref = \$vars->{$_};
    if (ref($$vref)) {
      $h->decodeStringRef(\$_,%opts) foreach (@{$$vref});
    } else {
      #$$vref = $h->decodeString($$vref,%opts); ##-- BUG here with YAML data (test-pp.t.yaml) UTF-8 flag not set after call!
      $h->decodeStringRef($vref,%opts);
    }
  }
  return $vars;
}

## \$string = $h->decodeString(\$string,%opts); ##-- decodes in-place
## $decoded = $h->decodeString( $string,%opts); ##-- decode by copy
##  + decodes string as UTF-8, optionally handling HTML-style escapes
##  + %opts:
##     allowHtmlEscapes => $bool,    ##-- whether to handle HTML escapes (default=false)
##     #encoding        => $enc,     ##-- source encoding (default=$h->{encoding}; see also $h->requestEncoding())
sub decodeString {
  my ($h,$str,%opts) = @_;
  return $h->decodeStringRef($str,%opts) if (ref($str));
  return ${$h->decodeStringRef(\$str,%opts)};
}

## \$string = $h->decodeStringRef(\$string,%opts); ##-- decodes in-place
##  + decodes string in-place as UTF-8, optionally handling HTML-style escapes
##  + %opts:
##     allowHtmlEscapes => $bool,    ##-- whether to handle HTML escapes (default=false)
##     #encoding         => $enc,     ##-- source encoding (default=$h->{encoding}; see also $h->requestEncoding())
sub decodeStringRef {
  my ($h,$sref,%opts) = @_;
  return $sref if (!defined($sref) || !ref($sref));
  utf8::decode($$sref) if (!utf8::is_utf8($$sref));
  if ($opts{allowHtmlEscapes}) {
    $$sref =~ s/\&\#(\d+)\;/pack('U',$1)/eg;
    $$sref =~ s/\&\#x([[:xdigit:]]+)\;/pack('U',hex($1))/eg;
  }
  return $$sref;
}


## \%vars = $h->trimVars(\%vars,%opts)
##  + trims leading and trailing whitespace from selected values in \%vars
##  + %opts:
##     vars    => \@vars,      ##-- list of vars to trim (default=keys(%vars))
sub trimVars {
  my ($h,$vars,%opts) = @_;
  return undef if (!defined($vars));
  my $keys = $opts{vars} || [keys %$vars];
  my ($vref);
  foreach (grep {exists $vars->{$_}} @$keys) {
    $vref = \$vars->{$_};
    if (ref($$vref)) {
      foreach (@{$$vref}) {
	$_ =~ s/^\s+//;
	$_ =~ s/\s+$//;
      }
    } else {
      $$vref =~ s/^\s+//;
      $$vref =~ s/\s+$//;
    }
  }
  return $vars;
}

## \%vars = $h->addVars(\%vars,\%push,$mode='push')
##  + CGI-like variable push; destructively adds\%push onto \%vars
##  + if $mode is 'push', dups are treated as array push
##  + if $mode is 'clobber', dups in %push clobber values in %vars
##  + if $mode is 'keep', dups in %push are ignored
sub addVars {
  my ($h,$vars,$push,$mode) = @_;
  $mode = $h->{pushMode} if (!defined($mode));
  $mode = 'push' if (!defined($mode));

CAB/Server/HTTP/Handler/CGI.pm  view on Meta::CPAN

	##-- multipart/form-data: part: anything other than 'form-data'
	$h->addVars($vars, { $opts{defaultName} => $part->content });
      }
    }
    return $vars;
  }
  elsif ($hreq->content_length > 0) {
    ##-- unknown content: use default data key
    return {
	    $opts{defaultName} => $hreq->content
	   };
  }
  return {}; ##-- no parameters at all
}

## \%params = $h->params($hreq,%opts)
## + wrapper for $h->pushVars($h->uriParams(),$h->contentParams())
## + %opts are passed to uriParams, contentParams
sub params {
  my ($h,$hreq,%opts) = @_;
  my $vars = $h->uriParams($hreq,%opts);
  $h->addVars($vars, $h->contentParams($hreq,%opts));
  return $vars;
}


## \%vars = $h->cgiParams($srv,$clientConn,$httpRequest, %opts)
##  + parses cgi parameters from client request
##  + only handles GET or POST requests
##  + wrapper for $h->uriParams(), $h->contentParams()
##  + %opts are passed to uriParams, contentParams
sub cgiParams {
  my ($h,$csock,$hreq,%opts) = @_;

  if ($hreq->method eq 'GET') {
    ##-- HTTP request: GET
    return $h->cerror($csock, RC_METHOD_NOT_ALLOWED, "CGI::cgiParams(): GET method not allowed") if (!$h->{allowGet});
    return $h->uriParams($hreq,%opts);
  }
  elsif ($hreq->method eq 'POST') {
    ##-- HTTP request: POST
    return $h->cerror($csock, RC_METHOD_NOT_ALLOWED, "CGI::cgiParams(): POST method not allowed") if (!$h->{allowPost});
    return $h->params($hreq,%opts);
  }
  else {
    ##-- HTTP request: unknown
    return $h->cerror($csock, RC_METHOD_NOT_ALLOWED, ("CGI::cgiParams(): method not allowed: ".$hreq->method));
  }

  return {};
}

## $enc = $h->messageEncoding($httpMessage,$defaultEncoding)
##  + attempts to guess messagencoding from (in order of descending priority):
##    - HTTP::Message header Content-Type charset variable
##    - HTTP::Message header Content-Encoding
##    - $defaultEncoding (default=undef)
sub messageEncoding {
  my ($h,$msg,$default) = @_;
  my $ctype = $msg->header('Content-Type'); ##-- note: $msg->content_type() truncates after ';' !
  ##-- see also HTTP::Message::decoded_content() for a better way to parse header parameters!
  ##
  return $1 if (defined($ctype) && $ctype =~ /\bcharset=([\w\-]+)/);
  #$ctype    = $msg->header('Content-Encoding');
  #return $1 if (defined($ctype) && $ctype =~ /\bcharset=([\w\-]+)/);
  #return $ctype if (defined($ctype));
  return $default;
}

## $enc = $h->getEncoding(@sources)
##  + attempts to guess request encoding from the first defined
##    encoding in @sources, each element $_ of which may be:
##     - a HASH-ref             : encoding is $_->{encoding}
##     - a HTTP::Message object : encoding is $h->messageEncoding($_)
##     - a literal scalar       : encoding is $_
sub getEncoding {
  my $h = shift;
  my ($enc);
  foreach (@_) {
    if (UNIVERSAL::isa($_,'HTTP::Message')) {
      $enc = $h->messageEncoding($_,undef);
    }
    elsif (UNIVERSAL::isa($_,'HASH')) {
      $enc = $_->{encoding};
    }
    elsif (!ref($_)) {
      $enc = $_;
    }
    return $enc if ($enc);
  }
  return undef;
}


## $enc = $h->requestEncoding($httpRequest,\%vars)
##  + attempts to guess request encoding from (in order of descending priority):
##    - CGI param 'encoding', from $vars->{encoding}
##    - HTTP::Message encoding via $h->messageEncoding($httpRequest)
##    - $h->{encoding}
sub requestEncoding {
  my ($h,$hreq,$vars) = @_;
  return $h->getEncoding($vars->{encoding},$hreq,$h->{encoding});
}

## $rsp = $h->run($server, $localPath, $clientConn, $httpRequest)
##  + return $h->{run}->(@_) if defined
sub run {
  my $h = shift;
  return $h->{run}->($h,@_) if ($h->{run});
  return $h->SUPER::run(@_);
}


## undef = $h->finish($server, $clientSocket)
##  + clean up handler state after run()
##  + override deletes @$h{qw(cgi vars cgisrc)}
sub finish {
  my $h = shift;
  return $h->{finish}->($h,@_) if ($h->{finish});
  delete(@$h{qw(cgi vars cgisrc)});
  return;

CAB/Server/HTTP/Handler/CGI.pm  view on Meta::CPAN

 \%params = $h->contentParams($hreq,%opts);

Parses POST-style content parameters from $hreq.
If $hreq content-type is neither 'application/x-www-form-urlencoded' nor 'multipart/form-data',
but content is present, returns $hreq content as the value of the pseudo-variable $opts{defaultName}.
Known %opts:

 defaultName => $name,       ##-- default parameter name (default='POSTDATA')
 defaultCharset => $charset, ##-- default charset

=item params

 \%params = $h->params($hreq,%opts);

Wrapper for $h-E<gt>pushVars($h-E<gt>uriParams(),$h-E<gt>contentParams())
%opts are passed to L</uriParams>(), L</contentParams>().


=item cgiParams

 \%vars = $h->cgiParams($srv,$clientConn,$httpRequest, %opts);


=over 4


=item *

parses cgi parameters from client request

=item *

only handles GET or POST requests

=item *

wrapper for $h-E<gt>uriParams(), $h-E<gt>contentParams()

=item *

%opts are passed to uriParams, contentParams

=back




=item decodeVars

 \%vars = $h->decodeVars(\%vars,%opts);

Decodes cgi-style variables using $h-E<gt>decodeString($str,%opts).
Known %opts:

 vars    => \@vars,      ##-- list of vars to decode (default=keys(%vars))
 someKey => $someVal,    ##-- passed to $h-E<gt>decodeString()

=item decodeString

 \$string = $h->decodeString(\$string,%opts); ##-- decodes in-place;
 $decoded = $h->decodeString( $string,%opts); ##-- decode by copy

Wrapper for L</decodeStringRef>().

=item decodeStringRef

 \$string = $h->decodeStringRef(\$string,%opts); ##-- decodes in-place;

Decodes string in-place as $h-E<gt>{encoding}, optionally handling HTML-style escapes.
Known %opts:

%opts:
 allowHtmlEscapes => $bool,    ##-- whether to handle HTML escapes (default=false)
 encoding         => $enc,     ##-- source encoding (default=$h->{encoding}; see also $h->requestEncoding())



=item messageEncoding

 $enc = $h->messageEncoding($httpMessage,$defaultEncoding);

Atempts to guess messagencoding from (in order of descending priority):

=over 4

=item *

HTTP::Message header Content-Type charset variable

=item *

HTTP::Message header Content-Encoding

=item *

$defaultEncoding (default=undef)

=back



=item requestEncoding

 $enc = $h->requestEncoding($httpRequest,\%vars);

Attempts to guess request encoding from (in order of descending priority):

=over 4

=item *

CGI param 'encoding', from $vars-E<gt>{encoding}

=item *

HTTP::Message encoding via $h-E<gt>messageEncoding($httpRequest)

=item *

$h-E<gt>{encoding}



( run in 1.445 second using v1.01-cache-2.11-cpan-39bf76dae61 )