Protocol.php 4.39 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?php

/*	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
*/

/**
* Low-level functions useful for both EPP clients and servers
* @package Net_EPP
* @version 0.0.4
* @author Gavin Brown <gavin.brown@nospam.centralnic.com>
* @revision $Id: Protocol.php,v 1.4 2011/06/28 09:48:02 gavin Exp $
*/

/**
* Low-level functions useful for both EPP clients and servers
* @package Net_EPP
*/
class Net_EPP_Protocol {

33
34
35
36
37
	static function _fread_nb($socket,$length) {
		$result = '';

		// Loop reading and checking info to see if we hit timeout
		$info = stream_get_meta_data($socket);
38
39
		$time_start = microtime(true);

40
41
42
43
44
45
46
47
48
49
50
51
		while (!$info['timed_out'] && !feof($socket)) {
			// Try read remaining data from socket
			$buffer = @fread($socket,$length - strlen($result));
			// If the buffer actually contains something then add it to the result
			if ($buffer !== false) {
				$result .= $buffer;
				// If we hit the length we looking for, break
				if (strlen($result) == $length) {
					break;
				}
			} else {
				// Sleep 0.25s
52
				usleep(250000);
53
54
55
			}
			// Update metadata
			$info = stream_get_meta_data($socket);
56
			$time_end = microtime(true);
57
58
			if (($time_end - $time_start) > 10000000) {
				throw new exception('Timeout while reading from EPP Server');
59
			}
60
61
62
63
		}

		// Check for timeout
		if ($info['timed_out']) {
64
			throw new Exception('Timeout while reading data from socket');
65
66
67
68
69
		}

		return $result;
	}

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108

	static function _fwrite_nb($socket,$buffer,$length) {
		// Loop writing and checking info to see if we hit timeout
		$info = stream_get_meta_data($socket);
		$time_start = microtime(true);

		$pos = 0;
		while (!$info['timed_out'] && !feof($socket)) {
			// Some servers don't like alot of data, so keep it small per chunk
			$wlen = $length - $pos;
			if ($wlen > 1024) { $wlen = 1024; }
			// Try write remaining data from socket
			$written = @fwrite($socket,substr($buffer,$pos),$wlen);
			// If we read something, bump up the position
			if ($written && $written !== false) {
				$pos += $written;
				// If we hit the length we looking for, break
				if ($pos == $length) {
					break;
				}
			} else {
				// Sleep 0.25s
				usleep(250000);
			}
			// Update metadata
			$info = stream_get_meta_data($socket);
			$time_end = microtime(true);
			if (($time_end - $time_start) > 10000000) {
				throw new exception('Timeout while writing to EPP Server');
			}
		}
		// Check for timeout
		if ($info['timed_out']) {
			throw new Exception('Timeout while writing data to socket');
		}

		return $pos;
	}

109
110
111
	/**
	* get an EPP frame from the remote peer
	* @param resource $socket a socket connected to the remote peer
112
113
	* @throws Exception on frame errors.
	* @return string the frame
114
115
	*/
	static function getFrame($socket) {
116
		// Read header
117
		$hdr = Net_EPP_Protocol::_fread_nb($socket,4);
118

119
		// Unpack first 4 bytes which is our length
120
121
122
		$unpacked = unpack('N', $hdr);
		$length = $unpacked[1];
		if ($length < 5) {
123
			throw new Exception(sprintf('Got a bad frame header length of %d bytes from peer', $length));
124
125

		} else {
126
			$length -= 4; // discard the length of the header itself
127
128
			// Read frame
			return Net_EPP_Protocol::_fread_nb($socket,$length);
129
130
131
132
133
134
135
		}
	}

	/**
	* send an EPP frame to the remote peer
	* @param resource $socket a socket connected to the remote peer
	* @param string $xml the XML to send
136
137
	* @throws Exception when it doesn't complete the write to the socket
	* @return the amount of bytes written to the frame
138
139
	*/
	static function sendFrame($socket, $xml) {
140
141
		// Grab XML length & add on 4 bytes for the counter
		$length = strlen($xml) + 4;
142
		$res = Net_EPP_Protocol::_fwrite_nb($socket, pack('N',$length) . $xml,$length);
143
144
		// Check our write matches
		if ($length != $res) {
145
			throw new Exception("Short write when sending XML");
146
147
148
		}

		return $res;
149
150
	}
}