Client.php 7.66 KB
Newer Older
1 2
<?php

3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
    /*	EPP Client class for PHP, Copyright 2005 CentralNic Ltd
        This program is free software; you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation; either version 2 of the License, or
        (at your option) any later version.

        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.

        You should have received a copy of the GNU General Public License
        along with this program; if not, write to the Free Software
        Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    */

    /**
     * A simple client class for the Extensible Provisioning Protocol (EPP)
     * @package Net_EPP
     * @version 0.0.4
     * @author Gavin Brown <gavin.brown@nospam.centralnic.com>
     * @revision $Id: Client.php,v 1.13 2010/10/21 11:55:07 gavin Exp $
     */
26
    require_once('Net/EPP/Protocol.php');
27

28
    $GLOBALS['Net_EPP_Client_Version'] = '0.0.6';
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60

    /**
     * A simple client class for the Extensible Provisioning Protocol (EPP)
     * @package Net_EPP
     */
    class Net_EPP_Client
    {

        /**
         * @var resource the socket resource, once connected
         */
        public $socket;
        /**
         * @var bool do output more debug messages
         */
        public $debug;

        /**
         * @var integer timeout to wait on commands
         */
        public $timeout;

        /**
         * constructor set initialize various objects
         * @param boolean set debugging on
         */
        public function __construct($debug = false)
        {
            $this->debug = $debug;
            $GLOBALS['debug'] = $debug;
            $this->socket = null;
        }
61

62 63 64 65 66 67 68
        /**
         * Establishes a connect to the server
         * This method establishes the connection to the server. If the connection was
         * established, then this method will call getFrame() and return the EPP <greeting>
         * frame which is sent by the server upon connection. If connection fails, then
         * an exception with a message explaining the error will be thrown and handled
         * in the calling code.
69 70 71 72 73 74
         * @param string   $host    the hostname
         * @param integer  $port    the TCP port
         * @param integer  $timeout the timeout in seconds
         * @param boolean  $ssl     whether to connect using SSL
         * @param resource $context a stream resource to use when setting up the socket connection
         *@param string $protocol whether to use TLS or SSL
75 76 77
         * @throws Exception on connection errors
         * @return a         string containing the server <greeting>
         */
78
        public function connect($host, $port = 700, $timeout = 1, $ssl = true, $context = null, $protocol = 'tls')
79 80 81 82
        {
            if ($this->debug) {
                syslog(LOG_INFO, "in connect");
            }
83 84
            
            $target = sprintf('%s://%s:%d', ($ssl === true ? $protocol : 'tcp'), $host, $port);
85 86 87
            if ($this->debug) {
                syslog(LOG_INFO, "connecting to {$target}");
            }
88
            
89 90 91 92 93 94 95 96 97 98 99 100 101
            if (is_resource($context)) {
                if ($this->debug) {
                    syslog(LOG_INFO, "using your provided context resource");
                }
                $result = stream_socket_client($target, $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $context);
            } else {
                $result = stream_socket_client($target, $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT);
            }
            if (is_resource($result)) {
                if ($errno == 0) {
                    if ($this->debug) {
                        $socketmeta = stream_get_meta_data($result);
                        if (isset($socketmeta['crypto'])) {
102
                            syslog(LOG_NOTICE, "socket opened with protocol ".$socketmeta['crypto']['protocol'].", cipher ".$socketmeta['crypto']['cipher_name'].", ".$socketmeta['crypto']['cipher_bits']." bits ".$socketmeta['crypto']['cipher_version']);
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
                        } else {
                            syslog(LOG_INFO, "socket opened without crypt");
                        }
                    }
                    // Set our socket
                    $this->socket = $result;
                } else {
                    throw new Exception("non errono 0 retrieved from socket connection: {$errno}");
                }
            } else {
                if ($result === false && $errno == 0) {
                    throw new Exception("Connection could not be opened due to socket problem.  Reasons can be unmatched peer name, tls not supported...");
                } else {
                    throw new Exception("Connection could not be opened: $errno $errstr");
                }
            }

            // Set stream timeout
            if (!stream_set_timeout($this->socket, $timeout)) {
                throw new Exception("Failed to set timeout on socket: $errstr (code $errno)");
            }
            $this->timeout = $timeout;
            $GLOBALS['timeout'] = $timeout;
126
            
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
            // Set blocking
            if (!stream_set_blocking($this->socket, 0)) {
                throw new Exception("Failed to set blocking on socket: $errstr (code $errno)");
            }
            if ($this->debug) {
                syslog(LOG_INFO, "trying to get frame from server");
            }
            return $this->getFrame();
        }

        /**
         * Get an EPP frame from the server.
         * This retrieves a frame from the server. Since the connection is blocking, this
         * method will wait until one becomes available. If the connection has been broken,
         * this method will return a string containing the XML from the server
         * @throws Exception on frame errors
         * @return a         string containing the frame
         */
        public function getFrame()
        {
            return Net_EPP_Protocol::getFrame($this->socket);
        }

        /**
         * Send an XML frame to the server.
         * This method sends an EPP frame to the server.
         * @param string the XML data to send
         * @throws Exception when it doesn't complete the write to the socket
         * @return boolean   the result of the fwrite() operation
         */
        public function sendFrame($xml)
        {
            return Net_EPP_Protocol::sendFrame($this->socket, $xml);
        }

        /**
         * a wrapper around sendFrame() and getFrame()
         * @param  string    $xml the frame to send to the server
         * @throws Exception when it doesn't complete the write to the socket
         * @return string    the frame returned by the server, or an error object
         */
        public function request($xml)
        {
            $res = $this->sendFrame($xml);
            return $this->getFrame();
        }

        /**
         * Close the connection.
         * This method closes the connection to the server. Note that the
         * EPP specification indicates that clients should send a <logout>
         * command before ending the session.
         * @return boolean the result of the fclose() operation
         */
        public function disconnect()
        {
            return @fclose($this->socket);
        }

        /**
         * ping the connection to check that it's up
         * @return boolean
         */
        public function ping()
        {
            return (!is_resource($this->socket) || feof($this->socket) ? false : true);
        }
    }