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>.