File Coverage

blib/lib/Business/OnlinePayment/PPIPayMover/SecureHttp.pm
Criterion Covered Total %
statement 65 86 75.5
branch 11 22 50.0
condition n/a
subroutine 9 11 81.8
pod 0 7 0.0
total 85 126 67.4


line stmt bran cond sub pod time code
1 6     6   35 use strict;
  6         13  
  6         2023  
2             package Business::OnlinePayment::PPIPayMover::SecureHttp;
3 6     6   2219 use Socket;
  6         15795  
  6         4636  
4 6     6   2779 use Net::SSLeay qw(die_now die_if_ssl_error) ;
  6         24843  
  6         10086  
5             1;
6            
7             # constuctor
8             sub new
9             {
10 4     4 0 8 my $class = shift;
11 4         11 my $self = {};
12 4         22 bless $self, $class;
13 4         30 $self->{ctx} = undef;
14 4         6 $self->{ssl} = undef;
15 4         10 $self->{strError} = "";
16 4         20 return $self;
17             }
18            
19             sub Init
20             {
21 4     4 0 12 my $self = shift;
22            
23 4         8633 Net::SSLeay::load_error_strings();
24 4         119 Net::SSLeay::ERR_load_crypto_strings();
25 4         572 Net::SSLeay::SSLeay_add_ssl_algorithms();
26 4         51 Net::SSLeay::randomize();
27            
28 4         5306 $self->{ctx} = Net::SSLeay::CTX_new();
29 4 50       27 if(!$self->{ctx}) {
30 0         0 $self->{strError} .= "Failed to create SSL_CTX. \n" .
31             "SSLeay error: " . Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error);
32 0         0 return 0;
33             }
34            
35 4 50       31 if(!Net::SSLeay::CTX_set_options($self->{ctx}, &Net::SSLeay::OP_ALL)) {
36             # For some reason the if statement above always returns false,
37             # but SSLeay reports no error. Ignore this error, since
38             # everything still works fine.
39             #
40             #$self->{strError} .= "Failed to set SSL_CTX options. \n" .
41             # "SSLeay error: " . Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error) . "\n";
42             }
43            
44 4         571 $self->{ssl} = Net::SSLeay::new($self->{ctx});
45 4 50       20 if(!$self->{ssl}) {
46 0         0 $self->{strError} .= "Failed to create an SSL. \n" .
47             "SSLeay error: " . Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error);
48 0         0 return 0;
49             }
50            
51 4         32 return 1;
52             }
53            
54             sub Connect
55             {
56 4     4 0 12 my $self = shift;
57 4         12 my ($destServer, $port) = @_;
58 4 50       29 $port = getservbyname($port, 'tcp') unless $port =~ /^\d+$/;
59            
60 4         11803 my $destIp = gethostbyname ($destServer);
61 4 50       58 if(!defined($destIp)) {
62 0         0 $self->{strError} .= "Couldn't resolve host name (gethostbyname) using host: $destServer\n";
63 0         0 return 0;
64             }
65            
66 4         45 my $destServerSockAddr = sockaddr_in($port, $destIp);
67            
68 4 50       239 if(!socket (S, AF_INET, SOCK_STREAM, 0)) {
69 0         0 $self->{strError} .= "Failed to create a socket. $!";
70 0         0 return 0;
71             }
72            
73 4 50       397770 if(!connect (S, $destServerSockAddr)) {
74 0         0 $self->{strError} .= "Failed to connect. $!";
75 0         0 return 0;
76             }
77            
78 4         49 select (S); $| = 1; select (STDOUT); # Eliminate STDIO buffering
  4         28  
  4         27  
79 4         173 Net::SSLeay::set_fd($self->{ssl}, fileno(S)); # Must use fileno
80 4 50       1250239 if (! Net::SSLeay::connect($self->{ssl})) {
81 0         0 $self->{strError} .= "Failed to make an ssl connect. \n" .
82             "SSLeay error: " . Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error);
83 0         0 return 0;
84             }
85            
86 4         72 return 1;
87             }
88            
89             sub DoSecurePost
90             {
91 4     4 0 18 my $self = shift;
92 4         22 my ($strPath, $strContent, $Response) = @_;
93 4         15 my $PostString = "POST ";
94 4         19 $PostString .= $strPath;
95 4         15 $PostString .= " HTTP/1.0\r\nContent-Type: application/x-www-form-urlencoded\r\n";
96 4         12 $PostString .= "Content-Length: ";
97 4         14 $PostString .= length($strContent);
98 4         13 $PostString .= " \r\n\r\n";
99 4         21 $PostString .= $strContent;
100            
101 4 50       61 if(!Net::SSLeay::ssl_write_all($self->{ssl}, $PostString)) {
102 0         0 $self->{strError} .= "Failed to write. " .
103             "SSLeay error: " . Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error);
104 0         0 return 0;
105             }
106            
107 4         19771 shutdown S, 1; # Half close --> No more output, sends EOF to server
108            
109 4 50       40 if( $^O eq "MSWin32" ) {
110             # Windows doesn't implement ALRM signal,
111             # so don't use a timeout.
112             # May hang client system.
113 0         0 $$Response = Net::SSLeay::ssl_read_all($self->{ssl});
114             } else {
115             # This block uses the alarm signal
116             # to see if the server times out responding.
117 4         13 eval {
118             local $SIG{ ALRM } = sub {
119 0     0   0 $self->{strError} .= "Server timed out.";
120 0         0 close S;
121 4         136 };
122 4         45 alarm 270; # Alarm on 4.5 min timeout
123             # Read in response from server
124 4         44 $$Response = Net::SSLeay::ssl_read_all($self->{ssl});
125             };
126 4         468334 alarm 0; # Alarm off
127            
128             }
129            
130 4 50       40 if ( !defined( $$Response ) ) {
131 0         0 $self->{strError} .= "Failed to read from socket. " .
132             "SSLeay error: " . Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error);
133 0         0 return 0;
134             }
135 4         40 return 1;
136             }
137            
138             sub DisconnectFromServer
139             {
140 4     4 0 18 my $self = shift;
141 4         654 Net::SSLeay::free ($self->{ssl}); # Tear down connection
142 4         54 Net::SSLeay::CTX_free ($self->{ctx});
143 4         180 close S;
144             }
145            
146             sub CleanUp
147             {
148 4     4 0 30 return 1;
149             }
150            
151             sub GetErrorString
152             {
153 0     0 0   my $self = shift;
154 0           return $self->{strError};
155             }