21 namespace Erebot\Proxy;
27 class HTTP extends \Erebot\Proxy\Base
29 public function proxify(\Erebot\URIInterface $proxyURI, \Erebot\URIInterface $nextURI)
31 $credentials = $proxyURI->getUserInfo();
32 $host = $nextURI->getHost();
33 $port = $nextURI->getPort();
34 $scheme = $nextURI->getScheme();
37 $port = getservbyname($scheme,
'tcp');
39 if (!is_int($port) || $port <= 0 || $port > 65535) {
40 throw new \Erebot\InvalidValueException(
'Invalid port');
44 $request .= sprintf(
"CONNECT %s:%d HTTP/1.0\r\n", $host, $port);
45 $request .= sprintf(
"Host: %s:%d\r\n", $host, $port);
46 $request .=
"User-Agent: Erebot/dev-master\r\n";
48 if ($credentials !== null) {
50 "Proxy-Authorization: basic %s\r\n",
51 base64_encode($credentials)
56 for ($written = 0, $len = strlen($request); $written < $len; $written += $fwrite) {
57 $fwrite = fwrite($this->_socket, substr($request, $written));
58 if ($fwrite ===
false) {
59 throw new \Erebot\Exception(
'Connection closed by proxy');
63 $line = stream_get_line($this->_socket, 4096,
"\r\n");
64 if ($line ===
false) {
65 throw new \Erebot\InvalidValueException(
66 'Invalid response from proxy'
70 $this->_logger->debug(
72 array(
'line' => addcslashes($line,
"\000..\037"))
74 $contents = array_filter(explode(
" ", $line));
76 switch ((
int) $contents[1]) {
80 throw new \Erebot\Exception(
'Proxy authentication required');
82 throw new \Erebot\Exception(
'Connection rejected by proxy');
88 for ($i = 0; $i < $max; $i++) {
89 $line = stream_get_line($this->_socket, 4096,
"\r\n");
90 if ($line ===
false) {
91 throw new \Erebot\InvalidValueException(
92 'Invalid response from proxy'
98 $this->_logger->debug(
100 array(
'line' => addcslashes($line,
"\000..\037"))
104 throw new \Erebot\InvalidValueException(
105 'Endless loop detected in proxy response'
Proxies data through an HTTP proxy.