http://sulfurzona.com/
News
Service
Magazine
Software (Battle City Game, Wallpaper manager, Superpad, VG-NOW, Puzzle Game, Netler Internet Browser, ..)
Dune Game (Dune III, Dune IV, Cheats, Forum, ..)
Games free
Turbo Pascal (Assembler, Docs, Sources, Debbugers, ..)
Books (Docs for developers)
Forum
Guest book
Компьютерная диагностика двигателя автомобиля (адаптер К-линии)Компьютерная диагностика двигателя автомобиля (адаптер К-линии)
 
 
 

PHP и WEB для новичков: proxy пишем сами

 
Все больше у нас в Украине набирает популярности файлообменник EX.UA, на котором можно выкладывать различные файлы для скачивания пользователями сети.
 
Вот и мне по роду моей деятельности приходится скачивать оттуда рабочие материалы, которые из-за их большого объема мои коллеги не могут прислать по электронной почте.
 
Находясь в Киеве, скачать что угодно с этого ресурса не представляет особого труда, поскольку ресурс очень удобный, обладает поисковой машиной и предлагает скачать файлы либо напрямую, либо как торрент-раздачу.
 
Но так уж сложилось, что мне часто приходится бывать в Москве и, находясь там длительное время, скачать что-то с EX.UA не представляется возможным, потому что посетители с IP-адресами не принадлежащими UA-IX (http://ru.wikipedia.org/wiki/UA-IX) не допускаются к поисковой службе и даже по прямым ссылкам на страницы.
 
Решить проблему обмена большими файлами можно при помощи других файлообменников либо FTP на своём или офисном хостинге. Но все эти способы годятся для обычных пользователей, а мы с вами программисты и не привыкли идти обычным путем, т.е. по наименьшему сопротивлению.
 
Ведь девиз большинства программистов звучит примерно как: “Лучше потратить час на написание программы, которая будет за тебя выполнять работу, чем самому делать это вручную всю жизнь”.
 
Вот и я подумал, что отучить офисных дам от уже привычного для них EX.UA будет сложно, а приучить их работать с FTP практически невозможно. Думаю, что автор выражения “офисный планктон” по-своему прав. Среди женского офисного персонала у нас ещё мало личностей, умеющих не только включать компьютер, но и пользоваться им на все 100%.
 
Только не подумайте, что я страдаю мужским шовинизмом. У меня душа радуется и наполняется гордостью за тех моих знакомых девушек, которые и HTML знают, и умело пользуются админкой сайта с его WYSIWYG-редактором (http://ru.wikipedia.org/wiki/WYSIWYG) и даже пытаются корректировать JavaScript-код или во всю ставят и настраивают сайты на Joomla.
 
Но девушки, не желающие совершенствоваться в том, что им необходимо по работе, упорно проявляющие свою компьютерную безграмотность меня просто обескураживают. Да что и говорить, и среди парней таких личностей встречается не мало. Ну да я отвлекся.
 

Что такое PROXY?

Если кратко, то это своего рода посредник между пользователем и сетевым ресурсом. Часто прокси используют для ускорения просмотра веб-страниц или чтобы обезопасить себя от сайтов, тем или иным образом собирающих информацию о посетителе. Такие прокси ещё называют анонимайзерами (http://ru.wikipedia.org/wiki/Анонимайзер).
 
В таком случае прокси позволяет не только спрятать истинный IP-адрес компьютера пользователя, таким образом, скрыв его истинное местоположение, но и подставить заведомо ложную информацию, например, о его браузере, не говоря уже об элементарной защите от взлома ПК посредством специальных пакетов-троянов, если сайт из разряда неблагонадежных.
 
Собственно более подробно о прокси можно прочесть на странице http://ru.wikipedia.org/wiki/Прокси-сервер.
 

Какие ставились задачи

Вот мне и пришлось написать такой анонимайзер, разместив его на своем украинском хостинге. Это позволило мне посещать ресурс EX.UA, просматривать его странички и скачивать с него файлы, находясь в далекой Москве, поскольку посредником между моим компьютером и ресурсом EX.UA стал прокси на моем хостинге, имеющем украинский IP-адрес.
Перед мной стояли следующие задачи:
1) просмотр веб-страниц, защищенных IP-фильтром;
2) навигационная панель должна быть всегда видна, независимо от просматриваемой страницы;
3) не давать сайту выходить из-под контроля анонимайзера при клике на  ссылки;
4) давать скачивать файлы.
 

Начнем

Как показала практика, первые три задачи в реализации довольно просты. Навигационную панель нашего прокси можно было бы сделать при помощи фрейма (HTML-тег <frame>). Это было бы проще намного.
 
Но, поскольку многие уважающие себя сайты сделаны добросовестно с защитой от Clickjacking (http://ru.wikipedia.org/wiki/Кликджекинг), и способны выбраться из фрейма в топ документа, то я решил применить JavaScript-иньекцию, которая позволяет контролировать веб-страницу и ее ссылки, и не выпускать их из-под контроля. Это как раз обеспечит то, что наша навигационная панель будет всегда с нами ;)
 
Например, на нашем подопытном сайте WWW.EX.UA, с которого, собственно, будем пытаться просматривать странички и качать файлы, чтобы выбраться из фрейма используют следующий код, написанный на JavaScript:
 
<script type='text/javascript'>
if (window.top != window.self) window.top.location = window.self.location;
</script>
 
PHP и WEB для новичков: proxy пишем сами
Рис. 1. Все-таки нам удалось ;)
 
Просто и эффективно, но мы это обойдем. Как можно видеть на рис. 1, вверху страницы маячит наша навигационная панель ;)
Увы, если на странице есть форма, например, форма поиска, то при отправке данных из такой формы страница выберется из нашего окружения и наш прокси уже будет над ней не властен. Поэтому решение данной задачи оставляю вам вместо домашнего задания.
Итак, будем идти по порядку.
 

Шаблон навигационной панели

Давайте заранее приготовим HTML-код нашей панели навигации, чтобы затем вставить ее в соответствующее место просматриваемой веб-страницы. PHP-код следующий:
 
<?
ob_start();
// Код навигационной формы
?>
<div style="width: 100%; height: 26px; background-color: #F88;">
<form id="url_form" method="get" style="margin: 0px">
<TABLE cellSpacing="0" cellPadding="1" border="0">
 <TR>
  <TD align="right" style="color: #fff;"><b>URL:</b></TD>
  <TD><input name="site" id="site" type="text" style="width: 500px" value=""></TD>
  <TD align="right"><input type="submit" value="GO =>"></TD>
 </TR>
</TABLE>
</form>
</div>
<?
   $panel = ob_get_contents();
   ob_end_clean();
?>
 
Здесь командой ob_start начинаем буферизацию вывода, затем идет HTML-код нашей панели, а потом результат вывода получаем в переменную $panel и командой ob_end_clean очищаем буфер вывода и отключаем буферизацию вывода. В результате переменная $panel будет содержать текст с HTML-кодом нашей навигационной панели.
 

Получение и просмотр веб-страницы

Поскольку форма нашей панели передает данные адреса просматриваемой веб-страницы методом GET, то проверяем, был ли получен параметр site в массиве $_GET. Если такой параметр присутствует и длина строки в нем больше нуля, то параметр не пустой и приступаем к загрузке и разбору страницы:
 
if (isset($_GET["site"]) and (strlen($_GET["site"])>0)) {
     $asite = $_GET["site"];
     // Выделяем домен сайта без "http://"
     $asite = 'http://'.str_replace( 'http://', '', $asite);
 
     // Загружаем страницу с указанного адреса
     $html = file_get_contents($asite);
 
     // Устанавливаем базовый URL
     $html = str_replace( '<head>', '<head><base href="'.$asite.'">', $html);
 
     // Избавляемся от конца веб-страницы
     $html = str_replace( '</html>', '', $html);
 
 
 
 
     $html = str_replace( '</body>', '', $html);
 
     // Ищем тег BODY, чтобы после него вставить нашу навигационную форму
     $k = strpos($html,'<body');
     if (!$k) $k = strpos($html,'<BODY');
     
     if ($k) {
         $tmp = substr( $html, 0, $k );
         $html = substr( $html, $k, strlen($html) );
         $k = strpos($html,'>');
         $tmp .= substr( $html, 0, $k+1 ).$panel.substr( $html, $k+1, strlen($html) );
         $html = $tmp;
        }
        else // Если тег BODY не найден, то ищем HEAD и корректируем веб-страницу
             $html = str_replace( '</head>', '</head><body>'.$panel, $html);
     echo $html;
    }
    else echo $panel;
 
В данном PHP-коде сначала корректируем адрес сайта в $asite, чтобы он всегда был с префиксом. Если пользователь укажет его без префикса http://, то адрес будет исправлен. А если префикс уже окажется там, то на всякий случай его вырезаем из адреса, чтобы не получилось в нем двух префиксов.
 
При помощи команды file_get_contents получаем текст HTML-кода веб-страницы в переменную $html. Вслед за этим ищем в коде страницы тег <HEAD> и заменяем его на такой же, но с тегом BASE, чтобы все ресурсы (картинки, ссылки, JS-скрипты) страницы загружались и работали правильно.
 
Это необходимо сделать, поскольку практически всегда веб-страницы содержат не прямые, а относительные ссылки на собственные ресурсы. У нас ведь в прокси страница будет загружаться в браузер с адреса прокси, а ресурсы, необходимые для корректного отображения веб-страницы, находятся на ее домашнем сервере.
Далее удаляем из кода страницы замыкающие теги BODY и HTML, поскольку нам в конец этой страницы предстоит сделать инъекцию ;). После этого ищем открывающий тег BODY, написанный либо строчными, либо прописными буквами.
 
Все, что до этого тега копируем в переменную $tmp, а вторую часть страницы в переменную $html. Затем в этой части ищем первый попавшийся знак “>” – он же замыкающий для тега BODY, поскольку в этом теге могут быть какие-то важные для верстки страницы параметры. После чего в переменной $tmp собираем весь код веб-страницы, но уже с нашей навигационной панелью.
 
Если по каким-то причинам тег BODY в странице отсутствует, то ищем закрывающий тег HEAD и корректируем страницу так, чтобы в ней был тег BODY, затем шла бы наша панель. Ведь в конце нашего PHP-скрипта мы всё равно будем закрывать страницу тегами </BODY> и </HTML>.
 
Когда все необходимые действия выполнены, командой echo $html выводим содержимое переменной $html в браузер пользователя. Если никаких параметров пользователь нашему проксику не передавал, то просто выводим навигационную панель в ветви else echo $panel.
Замыкает вывод в браузер пользователя наша JavaScript-инъекция:
 
<script>
function CatchClick( url ) {
 var d = document.getElementById("site");
 d.value = url;
 var d2 = document.getElementById("url_form");
 d2.submit();
}
 
document.body.style.margin = 0;
// Все ссылки внутри объекта links
var links = document.getElementsByTagName("a");
// Перебираем ссылки и ставим ловушку и очищаем таргетинг
for (i = 0; i < links.length; i ++) {
      links[i].href = 'javascript:CatchClick('' + links[i].href + '');';
      links[i].target = '';
     }
</script>
</body>
</html>
 
Данная инъекция представляет собой обыкновенный JavaScript, где сначала объявляется функция CatchClick, которая будет вызываться при клике на любой ссылке страницы. Затем для тела страницы устанавливается нулевой внешний отступ (margin), чтобы наша панель плотно встала к границе окна браузера.
 
Потом в переменную links получаем список всех ссылок документа, перебираем их в цикле и переназначаем для каждой оригинальную ссылку на вызов нашей функции CatchClick и очищаем таргетинг, чтобы новый документ по ссылке открывался не в новом окне браузера, а в текущем.
 

Подытожим

У нас получился прокси, позволяющий просматривать веб-странички, но не способный скачивать файлы – объем журнальной статьи не позволяет рассказать еще и об этом. Это можете попробовать сделать сами. Маленькая подсказка: читайте документацию по библиотеке CURL (http://htmlweb.ru/php/php_curl.php).
 
Добавлю, что данный прокси очень прост и не обеспечивает защиты ПК пользователя от всяких нехороших JavaScript’ов. К тому же, если кто-то из вас захочет, используя данный прокси, “накручивать” посещаемость своего сайта, либо кликабельность объявлений Google AdSense, то я вас разочарую.
 
Несмотря на то, что прокси подгружает веб-страницу сам, используя сервер хостинга, тем не менее, все остальные ресурсы страницы подгружает уже браузер пользователя. В том числе и JS-скрипты гугла и рейтинговых счетчиков.
 
А уж их серверы способны узнать IP-адрес пользователя, поскольку соединяются с браузером напрямую. К тому же следующий простенький пример, если открыть его в нашем прокси, сначала в части PHP определит нас как ПК с IP сервера нашего хостинг-провайдера, и наш браузер как “Agent: PHP/5.2.17”, но JavaScript, который выполнится уже в браузере, определит его безошибочно (рис. 2).
 
PHP и WEB для новичков: proxy пишем сами
Рис. 2. Никуда не скрыться
 
<html>
<?
 echo "<BR>IP: ".$_SERVER['REMOTE_ADDR'];
 echo "<BR>Agent: ".$_SERVER['HTTP_USER_AGENT'];
?>
<script>
alert('Agent: ' + navigator.userAgent + ' Host: ' + window.location.host);
</script>
</html>
 
Собственно задачи обеспечения безопасности я перед собой и не ставил. Мне просто необходимо было открывать странички и скачивать файлы. Этого я добился. Удавалось скачать файлы даже размером более 600 Мб.
 

Подсказки для скачивания файлов

Еще подскажу, что для скачивания большого файла скрипту понадобится работать до тех пор, пока файл не будет полностью передан. А в случае сотен мегабайт это время может занять многие минуты, а не 30 секунд, которые по умолчанию отводятся каждому скрипту на выполнение сервером Apache.
 
Поэтому в самом начале скрипта вашего прокси не забудьте отключить ограничение времени выполнения скрипта следующим PHP-кодом:
 
// Отключаем ограничение времени выполнения скрипта
error_reporting(2047);
@set_time_limit(0);
@ini_set('max_execution_time',0);
@ini_set('output_buffering',0);
 
ну а когда ваш скрипт будет способен определить, что запрашиваемый пользователем адрес ведет не на веб-страницу, а на файл, то вам пригодится следующий PHP-код:
 
// Это не веб-страница, это, вероятно, файл, качаем и выдаем его пользователю
header('Content-type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$filename.'"');
readfile('http://'.$asite);
exit;
 
Ну вот. Вам лишь остается добавить недостающие участки этой “мозаики”.
 
© Владислав Демьянишин
 
 
На нашем сайте можно не только бесплатно скачать игры, но и документацию и книги по программированию на MIDLetPascal, Turbo Pascal 6, Turbo Pascal 7, Borland Pascal, по программированию устройств Sound Blaster, Adlib, VESA BIOS, справочник Norton Guide и много другой полезной информации для программистов, включая примеры решения реальных задач по созданию резидентных программ. Предлагаю также посетить Марья искусница - сайт о рукоделии (http://mariya-iskusnica.ru).
 

Журнал > Программирование > PHP и WEB для новичков (HTML, JavaScript, PHP, MySQL) > PHP и WEB для новичков: proxy пишем сами
 
 
 
189
 
ВКонтакте
Facebook
 
 
 
На главную страницу На предыдущую страницу На начало страницы
 
 
Украинский портАл Украина онлайн Рейтинг@Mail.ru Рейтинг Сайтов YandeG Rambler's Top100