Completed
Push — 3.5 ( 1a9180...1bec8a )
by Daniel
24s
created

SimpleSocket::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 8
nc 2
nop 4
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 *  base include file for SimpleTest
4
 *  @package    SimpleTest
5
 *  @subpackage MockObjects
6
 *  @version    $Id: socket.php 1723 2008-04-08 00:34:10Z lastcraft $
7
 */
8
9
/**#@+
10
 * include SimpleTest files
11
 */
12
require_once(dirname(__FILE__) . '/compatibility.php');
13
/**#@-*/
14
15
/**
16
 *    Stashes an error for later. Useful for constructors
17
 *    until PHP gets exceptions.
18
 *    @package SimpleTest
19
 *    @subpackage WebTester
20
 */
21
class SimpleStickyError {
22
    var $_error = 'Constructor not chained';
23
24
    /**
25
     *    Sets the error to empty.
26
     *    @access public
27
     */
28
    function SimpleStickyError() {
29
        $this->_clearError();
30
    }
31
32
    /**
33
     *    Test for an outstanding error.
34
     *    @return boolean           True if there is an error.
35
     *    @access public
36
     */
37
    function isError() {
38
        return ($this->_error != '');
39
    }
40
41
    /**
42
     *    Accessor for an outstanding error.
43
     *    @return string     Empty string if no error otherwise
44
     *                       the error message.
45
     *    @access public
46
     */
47
    function getError() {
48
        return $this->_error;
49
    }
50
51
    /**
52
     *    Sets the internal error.
53
     *    @param string       Error message to stash.
54
     *    @access protected
55
     */
56
    function _setError($error) {
57
        $this->_error = $error;
58
    }
59
60
    /**
61
     *    Resets the error state to no error.
62
     *    @access protected
63
     */
64
    function _clearError() {
65
        $this->_setError('');
66
    }
67
}
68
69
/**
70
 *    Wrapper for TCP/IP socket.
71
 *    @package SimpleTest
72
 *    @subpackage WebTester
73
 */
74
class SimpleSocket extends SimpleStickyError {
75
    var $_handle;
76
    var $_is_open = false;
77
    var $_sent = '';
78
    var $lock_size;
79
80
    /**
81
     *    Opens a socket for reading and writing.
82
     *    @param string $host          Hostname to send request to.
83
     *    @param integer $port         Port on remote machine to open.
84
     *    @param integer $timeout      Connection timeout in seconds.
85
     *    @param integer $block_size   Size of chunk to read.
86
     *    @access public
87
     */
88
    function SimpleSocket($host, $port, $timeout, $block_size = 255) {
89
        $this->SimpleStickyError();
90
        if (! ($this->_handle = $this->_openSocket($host, $port, $error_number, $error, $timeout))) {
91
            $this->_setError("Cannot open [$host:$port] with [$error] within [$timeout] seconds");
92
            return;
93
        }
94
        $this->_is_open = true;
95
        $this->_block_size = $block_size;
96
        SimpleTestCompatibility::setTimeout($this->_handle, $timeout);
97
    }
98
99
    /**
100
     *    Writes some data to the socket and saves alocal copy.
101
     *    @param string $message       String to send to socket.
102
     *    @return boolean              True if successful.
103
     *    @access public
104
     */
105
    function write($message) {
106
        if ($this->isError() || ! $this->isOpen()) {
107
            return false;
108
        }
109
        $count = fwrite($this->_handle, $message);
110
        if (! $count) {
111
            if ($count === false) {
112
                $this->_setError('Cannot write to socket');
113
                $this->close();
114
            }
115
            return false;
116
        }
117
        fflush($this->_handle);
118
        $this->_sent .= $message;
119
        return true;
120
    }
121
122
    /**
123
     *    Reads data from the socket. The error suppresion
124
     *    is a workaround for PHP4 always throwing a warning
125
     *    with a secure socket.
126
     *    @return integer/boolean           Incoming bytes. False
127
     *                                     on error.
128
     *    @access public
129
     */
130
    function read() {
131
        if ($this->isError() || ! $this->isOpen()) {
132
            return false;
133
        }
134
        $raw = @fread($this->_handle, $this->_block_size);
135
        if ($raw === false) {
136
            $this->_setError('Cannot read from socket');
137
            $this->close();
138
        }
139
        return $raw;
140
    }
141
142
    /**
143
     *    Accessor for socket open state.
144
     *    @return boolean           True if open.
145
     *    @access public
146
     */
147
    function isOpen() {
148
        return $this->_is_open;
149
    }
150
151
    /**
152
     *    Closes the socket preventing further reads.
153
     *    Cannot be reopened once closed.
154
     *    @return boolean           True if successful.
155
     *    @access public
156
     */
157
    function close() {
158
        $this->_is_open = false;
159
        return fclose($this->_handle);
160
    }
161
162
    /**
163
     *    Accessor for content so far.
164
     *    @return string        Bytes sent only.
165
     *    @access public
166
     */
167
    function getSent() {
168
        return $this->_sent;
169
    }
170
171
    /**
172
     *    Actually opens the low level socket.
173
     *    @param string $host          Host to connect to.
174
     *    @param integer $port         Port on host.
175
     *    @param integer $error_number Recipient of error code.
176
     *    @param string $error         Recipoent of error message.
177
     *    @param integer $timeout      Maximum time to wait for connection.
178
     *    @access protected
179
     */
180
    function _openSocket($host, $port, &$error_number, &$error, $timeout) {
181
        return @fsockopen($host, $port, $error_number, $error, $timeout);
182
    }
183
}
184
185
/**
186
 *    Wrapper for TCP/IP socket over TLS.
187
 *    @package SimpleTest
188
 *    @subpackage WebTester
189
 */
190
class SimpleSecureSocket extends SimpleSocket {
191
192
    /**
193
     *    Opens a secure socket for reading and writing.
194
     *    @param string $host      Hostname to send request to.
195
     *    @param integer $port     Port on remote machine to open.
196
     *    @param integer $timeout  Connection timeout in seconds.
197
     *    @access public
198
     */
199
    function SimpleSecureSocket($host, $port, $timeout) {
200
        $this->SimpleSocket($host, $port, $timeout);
201
    }
202
203
    /**
204
     *    Actually opens the low level socket.
205
     *    @param string $host          Host to connect to.
206
     *    @param integer $port         Port on host.
207
     *    @param integer $error_number Recipient of error code.
208
     *    @param string $error         Recipient of error message.
209
     *    @param integer $timeout      Maximum time to wait for connection.
210
     *    @access protected
211
     */
212
    function _openSocket($host, $port, &$error_number, &$error, $timeout) {
213
        return parent::_openSocket("tls://$host", $port, $error_number, $error, $timeout);
214
    }
215
}
216
?>
217