Файл: DESURE-dcms-f12de01ac63e/sys/plugins/classes/http_client.class.php
Строк: 290
<?php
/**
* Своя реализация работы по HTTP протоколу (аналог cUrl)
* Умеет отправлять GET, POST, COOKIE, FILES
* Также можно задать Referer, User-Agent
* Можно работать через прокси (HTTP, SOCKS4, SOCKS5)
*/
class http_client
{
public $ua = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.83 Safari/535.11';
public $timeout = 20; // таймаут запроса (сек)
public $referer = '';
public $accept = '*/*';
public $accept_encoding = 'identity';
public $accept_charset = 'windows-1251,utf-8;q=0.7,*;q=0.3';
public $accept_language = 'ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4';
protected $_url;
protected $_post = array(); // массив с POST
protected $_cookie = array(); // массив с COOKIE
protected $_files = array(); //
protected $_sock = null;
protected $_http_proxy = false; // HTTP прокси
protected $_socks_proxy = false; // SOCKS прокси
protected $_boundary = false; // разделитель для отправляемых данных
public $errn;
public $errs;
/**
* @param string|url $url
*/
function __construct($url)
{
if ($url instanceof url) {
$url = $url->getUrl();
}
$this->_url = $url;
$this->dataReset();
}
/**
* Сброс всех данных для запроса
*/
public function dataReset()
{
$this->_boundary = passgen();
$this->_post = array();
$this->_cookie = array();
$this->_sock = null;
$this->errn = '';
$this->errs = '';
}
/**
* Подключение к сокету хоста или прокси сервера
* @return boolean
*/
protected function _connect()
{
if ($this->_http_proxy) {
$purl = @parse_url($this->_http_proxy);
} else {
$purl = @parse_url($this->_url);
}
if (!empty($purl['host'])) {
$port = empty($purl['port']) ? 80 : $purl['port'];
if (empty($purl['scheme'])) {
$scheme = '';
} elseif ($purl['scheme'] == 'https') {
$scheme = 'ssl://';
$port = '443';
} else {
$scheme = '';
}
if ($this->_socks_proxy) {
$spurl = @parse_url($this->_socks_proxy);
$sport = empty($spurl['port']) ? 9050 : $spurl['port'];
if (!$this->_sock = @fsockopen('tcp://' . $spurl['host'], $sport, $this->errn, $this->errs,
$this->timeout)
) {
misc::log($spurl['host'] . ' (Прокси-сервер) - Не удалось подключиться', 'http_client');
} else {
$packet = "x05x01x00";
fwrite($this->_sock, $packet, strlen($packet));
$response = fread($this->_sock, 3);
fwrite($this->_sock,
"x05x01x00x03" . chr(strlen($purl['host'])) . $purl['host'] . pack("n", $port));
$response = fread($this->_sock, 2048);
if (ord($response[0]) == 5) {
$status = ord($response[1]);
if ($status != 0) {
misc::log($spurl['host'] . ' (Прокси-сервер) - Не удалось подключиться', 'http_client');
return false;
} else {
misc::log($spurl['host'] . ' (Прокси-сервер) - Успешно подключились', 'http_client');
return true;
}
} else {
misc::log($spurl['host'] . ' (Прокси-сервер) - Не удалось подключиться', 'http_client');
return false;
}
}
}
if (!$this->_sock = @fsockopen($scheme . $purl['host'], $port, $this->errn, $this->errs, $this->timeout)) {
misc::log($scheme . $purl['host'] . ($this->_http_proxy ? ' (Прокси-сервер)' : '') . ' - Не удалось подключиться',
'http_client');
return false;
} else {
stream_set_timeout($this->_sock, $this->timeout);
misc::log($scheme . $purl['host'] . ($this->_http_proxy ? ' (Прокси-сервер)' : '') . ' - Успешно подключились',
'http_client');
return true;
}
}
}
/**
* Закрытие подключения
*/
protected function _disconnect()
{
fclose($this->_sock);
misc::log('Сокет закрыт', 'http_client');
}
/**
* Установка прокси-сервера
* @param string $proxy Адрес прокси
* @param boolean $socks используется socks
*/
public function set_proxy($proxy, $socks = true)
{
if ($proxy === false) {
$this->_http_proxy = false;
$this->_socks_proxy = false;
}
if ($socks) {
$this->_socks_proxy = $proxy;
} else {
$this->_http_proxy = $proxy;
}
}
/**
* Установка POST переменной
* @param string $name Имя
* @param string $value Значение
*/
public function set_post($name, $value = '')
{
$this->_post[$name] = $value;
}
/**
* Установка COOKIE
* @param string $name Имя
* @param string $value Значение
*/
public function set_cookie($name, $value = null)
{
$this->_cookie[] = urlencode($name) . '=' . urlencode($value);
}
/**
* Прикрепление файла для отправки
* @param string $name Имя поля, в котором будет передаваться файл
* @param string $path Путь к файлу на сервере
* @param boolean $filename Имя файла
* @return boolean
*/
public function set_file($name, $path, $filename = false)
{
if (!$content = @file_get_contents($path)) {
return false;
}
if ($filename === false) {
$filename = basename($path);
}
$this->_files[$name] = array('name' => $filename, 'content' => $content);
return true;
}
/**
* Сохранение полученных данных в файл
* @param string $file_path путь к файлу на сервере
* @param int $max_size максимальный размер принимаемых данных
* @return boolean
*/
public function save_content($file_path, $max_size = 0)
{
misc::log('Запрос на сохранение файла (' . $this->_url . ')', 'http_client');
if (!$fo = @fopen($file_path, 'wb')) {
@unlink($file_path);
misc::log('Не удалось открыть указатель ресурса', 'http_client');
return false;
}
if (!$this->_connect()) {
@unlink($file_path);
misc::log('Соединение разорвано', 'http_client');
return false;
}
fputs($this->_sock, $this->getOutputHeaders());
$headers = '';
while (!feof($this->_sock)) {
$data = fgets($this->_sock, 2048);
if ($data == "rn") {
break;
}
$headers .= $data;
}
$saved = 0;
while (!feof($this->_sock)) {
if ($data = fgets($this->_sock, 4096)) {
$saved += strlen($data);
if ($max_size && $saved > $max_size) {
@unlink($file_path);
misc::log('Превышено ограничение на длину скачиваемого файла', 'http_client');
return false;
}
if (!@fwrite($fo, $data)) {
@unlink($file_path);
misc::log('Не удалось сохранить файл', 'http_client');
return false;
}
}
}
$size = filesize($file_path);
if ($size) {
misc::log('Файл успешно получен и сохранен ' . misc::getDataCapacity($size), 'http_client');
} else {
misc::log('Получен файл с нулевым размером', 'http_client');
}
fclose($fo);
$this->_disconnect();
return (bool)$size;
}
/**
* Получение имени файла из ответа
* @return string
*/
public function getFileName()
{
$headers = $this->get_headers();
if ($headers) {
if (preg_match('/Content-Disposition: .*filename=([^ nr]+)/i', $headers, $m)) {
return $m[1];
}
}
$path = @parse_url($this->_url);
return basename($path['path']);
}
/**
* Получение заголовков ответа
* @return string
*/
public function getHeaders()
{
return $this->get_headers();
}
/**
* Получение содержимого ответа
* @param boolean $with_headers включать заголовки
* @return string
*/
public function getContent($with_headers = false)
{
return $this->get_content($with_headers);
}
/**
* Получение содержимого ответа
* @param boolean $with_headers включать заголовки
* @return string
*/
public function get_content($with_headers = false)
{
misc::log('Запрос на получение контента (' . $this->_url . ')', 'http_client');
if (!$this->_connect()) {
misc::log('Соединение разорвано', 'http_client');
return false;
}
$output_headers = $this->getOutputHeaders();
fputs($this->_sock, $output_headers, strlen($output_headers));
$headers = '';
while (!feof($this->_sock)) {
$data = fgets($this->_sock, 2048);
if ($data == "rn") {
break;
}
$headers .= $data;
}
if ($with_headers) {
$content = $headers . "rn";
} else {
$content = '';
}
while (!feof($this->_sock)) {
if ($data = fgets($this->_sock, 4096)) {
$content .= $data;
}
}
misc::log('Контент успешно получен (' . misc::getDataCapacity(strlen($content)) . ')', 'http_client');
$this->_disconnect();
return $content;
}
/**
* Получение заголовков ответа
* @return string
*/
public function get_headers()
{
misc::log('Запрос на получение заголовков (' . $this->_url . ')', 'http_client');
if (!$this->_connect()) {
misc::log('Соединение разорвано', 'http_client');
return false;
}
$output_headers = $this->getOutputHeaders();
fputs($this->_sock, $output_headers, strlen($output_headers));
$headers = '';
while (!feof($this->_sock)) {
$data = fgets($this->_sock, 2048);
if ($data == "rn") {
break;
}
$headers .= $data;
}
misc::log('Заголовки успешно получены', 'http_client');
$this->_disconnect();
return $headers;
}
/**
* формирование данных для multipart/form-data
* @return string
*/
protected function _multipart()
{
$data = array();
if ($this->_post) {
foreach ($this->_post as $key => $value) {
$data[] = "--{$this->_boundary}rnContent-Disposition: form-data; name='" . urlencode($key) . "'rnrn$value";
}
}
if ($this->_files) {
foreach ($this->_files as $name => $value) {
$data[] = "--{$this->_boundary}rnContent-Disposition: form-data; name="" . urlencode($name) . ""; filename="" . urlencode($value['name']) . ""rnContent-Type: " . files_types::get_mime($value['name']) . "rnContent-Transfer-Encoding: binaryrnrn{$value['content']}";
}
}
return implode("rn", $data) . "rn--{$this->_boundary}--rn";
}
/**
* Получение заголовков запроса
* @return string
*/
function getOutputHeaders()
{
$headers = array();
$purl = @parse_url($this->_url);
$scheme = empty($purl['scheme']) ? 'http' : $purl['scheme'];
$host = empty($purl['host']) ? '' : $purl['host'];
if ($this->_http_proxy) $path = $scheme . '://' . $host . (empty($purl['path']) ? '/' : $purl['path']);
else $path = empty($purl['path']) ? '/' : $purl['path'];
$query = empty($purl['query']) ? '' : '?' . $purl['query'];
$headers[] = ($this->_post ? 'POST' : 'GET') . ' ' . $path . $query . ' HTTP/1.0';
$headers[] = 'Host: ' . $host;
if ($this->accept) $headers[] = 'Accept: ' . $this->accept;
if ($this->accept_charset) $headers[] = 'Accept-Charset: ' . $this->accept_charset;
if ($this->accept_encoding) $headers[] = 'Accept-Encoding: ' . $this->accept_encoding;
if ($this->accept_language) $headers[] = 'Accept-Language: ' . $this->accept_language;
if ($this->referer) $headers[] = 'Referer: ' . $this->referer;
if ($this->_cookie) $headers[] = 'Cookie: ' . implode(';', $this->_cookie);
if ($this->ua) $headers[] = 'User-Agent: ' . $this->ua;
if ($this->_files || $this->_post) {
$post_data = $this->_multipart();
$headers[] = 'Content-Type: multipart/form-data; boundary=' . $this->_boundary;
$headers[] = 'Content-Length: ' . strlen($post_data);
}
if (isset($purl['user']) && isset($purl['pass']))
$headers[] = 'Authorization: Basic ' . base64_encode($purl['user'] . ':' . $purl['pass']);
$headers[] = 'Connection: Close';
$header = implode("rn", $headers) . "rnrn";
if (!empty($post_data)) $header .= $post_data;
return $header;
}
}