Giuseppe
I hope people will be able to point out improvements in the way I've done
this as it was kind of done as a quick workaround, but we're currently using
it live on our system.
This is the WSH code:
<?xml version="1.0"?>
<component>
<registration
description="OpenSRS Wrapper"
progid="OpenSRSwrapper.WSC"
classid="{E0562DED-25E7-4F65-88C6-1AFF06E60140}"
remotable="true"/>
<public>
<method name="lookup" internalName="lookup"/>
<method name="checkSock" internalName="checkSock"/>
</public>
<implements type="ASP" id="ASP"/>
<script language="PerlScript">
#!/usr/bin/perl
use vars qw(
%in $cgi $path_templates %actions $action %cc_types $XML_Client
%contact_keys %data
);
( %in, $cgi, $path_templates, %actions, $action, %cc_types,
$XML_Client,
%contact_keys, %data ) = ();
# pull in conf file with defined values
# XXX NOTE XXX Update this configuration file
BEGIN {
do "<location of your OpenSRS conf file>/OpenSRS.conf";
}
#use Data::Dumper;
use strict;
use lib $PATH_LIB;
use RACE;
do "$PATH_LIB/cgi-lib.pl";
use OpenSRS::XML_Client qw(:default);
# create a client object which we will use to connect to the OpenSRS server
$XML_Client = new OpenSRS::XML_Client(%OPENSRS);
$XML_Client->login;
####################################################################
### Begin subroutines
###################################################################
sub lookup {
my (%HTML,$status,$match_string,$matches);
my ($xcp_request,$lookup_results,$match,$error_msg);
my ($matchRef);
my ($domain) = @_;
my $affiliate_id = "<Your affiliate ID>";
$lookup_results = $XML_Client->send_cmd( $domain );
return $lookup_results;
##exit;
}
sub checkSock {
my ($sock_status);
#%sock_status = 0;
$sock_status = $XML_Client->get_socket_status;
return $sock_status;
##exit;
}
</script>
</component>
Save this in a text file called OpenSRSwrapper.wsc and save it. In Windows
explorer you can then right-click on the file and one of the options is to
register COM object. This will then allow you to call it in ASP with usual
syntax, server.CreateObject("OpenSRSwrapper.WSC") and you can call the
functions using objName.lookup(yourXMLstring).
In fact there's no reason why you couldn't bypass the above steps and
include the above code in an ASP page (without the XML stuff wrapping it at
top and bottom) and wrap it with <script language='PerlScript'
runAt='SERVER'> ... </script> You could then simply call the Perl lookup sub
directly from ordinary vbscript ASP pages. Someone who knew more Perl than
me could probably wrap the API much better than this so you could call the
OpenSRS functions directly from ASP without having to build and decode the
OpenSRS XML yourself.
Because I decided to retain control over building and reading the XML, I
also hacked the XML_Client.pm. This was necessary to allow OpenSRS to use
its existing functions to perform the connection, but allowed me to use
slightly altered versions to pass in XML and get XML out.
So I altered the send_cmd sub:
####################################################
# send a command to the OpenSRS server
sub send_cmd {
my ( $data, $response_code, $response_text, $fh, $key );
my $self = shift;
my $requestData = shift;
my $action = $requestData->{action};
my $object = $requestData->{object};
if ( not defined $self->{_OPS} )
{
$self->{_OPS} = new OPS();
}
# make or get the socket filehandle
if ( not $self->init_socket( ) ) {
$data->{is_success} = 0;
$data->{response_code} = 400;
$data->{response_text} = "Unable to establish socket";
return $data;
}
# all opensrs actions happen here
my %auth = $self->authenticate($self->{username},$self->{private_key});
if (not $auth{is_success}) {
close_socket( );
$data->{is_success} = 0;
$data->{response_code} = 400;
$data->{response_text} = "Authentication Error: $auth{error}";
return $data;
}
$self->send_data_new( $requestData );
$data = $self->read_data_new( );
return ($data);
}
This soloely modifies it to use send_date_new and read_data_new instead of
send_data and read_data.
Then I added the new subs:
###############################################################
## My Read Data!!!!!!!!!
sub read_data_new {
my ( $buf );
my $self = shift;
my %args = @_;
# Read the length of this input.
$buf = $self->{_OPS}->read_data( $self->{_fh} );
$buf = ($self->{_cipher}) ? $self->{_cipher}->decrypt($buf) : $buf;
return $buf;
}
# Sends request to the server.
# XXX Need error checking?
sub send_data_new {
my $self = shift;
my $message = shift; # hash ref or binary data (for challenge)
##return $message;
##exit;
my %args = @_; # other flags
my $data_to_send;
##if ( not $args{no_xml} )
##{
## $message->{protocol} = "XCP";
## $data_to_send = $self->{_OPS}->encode( $message );
# have to lowercase the action and object keys
# because OPS.pm uppercases them
## $message->{action} = lc $message->{action};
## $message->{object} = lc $message->{object};
##}
##else
##{
# no XML encoding
$data_to_send = $message;
##}
$data_to_send = $self->{_cipher}->encrypt($data_to_send) if
$self->{_cipher};
return $self->{_OPS}->write_data( $self->{_fh}, $data_to_send );
}
These are just the original send_data and read_data with stuff cut out.
The above was all done for speed of development. I briefly looked at
creating a native COM object, but found the documentation of the encryption
pretty much non-existant. A proper COM object would probably perform a lot
better.
A final point - when reading the XML responses, the MS XMLDom object
doesn't like the OpenSRS DTD, it doesn't recognise the data types. You are
therefore better to cut the line out of the XML response that refers to the
DTD before passing the XML to the XMLDOM object. The DTD is also very
unhelpful, from the point of view of the XMLDOM by having all of its items
called "item". It would be a lot simpler to extract results if you could use
named named elements instead of all elements having the same name and being
identified by an Attribute.
Tony Levaggi
Tetradom NZ
-----Original Message-----
From: Giuseppe Simone Aielli [mailto:[EMAIL PROTECTED]]
Sent: Thursday, 23 August 2001 7:50 p.m.
To: Tony Levaggi
Subject: Re: Payment Processing - NT Com Component follow up
Hi Tony,
I find your solution to be effectively much more beautiful than mine.
First, being "compatible" with Perl it's gonna be much easier to upgrade,
and this solves the issue of manitance, which is big, as we can see Tucows
is releasing new version every few weeeks.
Second, it seems to be much easier to implement than writing his own client
in VB, Java or wichever language.
Tird: in my opinion there seem to be no problems for this kind of
development; it offers almost all the same as a new COM DLL.
Now I ask myself if you want to share some line of code with the rest of the
guys at Devlist, or if you would please supply some other "light" on this
solution.
Thank you very much,
gsa
----- Original Message -----
From: Tony Levaggi
To: 'Giuseppe Simone Aielli'
Sent: Thursday, August 23, 2001 6:48 AM
Subject: RE: Payment Processing - NT Com Component follow up
In the end, I created a pseudo COM component using Windows Scripting Host
and PerlScript (which is installed by default if you use ActivePerl as your
Win32k Perl environment).
This allows you to create a Com object directly from Perlscript - very
simple Perl to wrap calls to the functions in the OpenSRS Perl libraries.
Alternately, you could create a wrapper ASP page, with the scripting
language set to Perlscript. This can include any Perl libraries, so you can
create an ASP function that can be called from other ASP pages (written in
Vbscript/Javascript) that again wraps the OpenSRS Perl functions.
In my case the poor documentation of the encryption in OpenSRS led me to
leave the connection & encryption in the OpenSRS client, but build and
decode the XML requests/responses in ASP.
Tony Levaggi
-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]]On
Behalf Of Giuseppe Simone Aielli
Sent: Tuesday, 21 August 2001 6:36 p.m.
To: [EMAIL PROTECTED]; Scott McKee
Cc: [EMAIL PROTECTED]
Subject: Re: Payment Processing - NT Com Component follow up
Hi,
in my opinion, the success of a COM client component of OpenSRS must be in
the word Open. There have been several attempts in the past (Java, PHP),
which can be found on Sourceforge, and all are quite interesting.
http://sourceforge.net/projects/opensrsjava/ and
http://sourceforge.net/projects/opensrs-php/
The Java client, which is still in development I believe, could be easily
compiled in the form of a DLL, which can in turn be called from ASP. However
there must be an opensource team to develop the component, because it can
assure the compliance with new APIs & features released by Tucows -as soon
as they come-, and it is not possible to simply write a client using only
ASP, because of its limited support for direct socket conncetions; it should
be (at least) a Visual Basic DLL.
It is quite unbeliveable that no one of the alternative client projects for
SRS addresses the major lack of this system: it is badly supported under
Windows (exept for the wonderful work done by Atlcon.net). As if Unix was
the only system out there...
So I call every VB programmer in the list to have a look at our Opensource
VB projects (http://sourceforge.net/projects/aspdns/ and
http://sourceforge.net/projects/easywhois/) which are two examples, not so
far from what I meant here to explain.
Regards,
gsa