metaregistrar / php-epp-client

Object-oriented PHP EPP Client
https://www.metaregistrar.com/docs/
MIT License
210 stars 153 forks source link

getCheckedDomains returns empty #270

Closed matbcvo closed 3 years ago

matbcvo commented 4 years ago

$response->getCheckedDomains(); returns empty, though EPP request (checking two domains) was successful. Could someone explain me what's the problem?

PHP code

<?php
require("autoloader.php");

use Metaregistrar\EPP\eppConnection;
use Metaregistrar\EPP\eppException;
use Metaregistrar\EPP\eppCheckResponse;
use Metaregistrar\EPP\eppCheckDomainRequest;
use Metaregistrar\EPP\eppCheckDomainResponse;
use Metaregistrar\EPP\eppDomain;
use Metaregistrar\EPP\eppContact;
use Metaregistrar\EPP\eppHost;
use Metaregistrar\EPP\eppContactHandle;
use Metaregistrar\EPP\eppContactPostalInfo;
use Metaregistrar\EPP\eppCheckContactRequest;
use Metaregistrar\EPP\eppCheckHostRequest;
use Metaregistrar\EPP\eppCreateDomainRequest;
use Metaregistrar\EPP\eppCreateHostRequest;
use Metaregistrar\EPP\eppPollRequest;
use Metaregistrar\EPP\eppPollResponse;

$conn = new Metaregistrar\EPP\eppConnection(true);
$conn->setHostname('tls://testepp.internet.ee');
$conn->setPort(700);
$conn->setUsername('XXXXXXXXXXXXX');
$conn->setPassword('XXXXXXXXXXXXX');
$conn->enableCertification('XXXXXXXXXXXXX.pem', null);
$conn->addDefaultNamespace2('https://epp.tld.ee/schema/epp-ee-1.0.xsd', 'xmlns');
$conn->setServices(array(
        'https://epp.tld.ee/schema/domain-eis-1.0.xsd' => 'domain',
        'https://epp.tld.ee/schema/contact-ee-1.1.xsd' => 'contact',
));

try {
        // Connect and login to the EPP server
        if ($conn->login()) {
                $domains = ['example.ee', 'example2.ee'];
                checkdomains($conn, $domains);
                $conn->logout();
        }
} catch (eppException $e) {
    echo "ERROR: " . $e->getMessage()."\n";
    echo $e->getLastCommand();
    echo "\n\n";
}
/**
 * @param $conn eppConnection
 * @param $domains array of domain names
 */
function checkdomains($conn, $domains) {
    // Create request to be sent to EPP service
    $check = new eppCheckDomainRequest($domains);
    // Write request to EPP service, read and check the results
    if ($response = $conn->request($check)) {
        /* @var $response eppCheckDomainResponse */
        // Walk through the results
        $checks = $response->getCheckedDomains();
        print_r($checks);
        foreach ($checks as $check) {
            echo $check['domainname'] . " is " . ($check['available'] ? 'free' : 'taken');
            if ($check['available']) {
                echo ' (' . $check['reason'] .')';
            }
            echo "\n";
        }
    }
}
?>

Debug

==== LOG ====
-----Connection made-----2020-06-03 21:11:20-----
Stream opened with protocol TLSv1.2, cipher ECDHE-RSA-AES128-GCM-SHA256, 128 bits TLSv1.2
-----END-----2020-06-03 21:11:20-----

-----WRITE-----2020-06-03 21:11:20-----
<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd">
  <command>
    <login>
      <clID>XXXXXXXXXXXXXXXX</clID>
      <pw>XXXXXXXXXXXXXXXX</pw>
      <options>
        <version>1.0</version>
        <lang>en</lang>
      </options>
      <svcs>
        <objURI>https://epp.tld.ee/schema/domain-eis-1.0.xsd</objURI>
        <objURI>https://epp.tld.ee/schema/contact-ee-1.1.xsd</objURI>
      </svcs>
    </login>
    <clTRID>5ed7f5d857e62</clTRID>
  </command>
</epp>

-----END-----2020-06-03 21:11:20-----

-----READ-----2020-06-03 21:11:20-----
<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="lib/schemas/epp-ee-1.0.xsd">
  <response>
    <result code="1000">
      <msg>Command completed successfully</msg>
    </result>
    <trID>
      <clTRID>5ed7f5d857e62</clTRID>
      <svTRID>ccReg-9726559372</svTRID>
    </trID>
  </response>
</epp>

-----END-----2020-06-03 21:11:20-----

-----LOGIN-----2020-06-03 21:11:20-----
Logged in
-----END-----2020-06-03 21:11:20-----

-----WRITE-----2020-06-03 21:11:20-----
<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd" xmlns:domain="https://epp.tld.ee/schema/domain-eis-1.0.xsd" xmlns:contact="https://epp.tld.ee/schema/contact-ee-1.1.xsd">
  <command>
    <check>
      <domain:check>
        <domain:name>example.ee</domain:name>
        <domain:name>example2.ee</domain:name>
      </domain:check>
    </check>
    <clTRID>5ed7f5d8ad8c7</clTRID>
  </command>
</epp>

-----END-----2020-06-03 21:11:20-----

-----READ-----2020-06-03 21:11:21-----
<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="lib/schemas/epp-ee-1.0.xsd">
  <response>
    <result code="1000">
      <msg>Command completed successfully</msg>
    </result>
    <resData>
      <domain:chkData xmlns:domain="https://epp.tld.ee/schema/domain-eis-1.0.xsd">
        <domain:cd>
          <domain:name avail="1">example.ee</domain:name>
        </domain:cd>
        <domain:cd>
          <domain:name avail="0">example2.ee</domain:name>
          <domain:reason>in use</domain:reason>
        </domain:cd>
      </domain:chkData>
    </resData>
    <trID>
      <clTRID>5ed7f5d8ad8c7</clTRID>
      <svTRID>ccReg-2459499613</svTRID>
    </trID>
  </response>
</epp>

-----END-----2020-06-03 21:11:21-----

-----WRITE-----2020-06-03 21:11:21-----
<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd" xmlns:domain="https://epp.tld.ee/schema/domain-eis-1.0.xsd" xmlns:contact="https://epp.tld.ee/schema/contact-ee-1.1.xsd">
  <command>
    <logout></logout>
    <clTRID>5ed7f5d922681</clTRID>
  </command>
</epp>

-----END-----2020-06-03 21:11:21-----

-----READ-----2020-06-03 21:11:21-----
<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="lib/schemas/epp-ee-1.0.xsd">
  <response>
    <result code="1500">
      <msg>Command completed successfully; ending session</msg>
    </result>
    <trID>
      <clTRID>5ed7f5d922681</clTRID>
      <svTRID>ccReg-9567716102</svTRID>
    </trID>
  </response>
</epp>

-----END-----2020-06-03 21:11:21-----

-----LOGOUT-----2020-06-03 21:11:21-----
Logged out
-----END-----2020-06-03 21:11:21-----

-----DISCONNECT-----2020-06-03 21:11:21-----
Disconnected
-----END-----2020-06-03 21:11:21-----

https://github.com/internetee/registry/blob/master/doc/epp_examples.md#epp-domain-with-valid-domain-checks-a-domain

metaregistrar commented 4 years ago

The .EE registry has a different xmlns:domain definition, not standard epp

<domain:chkData xmlns:domain="https://epp.tld.ee/schema/domain-eis-1.0.xsd">

I see that they also have their own xmlns:epp and xmlns:contact definitions.

<epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd" xmlns:domain="https://epp.tld.ee/schema/domain-eis-1.0.xsd" xmlns:contact="https://epp.tld.ee/schema/contact-ee-1.1.xsd">

Since the EPP library expects the standard urn:ietf:params:xml:ns:domain-1.0, urn:ietf:params:xml:ns:contact-1.0 and urn:ietf:params:xml:ns:host-1.0 definitions, the XPATH queries that retrieve the data will fail.

In this case, you will have to define these extensions in the Protocols/EPP/eppExtensions directory, and create matching eppResponses so that the XPATH statements will not fail.

Please try this first, after creating the eppConnection:

$conn->setServices([
            'https://epp.tld.ee/schema/epp-ee-1.0.xsd' => '',
            'https://epp.tld.ee/schema/domain-eis-1.0.xsd' => 'domain',
            'https://epp.tld.ee/schema/contact-ee-1.1.xsd => 'contact'
        ]);

Maybe that will be a quick fix to solve the problem

matbcvo commented 4 years ago

Thank you for reply. I updated php-epp-client to latest version (1.0.10). When I add this after creating the eppConnection:

$conn->setServices([
            'https://epp.tld.ee/schema/epp-ee-1.0.xsd' => '',
            'https://epp.tld.ee/schema/domain-eis-1.0.xsd' => 'domain',
            'https://epp.tld.ee/schema/contact-ee-1.1.xsd' => 'contact'
        ]);

Then I am getting PHP error.

ERROR: Error 2001: 2:0: ERROR: Element '{https://epp.tld.ee/schema/epp-ee-1.0.xsd}epp', attribute 'xmlns:': The attribute 'xmlns:' is not allowed.
<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="lib/schemas/epp-ee-1.0.xsd">
  <response>
    <result code="2001">
      <msg lang="en">2:0: ERROR: Element '{https://epp.tld.ee/schema/epp-ee-1.0.xsd}epp', attribute 'xmlns:': The attribute 'xmlns:' is not allowed.</msg>
    </result>
    <trID>
      <clTRID>5eda8e85cc830</clTRID>
      <svTRID>ccReg-0853822956</svTRID>
    </trID>
  </response>
</epp>

PHP Fatal error:  Uncaught Metaregistrar\EPP\eppException: Error 2001: 2:0: ERROR: Element '{https://epp.tld.ee/schema/epp-ee-1.0.xsd}epp', attribute 'xmlns:': The attribute 'xmlns:' is not allowed. in /Protocols/EPP/eppResponses/eppResponse.php:188
Stack trace:
#0 /Protocols/EPP/eppConnection.php(440): Metaregistrar\EPP\eppResponse->Success()
#1 /Protocols/EPP/eppConnection.php(409): Metaregistrar\EPP\eppConnection->request(Object(Metaregistrar\EPP\eppLogoutRequest))
#2 /Protocols/EPP/eppConnection.php(257): Metaregistrar\EPP\eppConnection->logout()
#3 [internal function]: Metaregistrar\EPP\eppConnection->__destruct()
#4 {main}
  thrown in /Protocols/EPP/eppResponses/eppResponse.php on line 188

Also... I created Protocols/EPP/eppExtensions/eif/eppResponses/eifEppCheckDomainResponse.php file (with getCheckedDomains method) and used that xPath query: /epp:epp/epp:response/epp:resData/domain:chkData/domain:cd And it returns:

DOMNodeList Object
(
    [length] => 0
)

Which means xPath query is not correct, but looks correct for me... Any ideas?

eifEppCheckDomainResponse.php

<?php
namespace Metaregistrar\EPP;

class eifEppCheckDomainResponse extends eppCheckDomainResponse {
    function __construct() {
        parent::__construct();
    }
    /**
     *
     * @return array of checked domains with status true/false
     */
    public function getCheckedDomains() {
      $result = null;
        if ($this->getResultCode() == self::RESULT_SUCCESS) {
            $result = array();
            $xpath = $this->xPath();
            $domains = $xpath->query('/epp:epp/epp:response/epp:resData/domain:chkData/domain:cd');
            print_r($domains);
            foreach ($domains as $domain) {
                $childs = $domain->childNodes;
                $checkeddomain = array('domainname' => null, 'available' => false, 'reason' => null);
                foreach ($childs as $child) {
                    if ($child instanceof DOMElement) {
                        if ($child->localName=='name') {
                            $available = $child->getAttribute('avail');
                            switch ($available) {
                                case '0':
                                case 'false':
                                    $checkeddomain['available'] = false;
                                    break;
                                case '1':
                                case 'true':
                                    $checkeddomain['available'] = true;
                                    break;
                            }
                            $checkeddomain['domainname'] = $child->nodeValue;
                        }
                        if ($child->localName=='reason') {
                            $checkeddomain['reason'] = $child->nodeValue;
                        }
                    }
                }
                $result[] = $checkeddomain;
            }
        }
        return ($result);
    }
}
include_once(dirname(__FILE__) . '/Protocols/EPP/eppExtensions/eif/eppResponses/eifEppCheckDomainResponse.php');
$conn->addCommandResponse('Metaregistrar\EPP\eppCheckDomainRequest', 'Metaregistrar\EPP\eifEppCheckDomainResponse');
matbcvo commented 3 years ago

I checked xPath query using http://xpather.com/ website and it said Error: Prefix 'epp' has not been declared.

/epp:epp/epp:response/epp:resData/domain:chkData/domain:cd

-----READ-----2020-09-15 15:28:00-----
<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="lib/schemas/epp-ee-1.0.xsd">
  <response>
    <result code="1000">
      <msg>Command completed successfully</msg>
    </result>
    <resData>
      <domain:chkData xmlns:domain="https://epp.tld.ee/schema/domain-eis-1.0.xsd">
        <domain:cd>
          <domain:name avail="1">elikom.ee</domain:name>
        </domain:cd>
        <domain:cd>
          <domain:name avail="1">elikom2.ee</domain:name>
        </domain:cd>
      </domain:chkData>
    </resData>
    <trID>
      <clTRID>5f60c16033b6d</clTRID>
      <svTRID>ccReg-8280313710</svTRID>
    </trID>
  </response>
</epp>

-----END-----2020-09-15 15:28:00-----

Seems because server response does not have epp namespace declared. This xPath query works when I add xmlns:epp="https://epp.tld.ee/schema/epp-ee-1.0.xsd" So it looks like this: <epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd" xmlns:epp="https://epp.tld.ee/schema/epp-ee-1.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="lib/schemas/epp-ee-1.0.xsd">

http://xpather.com/HfULSQBI (without epp namespace) http://xpather.com/PO6PmLeM (with epp namespace)

I tried like that:

$xpath = $this->xPath();
$xpath->registerNamespace('epp', 'https://epp.tld.ee/schema/epp-ee-1.0.xsd');
$domains = $xpath->query('/epp:epp/epp:response/epp:resData/domain:chkData/domain:cd');

Still doesn't work.

Have any idea how to add epp namespace declaration to server response?

Request (to EPP server) have epp namespace declared.

-----WRITE-----2020-09-15 15:28:00-----
<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd" xmlns:epp="https://epp.tld.ee/schema/epp-ee-1.0.xsd" xmlns:domain="https://epp.tld.ee/schema/domain-eis-1.0.xsd" xmlns:contact="https://epp.tld.ee/schema/contact-ee-1.1.xsd" xmlns:eif="http://internet.ee">
  <command>
    <check>
      <domain:check>
        <domain:name>elikom.ee</domain:name>
        <domain:name>elikom2.ee</domain:name>
      </domain:check>
    </check>
    <clTRID>5f60c16033b6d</clTRID>
  </command>
</epp>

-----END-----2020-09-15 15:28:00-----
metaregistrar commented 3 years ago

The correct way to add an extension is to add it as a directory to the Protocols/EPP/eppExtensions directory.

In this directory you can create the files that are needed to set the correct namespaces. See the other extensions in this directory for examples how to use it.