Protocol.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. <?php
  2. /* EPP Client class for PHP, Copyright 2005 CentralNic Ltd
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  14. */
  15. /**
  16. * Low-level functions useful for both EPP clients and servers
  17. * @package Net_EPP
  18. * @version 0.0.4
  19. * @author Gavin Brown <gavin.brown@nospam.centralnic.com>
  20. * @revision $Id: Protocol.php,v 1.4 2011/06/28 09:48:02 gavin Exp $
  21. */
  22. /**
  23. * Low-level functions useful for both EPP clients and servers
  24. * @package Net_EPP
  25. */
  26. class Net_EPP_Protocol {
  27. static function _fread_nb($socket,$length) {
  28. $result = '';
  29. // Loop reading and checking info to see if we hit timeout
  30. $info = stream_get_meta_data($socket);
  31. $time_start = microtime(true);
  32. while (!$info['timed_out'] && !feof($socket)) {
  33. // Try read remaining data from socket
  34. $buffer = @fread($socket,$length - strlen($result));
  35. // If the buffer actually contains something then add it to the result
  36. if ($buffer !== false) {
  37. $result .= $buffer;
  38. // If we hit the length we looking for, break
  39. if (strlen($result) == $length) {
  40. break;
  41. }
  42. } else {
  43. // Sleep 0.25s
  44. usleep(250000);
  45. }
  46. // Update metadata
  47. $info = stream_get_meta_data($socket);
  48. $time_end = microtime(true);
  49. if (($time_end - $time_start) > 10000000) {
  50. throw new exception('Timeout while reading from EPP Server');
  51. }
  52. }
  53. // Check for timeout
  54. if ($info['timed_out']) {
  55. throw new Exception('Timeout while reading data from socket');
  56. }
  57. return $result;
  58. }
  59. static function _fwrite_nb($socket,$buffer,$length) {
  60. // Loop writing and checking info to see if we hit timeout
  61. $info = stream_get_meta_data($socket);
  62. $time_start = microtime(true);
  63. $pos = 0;
  64. while (!$info['timed_out'] && !feof($socket)) {
  65. // Some servers don't like alot of data, so keep it small per chunk
  66. $wlen = $length - $pos;
  67. if ($wlen > 1024) { $wlen = 1024; }
  68. // Try write remaining data from socket
  69. $written = @fwrite($socket,substr($buffer,$pos),$wlen);
  70. // If we read something, bump up the position
  71. if ($written && $written !== false) {
  72. $pos += $written;
  73. // If we hit the length we looking for, break
  74. if ($pos == $length) {
  75. break;
  76. }
  77. } else {
  78. // Sleep 0.25s
  79. usleep(250000);
  80. }
  81. // Update metadata
  82. $info = stream_get_meta_data($socket);
  83. $time_end = microtime(true);
  84. if (($time_end - $time_start) > 10000000) {
  85. throw new exception('Timeout while writing to EPP Server');
  86. }
  87. }
  88. // Check for timeout
  89. if ($info['timed_out']) {
  90. throw new Exception('Timeout while writing data to socket');
  91. }
  92. return $pos;
  93. }
  94. /**
  95. * get an EPP frame from the remote peer
  96. * @param resource $socket a socket connected to the remote peer
  97. * @throws Exception on frame errors.
  98. * @return string the frame
  99. */
  100. static function getFrame($socket) {
  101. // Read header
  102. $hdr = Net_EPP_Protocol::_fread_nb($socket,4);
  103. // Unpack first 4 bytes which is our length
  104. $unpacked = unpack('N', $hdr);
  105. $length = $unpacked[1];
  106. if ($length < 5) {
  107. throw new Exception(sprintf('Got a bad frame header length of %d bytes from peer', $length));
  108. } else {
  109. $length -= 4; // discard the length of the header itself
  110. // Read frame
  111. return Net_EPP_Protocol::_fread_nb($socket,$length);
  112. }
  113. }
  114. /**
  115. * send an EPP frame to the remote peer
  116. * @param resource $socket a socket connected to the remote peer
  117. * @param string $xml the XML to send
  118. * @throws Exception when it doesn't complete the write to the socket
  119. * @return the amount of bytes written to the frame
  120. */
  121. static function sendFrame($socket, $xml) {
  122. // Grab XML length & add on 4 bytes for the counter
  123. $length = strlen($xml) + 4;
  124. $res = Net_EPP_Protocol::_fwrite_nb($socket, pack('N',$length) . $xml,$length);
  125. // Check our write matches
  126. if ($length != $res) {
  127. throw new Exception("Short write when sending XML. Length of the XML: " . $length . " Response length: " . $res);
  128. }
  129. return $res;
  130. }
  131. }