2 package Business::OnlinePayment::PPIPayMover::SecureHttp;
\r
4 use Net::SSLeay qw(die_now die_if_ssl_error) ;
\r
12 bless $self, $class;
\r
13 $self->{ctx} = undef;
\r
14 $self->{ssl} = undef;
\r
15 $self->{strError} = "";
\r
23 Net::SSLeay::load_error_strings();
\r
24 Net::SSLeay::ERR_load_crypto_strings();
\r
25 Net::SSLeay::SSLeay_add_ssl_algorithms();
\r
26 Net::SSLeay::randomize();
\r
28 $self->{ctx} = Net::SSLeay::CTX_new();
\r
30 $self->{strError} .= "Failed to create SSL_CTX. \n" .
\r
31 "SSLeay error: " . Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error);
\r
35 if(!Net::SSLeay::CTX_set_options($self->{ctx}, &Net::SSLeay::OP_ALL)) {
\r
36 # For some reason the if statement above always returns false,
\r
37 # but SSLeay reports no error. Ignore this error, since
\r
38 # everything still works fine.
\r
40 #$self->{strError} .= "Failed to set SSL_CTX options. \n" .
\r
41 # "SSLeay error: " . Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error) . "\n";
\r
44 $self->{ssl} = Net::SSLeay::new($self->{ctx});
\r
46 $self->{strError} .= "Failed to create an SSL. \n" .
\r
47 "SSLeay error: " . Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error);
\r
57 my ($destServer, $port) = @_;
\r
58 $port = getservbyname($port, 'tcp') unless $port =~ /^\d+$/;
\r
60 my $destIp = gethostbyname ($destServer);
\r
61 if(!defined($destIp)) {
\r
62 $self->{strError} .= "Couldn't resolve host name (gethostbyname) using host: $destServer\n";
\r
66 my $destServerSockAddr = sockaddr_in($port, $destIp);
\r
68 if(!socket (S, AF_INET, SOCK_STREAM, 0)) {
\r
69 $self->{strError} .= "Failed to create a socket. $!";
\r
73 if(!connect (S, $destServerSockAddr)) {
\r
74 $self->{strError} .= "Failed to connect. $!";
\r
78 select (S); $| = 1; select (STDOUT); # Eliminate STDIO buffering
\r
79 Net::SSLeay::set_fd($self->{ssl}, fileno(S)); # Must use fileno
\r
80 if (! Net::SSLeay::connect($self->{ssl})) {
\r
81 $self->{strError} .= "Failed to make an ssl connect. \n" .
\r
82 "SSLeay error: " . Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error);
\r
92 my ($strPath, $strContent, $Response) = @_;
\r
93 my $PostString = "POST ";
\r
94 $PostString .= $strPath;
\r
95 $PostString .= " HTTP/1.0\r\nContent-Type: application/x-www-form-urlencoded\r\n";
\r
96 $PostString .= "Content-Length: ";
\r
97 $PostString .= length($strContent);
\r
98 $PostString .= " \r\n\r\n";
\r
99 $PostString .= $strContent;
\r
101 if(!Net::SSLeay::ssl_write_all($self->{ssl}, $PostString)) {
\r
102 $self->{strError} .= "Failed to write. " .
\r
103 "SSLeay error: " . Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error);
\r
107 shutdown S, 1; # Half close --> No more output, sends EOF to server
\r
109 if( $^O eq "MSWin32" ) {
\r
110 # Windows doesn't implement ALRM signal,
\r
111 # so don't use a timeout.
\r
112 # May hang client system.
\r
113 $$Response = Net::SSLeay::ssl_read_all($self->{ssl});
\r
115 # This block uses the alarm signal
\r
116 # to see if the server times out responding.
\r
118 local $SIG{ ALRM } = sub {
\r
119 $self->{strError} .= "Server timed out.";
\r
122 alarm 270; # Alarm on 4.5 min timeout
\r
123 # Read in response from server
\r
124 $$Response = Net::SSLeay::ssl_read_all($self->{ssl});
\r
126 alarm 0; # Alarm off
\r
130 if ( !defined( $$Response ) ) {
\r
131 $self->{strError} .= "Failed to read from socket. " .
\r
132 "SSLeay error: " . Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error);
\r
138 sub DisconnectFromServer
\r
141 Net::SSLeay::free ($self->{ssl}); # Tear down connection
\r
142 Net::SSLeay::CTX_free ($self->{ctx});
\r
154 return $self->{strError};
\r