Net-EPP

 view release on metacpan or  search on metacpan

lib/Net/EPP/Client.pm  view on Meta::CPAN

package Net::EPP::Client;
use Carp;
use IO::Socket::IP;
use IO::Socket::SSL;
use Net::EPP::Parser;
use Net::EPP::Frame::Response;
use Net::EPP::Protocol;
use bytes;
use strict;
use warnings;

=pod

=head1 NAME

Net::EPP::Client - a client library for the
L<TLS transport|https://www.rfc-editor.org/rfc/rfc5734.html> of the L<Extensible
Provisioning Protocol (EPP)|https://www.rfc-editor.org/info/std69>.

=head1 SYNOPSIS

	#!/usr/bin/perl
	use Net::EPP::Client;
	use strict;

	my $epp = Net::EPP::Client->new('host'  => 'epp.nic.tld');

	my $greeting = $epp->connect;

	$epp->send_frame('login.xml');

	my $answer = $epp->get_frame;

	my $answer = $epp->request('<epp><logout /></epp>');

=head1 DESCRIPTION

L<RFC 5743|https://www.rfc-editor.org/rfc/rfc5734.html> defines a TCP- (and
TLS-) based transport model for EPP, and this module implements a client for
that model. You can establish and manage EPP connections and send and receive
responses over this connection.

C<Net::EPP::Client> is a low-level EPP client. If you are writing applications,
you should use L<Net::EPP::Simple> instead.

=head1 CONSTRUCTOR

	my $epp = Net::EPP::Client->new(%PARAMS);

The constructor method creates a new EPP client object. It accepts a number of
parameters:

=over

=item * C<host>

MANDATORY. Specifies the computer to connect to. This may be a DNS hostname or
an IP address. If a hostname is provided, IPv6 will be used if available.

=item * C<port>

OPTIONAL. Specifies the TCP port to connect to. This defaults to C<700>.

=item * C<ssl>

OPTIONAL. If the value of this parameter is false, then a plaintext
connection will be created. Otherwise, L<IO::Socket::SSL> will be used to
provide an encrypted connection.

=item * C<frames>

DEPRECATED. If the value of this parameter is false, then the C<request()> and
C<get_frame()> methods (see below) will return strings instead of
C<Net::EPP::Frame::Response> objects.

=back

=cut

sub new {
    my ($package, %params) = @_;

    my $self;

    #
    # this is an undocumented and unsupported feature that allows clients to
    # connect to a local Unix socket instead of a TCP service. IIRC the only
    # use case for this was the old Net::EPP::Proxy module which went away 𝑛
    # decades ago, and it will be removed in a future release.
    #
    if (defined($params{'sock'})) {
        $self = {
            'sock' => $params{'sock'},
            'ssl'  => 0,
        };

    } else {
        croak("missing hostname") if (!defined($params{'host'}));

        $self = {
            'host' => $params{'host'},
            'port' => $params{'port'} || 700,

            #
            # since v0.27, TLS is enabled by default and must be explicitly
            # disabled.
            #
            'ssl' => (exists($params{'ssl'}) && !$params{'ssl'} ? 0 : 1),
        };
    }

    #
    # this option will also be removed in a future release.
    #
    $self->{'frames'} = (exists($params{'frames'}) && !$params{'frames'} ? 0 : 1);

    return bless($self, $package);
}

=pod

=head1 METHODS

=head2 CONNECTING TO A SERVER

	my $greeting = $epp->connect(%PARAMS);

This method establishes the TCP connection. You can use the C<%PARAMS> hash to
specify arguments that will be passed on to the constructors for
L<IO::Socket::IP> (such as a timeout) or L<IO::Socket::SSL> (such as
certificate information). Which of these modules will be used is determined by
the C<ssl> parameter that was provided when instantiating the object. See the
relevant manpage for examples.

This method will C<croak()> if connection fails, so be sure to use C<eval()> if
you want to catch the error.

By default, the return value for C<connect()> will be the EPP E<lt>greetingE<gt>
frame returned by the server. Please note that the same caveat about blocking
applies to this method as to C<get_frame()> (see below).

If you want to get the greeting yourself, set C<$params{no_greeting}> to C<1>.

If TLS is enabled, then you can use C<%params> to configure a client certificate
and/or server certificate validation behaviour.

=cut

sub connect {
    my ($self, %params) = @_;

    croak('already connected') if ($self->connected);

    if (defined($self->{'sock'})) {
        $self->_connect_unix(%params);

    } else {
        $self->_connect_tcp(%params);

    }

    return ($params{'no_greeting'} ? 1 : $self->get_frame);
}

sub _connect_tcp {
    my ($self, %params) = @_;

    my $class = ($self->{'ssl'} == 1 ? 'IO::Socket::SSL' : 'IO::Socket::IP');

    $self->{'connection'} = $class->new(
        'PeerAddr' => $self->{'host'},
        'PeerPort' => $self->{'port'},
        'Proto'    => 'tcp',
        'Type'     => SOCK_STREAM,
        %params
    );

    if (!defined($self->{'connection'}) || ($@ && $@ ne '')) {
        chomp($@);
        $@ =~ s/^$class:? ?//;
        croak("Connection to $self->{'host'}:$self->{'port'} failed: $@");
    }

    return 1;
}

sub _connect_unix {
    my ($self, %params) = @_;

    $self->{'connection'} = IO::Socket::UNIX->new(
        'Peer' => $self->{'sock'},
        'Type' => SOCK_STREAM,
        %params
    );

    if (!defined($self->{'connection'}) || ($@ && $@ ne '')) {
        croak("Connection to $self->{'host'}:$self->{'port'} failed: $@");
    }

    return 1;
}

=pod

=head2 COMMUNICATING WITH THE SERVER

	my $answer = $epp->request($question);

This is a simple wrapper around C<get_frame()> and C<send_frame()> (see below).
This method accepts a "question" frame as an argument, sends it to the server,
and then returns the next frame the server sends back.

=cut

sub request {
    my ($self, $frame) = @_;
    return $self->get_frame if ($self->send_frame($frame));
}

=pod

=head2 GETTING A FRAME FROM THE SERVER

	my $frame = $epp->get_frame;

This method returns an EPP response frame from the server. This will be a
L<Net::EPP::Frame::Response> object unless the C<frames> argument to the
constructor was false, in which case it will be a string containing a blob of



( run in 1.532 second using v1.01-cache-2.11-cpan-39bf76dae61 )