Skip to content

Commit

Permalink
Implement TCP connection
Browse files Browse the repository at this point in the history
  • Loading branch information
ben221199 committed Aug 8, 2024
1 parent a56340e commit 5693d8d
Show file tree
Hide file tree
Showing 11 changed files with 219 additions and 147 deletions.
37 changes: 20 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,38 +13,41 @@ This yocLibrary enables your project to send and receive with EPP (Extensible Pr

## Usage

### Serializing
### Reading

```php
use YOCLIB\EPP\EPPDocumentHelper;
use YOCLIB\EPP\Connections\EPPTCPConnection;
use YOCLIB\EPP\Elements\EPPEppElement;

$doc = EPPDocumentHelper::createEPPDocument();

$epp = $doc->createElementNS('urn:ietf:params:xml:ns:epp-1.0','epp');

$hello = $doc->createElementNS('urn:ietf:params:xml:ns:epp-1.0','hello');
$conn = new EPPTCPConnection(new SIDNTest());

$epp->appendChild($hello);
$doc = $conn->readDocument();

$doc->appendChild($epp);
/**@var EPPEppElement $epp*/
$epp = $doc->documentElement;

$xml = $doc->saveXML();
$hello = $epp->getHello();
```

### Deserializing
### Writing

```php
use YOCLIB\EPP\EPPDocumentHelper;
use YOCLIB\EPP\Elements\EPPEppElement;

$xml = '<?xml version="1.0" encoding="UTF-8" standalone="no"?><epp xmlns="urn:ietf:params:xml:ns:epp-1.0"><hello/></epp>';
use YOCLIB\EPP\Connections\EPPTCPConnection;
use YOCLIB\EPP\Registries\SIDNTest;

$doc = EPPDocumentHelper::createEPPDocument();

$doc->loadXML($xml);
$epp = $doc->createElementNS('urn:ietf:params:xml:ns:epp-1.0','epp');

/**@var EPPEppElement $epp*/
$epp = $doc->documentElement;
$hello = $doc->createElementNS('urn:ietf:params:xml:ns:epp-1.0','hello');

$hello = $epp->getHello();
$epp->appendChild($hello);

$doc->appendChild($epp);

$conn = new EPPTCPConnection(new SIDNTest());

$xml = $conn->writeDocument($doc);
```
24 changes: 24 additions & 0 deletions src/Connections/EPPBaseConnection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php
namespace YOCLIB\EPP\Connections;

use YOCLIB\EPP\EPPConnection;
use YOCLIB\EPP\EPPDocument;
use YOCLIB\EPP\EPPDocumentHelper;

abstract class EPPBaseConnection implements EPPConnection {

public function readDocument(): EPPDocument{
$doc = EPPDocumentHelper::createEPPDocument();
$doc->loadXML($this->readXML());
return $doc;
}

public abstract function readXML(): ?string;

public function writeDocument(EPPDocument $doc): void{
$this->writeXML($doc->saveXML());
}

public abstract function writeXML(string $xml): void;

}
80 changes: 80 additions & 0 deletions src/Connections/EPPTCPConnection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php
namespace YOCLIB\EPP\Connections;

use RuntimeException;
use YOCLIB\EPP\EPPConnection;
use YOCLIB\EPP\EPPRegistry;

class EPPTCPConnection extends EPPBaseConnection implements EPPConnection {

private $registry;
private $socket;

public function __construct(EPPRegistry $registry){
$this->registry = $registry;
$this->open();
}

/**
* Decode bytes to 32-bit integer
* @param string $data
* @return int
*/
private function decodeInteger(string $data): int{
return unpack('N',substr($data,0,4))[1] ?? -1;
}

/**
* Encode 32-bit integer to bytes
* @param int $integer
* @return string
*/
private function encodeInteger(int $integer): string{
return pack('N',$integer);
}

/**
* Ensure if connection is not closed
*/
private function ensureConnection(): void{
if($this->isClosed()){
throw new RuntimeException('Connection closed');
}
}

public function close(): bool{
$this->ensureConnection();
return fclose($this->socket);
}

/**
* Check if connection is closed
* @return bool
*/
public function isClosed(): bool{
return !is_resource($this->socket);
}

public function open(): bool{
$host = $this->registry->getHost();
$hostname = parse_url($host,PHP_URL_SCHEME).'://'.parse_url($host,PHP_URL_HOST);
$this->socket = fsockopen($hostname,$this->registry->getPort());
return $this->socket!==false;
}

public function readXML(): ?string{
$this->ensureConnection();
$length = $this->decodeInteger(fread($this->socket,4))-4;
if($length<0){
return null;
}
return fread($this->socket,$length);
}

public function writeXML(string $xml): void{
$this->ensureConnection();
$length = strlen($xml)+4;
fwrite($this->socket,$this->encodeInteger($length).$xml);
}

}
141 changes: 14 additions & 127 deletions src/EPPConnection.php
Original file line number Diff line number Diff line change
@@ -1,133 +1,20 @@
<?php
namespace YOCLIB\EPP;

/**
* Class EPPConnection
* @package YOCLIB\EPP
*/
class EPPConnection{
interface EPPConnection{

// /**
// * @var resource $resource
// */
// private $resource;
//
// /**
// * EPPConnection constructor.
// * @param resource $resource
// */
// public function __construct($resource){
// $this->resource = $resource;
// }
//
// /**
// * Close the connection
// */
// public function close(){
// fclose($this->resource);
// }
//
// /**
// * Convert document elements
// * @param EPPDocument|DOMDocument $doc
// * @return EPPDocument|DOMDocument|null
// */
// private function convertDOM($doc){
// return $this->convertElement($doc,$doc->documentElement);
// }
//
// /**
// * @param EPPDocument|DOMDocument $doc
// * @param $element
// * @return EPPDocument|DOMDocument|null
// */
// private function convertElement($doc,$element){
// foreach($element->childNodes AS $childNode){
// if($childNode instanceof DOMElement){
// $this->convertElement($doc,$childNode);
// }
// }
// return EPPSchemaHelper::convertElement($doc,$element);
// }
//
// /**
// * Decode bytes to 32-bit integer
// * @param string $data
// * @return int
// */
// private function decodeInteger($data){
// $int = unpack('N',substr($data,0,4));
// return $int[1];
// }
//
// /**
// * Encode 32-bit integer to bytes
// * @param int $data
// * @return string
// */
// private function encodeInteger($data){
// $int = pack('N',intval($data));
// return $int;
// }
//
// /**
// * Ensure if connection is not closed
// */
// private function ensureConnection(){
// if(!$this->isClosed()){
// throw new RuntimeException("Connection closed");
// }
// }
//
// /**
// * Check if connection is closed
// * @return bool
// */
// public function isClosed(){
// return is_resource($this->resource);
// }
//
// /**
// * Read DOM
// * @return EPPDocument|DOMDocument|null
// */
// public function readDOM(){
// $doc = new EPPDocument;
// $xml = $this->readXML();
// $doc->loadXML($xml);
// return $this->convertDOM($doc) ?? $doc;
// }
//
// /**
// * Read XML
// * @return string|null
// */
// public function readXML(){
// $this->ensureConnection();
// $length = $this->decodeInteger(fread($this->resource,4))-4;
// if($length<0){
// return null;
// }
// return fread($this->resource,$length);
// }
//
// /**
// * Write DOM
// * @param EPPDocument|DOMDocument $doc
// */
// public function writeDOM($doc){
// $xml = $doc->saveXML();
// $this->writeXML($xml);
// }
//
// /**
// * Write XML
// * @param string $xml
// */
// public function writeXML($xml){
// $this->ensureConnection();
// $length = strlen($xml)+4;
// fwrite($this->resource,$this->encodeInteger($length).$xml);
// }
public function close(): bool;

public function isClosed(): bool;

public function open(): bool;

public function readDocument(): EPPDocument;

public function readXML(): ?string;

public function writeDocument(EPPDocument $doc): void;

public function writeXML(string $xml);

}
6 changes: 4 additions & 2 deletions src/EPPDocumentHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@

class EPPDocumentHelper{

public const CONTENT_TYPE = 'application/epp+xml';

/**
* @return EPPDocument
*/
public static function createEPPDocument(): EPPDocument{
return new class(null,'application/epp+xml') extends XMLDocument implements EPPDocument{
return new class(null,self::CONTENT_TYPE) extends XMLDocument implements EPPDocument{

public function createElementNS(?string $namespace, string $qualifiedName, $options = null){
$element = parent::createElementNS($namespace, $qualifiedName, $options);
if($this->getContentType()==='application/epp+xml'){
if($this->getContentType()===EPPDocumentHelper::CONTENT_TYPE){
WhatWG::validate_and_extract($namespace,$qualifiedName,$prefix,$lname);
return EPPElementImpl::__createElementNS($this, $namespace, $lname, $prefix) ?? $element;
}
Expand Down
28 changes: 28 additions & 0 deletions src/EPPRegistry.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php
namespace YOCLIB\EPP;

abstract class EPPRegistry{

private $host;
private $port;

public function __construct(string $host,int $port){
$this->host = $host;
$this->port = $port;
}

/**
* @return string
*/
public function getHost(): string{
return $this->host;
}

/**
* @return int
*/
public function getPort(): int{
return $this->port;
}

}
12 changes: 12 additions & 0 deletions src/Registries/EURID.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php
namespace YOCLIB\EPP\Registries;

use YOCLIB\EPP\EPPRegistry;

class EURID extends EPPRegistry {

public function __construct(){
parent::__construct('ssl://epp.registry.eu',700);
}

}
12 changes: 12 additions & 0 deletions src/Registries/EURIDTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php
namespace YOCLIB\EPP\Registries;

use YOCLIB\EPP\EPPRegistry;

class EURIDTest extends EPPRegistry {

public function __construct(){
parent::__construct('ssl://epp.tryout.registry.eu',700);
}

}
Loading

0 comments on commit 5693d8d

Please sign in to comment.