<?php /** * base include file for SimpleTest * @package SimpleTest * @subpackage MockObjects * @version $Id: socket.php 1723 2008-04-08 00:34:10Z lastcraft $ */ /**#@+ * include SimpleTest files */ require_once(dirname(__FILE__) . '/compatibility.php'); /**#@-*/ /** * Stashes an error for later. Useful for constructors * until PHP gets exceptions. * @package SimpleTest * @subpackage WebTester */ class SimpleStickyError { var $_error = 'Constructor not chained'; /** * Sets the error to empty. * @access public */ function SimpleStickyError() { $this->_clearError(); } /** * Test for an outstanding error. * @return boolean True if there is an error. * @access public */ function isError() { return ($this->_error != ''); } /** * Accessor for an outstanding error. * @return string Empty string if no error otherwise * the error message. * @access public */ function getError() { return $this->_error; } /** * Sets the internal error. * @param string Error message to stash. * @access protected */ function _setError($error) { $this->_error = $error; } /** * Resets the error state to no error. * @access protected */ function _clearError() { $this->_setError(''); } } /** * Wrapper for TCP/IP socket. * @package SimpleTest * @subpackage WebTester */ class SimpleSocket extends SimpleStickyError { var $_handle; var $_is_open = false; var $_sent = ''; var $lock_size; /** * Opens a socket for reading and writing. * @param string $host Hostname to send request to. * @param integer $port Port on remote machine to open. * @param integer $timeout Connection timeout in seconds. * @param integer $block_size Size of chunk to read. * @access public */ function SimpleSocket($host, $port, $timeout, $block_size = 255) { $this->SimpleStickyError(); if (! ($this->_handle = $this->_openSocket($host, $port, $error_number, $error, $timeout))) { $this->_setError("Cannot open [$host:$port] with [$error] within [$timeout] seconds"); return; } $this->_is_open = true; $this->_block_size = $block_size; SimpleTestCompatibility::setTimeout($this->_handle, $timeout); } /** * Writes some data to the socket and saves alocal copy. * @param string $message String to send to socket. * @return boolean True if successful. * @access public */ function write($message) { if ($this->isError() || ! $this->isOpen()) { return false; } $count = fwrite($this->_handle, $message); if (! $count) { if ($count === false) { $this->_setError('Cannot write to socket'); $this->close(); } return false; } fflush($this->_handle); $this->_sent .= $message; return true; } /** * Reads data from the socket. The error suppresion * is a workaround for PHP4 always throwing a warning * with a secure socket. * @return integer/boolean Incoming bytes. False * on error. * @access public */ function read() { if ($this->isError() || ! $this->isOpen()) { return false; } $raw = @fread($this->_handle, $this->_block_size); if ($raw === false) { $this->_setError('Cannot read from socket'); $this->close(); } return $raw; } /** * Accessor for socket open state. * @return boolean True if open. * @access public */ function isOpen() { return $this->_is_open; } /** * Closes the socket preventing further reads. * Cannot be reopened once closed. * @return boolean True if successful. * @access public */ function close() { $this->_is_open = false; return fclose($this->_handle); } /** * Accessor for content so far. * @return string Bytes sent only. * @access public */ function getSent() { return $this->_sent; } /** * Actually opens the low level socket. * @param string $host Host to connect to. * @param integer $port Port on host. * @param integer $error_number Recipient of error code. * @param string $error Recipoent of error message. * @param integer $timeout Maximum time to wait for connection. * @access protected */ function _openSocket($host, $port, &$error_number, &$error, $timeout) { return @fsockopen($host, $port, $error_number, $error, $timeout); } } /** * Wrapper for TCP/IP socket over TLS. * @package SimpleTest * @subpackage WebTester */ class SimpleSecureSocket extends SimpleSocket { /** * Opens a secure socket for reading and writing. * @param string $host Hostname to send request to. * @param integer $port Port on remote machine to open. * @param integer $timeout Connection timeout in seconds. * @access public */ function SimpleSecureSocket($host, $port, $timeout) { $this->SimpleSocket($host, $port, $timeout); } /** * Actually opens the low level socket. * @param string $host Host to connect to. * @param integer $port Port on host. * @param integer $error_number Recipient of error code. * @param string $error Recipient of error message. * @param integer $timeout Maximum time to wait for connection. * @access protected */ function _openSocket($host, $port, &$error_number, &$error, $timeout) { return parent::_openSocket("tls://$host", $port, $error_number, $error, $timeout); } } ?>