• Руслан
  • 04 Фев 2009
  • Рубрика: PHP

Соединение с прокси-сервером через сокеты.

В веб-программировании при написании различных парсеров, граберов часто стоит задача скрыть настоящий адрес для того чтобы избежать ограничений, которые устанавливаются на количество запросов с одного ip адреса. Это легко достигается при использовании прокси-серверов. В сегодняшнем посте я покажу пример, как можно установить соединение с прокси-сервером из php-скрипта и передать http запрос используя сокеты. Это одновременно самый гибкий, но и самый сложный способ, который требует понимания протокола HTTP.

Итак, для начала потребуется настроенный веб-сервер с модулем mod_php, текстовый редактор и список хотя бы из одного рабочего прокси-сервера. Далее в тексте скрипта я использовал в качестве примера 203.178.133.10:3124. На момент написания статьи это был полностью рабочий прокси-сервер, но обещать что он останется таковым и впредь я, конечно, не могу. Свежий список рабочих прокси-серверов легко находится в гугле по запросу ‘free proxy list’.

Поскольку соединение будет устанавливаться через сокет, также потребуется минимум знаний о http-запросах. В данном случае http-запрос будет создан такими двумя строчками:

$http_request = ‘HEAD http://www.google.com/favicon.ico HTTP/1.1′ . “\r\n”;
$http_request .= ‘Host: www.google.com’ . “\r\n\r\n”;

Первая строка начинается с команды HEAD. Это значит что сервер в ответ на запрос отдаст не содержимое файла favicon.ico, а только http заголовки. Так как сейчас не ставится задача получить весь файл, этого будет вполне достаточно. Мы получим ответ, который говорит о том что файл на месте, убедимся в том что передача запросов через этот конкретный прокси работает и сэкономим целый килобайт данных за счет того, что сам файл передаваться не будет ;)

После команды HEAD пишем полный адрес файла, который мы будем запрашивать, версию протокола (просто оставьте без изменений) и два символа – переход на новую строку.

Вторая строка содержит имя хоста. И переход на новую строку два раза. Передача запроса по http должна обязательно закончиться передачей пустой строки, иначе веб-сервер будет считать, что запрос еще не закончен!!!

Теперь открываем текстовый редактор и копируем туда такой скрипт:

$proxyhost = '203.178.133.10';
$proxyport = 3124;
 
$http_request = 'HEAD http://www.google.com/favicon.ico HTTP/1.1' . "\r\n";
$http_request .= 'Host: www.google.com' . "\r\n\r\n";
 
$fp = fsockopen($proxyhost, $proxyport);
 
if ($fp) {
  //передаем запрос
  fwrite($fp,$http_request);
  //и читаем ответ
  while (!feof($fp)) {
    $http_response = fgets($fp, 1024);
    //в полученных строках находим код ответа
    if (preg_match('/^HTTP\/1\.\d (\d+) (.*)/', $http_response, $found)) {
      $response_code = $found[1];
      $response_text = $found[2];
      break;
    }
  }
 }
 else {
   echo 'Или нет соединения с интернет, или прокси-сервер не рабочий. ';
 }
 
if ($response_code == 200) {
  echo 'Передача закончилась успешно.';
 }

Функция fsockopen() устанавливает соединение с прокси-сервером, и в случае успеха возвращает указатель с которым мы можем дальше работать как с обычным указателем на файл. Для отправки данных используется fwrite(). Ответ сервера читаем построчно через функцию fgets(). В этом случае нам достаточно найти в ответе строку вида ‘HTTP/1.0 код_ответа текст_ответа’. Код и текст ответа извлекаем при помощи регулярного выражения и сохраняем в отдельных переменных. В конце проверяем код ответа – если он равен 200, значит запрос был успешным.

Если вам понравился этот сайт, вы можете подписаться на rss

Отзывы: 6 комментариев

  • ёклмн
    07 Апр 2009 в 19:04

    Читал про это уже на каком то другом сайте, но у вас намного интересней написано ;)

  • admin
    09 Апр 2009 в 23:36

    Спасибо :)

  • O_O
    24 Сен 2009 в 6:19

    офигеть… всё так просто….

  • Evgeniy
    17 Янв 2010 в 22:06

    Не:
    if ($response_code = 200) {
    echo ‘Передача закончилась успешно.’;
    }
    а,
    if ($response_code == 200) {
    echo ‘Передача закончилась успешно.’;
    }

  • Evgeniy
    17 Янв 2010 в 22:10

    Научись хоть без простейших ошибок писать код

  • Павел
    01 Март 2010 в 16:07

    А в чём смысл данной статьи? авторизация на прокси то не указано как производиться…

Ваш отзыв

Имя (*)

E-mail (*)

Сайт

Сообщение