31 $port = $nextURI->getPort();
32 $scheme = $nextURI->getScheme();
35 $port = getservbyname($scheme,
'tcp');
37 if (!is_int($port) || $port <= 0 || $port > 65535) {
38 throw new \Erebot\InvalidValueException(
'Invalid port');
42 $this->
write(
"\x05\x02\x00\x02");
43 $line = $this->
read(2);
45 if ($line[0] !=
"\x05") {
46 throw new \Erebot\InvalidValueException(
'Bad SOCKS version');
49 switch (ord($line[1])) {
56 throw new \Erebot\InvalidValueException(
'No acceptable method');
60 $host = $nextURI->getHost();
63 pack(
"Ca*n", strlen($host), $host, $port)
66 $line = $this->
read(4);
67 if ($line[0] !=
"\x05") {
68 throw new \Erebot\InvalidValueException(
'Bad SOCKS version');
71 $error = ord($line[1]);
76 'General SOCKS server failure',
77 'Connection not allowed by ruleset',
78 'Network unreachable',
82 'Command not supported',
83 'Address type not supported',
85 if (!isset($errors[$error])) {
86 throw new \Erebot\InvalidValueException(
'Unknown error');
88 throw new \Erebot\InvalidValueException($errors[$error]);
91 switch (ord($line[3])) {
97 $len = ord($this->
read(1));
106 throw new \Erebot\InvalidValueException(
107 'Address type not supported' 125 $username = $proxyURI->asParsedURL(PHP_URL_USER);
126 $password = $proxyURI->asParsedURL(PHP_URL_PASS);
128 if ($username === null || $password === null) {
129 throw new \Erebot\InvalidValueException(
130 'No username or password supplied' 134 $ulen = strlen($username);
135 $plen = strlen($password);
137 throw new \Erebot\InvalidValueException(
138 'Username too long (max. 255)' 143 throw new \Erebot\InvalidValueException(
144 'Password too long (max. 255)' 157 $line = $this->
read(2);
159 if ($line[0] !=
"\x01") {
160 throw new \Erebot\InvalidValueException(
161 'Bad subnegociation version' 165 if ($line[1] !=
"\x00") {
166 throw new \Erebot\InvalidValueException(
'Bad username or password');
183 for ($written = 0, $len = strlen($line); $written < $len; $written += $fwrite) {
184 $fwrite = fwrite($this->socket, substr($line, $written));
185 if ($fwrite ===
false) {
186 throw new \Erebot\Exception(
'Connection closed by proxy');
205 while (!feof($this->socket) && $clen < $len) {
206 $read = fread($this->socket, $len - $clen);
207 if ($read ===
false) {
208 throw new \Erebot\Exception(
'Connection closed by proxy');
211 $clen = strlen($contents);
Interface for a Uniform Resource Identifier parser/generator compatible with RFC 3986.
userpass(\Erebot\URIInterface $proxyURI)
Base class for a proxy client.
Proxies data through a SOCKS 5 proxy.