An epp xml frame system built on top of xml::libxml.
#!/usr/bin/perl
use Net::EPP::Client;
use Net::EPP::Frame;
use Net::EPP::ObjectSpec;
use Digest::MD5 qw(md5_hex);
use Time::HiRes qw(time);
use strict;
#
# establish a connection to an EPP server:
#
my $epp = Net::EPP::Client->new(
host => 'epp.registry.tld',
port => 700,
ssl => 1,
dom => 1,
);
my $greeting = $epp->connect;
#
# log in:
#
my $login = Net::EPP::Frame::Command::Login->new;
$login->clID->appendText($userid);
$login->pw->appendText($passwd);
#
# set the client transaction ID:
#
$login->clTRID->appendText(md5_hex(Time::HiRes::time().$$));
#
# check the response from the log in:
#
my $answer = $epp->request($login);
my $result = ($answer->getElementsByTagName('result'))[0];
if ($result->getAttribute('code') != 1000) {
die("Login failed!");
}
#
# OK, let's do a domain name check:
#
my $check = Net::EPP::Frame::Command::Check->new;
#
# get the spec from L<Net::EPP::Frame::ObjectSpec>:
#
my @spec = Net::EPP::Frame::ObjectSpec->spec('domain');
#
# create a domain object using the spec:
#
my $domain = $check->addObject(@spec);
#
# set the domain name we want to check:
#
my $name = $check->createElement('domain:name');
$name->appendText('example.tld');
#
# set the client transaction ID:
#
$check->clTRID->appendText(md5_hex(time().$$));
#
# assemble the frame:
#
$domain->addChild($name);
#
# send the request:
#
my $answer = $epp->request($check);
# and so on...
\s-1EPP\s0 is the Extensible Provisioning Protocol. \s-1EPP\s0 (defined in \s-1RFC\s0 4930) is an application layer client-server protocol for the provisioning and management of objects stored in a shared central repository. Specified in \s-1XML\s0, the protocol defines generic object management operations and an extensible framework that maps protocol operations to objects. As of writing, its only well-developed application is the provisioning of Internet domain names, hosts, and related contact details.
\s-1EPP\s0 uses \s-1XML\s0 documents called \*(L"frames\*(R" send data to and from clients and servers. This module implements a subclass of the XML::LibXML::Document module that simplifies the process of creation of these frames. It is designed to be used alongside the Net::EPP::Client module.
L<XML::LibXML::Node> +----L<XML::LibXML::Document> +----L<Net::EPP::Frame>
As a rule, you will not need to create Net::EPP::Frame objects directly. Instead, you should use one of the subclasses included with the distribution. The subclasses all inherit from Net::EPP::Frame.
Net::EPP::Frame is itself a subclass of XML::LibXML::Document so all the methods available from that class are also available to instances of Net::EPP::Frame.
The available subclasses of Net::EPP::Frame exist to add any additional elements required by the \s-1EPP\s0 specification. For example, the <login> frame must contain the <clID> and <pw> frames, so when you create a new Net::EPP::Frame::Command::Login object, you get these already defined.
These classes also have convenience methods, so for the above example, you can call the \*(C`$login->clID\*(C' and \*(C`$login->pw\*(C' methods to get the XML::LibXML::Node objects correesponding to those elements.
You could just as easily construct your \s-1EPP\s0 frames from templates or just lots of \*(C`printf()\*(C' calls. But using a programmatic approach such as this strongly couples the validity of your \s-1XML\s0 to the validity of your program. If the process by which your \s-1XML\s0 is built is broken, your program won't run. This has to be a win.
my $str = $frame->formatTimeStamp($timestamp);
This method returns a scalar in the required format (defined in \s-1RFC\s0 3339). This is a convenience method.
my $node = $frame->getNode($id); my $node = $frame->getNode($ns, $id);
This is another convenience method. It uses $id with the getElementsByTagName() method to get a list of nodes with that element name, and simply returns the first XML::LibXML::Element from the list.
If $ns is provided, then getElementsByTagNameNS() is used.
my $binary = $frame->header;
Returns a scalar containing the frame length packed into binary. This is only useful for low-level protocol stuff.
my $data = $frame->frame;
Returns a scalar containing the frame header (see the header() method above) concatenated with the \s-1XML\s0 frame itself. This is only useful for low-level protocol stuff.
Each subclass has its own subclasses for various objects, for example Net::EPP::Frame::Command::Check::Domain creates \*(C`<check>\*(C' frame for domain names.
Coverage for all combinations of command and object type is not complete, but work is ongoing.
CentralNic Ltd (http://www.centralnic.com/).
This module is (c) 2012 CentralNic Ltd. This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
XML::LibXML, the Perl bindings to the libxml library
The libxml website at <http://www.xmlsoft.org/>
the Net::EPP::Client module, for communicating with \s-1EPP\s0 servers.
the Net::EPP::Frame::ObjectSpec module, for managing \s-1EP\s0 object metadata.
RFCs 4930 and \s-1RFC\s0 4934, available from <http://www.ietf.org/>.
The CentralNic \s-1EPP\s0 site at <http://www.centralnic.com/resellers/epp>.