/** * Reads a part of response body encoded with chunked Transfer-Encoding * * @param int $bufferSize buffer size to use for reading * * @return string * @throws HTTP_Request2_MessageException */ protected function readChunked($bufferSize) { // at start of the next chunk? if (0 == $this->chunkLength) { $line = $this->socket->readLine($bufferSize); if ('' === $line && $this->socket->eof()) { $this->chunkLength = -1; // indicate missing chunk return ''; } elseif (!preg_match('/^([0-9a-f]+)/i', $line, $matches)) { throw new HTTP_Request2_MessageException("Cannot decode chunked response, invalid chunk length '{$line}'", HTTP_Request2_Exception::DECODE_ERROR); } else { $this->chunkLength = hexdec($matches[1]); // Chunk with zero length indicates the end if (0 == $this->chunkLength) { $this->socket->readLine($bufferSize); return ''; } } } $data = $this->socket->read(min($this->chunkLength, $bufferSize)); $this->chunkLength -= strlen($data); if (0 == $this->chunkLength) { $this->socket->readLine($bufferSize); // Trailing CRLF } return $data; }
/** * Constructor, tries to connect and authenticate to a SOCKS5 proxy * * @param string $address Proxy address, e.g. 'tcp://localhost:1080' * @param int $timeout Connection timeout (seconds) * @param array $contextOptions Stream context options * @param string $username Proxy user name * @param string $password Proxy password * * @throws HTTP_Request2_LogicException * @throws HTTP_Request2_ConnectionException * @throws HTTP_Request2_MessageException */ public function __construct($address, $timeout = 10, array $contextOptions = array(), $username = null, $password = null) { parent::__construct($address, $timeout, $contextOptions); if (strlen($username)) { $request = pack('C4', 5, 2, 0, 2); } else { $request = pack('C3', 5, 1, 0); } $this->write($request); $response = unpack('Cversion/Cmethod', $this->read(3)); if (5 != $response['version']) { throw new HTTP_Request2_MessageException('Invalid version received from SOCKS5 proxy: ' . $response['version'], HTTP_Request2_Exception::MALFORMED_RESPONSE); } switch ($response['method']) { case 2: $this->performAuthentication($username, $password); case 0: break; default: throw new HTTP_Request2_ConnectionException("Connection rejected by proxy due to unsupported auth method"); } }