Subject: | Use CGI::Util instead of CGI |
Date: | Fri, 14 Aug 2009 00:25:09 -0600 |
To: | bug-Business-OnlinePayment-PayflowPro [...] rt.cpan.org |
From: | Josh Rosenbaum <josh [...] infogears.com> |
This patch modifies Business::OnlinePayment::PayflowPro 0.07 to:
*) utilize CGI::Util to parse the response instead of CGI. This reduces the memory footprint and overhead of using the entire CGI module. (We fallback to the old CGI method of unescaping if CGI::Util is unavailable, such as is the case in older Perls.)
*) add a _get_response() routine which can be used to parse the response and get a hash of the values returned. This is useful if you need to get at a particular value in the returned response.
*) For our particular case, we had some very old legacy code that defined its own CGI package as well, so that was getting trounced on by the "use CGI" here and this fixes that.
Tests can be added if this patch is accepted.
-- Josh Rosenbaum
--- PayflowPro.pm.orig 2009-08-13 18:11:50.000000000 -0600
+++ PayflowPro.pm.new 2009-08-13 18:27:19.000000000 -0600
@@ -3,16 +3,29 @@
use strict;
use vars qw($VERSION $DEBUG);
use Carp qw(carp croak);
-use CGI;
use Digest::MD5;
use Business::OnlinePayment::HTTPS 0.06;
use base qw(Business::OnlinePayment::HTTPS);
-$VERSION = '0.07';
+$VERSION = '0.08';
$VERSION = eval $VERSION;
$DEBUG = 0;
+my $no_cgi_util;
+
+BEGIN {
+ eval {
+
+ # CGI::Util was included starting with Perl 5.6. For previous Perls, we need
+ # to be sure to use the old simple CGI based method of unescaping
+ require CGI::Util;
+ };
+ if ($@) {
+ $no_cgi_util = 1;
+ }
+}
+
# return current request_id or generate a new one if not yet set
sub request_id {
my $self = shift;
@@ -256,21 +269,21 @@
$self->response_headers( \%resp_headers );
# $page should contain name=value[[&name=value]...] pairs
- my $cgi = CGI->new("$page");
+ my $response = $self->_get_response( \$page );
# AVS and CVS values may be set on success or failure
my $avs_code;
- if ( defined $cgi->param("AVSADDR") or defined $cgi->param("AVSZIP") ) {
- if ( $cgi->param("AVSADDR") eq "Y" && $cgi->param("AVSZIP") eq "Y" ) {
+ if ( defined $response->{"AVSADDR"} or defined $response->{"AVSZIP"} ) {
+ if ( $response->{"AVSADDR"} eq "Y" && $response->{"AVSZIP"} eq "Y" ) {
$avs_code = "Y";
}
- elsif ( $cgi->param("AVSADDR") eq "Y" ) {
+ elsif ( $response->{"AVSADDR"} eq "Y" ) {
$avs_code = "A";
}
- elsif ( $cgi->param("AVSZIP") eq "Y" ) {
+ elsif ( $response->{"AVSZIP"} eq "Y" ) {
$avs_code = "Z";
}
- elsif ( $cgi->param("AVSADDR") eq "N" or $cgi->param("AVSZIP") eq "N" )
+ elsif ( $response->{"AVSADDR"} eq "N" or $response->{"AVSZIP"} eq "N" )
{
$avs_code = "N";
}
@@ -280,14 +293,14 @@
}
$self->avs_code($avs_code);
- $self->cvv2_response( $cgi->param("CVV2MATCH") );
- $self->result_code( $cgi->param("RESULT") );
- $self->order_number( $cgi->param("PNREF") );
- $self->error_message( $cgi->param("RESPMSG") );
- $self->authorization( $cgi->param("AUTHCODE") );
+ $self->cvv2_response( $response->{"CVV2MATCH"} );
+ $self->result_code( $response->{"RESULT"} );
+ $self->order_number( $response->{"PNREF"} );
+ $self->error_message( $response->{"RESPMSG"} );
+ $self->authorization( $response->{"AUTHCODE"} );
# RESULT must be an explicit zero, not just numerically equal
- if ( $cgi->param("RESULT") eq "0" ) {
+ if ( defined( $response->{"RESULT"} ) && $response->{"RESULT"} eq "0" ) {
$self->is_success(1);
}
else {
@@ -295,6 +308,38 @@
}
}
+# Make this a routine so that others can process the response page for params.
+# Based on parse_params in CGI by Lincoln D. Stein.
+sub _get_response {
+ my ( $self, $page ) = @_;
+
+ my %response;
+
+ if ( !defined($page) || ( ref($page) && !defined($$page) ) ) {
+ return \%response;
+ }
+
+ my ( $param, $value );
+ foreach ( split( /[&;]/, ref($page) ? $$page : $page ) ) {
+ ( $param, $value ) = split( '=', $_, 2 );
+ next unless defined $param;
+ $value = '' unless defined $value;
+
+ if ($no_cgi_util) { # use old pre-CGI::Util method of unescaping
+ $param =~ tr/+/ /; # pluses become spaces
+ $param =~ s/%([0-9a-fA-F]{2})/pack("c",hex($1))/ge;
+ $value =~ tr/+/ /; # pluses become spaces
+ $value =~ s/%([0-9a-fA-F]{2})/pack("c",hex($1))/ge;
+ }
+ else {
+ $param = CGI::Util::unescape($param);
+ $value = CGI::Util::unescape($value);
+ }
+ $response{$param} = $value;
+ }
+ return \%response;
+}
+
1;
__END__